Lines Matching +full:set +full:- +full:of +full:- +full:ports

1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
23 /* Caller must hold &ocelot->mact_lock */
29 /* Caller must hold &ocelot->mact_lock */
41 /* Caller must hold &ocelot->mact_lock */
48 /* Set the MAC address to handle and the vlan associated in a format in ocelot_mact_select()
75 /* Set MAC_CPU_COPY if the CPU port is used by a multicast entry */ in __ocelot_mact_learn()
83 if (mc_ports & BIT(ocelot->num_phys_ports)) in __ocelot_mact_learn()
102 mutex_lock(&ocelot->mact_lock); in ocelot_mact_learn()
104 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_learn()
115 mutex_lock(&ocelot->mact_lock); in ocelot_mact_forget()
126 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_forget()
138 mutex_lock(&ocelot->mact_lock); in ocelot_mact_lookup()
148 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_lookup()
149 return -ETIMEDOUT; in ocelot_mact_lookup()
155 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_lookup()
158 return -ENOENT; in ocelot_mact_lookup()
175 mutex_lock(&ocelot->mact_lock); in ocelot_mact_learn_streamdata()
186 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_learn_streamdata()
195 * - Do not copy the frame to the CPU extraction queues. in ocelot_mact_init()
196 * - Use the vlan and mac_cpoy for dmac lookup. in ocelot_mact_init()
205 * holding &ocelot->mact_lock is pointless. in ocelot_mact_init()
230 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_single_vlan_aware_bridge()
231 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_single_vlan_aware_bridge()
233 if (!ocelot_port || !ocelot_port->bridge || in ocelot_single_vlan_aware_bridge()
234 !br_vlan_enabled(ocelot_port->bridge)) in ocelot_single_vlan_aware_bridge()
238 bridge = ocelot_port->bridge; in ocelot_single_vlan_aware_bridge()
242 if (bridge == ocelot_port->bridge) in ocelot_single_vlan_aware_bridge()
246 "Only one VLAN-aware bridge is supported"); in ocelot_single_vlan_aware_bridge()
247 return -EBUSY; in ocelot_single_vlan_aware_bridge()
275 /* Set the vlan port members mask and issue a write command */ in ocelot_vlant_set_mask()
288 list_for_each_entry(vlan, &ocelot->vlans, list) { in ocelot_port_num_untagged_vlans()
289 if (!(vlan->portmask & BIT(port))) in ocelot_port_num_untagged_vlans()
294 * the bridge VLANs, which only matter in VLAN-aware mode. in ocelot_port_num_untagged_vlans()
296 if (vlan->vid >= OCELOT_RSV_VLAN_RANGE_START) in ocelot_port_num_untagged_vlans()
299 if (vlan->untagged & BIT(port)) in ocelot_port_num_untagged_vlans()
311 list_for_each_entry(vlan, &ocelot->vlans, list) { in ocelot_port_num_tagged_vlans()
312 if (!(vlan->portmask & BIT(port))) in ocelot_port_num_tagged_vlans()
315 if (!(vlan->untagged & BIT(port))) in ocelot_port_num_tagged_vlans()
322 /* We use native VLAN when we have to mix egress-tagged VLANs with exactly
323 * _one_ egress-untagged VLAN (_the_ native VLAN)
336 list_for_each_entry(vlan, &ocelot->vlans, list) in ocelot_port_find_native_vlan()
337 if (vlan->portmask & BIT(port) && vlan->untagged & BIT(port)) in ocelot_port_find_native_vlan()
345 * state of the port.
349 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_manage_port_tag()
353 if (ocelot_port->vlan_aware) { in ocelot_port_manage_port_tag()
380 REW_PORT_VLAN_CFG_PORT_VID(native_vlan->vid), in ocelot_port_manage_port_tag()
391 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_bridge_num_find()
392 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_bridge_num_find()
394 if (ocelot_port && ocelot_port->bridge == bridge) in ocelot_bridge_num_find()
395 return ocelot_port->bridge_num; in ocelot_bridge_num_find()
398 return -1; in ocelot_bridge_num_find()
407 /* Standalone ports use VID 0 */ in ocelot_vlan_unaware_pvid()
415 /* VLAN-unaware bridges use a reserved VID going from 4095 downwards */ in ocelot_vlan_unaware_pvid()
416 return VLAN_N_VID - bridge_num - 1; in ocelot_vlan_unaware_pvid()
423 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_set_pvid()
424 u16 pvid = ocelot_vlan_unaware_pvid(ocelot, ocelot_port->bridge); in ocelot_port_set_pvid()
427 ocelot_port->pvid_vlan = pvid_vlan; in ocelot_port_set_pvid()
429 if (ocelot_port->vlan_aware && pvid_vlan) in ocelot_port_set_pvid()
430 pvid = pvid_vlan->vid; in ocelot_port_set_pvid()
442 if (!pvid_vlan && ocelot_port->vlan_aware) in ocelot_port_set_pvid()
457 list_for_each_entry(vlan, &ocelot->vlans, list) in ocelot_bridge_vlan_find()
458 if (vlan->vid == vid) in ocelot_bridge_vlan_find()
472 portmask = vlan->portmask | BIT(port); in ocelot_vlan_member_add()
478 vlan->portmask = portmask; in ocelot_vlan_member_add()
480 * egress-tagging setting, so make sure to override an untagged in ocelot_vlan_member_add()
484 vlan->untagged |= BIT(port); in ocelot_vlan_member_add()
486 vlan->untagged &= ~BIT(port); in ocelot_vlan_member_add()
493 return -ENOMEM; in ocelot_vlan_member_add()
503 vlan->vid = vid; in ocelot_vlan_member_add()
504 vlan->portmask = portmask; in ocelot_vlan_member_add()
506 vlan->untagged = BIT(port); in ocelot_vlan_member_add()
507 INIT_LIST_HEAD(&vlan->list); in ocelot_vlan_member_add()
508 list_add_tail(&vlan->list, &ocelot->vlans); in ocelot_vlan_member_add()
522 portmask = vlan->portmask & ~BIT(port); in ocelot_vlan_member_del()
528 vlan->portmask = portmask; in ocelot_vlan_member_del()
529 if (vlan->portmask) in ocelot_vlan_member_del()
532 list_del(&vlan->list); in ocelot_vlan_member_del()
557 struct ocelot_vcap_block *block = &ocelot->block[VCAP_IS1]; in ocelot_port_vlan_filtering()
558 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_vlan_filtering()
563 list_for_each_entry(filter, &block->rules, list) { in ocelot_port_vlan_filtering()
564 if (filter->ingress_port_mask & BIT(port) && in ocelot_port_vlan_filtering()
565 filter->action.vid_replace_ena) { in ocelot_port_vlan_filtering()
568 return -EBUSY; in ocelot_port_vlan_filtering()
578 ocelot_port->bridge); in ocelot_port_vlan_filtering()
579 else if (ocelot_port->bridge) in ocelot_port_vlan_filtering()
581 ocelot_port->bridge); in ocelot_port_vlan_filtering()
585 ocelot_port->vlan_aware = vlan_aware; in ocelot_port_vlan_filtering()
597 ocelot_port_set_pvid(ocelot, port, ocelot_port->pvid_vlan); in ocelot_port_vlan_filtering()
608 /* We are adding an egress-tagged VLAN */ in ocelot_vlan_prepare()
611 "Port with egress-tagged VLANs cannot have more than one egress-untagged (native) VLAN"); in ocelot_vlan_prepare()
612 return -EBUSY; in ocelot_vlan_prepare()
615 /* We are adding an egress-tagged VLAN */ in ocelot_vlan_prepare()
618 "Port with more than one egress-untagged VLAN cannot have egress-tagged VLANs"); in ocelot_vlan_prepare()
619 return -EBUSY; in ocelot_vlan_prepare()
625 "VLAN range 4000-4095 reserved for VLAN-unaware bridging"); in ocelot_vlan_prepare()
626 return -EBUSY; in ocelot_vlan_prepare()
640 * egress-untagged to egress-tagged. in ocelot_vlan_add()
663 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_vlan_del()
670 if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid) in ocelot_vlan_del()
690 unsigned long all_ports = GENMASK(ocelot->num_phys_ports - 1, 0); in ocelot_vlan_init()
693 /* Clear VLAN table, by default all ports are members of all VLANs */ in ocelot_vlan_init()
702 /* We need VID 0 to get traffic on standalone ports. in ocelot_vlan_init()
708 /* Set vlan ingress filter mask to all ports but the CPU port by in ocelot_vlan_init()
713 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_vlan_init()
742 /* Wait at least the time it takes to receive a frame of maximum length in ocelot_port_flush()
744 * Worst-case delays for 10 kilobyte jumbo frames are: in ocelot_port_flush()
771 /* Re-enable flow control */ in ocelot_port_flush()
782 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_phylink_mac_link_down()
785 ocelot_port->speed = SPEED_UNKNOWN; in ocelot_phylink_mac_link_down()
790 if (ocelot->ops->cut_through_fwd) { in ocelot_phylink_mac_link_down()
791 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_phylink_mac_link_down()
792 ocelot->ops->cut_through_fwd(ocelot); in ocelot_phylink_mac_link_down()
793 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_phylink_mac_link_down()
800 dev_err(ocelot->dev, "failed to flush port %d: %d\n", in ocelot_phylink_mac_link_down()
823 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_phylink_mac_link_up()
827 ocelot_port->speed = speed; in ocelot_phylink_mac_link_up()
831 * to write "1000Mbps" into the LINK_SPEED field of DEV_CLOCK_CFG in ocelot_phylink_mac_link_up()
852 /* Take port out of reset by clearing the MAC_TX_RST, MAC_RX_RST and in ocelot_phylink_mac_link_up()
870 dev_err(ocelot->dev, "Unsupported speed on port %d: %d\n", in ocelot_phylink_mac_link_up()
875 /* Handle RX pause in all cases, with 2500base-X this is used for rate in ocelot_phylink_mac_link_up()
894 if (port != ocelot->npi) in ocelot_phylink_mac_link_up()
898 /* Undo the effects of ocelot_phylink_mac_link_down: in ocelot_phylink_mac_link_up()
904 /* If the port supports cut-through forwarding, update the masks before in ocelot_phylink_mac_link_up()
907 if (ocelot->ops->cut_through_fwd) { in ocelot_phylink_mac_link_up()
908 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_phylink_mac_link_up()
909 ocelot->ops->cut_through_fwd(ocelot); in ocelot_phylink_mac_link_up()
910 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_phylink_mac_link_up()
927 return -EIO; in ocelot_rx_frame_word()
936 return -EIO; in ocelot_rx_frame_word()
968 return (err < 0) ? err : -EIO; in ocelot_xtr_poll_xfh()
981 ocelot_ptp_gettime64(&ocelot->ptp_info, &ts); in ocelot_ptp_rx_timestamp()
985 full_ts_in_ns = (((tod_in_ns >> 32) - 1) << 32) | in ocelot_ptp_rx_timestamp()
993 shhwtstamps->hwtstamp = full_ts_in_ns; in ocelot_ptp_rx_timestamp()
1015 if (WARN_ON(src_port >= ocelot->num_phys_ports)) in ocelot_xtr_poll_frame()
1016 return -EINVAL; in ocelot_xtr_poll_frame()
1018 dev = ocelot->ops->port_to_netdev(ocelot, src_port); in ocelot_xtr_poll_frame()
1020 return -EINVAL; in ocelot_xtr_poll_frame()
1025 return -ENOMEM; in ocelot_xtr_poll_frame()
1028 buf_len = len - ETH_FCS_LEN; in ocelot_xtr_poll_frame()
1049 /* Update the statistics if part of the FCS was read before */ in ocelot_xtr_poll_frame()
1050 len -= ETH_FCS_LEN - sz; in ocelot_xtr_poll_frame()
1052 if (unlikely(dev->features & NETIF_F_RXFCS)) { in ocelot_xtr_poll_frame()
1057 if (ocelot->ptp) in ocelot_xtr_poll_frame()
1063 if (ocelot->ports[src_port]->bridge) in ocelot_xtr_poll_frame()
1064 skb->offload_fwd_mark = 1; in ocelot_xtr_poll_frame()
1066 skb->protocol = eth_type_trans(skb, dev); in ocelot_xtr_poll_frame()
1117 count = DIV_ROUND_UP(skb->len, 4); in ocelot_port_inject_frame()
1118 last = skb->len % 4; in ocelot_port_inject_frame()
1120 ocelot_write_rix(ocelot, ((u32 *)skb->data)[i], QS_INJ_WR, grp); in ocelot_port_inject_frame()
1130 QS_INJ_CTRL_VLD_BYTES(skb->len < OCELOT_BUFFER_CELL_SZ ? 0 : last) | in ocelot_port_inject_frame()
1138 skb->dev->stats.tx_packets++; in ocelot_port_inject_frame()
1139 skb->dev->stats.tx_bytes += skb->len; in ocelot_port_inject_frame()
1170 /* Caller must hold &ocelot->mact_lock */
1177 /* Set row and column to read from */ in ocelot_mact_read()
1187 return -ETIMEDOUT; in ocelot_mact_read()
1192 return -EINVAL; in ocelot_mact_read()
1199 return -EINVAL; in ocelot_mact_read()
1212 entry->vid = (mach >> 16) & 0xfff; in ocelot_mact_read()
1213 ether_addr_copy(entry->mac, mac); in ocelot_mact_read()
1222 mutex_lock(&ocelot->mact_lock); in ocelot_mact_flush()
1235 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_flush()
1249 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_flush()
1262 * thousands of times in a row seems rather pointless and inefficient. in ocelot_fdb_dump()
1264 mutex_lock(&ocelot->mact_lock); in ocelot_fdb_dump()
1267 for (i = 0; i < ocelot->num_mact_rows; i++) { in ocelot_fdb_dump()
1276 if (err == -EINVAL) in ocelot_fdb_dump()
1284 * VLAN-unaware bridging. in ocelot_fdb_dump()
1295 mutex_unlock(&ocelot->mact_lock); in ocelot_fdb_dump()
1310 block_vcap_is2 = &ocelot->block[VCAP_IS2]; in ocelot_trap_add()
1317 return -ENOMEM; in ocelot_trap_add()
1320 trap->prio = 1; in ocelot_trap_add()
1321 trap->id.cookie = cookie; in ocelot_trap_add()
1322 trap->id.tc_offload = false; in ocelot_trap_add()
1323 trap->block_id = VCAP_IS2; in ocelot_trap_add()
1324 trap->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_trap_add()
1325 trap->lookup = 0; in ocelot_trap_add()
1326 trap->action.cpu_copy_ena = true; in ocelot_trap_add()
1327 trap->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY; in ocelot_trap_add()
1328 trap->action.port_mask = 0; in ocelot_trap_add()
1329 trap->take_ts = take_ts; in ocelot_trap_add()
1330 trap->is_trap = true; in ocelot_trap_add()
1334 trap->ingress_port_mask |= BIT(port); in ocelot_trap_add()
1341 trap->ingress_port_mask &= ~BIT(port); in ocelot_trap_add()
1342 if (!trap->ingress_port_mask) in ocelot_trap_add()
1355 block_vcap_is2 = &ocelot->block[VCAP_IS2]; in ocelot_trap_del()
1362 trap->ingress_port_mask &= ~BIT(port); in ocelot_trap_del()
1363 if (!trap->ingress_port_mask) in ocelot_trap_del()
1374 lockdep_assert_held(&ocelot->fwd_domain_lock); in ocelot_get_bond_mask()
1376 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_get_bond_mask()
1377 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_get_bond_mask()
1382 if (ocelot_port->bond == bond) in ocelot_get_bond_mask()
1389 /* The logical port number of a LAG is equal to the lowest numbered physical
1397 return -ENOENT; in ocelot_bond_get_id()
1403 /* Returns the mask of user ports assigned to this DSA tag_8021q CPU port.
1404 * Note that when CPU ports are in a LAG, the user ports are assigned to the
1406 * port number of the LAG.
1419 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_dsa_8021q_cpu_assigned_ports()
1420 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_dsa_8021q_cpu_assigned_ports()
1425 if (ocelot_port->dsa_8021q_cpu == cpu) in ocelot_dsa_8021q_cpu_assigned_ports()
1429 if (cpu->bond) in ocelot_dsa_8021q_cpu_assigned_ports()
1430 mask &= ~ocelot_get_bond_mask(ocelot, cpu->bond); in ocelot_dsa_8021q_cpu_assigned_ports()
1436 * or the bit mask of CPU ports if said CPU port is in a LAG.
1440 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_assigned_dsa_8021q_cpu_mask()
1441 struct ocelot_port *cpu_port = ocelot_port->dsa_8021q_cpu; in ocelot_port_assigned_dsa_8021q_cpu_mask()
1446 if (cpu_port->bond) in ocelot_port_assigned_dsa_8021q_cpu_mask()
1447 return ocelot_get_bond_mask(ocelot, cpu_port->bond); in ocelot_port_assigned_dsa_8021q_cpu_mask()
1449 return BIT(cpu_port->index); in ocelot_port_assigned_dsa_8021q_cpu_mask()
1455 struct ocelot_port *ocelot_port = ocelot->ports[src_port]; in ocelot_get_bridge_fwd_mask()
1460 if (!ocelot_port || ocelot_port->stp_state != BR_STATE_FORWARDING) in ocelot_get_bridge_fwd_mask()
1463 bridge = ocelot_port->bridge; in ocelot_get_bridge_fwd_mask()
1467 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_get_bridge_fwd_mask()
1468 ocelot_port = ocelot->ports[port]; in ocelot_get_bridge_fwd_mask()
1473 if (ocelot_port->stp_state == BR_STATE_FORWARDING && in ocelot_get_bridge_fwd_mask()
1474 ocelot_port->bridge == bridge) in ocelot_get_bridge_fwd_mask()
1486 lockdep_assert_held(&ocelot->fwd_domain_lock); in ocelot_apply_bridge_fwd_mask()
1488 /* If cut-through forwarding is supported, update the masks before a in ocelot_apply_bridge_fwd_mask()
1492 if (joining && ocelot->ops->cut_through_fwd) in ocelot_apply_bridge_fwd_mask()
1493 ocelot->ops->cut_through_fwd(ocelot); in ocelot_apply_bridge_fwd_mask()
1496 * a source for the other ports. in ocelot_apply_bridge_fwd_mask()
1498 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_apply_bridge_fwd_mask()
1499 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_apply_bridge_fwd_mask()
1503 /* Unused ports can't send anywhere */ in ocelot_apply_bridge_fwd_mask()
1505 } else if (ocelot_port->is_dsa_8021q_cpu) { in ocelot_apply_bridge_fwd_mask()
1506 /* The DSA tag_8021q CPU ports need to be able to in ocelot_apply_bridge_fwd_mask()
1507 * forward packets to all ports assigned to them. in ocelot_apply_bridge_fwd_mask()
1511 } else if (ocelot_port->bridge) { in ocelot_apply_bridge_fwd_mask()
1512 struct net_device *bond = ocelot_port->bond; in ocelot_apply_bridge_fwd_mask()
1523 /* Standalone ports forward only to DSA tag_8021q CPU in ocelot_apply_bridge_fwd_mask()
1524 * ports (if those exist), or to the hardware CPU port in ocelot_apply_bridge_fwd_mask()
1534 /* If cut-through forwarding is supported and a port is leaving, there in ocelot_apply_bridge_fwd_mask()
1535 * is a chance that cut-through was disabled on the other ports due to in ocelot_apply_bridge_fwd_mask()
1537 * update the cut-through masks of the remaining ports no earlier than in ocelot_apply_bridge_fwd_mask()
1539 * the cut-through update and the forwarding domain update. in ocelot_apply_bridge_fwd_mask()
1541 if (!joining && ocelot->ops->cut_through_fwd) in ocelot_apply_bridge_fwd_mask()
1542 ocelot->ops->cut_through_fwd(ocelot); in ocelot_apply_bridge_fwd_mask()
1548 * tag_8021q mode, it is a bit mask of all active CPU ports.
1549 * PGID_SRC will take care of forwarding a packet from one user port to
1557 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_update_pgid_cpu()
1558 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_update_pgid_cpu()
1560 if (!ocelot_port || !ocelot_port->is_dsa_8021q_cpu) in ocelot_update_pgid_cpu()
1567 pgid_cpu = BIT(ocelot->num_phys_ports); in ocelot_update_pgid_cpu()
1574 struct ocelot_port *cpu_port = ocelot->ports[cpu]; in ocelot_port_setup_dsa_8021q_cpu()
1577 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_setup_dsa_8021q_cpu()
1579 cpu_port->is_dsa_8021q_cpu = true; in ocelot_port_setup_dsa_8021q_cpu()
1586 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_setup_dsa_8021q_cpu()
1592 struct ocelot_port *cpu_port = ocelot->ports[cpu]; in ocelot_port_teardown_dsa_8021q_cpu()
1595 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_teardown_dsa_8021q_cpu()
1597 cpu_port->is_dsa_8021q_cpu = false; in ocelot_port_teardown_dsa_8021q_cpu()
1600 ocelot_vlan_member_del(ocelot, cpu_port->index, vid); in ocelot_port_teardown_dsa_8021q_cpu()
1604 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_teardown_dsa_8021q_cpu()
1611 struct ocelot_port *cpu_port = ocelot->ports[cpu]; in ocelot_port_assign_dsa_8021q_cpu()
1613 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_assign_dsa_8021q_cpu()
1615 ocelot->ports[port]->dsa_8021q_cpu = cpu_port; in ocelot_port_assign_dsa_8021q_cpu()
1618 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_assign_dsa_8021q_cpu()
1624 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_unassign_dsa_8021q_cpu()
1626 ocelot->ports[port]->dsa_8021q_cpu = NULL; in ocelot_port_unassign_dsa_8021q_cpu()
1629 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_unassign_dsa_8021q_cpu()
1635 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_bridge_stp_state_set()
1638 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_bridge_stp_state_set()
1640 ocelot_port->stp_state = state; in ocelot_bridge_stp_state_set()
1643 ocelot_port->learn_ena) in ocelot_bridge_stp_state_set()
1651 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_bridge_stp_state_set()
1675 list_for_each_entry(mc, &ocelot->multicast, list) { in ocelot_multicast_get()
1676 if (ether_addr_equal(mc->addr, addr) && mc->vid == vid) in ocelot_multicast_get()
1693 unsigned long ports) in ocelot_pgid_alloc() argument
1699 return ERR_PTR(-ENOMEM); in ocelot_pgid_alloc()
1701 pgid->ports = ports; in ocelot_pgid_alloc()
1702 pgid->index = index; in ocelot_pgid_alloc()
1703 refcount_set(&pgid->refcount, 1); in ocelot_pgid_alloc()
1704 list_add_tail(&pgid->list, &ocelot->pgids); in ocelot_pgid_alloc()
1711 if (!refcount_dec_and_test(&pgid->refcount)) in ocelot_pgid_free()
1714 list_del(&pgid->list); in ocelot_pgid_free()
1725 * 3.9.1.6 IPv6 Multicast Entries, "Instead of a lookup in the in ocelot_mdb_get_pgid()
1726 * destination mask table (PGID), the destination set is programmed as in ocelot_mdb_get_pgid()
1727 * part of the entry MAC address.", and the DEST_IDX is set to 0. in ocelot_mdb_get_pgid()
1729 if (mc->entry_type == ENTRYTYPE_MACv4 || in ocelot_mdb_get_pgid()
1730 mc->entry_type == ENTRYTYPE_MACv6) in ocelot_mdb_get_pgid()
1731 return ocelot_pgid_alloc(ocelot, 0, mc->ports); in ocelot_mdb_get_pgid()
1733 list_for_each_entry(pgid, &ocelot->pgids, list) { in ocelot_mdb_get_pgid()
1735 * dummy PGID of zero that we have for MACv4/MACv6 entries in ocelot_mdb_get_pgid()
1737 if (pgid->index && pgid->ports == mc->ports) { in ocelot_mdb_get_pgid()
1738 refcount_inc(&pgid->refcount); in ocelot_mdb_get_pgid()
1747 list_for_each_entry(pgid, &ocelot->pgids, list) { in ocelot_mdb_get_pgid()
1748 if (pgid->index == index) { in ocelot_mdb_get_pgid()
1755 return ocelot_pgid_alloc(ocelot, index, mc->ports); in ocelot_mdb_get_pgid()
1758 return ERR_PTR(-ENOSPC); in ocelot_mdb_get_pgid()
1764 ether_addr_copy(addr, mc->addr); in ocelot_encode_ports_to_mdb()
1766 if (mc->entry_type == ENTRYTYPE_MACv4) { in ocelot_encode_ports_to_mdb()
1768 addr[1] = mc->ports >> 8; in ocelot_encode_ports_to_mdb()
1769 addr[2] = mc->ports & 0xff; in ocelot_encode_ports_to_mdb()
1770 } else if (mc->entry_type == ENTRYTYPE_MACv6) { in ocelot_encode_ports_to_mdb()
1771 addr[0] = mc->ports >> 8; in ocelot_encode_ports_to_mdb()
1772 addr[1] = mc->ports & 0xff; in ocelot_encode_ports_to_mdb()
1783 u16 vid = mdb->vid; in ocelot_port_mdb_add()
1788 mc = ocelot_multicast_get(ocelot, mdb->addr, vid); in ocelot_port_mdb_add()
1791 mc = devm_kzalloc(ocelot->dev, sizeof(*mc), GFP_KERNEL); in ocelot_port_mdb_add()
1793 return -ENOMEM; in ocelot_port_mdb_add()
1795 mc->entry_type = ocelot_classify_mdb(mdb->addr); in ocelot_port_mdb_add()
1796 ether_addr_copy(mc->addr, mdb->addr); in ocelot_port_mdb_add()
1797 mc->vid = vid; in ocelot_port_mdb_add()
1799 list_add_tail(&mc->list, &ocelot->multicast); in ocelot_port_mdb_add()
1804 ocelot_pgid_free(ocelot, mc->pgid); in ocelot_port_mdb_add()
1809 mc->ports |= BIT(port); in ocelot_port_mdb_add()
1813 dev_err(ocelot->dev, in ocelot_port_mdb_add()
1815 mc->addr, mc->vid); in ocelot_port_mdb_add()
1816 devm_kfree(ocelot->dev, mc); in ocelot_port_mdb_add()
1819 mc->pgid = pgid; in ocelot_port_mdb_add()
1823 if (mc->entry_type != ENTRYTYPE_MACv4 && in ocelot_port_mdb_add()
1824 mc->entry_type != ENTRYTYPE_MACv6) in ocelot_port_mdb_add()
1825 ocelot_write_rix(ocelot, pgid->ports, ANA_PGID_PGID, in ocelot_port_mdb_add()
1826 pgid->index); in ocelot_port_mdb_add()
1828 return ocelot_mact_learn(ocelot, pgid->index, addr, vid, in ocelot_port_mdb_add()
1829 mc->entry_type); in ocelot_port_mdb_add()
1840 u16 vid = mdb->vid; in ocelot_port_mdb_del()
1845 mc = ocelot_multicast_get(ocelot, mdb->addr, vid); in ocelot_port_mdb_del()
1847 return -ENOENT; in ocelot_port_mdb_del()
1852 ocelot_pgid_free(ocelot, mc->pgid); in ocelot_port_mdb_del()
1853 mc->ports &= ~BIT(port); in ocelot_port_mdb_del()
1854 if (!mc->ports) { in ocelot_port_mdb_del()
1855 list_del(&mc->list); in ocelot_port_mdb_del()
1856 devm_kfree(ocelot->dev, mc); in ocelot_port_mdb_del()
1860 /* We have a PGID with fewer ports now */ in ocelot_port_mdb_del()
1864 mc->pgid = pgid; in ocelot_port_mdb_del()
1868 if (mc->entry_type != ENTRYTYPE_MACv4 && in ocelot_port_mdb_del()
1869 mc->entry_type != ENTRYTYPE_MACv6) in ocelot_port_mdb_del()
1870 ocelot_write_rix(ocelot, pgid->ports, ANA_PGID_PGID, in ocelot_port_mdb_del()
1871 pgid->index); in ocelot_port_mdb_del()
1873 return ocelot_mact_learn(ocelot, pgid->index, addr, vid, in ocelot_port_mdb_del()
1874 mc->entry_type); in ocelot_port_mdb_del()
1882 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_bridge_join()
1889 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_bridge_join()
1891 ocelot_port->bridge = bridge; in ocelot_port_bridge_join()
1892 ocelot_port->bridge_num = bridge_num; in ocelot_port_bridge_join()
1896 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_bridge_join()
1908 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_bridge_leave()
1910 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_bridge_leave()
1915 ocelot_port->bridge = NULL; in ocelot_port_bridge_leave()
1916 ocelot_port->bridge_num = -1; in ocelot_port_bridge_leave()
1922 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_bridge_leave()
1928 unsigned long visited = GENMASK(ocelot->num_phys_ports - 1, 0); in ocelot_set_aggr_pgids()
1936 ocelot_write_rix(ocelot, GENMASK(ocelot->num_phys_ports - 1, 0), in ocelot_set_aggr_pgids()
1939 /* The visited ports bitmask holds the list of ports offloading any in ocelot_set_aggr_pgids()
1940 * bonding interface. Initially we mark all these ports as unvisited, in ocelot_set_aggr_pgids()
1943 * port ID == LAG ID. So we mark as visited all further ports in the in ocelot_set_aggr_pgids()
1945 * we set up the aggregation PGIDs only once per bonding interface. in ocelot_set_aggr_pgids()
1947 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_set_aggr_pgids()
1948 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_set_aggr_pgids()
1950 if (!ocelot_port || !ocelot_port->bond) in ocelot_set_aggr_pgids()
1956 /* Now, set PGIDs for each active LAG */ in ocelot_set_aggr_pgids()
1957 for (lag = 0; lag < ocelot->num_phys_ports; lag++) { in ocelot_set_aggr_pgids()
1958 struct net_device *bond = ocelot->ports[lag]->bond; in ocelot_set_aggr_pgids()
1968 for_each_set_bit(port, &bond_mask, ocelot->num_phys_ports) { in ocelot_set_aggr_pgids()
1969 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_set_aggr_pgids()
1975 if (ocelot_port->lag_tx_active) in ocelot_set_aggr_pgids()
1992 /* Mark all ports in the same LAG as visited to avoid applying in ocelot_set_aggr_pgids()
1995 for (port = lag; port < ocelot->num_phys_ports; port++) { in ocelot_set_aggr_pgids()
1996 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_set_aggr_pgids()
2001 if (ocelot_port->bond == bond) in ocelot_set_aggr_pgids()
2007 /* When offloading a bonding interface, the switch ports configured under the
2009 * of the lowest numbered physical port in that bond. Otherwise, in standalone/
2016 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_setup_logical_port_ids()
2017 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_setup_logical_port_ids()
2023 bond = ocelot_port->bond; in ocelot_setup_logical_port_ids()
2045 u16 vid = mc->vid; in ocelot_migrate_mc()
2047 dev_dbg(ocelot->dev, in ocelot_migrate_mc()
2049 mc->addr, mc->vid, from_mask, to_mask); in ocelot_migrate_mc()
2054 ocelot_pgid_free(ocelot, mc->pgid); in ocelot_migrate_mc()
2058 mc->ports &= ~from_mask; in ocelot_migrate_mc()
2059 mc->ports |= to_mask; in ocelot_migrate_mc()
2063 dev_err(ocelot->dev, in ocelot_migrate_mc()
2065 mc->addr, mc->vid); in ocelot_migrate_mc()
2066 devm_kfree(ocelot->dev, mc); in ocelot_migrate_mc()
2069 mc->pgid = pgid; in ocelot_migrate_mc()
2073 if (mc->entry_type != ENTRYTYPE_MACv4 && in ocelot_migrate_mc()
2074 mc->entry_type != ENTRYTYPE_MACv6) in ocelot_migrate_mc()
2075 ocelot_write_rix(ocelot, pgid->ports, ANA_PGID_PGID, in ocelot_migrate_mc()
2076 pgid->index); in ocelot_migrate_mc()
2078 return ocelot_mact_learn(ocelot, pgid->index, addr, vid, in ocelot_migrate_mc()
2079 mc->entry_type); in ocelot_migrate_mc()
2088 list_for_each_entry(mc, &ocelot->multicast, list) { in ocelot_migrate_mdbs()
2089 if (!(mc->ports & from_mask)) in ocelot_migrate_mdbs()
2102 * Logical port number for front port. If port is not a member of a LLAG,
2103 * then PORTID must be set to the physical port number.
2104 * If port is a member of a LLAG, then PORTID must be set to the common
2105 * PORTID_VAL used for all member ports of the LLAG.
2106 * The value must not exceed the number of physical ports on the device.
2118 lockdep_assert_held(&ocelot->fwd_domain_lock); in ocelot_migrate_lag_fdbs()
2120 list_for_each_entry(fdb, &ocelot->lag_fdbs, list) { in ocelot_migrate_lag_fdbs()
2121 if (fdb->bond != bond) in ocelot_migrate_lag_fdbs()
2124 err = ocelot_mact_forget(ocelot, fdb->addr, fdb->vid); in ocelot_migrate_lag_fdbs()
2126 dev_err(ocelot->dev, in ocelot_migrate_lag_fdbs()
2128 bond->name, fdb->addr, fdb->vid, ERR_PTR(err)); in ocelot_migrate_lag_fdbs()
2131 err = ocelot_mact_learn(ocelot, lag, fdb->addr, fdb->vid, in ocelot_migrate_lag_fdbs()
2134 dev_err(ocelot->dev, in ocelot_migrate_lag_fdbs()
2136 bond->name, fdb->addr, fdb->vid, ERR_PTR(err)); in ocelot_migrate_lag_fdbs()
2146 if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) { in ocelot_port_lag_join()
2149 return -EOPNOTSUPP; in ocelot_port_lag_join()
2152 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_lag_join()
2154 ocelot->ports[port]->bond = bond; in ocelot_port_lag_join()
2160 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_lag_join()
2171 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_lag_leave()
2175 ocelot->ports[port]->bond = NULL; in ocelot_port_lag_leave()
2186 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_lag_leave()
2192 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_lag_change()
2194 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_lag_change()
2196 ocelot_port->lag_tx_active = lag_tx_active; in ocelot_port_lag_change()
2201 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_lag_change()
2214 return -ENOMEM; in ocelot_lag_fdb_add()
2216 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_add()
2221 ether_addr_copy(fdb->addr, addr); in ocelot_lag_fdb_add()
2222 fdb->vid = vid; in ocelot_lag_fdb_add()
2223 fdb->bond = bond; in ocelot_lag_fdb_add()
2229 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_add()
2234 list_add_tail(&fdb->list, &ocelot->lag_fdbs); in ocelot_lag_fdb_add()
2235 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_add()
2247 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_del()
2252 list_for_each_entry_safe(fdb, tmp, &ocelot->lag_fdbs, list) { in ocelot_lag_fdb_del()
2253 if (!ether_addr_equal(fdb->addr, addr) || fdb->vid != vid || in ocelot_lag_fdb_del()
2254 fdb->bond != bond) in ocelot_lag_fdb_del()
2258 list_del(&fdb->list); in ocelot_lag_fdb_del()
2259 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_del()
2265 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_del()
2267 return -ENOENT; in ocelot_lag_fdb_del()
2272 * The length of VLAN tags is accounted for automatically via DEV_MAC_TAGS_CFG.
2274 * length of the tag and optional prefix needs to be accounted for privately,
2279 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_set_maxlen()
2284 if (port == ocelot->npi) { in ocelot_port_set_maxlen()
2287 if (ocelot->npi_inj_prefix == OCELOT_TAG_PREFIX_SHORT) in ocelot_port_set_maxlen()
2289 else if (ocelot->npi_inj_prefix == OCELOT_TAG_PREFIX_LONG) in ocelot_port_set_maxlen()
2295 /* Set Pause watermark hysteresis */ in ocelot_port_set_maxlen()
2304 atop_tot = (ocelot->packet_buffer_size - 9 * maxlen) / in ocelot_port_set_maxlen()
2307 ocelot_write_rix(ocelot, ocelot->ops->wm_enc(atop), SYS_ATOP, port); in ocelot_port_set_maxlen()
2308 ocelot_write(ocelot, ocelot->ops->wm_enc(atop_tot), SYS_ATOP_TOT_CFG); in ocelot_port_set_maxlen()
2314 int max_mtu = 65535 - ETH_HLEN - ETH_FCS_LEN; in ocelot_get_max_mtu()
2316 if (port == ocelot->npi) { in ocelot_get_max_mtu()
2317 max_mtu -= OCELOT_TAG_LEN; in ocelot_get_max_mtu()
2319 if (ocelot->npi_inj_prefix == OCELOT_TAG_PREFIX_SHORT) in ocelot_get_max_mtu()
2320 max_mtu -= OCELOT_SHORT_PREFIX_LEN; in ocelot_get_max_mtu()
2321 else if (ocelot->npi_inj_prefix == OCELOT_TAG_PREFIX_LONG) in ocelot_get_max_mtu()
2322 max_mtu -= OCELOT_LONG_PREFIX_LEN; in ocelot_get_max_mtu()
2332 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_set_learning()
2341 ocelot_port->learn_ena = enabled; in ocelot_port_set_learning()
2384 return -EINVAL; in ocelot_port_pre_bridge_flags()
2422 return -ERANGE; in ocelot_port_set_default_prio()
2441 return -EOPNOTSUPP; in ocelot_port_get_dscp_prio()
2445 /* Re-read ANA_DSCP_CFG for the translated DSCP */ in ocelot_port_get_dscp_prio()
2450 * to VLAN PCP or port-based default. in ocelot_port_get_dscp_prio()
2453 return -EOPNOTSUPP; in ocelot_port_get_dscp_prio()
2464 return -ERANGE; in ocelot_port_add_dscp_prio()
2530 struct ocelot_mirror *m = ocelot->mirror; in ocelot_mirror_get()
2533 if (m->to != to) { in ocelot_mirror_get()
2536 return ERR_PTR(-EBUSY); in ocelot_mirror_get()
2539 refcount_inc(&m->refcount); in ocelot_mirror_get()
2545 return ERR_PTR(-ENOMEM); in ocelot_mirror_get()
2547 m->to = to; in ocelot_mirror_get()
2548 refcount_set(&m->refcount, 1); in ocelot_mirror_get()
2549 ocelot->mirror = m; in ocelot_mirror_get()
2559 struct ocelot_mirror *m = ocelot->mirror; in ocelot_mirror_put()
2561 if (!refcount_dec_and_test(&m->refcount)) in ocelot_mirror_put()
2565 ocelot->mirror = NULL; in ocelot_mirror_put()
2605 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_init_port()
2607 skb_queue_head_init(&ocelot_port->tx_skbs); in ocelot_init_port()
2611 /* Set MAC IFG Gaps in ocelot_init_port()
2618 /* Load seed (0) and set MAC HDX late collision */ in ocelot_init_port()
2626 /* Set Max Length and maximum tags allowed */ in ocelot_init_port()
2634 /* Set SMAC of Pause frame (00:00:00:00:00:00) */ in ocelot_init_port()
2638 /* Enable transmission of pause frames */ in ocelot_init_port()
2646 /* Set default VLAN and tag type to 8021Q. */ in ocelot_init_port()
2654 /* Set the port's initial logical port ID value, enable receiving in ocelot_init_port()
2668 /* Configure and enable the CPU port module, which is a set of queues
2674 int cpu = ocelot->num_phys_ports; in ocelot_cpu_port_init()
2678 /* Instead set up a multicast destination PGID for traffic copied to in ocelot_cpu_port_init()
2708 * the number of 240-byte free memory words (aka 4-cell chunks) and not in ocelot_detect_features()
2712 ocelot->packet_buffer_size = 240 * SYS_MMGT_FREECNT(mmgt); in ocelot_detect_features()
2715 ocelot->num_frame_refs = QSYS_MMGT_EQ_CTRL_FP_FREE_CNT(eq_ctrl); in ocelot_detect_features()
2723 if (ocelot->ops->reset) { in ocelot_init()
2724 ret = ocelot->ops->reset(ocelot); in ocelot_init()
2726 dev_err(ocelot->dev, "Switch reset failed\n"); in ocelot_init()
2731 mutex_init(&ocelot->ptp_lock); in ocelot_init()
2732 mutex_init(&ocelot->mact_lock); in ocelot_init()
2733 mutex_init(&ocelot->fwd_domain_lock); in ocelot_init()
2734 mutex_init(&ocelot->tas_lock); in ocelot_init()
2735 spin_lock_init(&ocelot->ptp_clock_lock); in ocelot_init()
2736 spin_lock_init(&ocelot->ts_id_lock); in ocelot_init()
2738 ocelot->owq = alloc_ordered_workqueue("ocelot-owq", 0); in ocelot_init()
2739 if (!ocelot->owq) in ocelot_init()
2740 return -ENOMEM; in ocelot_init()
2744 destroy_workqueue(ocelot->owq); in ocelot_init()
2748 INIT_LIST_HEAD(&ocelot->multicast); in ocelot_init()
2749 INIT_LIST_HEAD(&ocelot->pgids); in ocelot_init()
2750 INIT_LIST_HEAD(&ocelot->vlans); in ocelot_init()
2751 INIT_LIST_HEAD(&ocelot->lag_fdbs); in ocelot_init()
2758 if (ocelot->ops->psfp_init) in ocelot_init()
2759 ocelot->ops->psfp_init(ocelot); in ocelot_init()
2761 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_init()
2768 /* Only use S-Tag */ in ocelot_init()
2780 /* Set MAC age time to default value. The entry is aged after in ocelot_init()
2788 regmap_field_write(ocelot->regfields[ANA_ADVLEARN_VLAN_CHK], 1); in ocelot_init()
2790 /* Setup frame ageing - fixed value "2 sec" - in 6.5 us units */ in ocelot_init()
2795 for (i = 0; i < ocelot->num_flooding_pgids; i++) in ocelot_init()
2806 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_init()
2809 /* Do not forward BPDU frames to the front ports. */ in ocelot_init()
2819 u32 val = ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports - 1, 0)); in ocelot_init()
2827 ocelot_rmw_rix(ocelot, ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports)), in ocelot_init()
2828 ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports)), in ocelot_init()
2830 ocelot_rmw_rix(ocelot, ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports)), in ocelot_init()
2831 ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports)), in ocelot_init()
2864 destroy_workqueue(ocelot->owq); in ocelot_deinit()
2870 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_deinit_port()
2872 skb_queue_purge(&ocelot_port->tx_skbs); in ocelot_deinit_port()