Lines Matching full:ale

30 /* ALE Registers */
41 /* ALE NetCP NU switch specific Registers */
54 * struct ale_entry_fld - The ALE tbl entry field description
73 * struct ale_dev_id - The ALE version/SoC specific configuration
74 * @dev_id: ALE version/SoC id
75 * @features: features supported by ALE
76 * @tbl_entries: number of ALE entries
77 * @major_ver_mask: mask of ALE Major Version Value in ALE_IDVER reg.
78 * @nu_switch_ale: NU Switch ALE
79 * @vlan_entry_tbl: ALE vlan entry fields description tbl
215 static int cpsw_ale_entry_get_fld(struct cpsw_ale *ale, in cpsw_ale_entry_get_fld() argument
223 if (!ale || !ale_entry) in cpsw_ale_entry_get_fld()
228 dev_err(ale->params.dev, "get: wrong ale fld id %d\n", fld_id); in cpsw_ale_entry_get_fld()
234 bits = ale->port_mask_bits; in cpsw_ale_entry_get_fld()
239 static void cpsw_ale_entry_set_fld(struct cpsw_ale *ale, in cpsw_ale_entry_set_fld() argument
248 if (!ale || !ale_entry) in cpsw_ale_entry_set_fld()
253 dev_err(ale->params.dev, "set: wrong ale fld id %d\n", fld_id); in cpsw_ale_entry_set_fld()
259 bits = ale->port_mask_bits; in cpsw_ale_entry_set_fld()
264 static int cpsw_ale_vlan_get_fld(struct cpsw_ale *ale, in cpsw_ale_vlan_get_fld() argument
268 return cpsw_ale_entry_get_fld(ale, ale_entry, in cpsw_ale_vlan_get_fld()
269 ale->vlan_entry_tbl, fld_id); in cpsw_ale_vlan_get_fld()
272 static void cpsw_ale_vlan_set_fld(struct cpsw_ale *ale, in cpsw_ale_vlan_set_fld() argument
277 cpsw_ale_entry_set_fld(ale, ale_entry, in cpsw_ale_vlan_set_fld()
278 ale->vlan_entry_tbl, fld_id, value); in cpsw_ale_vlan_set_fld()
281 /* The MAC address field in the ALE entry cannot be macroized as above */
298 static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry) in cpsw_ale_read() argument
302 WARN_ON(idx > ale->params.ale_entries); in cpsw_ale_read()
304 writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL); in cpsw_ale_read()
307 ale_entry[i] = readl_relaxed(ale->params.ale_regs + in cpsw_ale_read()
313 static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry) in cpsw_ale_write() argument
317 WARN_ON(idx > ale->params.ale_entries); in cpsw_ale_write()
320 writel_relaxed(ale_entry[i], ale->params.ale_regs + in cpsw_ale_write()
323 writel_relaxed(idx | ALE_TABLE_WRITE, ale->params.ale_regs + in cpsw_ale_write()
329 static int cpsw_ale_match_addr(struct cpsw_ale *ale, const u8 *addr, u16 vid) in cpsw_ale_match_addr() argument
334 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_match_addr()
337 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_match_addr()
350 static int cpsw_ale_match_vlan(struct cpsw_ale *ale, u16 vid) in cpsw_ale_match_vlan() argument
355 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_match_vlan()
356 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_match_vlan()
366 static int cpsw_ale_match_free(struct cpsw_ale *ale) in cpsw_ale_match_free() argument
371 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_match_free()
372 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_match_free()
380 static int cpsw_ale_find_ageable(struct cpsw_ale *ale) in cpsw_ale_find_ageable() argument
385 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_find_ageable()
386 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_find_ageable()
400 static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_flush_mcast() argument
406 ale->port_mask_bits); in cpsw_ale_flush_mcast()
414 ale->port_mask_bits); in cpsw_ale_flush_mcast()
419 int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid) in cpsw_ale_flush_multicast() argument
424 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_flush_multicast()
425 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_flush_multicast()
446 cpsw_ale_flush_mcast(ale, ale_entry, port_mask); in cpsw_ale_flush_multicast()
449 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_flush_multicast()
465 int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port, in cpsw_ale_add_ucast() argument
477 cpsw_ale_set_port_num(ale_entry, port, ale->port_num_bits); in cpsw_ale_add_ucast()
479 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); in cpsw_ale_add_ucast()
481 idx = cpsw_ale_match_free(ale); in cpsw_ale_add_ucast()
483 idx = cpsw_ale_find_ageable(ale); in cpsw_ale_add_ucast()
487 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_add_ucast()
491 int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port, in cpsw_ale_del_ucast() argument
497 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); in cpsw_ale_del_ucast()
502 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_del_ucast()
506 int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask, in cpsw_ale_add_mcast() argument
512 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); in cpsw_ale_add_mcast()
514 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_add_mcast()
523 ale->port_mask_bits); in cpsw_ale_add_mcast()
526 ale->port_mask_bits); in cpsw_ale_add_mcast()
529 idx = cpsw_ale_match_free(ale); in cpsw_ale_add_mcast()
531 idx = cpsw_ale_find_ageable(ale); in cpsw_ale_add_mcast()
535 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_add_mcast()
539 int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask, in cpsw_ale_del_mcast() argument
546 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); in cpsw_ale_del_mcast()
550 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_del_mcast()
554 ale->port_mask_bits); in cpsw_ale_del_mcast()
560 ale->port_mask_bits); in cpsw_ale_del_mcast()
564 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_del_mcast()
568 /* ALE NetCP NU switch specific vlan functions */
569 static void cpsw_ale_set_vlan_mcast(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_set_vlan_mcast() argument
575 idx = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_set_vlan_mcast()
577 writel(reg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_set_vlan_mcast()
580 idx = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_set_vlan_mcast()
582 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_set_vlan_mcast()
585 static void cpsw_ale_set_vlan_untag(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_set_vlan_untag() argument
588 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_set_vlan_untag()
592 bitmap_set(ale->p0_untag_vid_mask, vid, 1); in cpsw_ale_set_vlan_untag()
594 bitmap_clear(ale->p0_untag_vid_mask, vid, 1); in cpsw_ale_set_vlan_untag()
597 int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port_mask, int untag, in cpsw_ale_add_vlan() argument
603 idx = cpsw_ale_match_vlan(ale, vid); in cpsw_ale_add_vlan()
605 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_add_vlan()
609 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag); in cpsw_ale_add_vlan()
611 if (!ale->params.nu_switch_ale) { in cpsw_ale_add_vlan()
612 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_add_vlan()
614 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_add_vlan()
617 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_add_vlan()
620 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, unreg_mcast); in cpsw_ale_add_vlan()
623 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_add_vlan()
627 idx = cpsw_ale_match_free(ale); in cpsw_ale_add_vlan()
629 idx = cpsw_ale_find_ageable(ale); in cpsw_ale_add_vlan()
633 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_add_vlan()
637 static void cpsw_ale_del_vlan_modify(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_del_vlan_modify() argument
643 members = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_del_vlan_modify()
651 untag = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_del_vlan_modify()
653 reg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_del_vlan_modify()
655 unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_del_vlan_modify()
661 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag); in cpsw_ale_del_vlan_modify()
663 if (!ale->params.nu_switch_ale) { in cpsw_ale_del_vlan_modify()
664 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_del_vlan_modify()
666 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_del_vlan_modify()
669 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, in cpsw_ale_del_vlan_modify()
672 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_del_vlan_modify()
676 int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask) in cpsw_ale_del_vlan() argument
681 idx = cpsw_ale_match_vlan(ale, vid); in cpsw_ale_del_vlan()
685 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_del_vlan()
688 cpsw_ale_del_vlan_modify(ale, ale_entry, vid, port_mask); in cpsw_ale_del_vlan()
690 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, 0); in cpsw_ale_del_vlan()
694 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_del_vlan()
699 int cpsw_ale_vlan_add_modify(struct cpsw_ale *ale, u16 vid, int port_mask, in cpsw_ale_vlan_add_modify() argument
707 idx = cpsw_ale_match_vlan(ale, vid); in cpsw_ale_vlan_add_modify()
709 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_vlan_add_modify()
711 vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_add_modify()
713 reg_mcast_members = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_add_modify()
716 cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_add_modify()
718 untag_members = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_add_modify()
726 ret = cpsw_ale_add_vlan(ale, vid, vlan_members, untag_members, in cpsw_ale_vlan_add_modify()
729 dev_err(ale->params.dev, "Unable to add vlan\n"); in cpsw_ale_vlan_add_modify()
732 dev_dbg(ale->params.dev, "port mask 0x%x untag 0x%x\n", vlan_members, in cpsw_ale_vlan_add_modify()
738 void cpsw_ale_set_unreg_mcast(struct cpsw_ale *ale, int unreg_mcast_mask, in cpsw_ale_set_unreg_mcast() argument
745 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_set_unreg_mcast()
746 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_set_unreg_mcast()
752 cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_set_unreg_mcast()
758 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_set_unreg_mcast()
761 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_set_unreg_mcast()
765 static void cpsw_ale_vlan_set_unreg_mcast(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_vlan_set_unreg_mcast() argument
770 unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_set_unreg_mcast()
777 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_vlan_set_unreg_mcast()
782 cpsw_ale_vlan_set_unreg_mcast_idx(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_vlan_set_unreg_mcast_idx() argument
788 idx = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_set_unreg_mcast_idx()
791 unreg_mcast = readl(ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_vlan_set_unreg_mcast_idx()
798 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_vlan_set_unreg_mcast_idx()
801 void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port) in cpsw_ale_set_allmulti() argument
806 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_set_allmulti()
809 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_set_allmulti()
814 vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_set_allmulti()
820 if (!ale->params.nu_switch_ale) in cpsw_ale_set_allmulti()
821 cpsw_ale_vlan_set_unreg_mcast(ale, ale_entry, allmulti); in cpsw_ale_set_allmulti()
823 cpsw_ale_vlan_set_unreg_mcast_idx(ale, ale_entry, in cpsw_ale_set_allmulti()
826 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_set_allmulti()
1056 int cpsw_ale_control_set(struct cpsw_ale *ale, int port, int control, in cpsw_ale_control_set() argument
1070 if (port < 0 || port >= ale->params.ale_ports) in cpsw_ale_control_set()
1080 tmp = readl_relaxed(ale->params.ale_regs + offset); in cpsw_ale_control_set()
1082 writel_relaxed(tmp, ale->params.ale_regs + offset); in cpsw_ale_control_set()
1087 int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control) in cpsw_ale_control_get() argument
1100 if (port < 0 || port >= ale->params.ale_ports) in cpsw_ale_control_get()
1106 tmp = readl_relaxed(ale->params.ale_regs + offset) >> shift; in cpsw_ale_control_get()
1112 struct cpsw_ale *ale = from_timer(ale, t, timer); in cpsw_ale_timer() local
1114 cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1); in cpsw_ale_timer()
1116 if (ale->ageout) { in cpsw_ale_timer()
1117 ale->timer.expires = jiffies + ale->ageout; in cpsw_ale_timer()
1118 add_timer(&ale->timer); in cpsw_ale_timer()
1122 static void cpsw_ale_hw_aging_timer_start(struct cpsw_ale *ale) in cpsw_ale_hw_aging_timer_start() argument
1126 aging_timer = ale->params.bus_freq / 1000000; in cpsw_ale_hw_aging_timer_start()
1127 aging_timer *= ale->params.ale_ageout; in cpsw_ale_hw_aging_timer_start()
1131 dev_warn(ale->params.dev, in cpsw_ale_hw_aging_timer_start()
1132 "ALE aging timer overflow, set to max\n"); in cpsw_ale_hw_aging_timer_start()
1135 writel(aging_timer, ale->params.ale_regs + ALE_AGING_TIMER); in cpsw_ale_hw_aging_timer_start()
1138 static void cpsw_ale_hw_aging_timer_stop(struct cpsw_ale *ale) in cpsw_ale_hw_aging_timer_stop() argument
1140 writel(0, ale->params.ale_regs + ALE_AGING_TIMER); in cpsw_ale_hw_aging_timer_stop()
1143 static void cpsw_ale_aging_start(struct cpsw_ale *ale) in cpsw_ale_aging_start() argument
1145 if (!ale->params.ale_ageout) in cpsw_ale_aging_start()
1148 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) { in cpsw_ale_aging_start()
1149 cpsw_ale_hw_aging_timer_start(ale); in cpsw_ale_aging_start()
1153 timer_setup(&ale->timer, cpsw_ale_timer, 0); in cpsw_ale_aging_start()
1154 ale->timer.expires = jiffies + ale->ageout; in cpsw_ale_aging_start()
1155 add_timer(&ale->timer); in cpsw_ale_aging_start()
1158 static void cpsw_ale_aging_stop(struct cpsw_ale *ale) in cpsw_ale_aging_stop() argument
1160 if (!ale->params.ale_ageout) in cpsw_ale_aging_stop()
1163 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) { in cpsw_ale_aging_stop()
1164 cpsw_ale_hw_aging_timer_stop(ale); in cpsw_ale_aging_stop()
1168 del_timer_sync(&ale->timer); in cpsw_ale_aging_stop()
1171 void cpsw_ale_start(struct cpsw_ale *ale) in cpsw_ale_start() argument
1173 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 1); in cpsw_ale_start()
1174 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); in cpsw_ale_start()
1176 cpsw_ale_aging_start(ale); in cpsw_ale_start()
1179 void cpsw_ale_stop(struct cpsw_ale *ale) in cpsw_ale_stop() argument
1181 cpsw_ale_aging_stop(ale); in cpsw_ale_stop()
1182 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); in cpsw_ale_stop()
1183 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0); in cpsw_ale_stop()
1251 struct cpsw_ale *ale; in cpsw_ale_create() local
1262 ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL); in cpsw_ale_create()
1263 if (!ale) in cpsw_ale_create()
1266 ale->p0_untag_vid_mask = in cpsw_ale_create()
1270 if (!ale->p0_untag_vid_mask) in cpsw_ale_create()
1273 ale->params = *params; in cpsw_ale_create()
1274 ale->ageout = ale->params.ale_ageout * HZ; in cpsw_ale_create()
1275 ale->features = ale_dev_id->features; in cpsw_ale_create()
1276 ale->vlan_entry_tbl = ale_dev_id->vlan_entry_tbl; in cpsw_ale_create()
1278 rev = readl_relaxed(ale->params.ale_regs + ALE_IDVER); in cpsw_ale_create()
1279 ale->version = in cpsw_ale_create()
1280 (ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask) << 8) | in cpsw_ale_create()
1282 dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n", in cpsw_ale_create()
1283 ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask), in cpsw_ale_create()
1286 if (ale->features & CPSW_ALE_F_STATUS_REG && in cpsw_ale_create()
1287 !ale->params.ale_entries) { in cpsw_ale_create()
1289 readl_relaxed(ale->params.ale_regs + ALE_STATUS) & in cpsw_ale_create()
1291 /* ALE available on newer NetCP switches has introduced in cpsw_ale_create()
1292 * a register, ALE_STATUS, to indicate the size of ALE in cpsw_ale_create()
1302 ale->params.ale_entries = ale_entries; in cpsw_ale_create()
1304 dev_info(ale->params.dev, in cpsw_ale_create()
1305 "ALE Table size %ld\n", ale->params.ale_entries); in cpsw_ale_create()
1308 ale->port_mask_bits = ale->params.ale_ports; in cpsw_ale_create()
1309 ale->port_num_bits = order_base_2(ale->params.ale_ports); in cpsw_ale_create()
1310 ale->vlan_field_bits = ale->params.ale_ports; in cpsw_ale_create()
1312 /* Set defaults override for ALE on NetCP NU switch and for version in cpsw_ale_create()
1315 if (ale->params.nu_switch_ale) { in cpsw_ale_create()
1317 * Also there are N bits, where N is number of ale in cpsw_ale_create()
1321 ale->params.ale_ports; in cpsw_ale_create()
1325 ale->params.ale_ports; in cpsw_ale_create()
1330 ale->params.ale_ports; in cpsw_ale_create()
1335 ale->params.ale_ports; in cpsw_ale_create()
1341 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); in cpsw_ale_create()
1342 return ale; in cpsw_ale_create()
1345 void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data) in cpsw_ale_dump() argument
1349 for (i = 0; i < ale->params.ale_entries; i++) { in cpsw_ale_dump()
1350 cpsw_ale_read(ale, i, data); in cpsw_ale_dump()
1355 u32 cpsw_ale_get_num_entries(struct cpsw_ale *ale) in cpsw_ale_get_num_entries() argument
1357 return ale ? ale->params.ale_entries : 0; in cpsw_ale_get_num_entries()