Lines Matching full:ale

31 /* ALE Registers */
42 /* ALE NetCP NU switch specific Registers */
75 * struct ale_entry_fld - The ALE tbl entry field description
94 * struct cpsw_ale_dev_id - The ALE version/SoC specific configuration
95 * @dev_id: ALE version/SoC id
96 * @features: features supported by ALE
97 * @tbl_entries: number of ALE entries
100 * @nu_switch_ale: NU Switch ALE
101 * @vlan_entry_tbl: ALE vlan entry fields description tbl
264 static int cpsw_ale_entry_get_fld(struct cpsw_ale *ale, in cpsw_ale_entry_get_fld() argument
272 if (!ale || !ale_entry) in cpsw_ale_entry_get_fld()
277 dev_err(ale->params.dev, "get: wrong ale fld id %d\n", fld_id); in cpsw_ale_entry_get_fld()
283 bits = ale->port_mask_bits; in cpsw_ale_entry_get_fld()
288 static void cpsw_ale_entry_set_fld(struct cpsw_ale *ale, in cpsw_ale_entry_set_fld() argument
297 if (!ale || !ale_entry) in cpsw_ale_entry_set_fld()
302 dev_err(ale->params.dev, "set: wrong ale fld id %d\n", fld_id); in cpsw_ale_entry_set_fld()
308 bits = ale->port_mask_bits; in cpsw_ale_entry_set_fld()
313 static int cpsw_ale_vlan_get_fld(struct cpsw_ale *ale, in cpsw_ale_vlan_get_fld() argument
317 return cpsw_ale_entry_get_fld(ale, ale_entry, in cpsw_ale_vlan_get_fld()
318 ale->vlan_entry_tbl, fld_id); in cpsw_ale_vlan_get_fld()
321 static void cpsw_ale_vlan_set_fld(struct cpsw_ale *ale, in cpsw_ale_vlan_set_fld() argument
326 cpsw_ale_entry_set_fld(ale, ale_entry, in cpsw_ale_vlan_set_fld()
327 ale->vlan_entry_tbl, fld_id, value); in cpsw_ale_vlan_set_fld()
330 /* The MAC address field in the ALE entry cannot be macroized as above */
347 static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry) in cpsw_ale_read() argument
351 WARN_ON(idx > ale->params.ale_entries); in cpsw_ale_read()
353 writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL); in cpsw_ale_read()
356 ale_entry[i] = readl_relaxed(ale->params.ale_regs + in cpsw_ale_read()
362 static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry) in cpsw_ale_write() argument
366 WARN_ON(idx > ale->params.ale_entries); in cpsw_ale_write()
369 writel_relaxed(ale_entry[i], ale->params.ale_regs + in cpsw_ale_write()
372 writel_relaxed(idx | ALE_TABLE_WRITE, ale->params.ale_regs + in cpsw_ale_write()
378 static int cpsw_ale_match_addr(struct cpsw_ale *ale, const u8 *addr, u16 vid) in cpsw_ale_match_addr() argument
383 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_match_addr()
386 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_match_addr()
399 static int cpsw_ale_match_vlan(struct cpsw_ale *ale, u16 vid) in cpsw_ale_match_vlan() argument
404 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_match_vlan()
405 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_match_vlan()
415 static int cpsw_ale_match_free(struct cpsw_ale *ale) in cpsw_ale_match_free() argument
420 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_match_free()
421 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_match_free()
429 static int cpsw_ale_find_ageable(struct cpsw_ale *ale) in cpsw_ale_find_ageable() argument
434 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_find_ageable()
435 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_find_ageable()
449 static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_flush_mcast() argument
455 ale->port_mask_bits); in cpsw_ale_flush_mcast()
463 ale->port_mask_bits); in cpsw_ale_flush_mcast()
468 int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid) in cpsw_ale_flush_multicast() argument
473 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_flush_multicast()
474 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_flush_multicast()
495 cpsw_ale_flush_mcast(ale, ale_entry, port_mask); in cpsw_ale_flush_multicast()
498 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_flush_multicast()
514 int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port, in cpsw_ale_add_ucast() argument
526 cpsw_ale_set_port_num(ale_entry, port, ale->port_num_bits); in cpsw_ale_add_ucast()
528 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); in cpsw_ale_add_ucast()
530 idx = cpsw_ale_match_free(ale); in cpsw_ale_add_ucast()
532 idx = cpsw_ale_find_ageable(ale); in cpsw_ale_add_ucast()
536 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_add_ucast()
540 int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port, in cpsw_ale_del_ucast() argument
546 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); in cpsw_ale_del_ucast()
551 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_del_ucast()
555 int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask, in cpsw_ale_add_mcast() argument
561 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); in cpsw_ale_add_mcast()
563 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_add_mcast()
572 ale->port_mask_bits); in cpsw_ale_add_mcast()
575 ale->port_mask_bits); in cpsw_ale_add_mcast()
578 idx = cpsw_ale_match_free(ale); in cpsw_ale_add_mcast()
580 idx = cpsw_ale_find_ageable(ale); in cpsw_ale_add_mcast()
584 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_add_mcast()
588 int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask, in cpsw_ale_del_mcast() argument
595 idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); in cpsw_ale_del_mcast()
599 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_del_mcast()
603 ale->port_mask_bits); in cpsw_ale_del_mcast()
609 ale->port_mask_bits); in cpsw_ale_del_mcast()
613 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_del_mcast()
617 /* ALE NetCP NU switch specific vlan functions */
618 static void cpsw_ale_set_vlan_mcast(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_set_vlan_mcast() argument
624 idx = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_set_vlan_mcast()
626 writel(reg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_set_vlan_mcast()
629 idx = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_set_vlan_mcast()
631 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_set_vlan_mcast()
634 static void cpsw_ale_set_vlan_untag(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_set_vlan_untag() argument
637 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_set_vlan_untag()
641 bitmap_set(ale->p0_untag_vid_mask, vid, 1); in cpsw_ale_set_vlan_untag()
643 bitmap_clear(ale->p0_untag_vid_mask, vid, 1); in cpsw_ale_set_vlan_untag()
646 int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port_mask, int untag, in cpsw_ale_add_vlan() argument
652 idx = cpsw_ale_match_vlan(ale, vid); in cpsw_ale_add_vlan()
654 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_add_vlan()
658 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag); in cpsw_ale_add_vlan()
660 if (!ale->params.nu_switch_ale) { in cpsw_ale_add_vlan()
661 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_add_vlan()
663 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_add_vlan()
666 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_add_vlan()
669 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, unreg_mcast); in cpsw_ale_add_vlan()
672 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_add_vlan()
676 idx = cpsw_ale_match_free(ale); in cpsw_ale_add_vlan()
678 idx = cpsw_ale_find_ageable(ale); in cpsw_ale_add_vlan()
682 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_add_vlan()
686 static void cpsw_ale_vlan_del_modify_int(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_vlan_del_modify_int() argument
692 members = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_del_modify_int()
696 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, 0); in cpsw_ale_vlan_del_modify_int()
701 untag = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_del_modify_int()
703 reg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_del_modify_int()
705 unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_del_modify_int()
711 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag); in cpsw_ale_vlan_del_modify_int()
713 if (!ale->params.nu_switch_ale) { in cpsw_ale_vlan_del_modify_int()
714 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_vlan_del_modify_int()
716 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_vlan_del_modify_int()
719 cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, in cpsw_ale_vlan_del_modify_int()
722 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_vlan_del_modify_int()
726 int cpsw_ale_vlan_del_modify(struct cpsw_ale *ale, u16 vid, int port_mask) in cpsw_ale_vlan_del_modify() argument
731 idx = cpsw_ale_match_vlan(ale, vid); in cpsw_ale_vlan_del_modify()
735 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_vlan_del_modify()
737 cpsw_ale_vlan_del_modify_int(ale, ale_entry, vid, port_mask); in cpsw_ale_vlan_del_modify()
738 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_vlan_del_modify()
743 int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask) in cpsw_ale_del_vlan() argument
748 idx = cpsw_ale_match_vlan(ale, vid); in cpsw_ale_del_vlan()
752 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_del_vlan()
758 * remove port_mask ports from VLAN ALE entry excluding Host port. in cpsw_ale_del_vlan()
760 members = cpsw_ale_vlan_get_fld(ale, ale_entry, ALE_ENT_VID_MEMBER_LIST); in cpsw_ale_del_vlan()
765 cpsw_ale_set_vlan_untag(ale, ale_entry, vid, 0); in cpsw_ale_del_vlan()
769 cpsw_ale_vlan_del_modify_int(ale, ale_entry, vid, port_mask); in cpsw_ale_del_vlan()
772 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_del_vlan()
777 int cpsw_ale_vlan_add_modify(struct cpsw_ale *ale, u16 vid, int port_mask, in cpsw_ale_vlan_add_modify() argument
785 idx = cpsw_ale_match_vlan(ale, vid); in cpsw_ale_vlan_add_modify()
787 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_vlan_add_modify()
789 vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_add_modify()
791 reg_mcast_members = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_add_modify()
794 cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_add_modify()
796 untag_members = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_add_modify()
804 ret = cpsw_ale_add_vlan(ale, vid, vlan_members, untag_members, in cpsw_ale_vlan_add_modify()
807 dev_err(ale->params.dev, "Unable to add vlan\n"); in cpsw_ale_vlan_add_modify()
810 dev_dbg(ale->params.dev, "port mask 0x%x untag 0x%x\n", vlan_members, in cpsw_ale_vlan_add_modify()
816 void cpsw_ale_set_unreg_mcast(struct cpsw_ale *ale, int unreg_mcast_mask, in cpsw_ale_set_unreg_mcast() argument
823 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_set_unreg_mcast()
824 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_set_unreg_mcast()
830 cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_set_unreg_mcast()
836 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_set_unreg_mcast()
839 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_set_unreg_mcast()
843 static void cpsw_ale_vlan_set_unreg_mcast(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_vlan_set_unreg_mcast() argument
848 unreg_mcast = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_set_unreg_mcast()
855 cpsw_ale_vlan_set_fld(ale, ale_entry, in cpsw_ale_vlan_set_unreg_mcast()
860 cpsw_ale_vlan_set_unreg_mcast_idx(struct cpsw_ale *ale, u32 *ale_entry, in cpsw_ale_vlan_set_unreg_mcast_idx() argument
866 idx = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_vlan_set_unreg_mcast_idx()
869 unreg_mcast = readl(ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_vlan_set_unreg_mcast_idx()
876 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_vlan_set_unreg_mcast_idx()
879 void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti, int port) in cpsw_ale_set_allmulti() argument
884 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_set_allmulti()
887 cpsw_ale_read(ale, idx, ale_entry); in cpsw_ale_set_allmulti()
892 vlan_members = cpsw_ale_vlan_get_fld(ale, ale_entry, in cpsw_ale_set_allmulti()
898 if (!ale->params.nu_switch_ale) in cpsw_ale_set_allmulti()
899 cpsw_ale_vlan_set_unreg_mcast(ale, ale_entry, allmulti); in cpsw_ale_set_allmulti()
901 cpsw_ale_vlan_set_unreg_mcast_idx(ale, ale_entry, in cpsw_ale_set_allmulti()
904 cpsw_ale_write(ale, idx, ale_entry); in cpsw_ale_set_allmulti()
1134 int cpsw_ale_control_set(struct cpsw_ale *ale, int port, int control, in cpsw_ale_control_set() argument
1148 if (port < 0 || port >= ale->params.ale_ports) in cpsw_ale_control_set()
1158 tmp = readl_relaxed(ale->params.ale_regs + offset); in cpsw_ale_control_set()
1160 writel_relaxed(tmp, ale->params.ale_regs + offset); in cpsw_ale_control_set()
1165 int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control) in cpsw_ale_control_get() argument
1178 if (port < 0 || port >= ale->params.ale_ports) in cpsw_ale_control_get()
1184 tmp = readl_relaxed(ale->params.ale_regs + offset) >> shift; in cpsw_ale_control_get()
1188 int cpsw_ale_rx_ratelimit_mc(struct cpsw_ale *ale, int port, unsigned int ratelimit_pps) in cpsw_ale_rx_ratelimit_mc() argument
1195 dev_err(ale->params.dev, "ALE MC port:%d ratelimit min value 1000pps\n", port); in cpsw_ale_rx_ratelimit_mc()
1200 dev_info(ale->params.dev, "ALE port:%d MC ratelimit set to %dpps (requested %d)\n", in cpsw_ale_rx_ratelimit_mc()
1203 cpsw_ale_control_set(ale, port, ALE_PORT_MCAST_LIMIT, val); in cpsw_ale_rx_ratelimit_mc()
1205 dev_dbg(ale->params.dev, "ALE port:%d MC ratelimit set %d\n", in cpsw_ale_rx_ratelimit_mc()
1210 int cpsw_ale_rx_ratelimit_bc(struct cpsw_ale *ale, int port, unsigned int ratelimit_pps) in cpsw_ale_rx_ratelimit_bc() argument
1217 dev_err(ale->params.dev, "ALE port:%d BC ratelimit min value 1000pps\n", port); in cpsw_ale_rx_ratelimit_bc()
1222 dev_info(ale->params.dev, "ALE port:%d BC ratelimit set to %dpps (requested %d)\n", in cpsw_ale_rx_ratelimit_bc()
1225 cpsw_ale_control_set(ale, port, ALE_PORT_BCAST_LIMIT, val); in cpsw_ale_rx_ratelimit_bc()
1227 dev_dbg(ale->params.dev, "ALE port:%d BC ratelimit set %d\n", in cpsw_ale_rx_ratelimit_bc()
1234 struct cpsw_ale *ale = from_timer(ale, t, timer); in cpsw_ale_timer() local
1236 cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1); in cpsw_ale_timer()
1238 if (ale->ageout) { in cpsw_ale_timer()
1239 ale->timer.expires = jiffies + ale->ageout; in cpsw_ale_timer()
1240 add_timer(&ale->timer); in cpsw_ale_timer()
1244 static void cpsw_ale_hw_aging_timer_start(struct cpsw_ale *ale) in cpsw_ale_hw_aging_timer_start() argument
1248 aging_timer = ale->params.bus_freq / 1000000; in cpsw_ale_hw_aging_timer_start()
1249 aging_timer *= ale->params.ale_ageout; in cpsw_ale_hw_aging_timer_start()
1253 dev_warn(ale->params.dev, in cpsw_ale_hw_aging_timer_start()
1254 "ALE aging timer overflow, set to max\n"); in cpsw_ale_hw_aging_timer_start()
1257 writel(aging_timer, ale->params.ale_regs + ALE_AGING_TIMER); in cpsw_ale_hw_aging_timer_start()
1260 static void cpsw_ale_hw_aging_timer_stop(struct cpsw_ale *ale) in cpsw_ale_hw_aging_timer_stop() argument
1262 writel(0, ale->params.ale_regs + ALE_AGING_TIMER); in cpsw_ale_hw_aging_timer_stop()
1265 static void cpsw_ale_aging_start(struct cpsw_ale *ale) in cpsw_ale_aging_start() argument
1267 if (!ale->params.ale_ageout) in cpsw_ale_aging_start()
1270 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) { in cpsw_ale_aging_start()
1271 cpsw_ale_hw_aging_timer_start(ale); in cpsw_ale_aging_start()
1275 timer_setup(&ale->timer, cpsw_ale_timer, 0); in cpsw_ale_aging_start()
1276 ale->timer.expires = jiffies + ale->ageout; in cpsw_ale_aging_start()
1277 add_timer(&ale->timer); in cpsw_ale_aging_start()
1280 static void cpsw_ale_aging_stop(struct cpsw_ale *ale) in cpsw_ale_aging_stop() argument
1282 if (!ale->params.ale_ageout) in cpsw_ale_aging_stop()
1285 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) { in cpsw_ale_aging_stop()
1286 cpsw_ale_hw_aging_timer_stop(ale); in cpsw_ale_aging_stop()
1290 del_timer_sync(&ale->timer); in cpsw_ale_aging_stop()
1293 void cpsw_ale_start(struct cpsw_ale *ale) in cpsw_ale_start() argument
1307 ale_prescale = ale->params.bus_freq / ALE_RATE_LIMIT_MIN_PPS; in cpsw_ale_start()
1308 writel((u32)ale_prescale, ale->params.ale_regs + ALE_PRESCALE); in cpsw_ale_start()
1313 cpsw_ale_control_set(ale, 0, ALE_RATE_LIMIT, 1); in cpsw_ale_start()
1315 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 1); in cpsw_ale_start()
1316 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); in cpsw_ale_start()
1318 cpsw_ale_aging_start(ale); in cpsw_ale_start()
1321 void cpsw_ale_stop(struct cpsw_ale *ale) in cpsw_ale_stop() argument
1323 cpsw_ale_aging_stop(ale); in cpsw_ale_stop()
1324 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); in cpsw_ale_stop()
1325 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0); in cpsw_ale_stop()
1491 .name = "cpsw-ale",
1494 static int cpsw_ale_regfield_init(struct cpsw_ale *ale) in cpsw_ale_regfield_init() argument
1496 const struct reg_field *reg_fields = ale->params.reg_fields; in cpsw_ale_regfield_init()
1497 struct device *dev = ale->params.dev; in cpsw_ale_regfield_init()
1498 struct regmap *regmap = ale->regmap; in cpsw_ale_regfield_init()
1501 for (i = 0; i < ale->params.num_fields; i++) { in cpsw_ale_regfield_init()
1502 ale->fields[i] = devm_regmap_field_alloc(dev, regmap, in cpsw_ale_regfield_init()
1504 if (IS_ERR(ale->fields[i])) { in cpsw_ale_regfield_init()
1506 return PTR_ERR(ale->fields[i]); in cpsw_ale_regfield_init()
1517 struct cpsw_ale *ale; in cpsw_ale_create() local
1529 ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL); in cpsw_ale_create()
1530 if (!ale) in cpsw_ale_create()
1532 ale->regmap = devm_regmap_init_mmio(params->dev, params->ale_regs, in cpsw_ale_create()
1534 if (IS_ERR(ale->regmap)) { in cpsw_ale_create()
1535 dev_err(params->dev, "Couldn't create CPSW ALE regmap\n"); in cpsw_ale_create()
1539 ale->params = *params; in cpsw_ale_create()
1540 ret = cpsw_ale_regfield_init(ale); in cpsw_ale_create()
1544 ale->p0_untag_vid_mask = devm_bitmap_zalloc(params->dev, VLAN_N_VID, in cpsw_ale_create()
1546 if (!ale->p0_untag_vid_mask) in cpsw_ale_create()
1549 ale->ageout = ale->params.ale_ageout * HZ; in cpsw_ale_create()
1550 ale->features = ale_dev_id->features; in cpsw_ale_create()
1551 ale->vlan_entry_tbl = ale_dev_id->vlan_entry_tbl; in cpsw_ale_create()
1553 regmap_field_read(ale->fields[MINOR_VER], &rev_minor); in cpsw_ale_create()
1554 regmap_field_read(ale->fields[MAJOR_VER], &rev_major); in cpsw_ale_create()
1555 ale->version = rev_major << 8 | rev_minor; in cpsw_ale_create()
1556 dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n", in cpsw_ale_create()
1559 if (ale->features & CPSW_ALE_F_STATUS_REG && in cpsw_ale_create()
1560 !ale->params.ale_entries) { in cpsw_ale_create()
1561 regmap_field_read(ale->fields[ALE_ENTRIES], &ale_entries); in cpsw_ale_create()
1562 /* ALE available on newer NetCP switches has introduced in cpsw_ale_create()
1563 * a register, ALE_STATUS, to indicate the size of ALE in cpsw_ale_create()
1573 ale->params.ale_entries = ale_entries; in cpsw_ale_create()
1576 if (ale->features & CPSW_ALE_F_STATUS_REG && in cpsw_ale_create()
1577 !ale->params.num_policers) { in cpsw_ale_create()
1578 regmap_field_read(ale->fields[ALE_POLICERS], &policers); in cpsw_ale_create()
1583 ale->params.num_policers = policers; in cpsw_ale_create()
1586 dev_info(ale->params.dev, in cpsw_ale_create()
1587 "ALE Table size %ld, Policers %ld\n", ale->params.ale_entries, in cpsw_ale_create()
1588 ale->params.num_policers); in cpsw_ale_create()
1591 ale->port_mask_bits = ale->params.ale_ports; in cpsw_ale_create()
1592 ale->port_num_bits = order_base_2(ale->params.ale_ports); in cpsw_ale_create()
1593 ale->vlan_field_bits = ale->params.ale_ports; in cpsw_ale_create()
1595 /* Set defaults override for ALE on NetCP NU switch and for version in cpsw_ale_create()
1598 if (ale->params.nu_switch_ale) { in cpsw_ale_create()
1600 * Also there are N bits, where N is number of ale in cpsw_ale_create()
1604 ale->params.ale_ports; in cpsw_ale_create()
1608 ale->params.ale_ports; in cpsw_ale_create()
1613 ale->params.ale_ports; in cpsw_ale_create()
1618 ale->params.ale_ports; in cpsw_ale_create()
1624 cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); in cpsw_ale_create()
1625 return ale; in cpsw_ale_create()
1628 void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data) in cpsw_ale_dump() argument
1632 for (i = 0; i < ale->params.ale_entries; i++) { in cpsw_ale_dump()
1633 cpsw_ale_read(ale, i, data); in cpsw_ale_dump()
1638 void cpsw_ale_restore(struct cpsw_ale *ale, u32 *data) in cpsw_ale_restore() argument
1642 for (i = 0; i < ale->params.ale_entries; i++) { in cpsw_ale_restore()
1643 cpsw_ale_write(ale, i, data); in cpsw_ale_restore()
1648 u32 cpsw_ale_get_num_entries(struct cpsw_ale *ale) in cpsw_ale_get_num_entries() argument
1650 return ale ? ale->params.ale_entries : 0; in cpsw_ale_get_num_entries()
1653 /* Reads the specified policer index into ALE POLICER registers */
1654 static void cpsw_ale_policer_read_idx(struct cpsw_ale *ale, u32 idx) in cpsw_ale_policer_read_idx() argument
1657 writel_relaxed(idx, ale->params.ale_regs + ALE_POLICER_TBL_CTL); in cpsw_ale_policer_read_idx()
1660 /* Writes the ALE POLICER registers into the specified policer index */
1661 static void cpsw_ale_policer_write_idx(struct cpsw_ale *ale, u32 idx) in cpsw_ale_policer_write_idx() argument
1665 writel_relaxed(idx, ale->params.ale_regs + ALE_POLICER_TBL_CTL); in cpsw_ale_policer_write_idx()
1669 static void cpsw_ale_policer_thread_idx_enable(struct cpsw_ale *ale, u32 idx, in cpsw_ale_policer_thread_idx_enable() argument
1672 regmap_field_write(ale->fields[ALE_THREAD_CLASS_INDEX], idx); in cpsw_ale_policer_thread_idx_enable()
1673 regmap_field_write(ale->fields[ALE_THREAD_VALUE], thread_id); in cpsw_ale_policer_thread_idx_enable()
1674 regmap_field_write(ale->fields[ALE_THREAD_ENABLE], enable ? 1 : 0); in cpsw_ale_policer_thread_idx_enable()
1678 static void cpsw_ale_policer_reset(struct cpsw_ale *ale) in cpsw_ale_policer_reset() argument
1682 for (i = 0; i < ale->params.num_policers ; i++) { in cpsw_ale_policer_reset()
1683 cpsw_ale_policer_read_idx(ale, i); in cpsw_ale_policer_reset()
1684 regmap_field_write(ale->fields[POL_PORT_MEN], 0); in cpsw_ale_policer_reset()
1685 regmap_field_write(ale->fields[POL_PRI_MEN], 0); in cpsw_ale_policer_reset()
1686 regmap_field_write(ale->fields[POL_OUI_MEN], 0); in cpsw_ale_policer_reset()
1687 regmap_field_write(ale->fields[POL_DST_MEN], 0); in cpsw_ale_policer_reset()
1688 regmap_field_write(ale->fields[POL_SRC_MEN], 0); in cpsw_ale_policer_reset()
1689 regmap_field_write(ale->fields[POL_OVLAN_MEN], 0); in cpsw_ale_policer_reset()
1690 regmap_field_write(ale->fields[POL_IVLAN_MEN], 0); in cpsw_ale_policer_reset()
1691 regmap_field_write(ale->fields[POL_ETHERTYPE_MEN], 0); in cpsw_ale_policer_reset()
1692 regmap_field_write(ale->fields[POL_IPSRC_MEN], 0); in cpsw_ale_policer_reset()
1693 regmap_field_write(ale->fields[POL_IPDST_MEN], 0); in cpsw_ale_policer_reset()
1694 regmap_field_write(ale->fields[POL_EN], 0); in cpsw_ale_policer_reset()
1695 regmap_field_write(ale->fields[POL_RED_DROP_EN], 0); in cpsw_ale_policer_reset()
1696 regmap_field_write(ale->fields[POL_YELLOW_DROP_EN], 0); in cpsw_ale_policer_reset()
1697 regmap_field_write(ale->fields[POL_PRIORITY_THREAD_EN], 0); in cpsw_ale_policer_reset()
1699 cpsw_ale_policer_thread_idx_enable(ale, i, 0, 0); in cpsw_ale_policer_reset()
1704 void cpsw_ale_classifier_setup_default(struct cpsw_ale *ale, int num_rx_ch) in cpsw_ale_classifier_setup_default() argument
1736 cpsw_ale_policer_reset(ale); in cpsw_ale_classifier_setup_default()
1743 cpsw_ale_policer_read_idx(ale, idx); in cpsw_ale_classifier_setup_default()
1744 regmap_field_write(ale->fields[POL_PRI_VAL], pri); in cpsw_ale_classifier_setup_default()
1745 regmap_field_write(ale->fields[POL_PRI_MEN], 1); in cpsw_ale_classifier_setup_default()
1746 cpsw_ale_policer_write_idx(ale, idx); in cpsw_ale_classifier_setup_default()
1749 cpsw_ale_policer_thread_idx_enable(ale, idx, in cpsw_ale_classifier_setup_default()