Lines Matching +full:dra7 +full:- +full:cpsw +full:- +full:switch

1 // SPDX-License-Identifier: GPL-2.0
3 * Texas Instruments N-Port Ethernet Switch Address Lookup Engine
24 #define BITMASK(bits) (BIT(bits) - 1)
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
100 * @nu_switch_ale: NU Switch ALE
134 idx2 = (start + bits - 1) / 32; in cpsw_ale_get_field()
137 idx2 = 2 - idx2; /* flip */ in cpsw_ale_get_field()
138 hi_val = ale_entry[idx2] << ((idx2 * 32) - start); in cpsw_ale_get_field()
140 start -= idx * 32; in cpsw_ale_get_field()
141 idx = 2 - idx; /* flip */ in cpsw_ale_get_field()
152 idx2 = (start + bits - 1) / 32; in cpsw_ale_set_field()
155 idx2 = 2 - idx2; /* flip */ in cpsw_ale_set_field()
156 ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32))); in cpsw_ale_set_field()
157 ale_entry[idx2] |= (value >> ((idx2 * 32) - start)); in cpsw_ale_set_field()
159 start -= idx * 32; in cpsw_ale_set_field()
160 idx = 2 - idx; /* flip */ in cpsw_ale_set_field()
261 return -EINVAL; in cpsw_ale_entry_get_fld()
264 if (!(entry_fld->flags & ALE_FLD_ALLOWED)) { in cpsw_ale_entry_get_fld()
265 dev_err(ale->params.dev, "get: wrong ale fld id %d\n", fld_id); in cpsw_ale_entry_get_fld()
266 return -ENOENT; in cpsw_ale_entry_get_fld()
269 bits = entry_fld->num_bits; in cpsw_ale_entry_get_fld()
270 if (entry_fld->flags & ALE_FLD_SIZE_PORT_MASK_BITS) in cpsw_ale_entry_get_fld()
271 bits = ale->port_mask_bits; in cpsw_ale_entry_get_fld()
273 return cpsw_ale_get_field(ale_entry, entry_fld->start_bit, bits); in cpsw_ale_entry_get_fld()
289 if (!(entry_fld->flags & ALE_FLD_ALLOWED)) { in cpsw_ale_entry_set_fld()
290 dev_err(ale->params.dev, "set: wrong ale fld id %d\n", fld_id); in cpsw_ale_entry_set_fld()
294 bits = entry_fld->num_bits; in cpsw_ale_entry_set_fld()
295 if (entry_fld->flags & ALE_FLD_SIZE_PORT_MASK_BITS) in cpsw_ale_entry_set_fld()
296 bits = ale->port_mask_bits; in cpsw_ale_entry_set_fld()
298 cpsw_ale_set_field(ale_entry, entry_fld->start_bit, bits, value); in cpsw_ale_entry_set_fld()
306 ale->vlan_entry_tbl, fld_id); in cpsw_ale_vlan_get_fld()
315 ale->vlan_entry_tbl, fld_id, value); in cpsw_ale_vlan_set_fld()
324 addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8); in cpsw_ale_get_addr()
332 cpsw_ale_set_field(ale_entry, 40 - 8*i, 8, addr[i]); in cpsw_ale_set_addr()
339 WARN_ON(idx > ale->params.ale_entries); in cpsw_ale_read()
341 writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL); in cpsw_ale_read()
344 ale_entry[i] = readl_relaxed(ale->params.ale_regs + in cpsw_ale_read()
354 WARN_ON(idx > ale->params.ale_entries); in cpsw_ale_write()
357 writel_relaxed(ale_entry[i], ale->params.ale_regs + in cpsw_ale_write()
360 writel_relaxed(idx | ALE_TABLE_WRITE, ale->params.ale_regs + in cpsw_ale_write()
371 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_match_addr()
384 return -ENOENT; in cpsw_ale_match_addr()
392 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_match_vlan()
400 return -ENOENT; in cpsw_ale_match_vlan()
408 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_match_free()
414 return -ENOENT; in cpsw_ale_match_free()
422 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_find_ageable()
434 return -ENOENT; in cpsw_ale_find_ageable()
443 ale->port_mask_bits); in cpsw_ale_flush_mcast()
451 ale->port_mask_bits); in cpsw_ale_flush_mcast()
461 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_flush_multicast()
467 /* if vid passed is -1 then remove all multicast entry from in cpsw_ale_flush_multicast()
472 if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid) in cpsw_ale_flush_multicast()
514 cpsw_ale_set_port_num(ale_entry, port, ale->port_num_bits); in cpsw_ale_add_ucast()
522 return -ENOMEM; in cpsw_ale_add_ucast()
536 return -ENOENT; in cpsw_ale_del_ucast()
560 ale->port_mask_bits); in cpsw_ale_add_mcast()
563 ale->port_mask_bits); in cpsw_ale_add_mcast()
570 return -ENOMEM; in cpsw_ale_add_mcast()
585 return -ENOENT; in cpsw_ale_del_mcast()
591 ale->port_mask_bits); in cpsw_ale_del_mcast()
597 ale->port_mask_bits); in cpsw_ale_del_mcast()
605 /* ALE NetCP NU switch specific vlan functions */
614 writel(reg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_set_vlan_mcast()
619 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_set_vlan_mcast()
629 bitmap_set(ale->p0_untag_vid_mask, vid, 1); in cpsw_ale_set_vlan_untag()
631 bitmap_clear(ale->p0_untag_vid_mask, vid, 1); in cpsw_ale_set_vlan_untag()
648 if (!ale->params.nu_switch_ale) { in cpsw_ale_add_vlan()
668 return -ENOMEM; in cpsw_ale_add_vlan()
701 if (!ale->params.nu_switch_ale) { in cpsw_ale_vlan_del_modify_int()
721 return -ENOENT; in cpsw_ale_vlan_del_modify()
738 return -ENOENT; in cpsw_ale_del_vlan()
742 /* if !port_mask - force remove VLAN (legacy). in cpsw_ale_del_vlan()
744 * if no - remove VLAN. in cpsw_ale_del_vlan()
752 /* last port or force remove - remove VLAN */ in cpsw_ale_del_vlan()
795 dev_err(ale->params.dev, "Unable to add vlan\n"); in cpsw_ale_vlan_add_modify()
798 dev_dbg(ale->params.dev, "port mask 0x%x untag 0x%x\n", vlan_members, in cpsw_ale_vlan_add_modify()
811 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_set_unreg_mcast()
857 unreg_mcast = readl(ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_vlan_set_unreg_mcast_idx()
864 writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx)); in cpsw_ale_vlan_set_unreg_mcast_idx()
872 for (idx = 0; idx < ale->params.ale_entries; idx++) { in cpsw_ale_set_allmulti()
883 if (port != -1 && !(vlan_members & BIT(port))) in cpsw_ale_set_allmulti()
886 if (!ale->params.nu_switch_ale) in cpsw_ale_set_allmulti()
1130 return -EINVAL; in cpsw_ale_control_set()
1133 if (info->port_offset == 0 && info->port_shift == 0) in cpsw_ale_control_set()
1136 if (port < 0 || port >= ale->params.ale_ports) in cpsw_ale_control_set()
1137 return -EINVAL; in cpsw_ale_control_set()
1139 mask = BITMASK(info->bits); in cpsw_ale_control_set()
1141 return -EINVAL; in cpsw_ale_control_set()
1143 offset = info->offset + (port * info->port_offset); in cpsw_ale_control_set()
1144 shift = info->shift + (port * info->port_shift); in cpsw_ale_control_set()
1146 tmp = readl_relaxed(ale->params.ale_regs + offset); in cpsw_ale_control_set()
1148 writel_relaxed(tmp, ale->params.ale_regs + offset); in cpsw_ale_control_set()
1160 return -EINVAL; in cpsw_ale_control_get()
1163 if (info->port_offset == 0 && info->port_shift == 0) in cpsw_ale_control_get()
1166 if (port < 0 || port >= ale->params.ale_ports) in cpsw_ale_control_get()
1167 return -EINVAL; in cpsw_ale_control_get()
1169 offset = info->offset + (port * info->port_offset); in cpsw_ale_control_get()
1170 shift = info->shift + (port * info->port_shift); in cpsw_ale_control_get()
1172 tmp = readl_relaxed(ale->params.ale_regs + offset) >> shift; in cpsw_ale_control_get()
1173 return tmp & BITMASK(info->bits); in cpsw_ale_control_get()
1183 dev_err(ale->params.dev, "ALE MC port:%d ratelimit min value 1000pps\n", port); in cpsw_ale_rx_ratelimit_mc()
1184 return -EINVAL; in cpsw_ale_rx_ratelimit_mc()
1188 dev_info(ale->params.dev, "ALE port:%d MC ratelimit set to %dpps (requested %d)\n", in cpsw_ale_rx_ratelimit_mc()
1189 port, ratelimit_pps - remainder, ratelimit_pps); in cpsw_ale_rx_ratelimit_mc()
1193 dev_dbg(ale->params.dev, "ALE port:%d MC ratelimit set %d\n", in cpsw_ale_rx_ratelimit_mc()
1205 dev_err(ale->params.dev, "ALE port:%d BC ratelimit min value 1000pps\n", port); in cpsw_ale_rx_ratelimit_bc()
1206 return -EINVAL; in cpsw_ale_rx_ratelimit_bc()
1210 dev_info(ale->params.dev, "ALE port:%d BC ratelimit set to %dpps (requested %d)\n", in cpsw_ale_rx_ratelimit_bc()
1211 port, ratelimit_pps - remainder, ratelimit_pps); in cpsw_ale_rx_ratelimit_bc()
1215 dev_dbg(ale->params.dev, "ALE port:%d BC ratelimit set %d\n", in cpsw_ale_rx_ratelimit_bc()
1226 if (ale->ageout) { in cpsw_ale_timer()
1227 ale->timer.expires = jiffies + ale->ageout; in cpsw_ale_timer()
1228 add_timer(&ale->timer); in cpsw_ale_timer()
1236 aging_timer = ale->params.bus_freq / 1000000; in cpsw_ale_hw_aging_timer_start()
1237 aging_timer *= ale->params.ale_ageout; in cpsw_ale_hw_aging_timer_start()
1241 dev_warn(ale->params.dev, in cpsw_ale_hw_aging_timer_start()
1245 writel(aging_timer, ale->params.ale_regs + ALE_AGING_TIMER); in cpsw_ale_hw_aging_timer_start()
1250 writel(0, ale->params.ale_regs + ALE_AGING_TIMER); in cpsw_ale_hw_aging_timer_stop()
1255 if (!ale->params.ale_ageout) in cpsw_ale_aging_start()
1258 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) { in cpsw_ale_aging_start()
1263 timer_setup(&ale->timer, cpsw_ale_timer, 0); in cpsw_ale_aging_start()
1264 ale->timer.expires = jiffies + ale->ageout; in cpsw_ale_aging_start()
1265 add_timer(&ale->timer); in cpsw_ale_aging_start()
1270 if (!ale->params.ale_ageout) in cpsw_ale_aging_stop()
1273 if (ale->features & CPSW_ALE_F_HW_AUTOAGING) { in cpsw_ale_aging_stop()
1278 del_timer_sync(&ale->timer); in cpsw_ale_aging_stop()
1295 ale_prescale = ale->params.bus_freq / ALE_RATE_LIMIT_MIN_PPS; in cpsw_ale_start()
1296 writel((u32)ale_prescale, ale->params.ale_regs + ALE_PRESCALE); in cpsw_ale_start()
1299 * The actual Rate Limit cfg enabled per-port by port.BCAST/MCAST_LIMIT in cpsw_ale_start()
1401 /* am3/4/5, dra7. dm814x, 66ak2hk-gbe */
1402 .dev_id = "cpsw",
1410 .dev_id = "66ak2h-xgbe",
1434 .dev_id = "am65x-cpsw2g",
1443 .dev_id = "j721e-cpswxg",
1450 .dev_id = "am64-cpswxg",
1467 while (id->dev_id) { in cpsw_ale_match_id()
1468 if (strcmp(dev_id, id->dev_id) == 0) in cpsw_ale_match_id()
1479 .name = "cpsw-ale",
1484 const struct reg_field *reg_fields = ale->params.reg_fields; in cpsw_ale_regfield_init()
1485 struct device *dev = ale->params.dev; in cpsw_ale_regfield_init()
1486 struct regmap *regmap = ale->regmap; in cpsw_ale_regfield_init()
1489 for (i = 0; i < ale->params.num_fields; i++) { in cpsw_ale_regfield_init()
1490 ale->fields[i] = devm_regmap_field_alloc(dev, regmap, in cpsw_ale_regfield_init()
1492 if (IS_ERR(ale->fields[i])) { in cpsw_ale_regfield_init()
1494 return PTR_ERR(ale->fields[i]); in cpsw_ale_regfield_init()
1508 ale_dev_id = cpsw_ale_match_id(cpsw_ale_id_match, params->dev_id); in cpsw_ale_create()
1510 return ERR_PTR(-EINVAL); in cpsw_ale_create()
1512 params->ale_entries = ale_dev_id->tbl_entries; in cpsw_ale_create()
1513 params->nu_switch_ale = ale_dev_id->nu_switch_ale; in cpsw_ale_create()
1514 params->reg_fields = ale_dev_id->reg_fields; in cpsw_ale_create()
1515 params->num_fields = ale_dev_id->num_fields; in cpsw_ale_create()
1517 ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL); in cpsw_ale_create()
1519 return ERR_PTR(-ENOMEM); in cpsw_ale_create()
1520 ale->regmap = devm_regmap_init_mmio(params->dev, params->ale_regs, in cpsw_ale_create()
1522 if (IS_ERR(ale->regmap)) { in cpsw_ale_create()
1523 dev_err(params->dev, "Couldn't create CPSW ALE regmap\n"); in cpsw_ale_create()
1524 return ERR_PTR(-ENOMEM); in cpsw_ale_create()
1527 ale->params = *params; in cpsw_ale_create()
1532 ale->p0_untag_vid_mask = devm_bitmap_zalloc(params->dev, VLAN_N_VID, in cpsw_ale_create()
1534 if (!ale->p0_untag_vid_mask) in cpsw_ale_create()
1535 return ERR_PTR(-ENOMEM); in cpsw_ale_create()
1537 ale->ageout = ale->params.ale_ageout * HZ; in cpsw_ale_create()
1538 ale->features = ale_dev_id->features; in cpsw_ale_create()
1539 ale->vlan_entry_tbl = ale_dev_id->vlan_entry_tbl; in cpsw_ale_create()
1541 regmap_field_read(ale->fields[MINOR_VER], &rev_minor); in cpsw_ale_create()
1542 regmap_field_read(ale->fields[MAJOR_VER], &rev_major); in cpsw_ale_create()
1543 ale->version = rev_major << 8 | rev_minor; in cpsw_ale_create()
1544 dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n", in cpsw_ale_create()
1547 if (ale->features & CPSW_ALE_F_STATUS_REG && in cpsw_ale_create()
1548 !ale->params.ale_entries) { in cpsw_ale_create()
1549 regmap_field_read(ale->fields[ALE_ENTRIES], &ale_entries); in cpsw_ale_create()
1558 return ERR_PTR(-EINVAL); in cpsw_ale_create()
1561 ale->params.ale_entries = ale_entries; in cpsw_ale_create()
1564 if (ale->features & CPSW_ALE_F_STATUS_REG && in cpsw_ale_create()
1565 !ale->params.num_policers) { in cpsw_ale_create()
1566 regmap_field_read(ale->fields[ALE_POLICERS], &policers); in cpsw_ale_create()
1568 return ERR_PTR(-EINVAL); in cpsw_ale_create()
1571 ale->params.num_policers = policers; in cpsw_ale_create()
1574 dev_info(ale->params.dev, in cpsw_ale_create()
1575 "ALE Table size %ld, Policers %ld\n", ale->params.ale_entries, in cpsw_ale_create()
1576 ale->params.num_policers); in cpsw_ale_create()
1579 ale->port_mask_bits = ale->params.ale_ports; in cpsw_ale_create()
1580 ale->port_num_bits = order_base_2(ale->params.ale_ports); in cpsw_ale_create()
1581 ale->vlan_field_bits = ale->params.ale_ports; in cpsw_ale_create()
1583 /* Set defaults override for ALE on NetCP NU switch and for version in cpsw_ale_create()
1586 if (ale->params.nu_switch_ale) { in cpsw_ale_create()
1592 ale->params.ale_ports; in cpsw_ale_create()
1596 ale->params.ale_ports; in cpsw_ale_create()
1601 ale->params.ale_ports; in cpsw_ale_create()
1606 ale->params.ale_ports; in cpsw_ale_create()
1620 for (i = 0; i < ale->params.ale_entries; i++) { in cpsw_ale_dump()
1630 for (i = 0; i < ale->params.ale_entries; i++) { in cpsw_ale_restore()
1638 return ale ? ale->params.ale_entries : 0; in cpsw_ale_get_num_entries()
1645 writel_relaxed(idx, ale->params.ale_regs + ALE_POLICER_TBL_CTL); in cpsw_ale_policer_read_idx()
1653 writel_relaxed(idx, ale->params.ale_regs + ALE_POLICER_TBL_CTL); in cpsw_ale_policer_write_idx()
1660 regmap_field_write(ale->fields[ALE_THREAD_CLASS_INDEX], idx); in cpsw_ale_policer_thread_idx_enable()
1661 regmap_field_write(ale->fields[ALE_THREAD_VALUE], thread_id); in cpsw_ale_policer_thread_idx_enable()
1662 regmap_field_write(ale->fields[ALE_THREAD_ENABLE], enable ? 1 : 0); in cpsw_ale_policer_thread_idx_enable()
1670 for (i = 0; i < ale->params.num_policers ; i++) { in cpsw_ale_policer_reset()
1672 regmap_field_write(ale->fields[POL_PORT_MEN], 0); in cpsw_ale_policer_reset()
1673 regmap_field_write(ale->fields[POL_PRI_MEN], 0); in cpsw_ale_policer_reset()
1674 regmap_field_write(ale->fields[POL_OUI_MEN], 0); in cpsw_ale_policer_reset()
1675 regmap_field_write(ale->fields[POL_DST_MEN], 0); in cpsw_ale_policer_reset()
1676 regmap_field_write(ale->fields[POL_SRC_MEN], 0); in cpsw_ale_policer_reset()
1677 regmap_field_write(ale->fields[POL_OVLAN_MEN], 0); in cpsw_ale_policer_reset()
1678 regmap_field_write(ale->fields[POL_IVLAN_MEN], 0); in cpsw_ale_policer_reset()
1679 regmap_field_write(ale->fields[POL_ETHERTYPE_MEN], 0); in cpsw_ale_policer_reset()
1680 regmap_field_write(ale->fields[POL_IPSRC_MEN], 0); in cpsw_ale_policer_reset()
1681 regmap_field_write(ale->fields[POL_IPDST_MEN], 0); in cpsw_ale_policer_reset()
1682 regmap_field_write(ale->fields[POL_EN], 0); in cpsw_ale_policer_reset()
1683 regmap_field_write(ale->fields[POL_RED_DROP_EN], 0); in cpsw_ale_policer_reset()
1684 regmap_field_write(ale->fields[POL_YELLOW_DROP_EN], 0); in cpsw_ale_policer_reset()
1685 regmap_field_write(ale->fields[POL_PRIORITY_THREAD_EN], 0); in cpsw_ale_policer_reset()
1695 /* IEEE802.1D-2004, Standard for Local and metropolitan area networks in cpsw_ale_classifier_setup_default()
1696 * Table G-2 - Traffic type acronyms in cpsw_ale_classifier_setup_default()
1697 * Table G-3 - Defining traffic types in cpsw_ale_classifier_setup_default()
1705 * pri_thread_map[8-1][0] i.e. thread 2 in cpsw_ale_classifier_setup_default()
1724 regmap_field_write(ale->fields[POL_PRI_VAL], pri); in cpsw_ale_classifier_setup_default()
1725 regmap_field_write(ale->fields[POL_PRI_MEN], 1); in cpsw_ale_classifier_setup_default()
1730 pri_thread_map[num_rx_ch - 1][pri], in cpsw_ale_classifier_setup_default()