Lines Matching full:ocelot
3 * Microsemi Ocelot Switch driver
7 #include <linux/dsa/ocelot.h>
14 #include "ocelot.h"
30 /* Caller must hold &ocelot->mact_lock */
31 static inline u32 ocelot_mact_read_macaccess(struct ocelot *ocelot) in ocelot_mact_read_macaccess() argument
33 return ocelot_read(ocelot, ANA_TABLES_MACACCESS); in ocelot_mact_read_macaccess()
36 /* Caller must hold &ocelot->mact_lock */
37 static inline int ocelot_mact_wait_for_completion(struct ocelot *ocelot) in ocelot_mact_wait_for_completion() argument
42 ocelot, val, in ocelot_mact_wait_for_completion()
48 /* Caller must hold &ocelot->mact_lock */
49 static void ocelot_mact_select(struct ocelot *ocelot, in ocelot_mact_select() argument
66 ocelot_write(ocelot, macl, ANA_TABLES_MACLDATA); in ocelot_mact_select()
67 ocelot_write(ocelot, mach, ANA_TABLES_MACHDATA); in ocelot_mact_select()
71 static int __ocelot_mact_learn(struct ocelot *ocelot, int port, in __ocelot_mact_learn() argument
90 if (mc_ports & BIT(ocelot->num_phys_ports)) in __ocelot_mact_learn()
93 ocelot_mact_select(ocelot, mac, vid); in __ocelot_mact_learn()
96 ocelot_write(ocelot, cmd, ANA_TABLES_MACACCESS); in __ocelot_mact_learn()
98 err = ocelot_mact_wait_for_completion(ocelot); in __ocelot_mact_learn()
103 int ocelot_mact_learn(struct ocelot *ocelot, int port, in ocelot_mact_learn() argument
109 mutex_lock(&ocelot->mact_lock); in ocelot_mact_learn()
110 ret = __ocelot_mact_learn(ocelot, port, mac, vid, type); in ocelot_mact_learn()
111 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_learn()
117 int ocelot_mact_forget(struct ocelot *ocelot, in ocelot_mact_forget() argument
122 mutex_lock(&ocelot->mact_lock); in ocelot_mact_forget()
124 ocelot_mact_select(ocelot, mac, vid); in ocelot_mact_forget()
127 ocelot_write(ocelot, in ocelot_mact_forget()
131 err = ocelot_mact_wait_for_completion(ocelot); in ocelot_mact_forget()
133 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_forget()
139 int ocelot_mact_lookup(struct ocelot *ocelot, int *dst_idx, in ocelot_mact_lookup() argument
145 mutex_lock(&ocelot->mact_lock); in ocelot_mact_lookup()
147 ocelot_mact_select(ocelot, mac, vid); in ocelot_mact_lookup()
150 ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID | in ocelot_mact_lookup()
154 if (ocelot_mact_wait_for_completion(ocelot)) { in ocelot_mact_lookup()
155 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_lookup()
160 val = ocelot_read(ocelot, ANA_TABLES_MACACCESS); in ocelot_mact_lookup()
162 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_lookup()
174 int ocelot_mact_learn_streamdata(struct ocelot *ocelot, int dst_idx, in ocelot_mact_learn_streamdata() argument
182 mutex_lock(&ocelot->mact_lock); in ocelot_mact_learn_streamdata()
184 ocelot_write(ocelot, in ocelot_mact_learn_streamdata()
191 ret = __ocelot_mact_learn(ocelot, dst_idx, mac, vid, type); in ocelot_mact_learn_streamdata()
193 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_learn_streamdata()
199 static void ocelot_mact_init(struct ocelot *ocelot) in ocelot_mact_init() argument
205 ocelot_rmw(ocelot, 0, in ocelot_mact_init()
212 * holding &ocelot->mact_lock is pointless. in ocelot_mact_init()
214 ocelot_write(ocelot, MACACCESS_CMD_INIT, ANA_TABLES_MACACCESS); in ocelot_mact_init()
217 void ocelot_pll5_init(struct ocelot *ocelot) in ocelot_pll5_init() argument
220 * The values are coming from the VTSS API for Ocelot in ocelot_pll5_init()
222 regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG4, in ocelot_pll5_init()
225 regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG0, in ocelot_pll5_init()
237 regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG2, in ocelot_pll5_init()
247 static void ocelot_vcap_enable(struct ocelot *ocelot, int port) in ocelot_vcap_enable() argument
249 ocelot_write_gix(ocelot, ANA_PORT_VCAP_S2_CFG_S2_ENA | in ocelot_vcap_enable()
253 ocelot_write_gix(ocelot, ANA_PORT_VCAP_CFG_S1_ENA, in ocelot_vcap_enable()
256 ocelot_rmw_gix(ocelot, REW_PORT_CFG_ES0_EN, in ocelot_vcap_enable()
261 static int ocelot_single_vlan_aware_bridge(struct ocelot *ocelot, in ocelot_single_vlan_aware_bridge() argument
267 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_single_vlan_aware_bridge()
268 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_single_vlan_aware_bridge()
290 static inline u32 ocelot_vlant_read_vlanaccess(struct ocelot *ocelot) in ocelot_vlant_read_vlanaccess() argument
292 return ocelot_read(ocelot, ANA_TABLES_VLANACCESS); in ocelot_vlant_read_vlanaccess()
295 static inline int ocelot_vlant_wait_for_completion(struct ocelot *ocelot) in ocelot_vlant_wait_for_completion() argument
300 ocelot, in ocelot_vlant_wait_for_completion()
307 static int ocelot_vlant_set_mask(struct ocelot *ocelot, u16 vid, u32 mask) in ocelot_vlant_set_mask() argument
310 ocelot_write(ocelot, ANA_TABLES_VLANTIDX_V_INDEX(vid), in ocelot_vlant_set_mask()
313 ocelot_write(ocelot, ANA_TABLES_VLANACCESS_VLAN_PORT_MASK(mask) | in ocelot_vlant_set_mask()
317 return ocelot_vlant_wait_for_completion(ocelot); in ocelot_vlant_set_mask()
320 static int ocelot_port_num_untagged_vlans(struct ocelot *ocelot, int port) in ocelot_port_num_untagged_vlans() argument
325 list_for_each_entry(vlan, &ocelot->vlans, list) { in ocelot_port_num_untagged_vlans()
343 static int ocelot_port_num_tagged_vlans(struct ocelot *ocelot, int port) in ocelot_port_num_tagged_vlans() argument
348 list_for_each_entry(vlan, &ocelot->vlans, list) { in ocelot_port_num_tagged_vlans()
362 static bool ocelot_port_uses_native_vlan(struct ocelot *ocelot, int port) in ocelot_port_uses_native_vlan() argument
364 return ocelot_port_num_tagged_vlans(ocelot, port) && in ocelot_port_uses_native_vlan()
365 ocelot_port_num_untagged_vlans(ocelot, port) == 1; in ocelot_port_uses_native_vlan()
369 ocelot_port_find_native_vlan(struct ocelot *ocelot, int port) in ocelot_port_find_native_vlan() argument
373 list_for_each_entry(vlan, &ocelot->vlans, list) in ocelot_port_find_native_vlan()
384 static void ocelot_port_manage_port_tag(struct ocelot *ocelot, int port) in ocelot_port_manage_port_tag() argument
386 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_manage_port_tag()
391 uses_native_vlan = ocelot_port_uses_native_vlan(ocelot, port); in ocelot_port_manage_port_tag()
395 else if (ocelot_port_num_untagged_vlans(ocelot, port)) in ocelot_port_manage_port_tag()
403 ocelot_rmw_gix(ocelot, REW_TAG_CFG_TAG_CFG(tag_cfg), in ocelot_port_manage_port_tag()
414 native_vlan = ocelot_port_find_native_vlan(ocelot, port); in ocelot_port_manage_port_tag()
416 ocelot_rmw_gix(ocelot, in ocelot_port_manage_port_tag()
423 int ocelot_bridge_num_find(struct ocelot *ocelot, in ocelot_bridge_num_find() argument
428 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_bridge_num_find()
429 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_bridge_num_find()
439 static u16 ocelot_vlan_unaware_pvid(struct ocelot *ocelot, in ocelot_vlan_unaware_pvid() argument
448 bridge_num = ocelot_bridge_num_find(ocelot, bridge); in ocelot_vlan_unaware_pvid()
457 static void ocelot_port_set_pvid(struct ocelot *ocelot, int port, in ocelot_port_set_pvid() argument
460 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_set_pvid()
461 u16 pvid = ocelot_vlan_unaware_pvid(ocelot, ocelot_port->bridge); in ocelot_port_set_pvid()
469 ocelot_rmw_gix(ocelot, in ocelot_port_set_pvid()
483 ocelot_rmw_gix(ocelot, val, in ocelot_port_set_pvid()
489 static struct ocelot_bridge_vlan *ocelot_bridge_vlan_find(struct ocelot *ocelot, in ocelot_bridge_vlan_find() argument
494 list_for_each_entry(vlan, &ocelot->vlans, list) in ocelot_bridge_vlan_find()
501 static int ocelot_vlan_member_add(struct ocelot *ocelot, int port, u16 vid, in ocelot_vlan_member_add() argument
504 struct ocelot_bridge_vlan *vlan = ocelot_bridge_vlan_find(ocelot, vid); in ocelot_vlan_member_add()
511 err = ocelot_vlant_set_mask(ocelot, vid, portmask); in ocelot_vlan_member_add()
534 err = ocelot_vlant_set_mask(ocelot, vid, portmask); in ocelot_vlan_member_add()
545 list_add_tail(&vlan->list, &ocelot->vlans); in ocelot_vlan_member_add()
550 static int ocelot_vlan_member_del(struct ocelot *ocelot, int port, u16 vid) in ocelot_vlan_member_del() argument
552 struct ocelot_bridge_vlan *vlan = ocelot_bridge_vlan_find(ocelot, vid); in ocelot_vlan_member_del()
561 err = ocelot_vlant_set_mask(ocelot, vid, portmask); in ocelot_vlan_member_del()
575 static int ocelot_add_vlan_unaware_pvid(struct ocelot *ocelot, int port, in ocelot_add_vlan_unaware_pvid() argument
578 u16 vid = ocelot_vlan_unaware_pvid(ocelot, bridge); in ocelot_add_vlan_unaware_pvid()
580 return ocelot_vlan_member_add(ocelot, port, vid, true); in ocelot_add_vlan_unaware_pvid()
583 static int ocelot_del_vlan_unaware_pvid(struct ocelot *ocelot, int port, in ocelot_del_vlan_unaware_pvid() argument
586 u16 vid = ocelot_vlan_unaware_pvid(ocelot, bridge); in ocelot_del_vlan_unaware_pvid()
588 return ocelot_vlan_member_del(ocelot, port, vid); in ocelot_del_vlan_unaware_pvid()
591 int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, in ocelot_port_vlan_filtering() argument
594 struct ocelot_vcap_block *block = &ocelot->block[VCAP_IS1]; in ocelot_port_vlan_filtering()
595 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_vlan_filtering()
609 err = ocelot_single_vlan_aware_bridge(ocelot, extack); in ocelot_port_vlan_filtering()
614 err = ocelot_del_vlan_unaware_pvid(ocelot, port, in ocelot_port_vlan_filtering()
617 err = ocelot_add_vlan_unaware_pvid(ocelot, port, in ocelot_port_vlan_filtering()
629 ocelot_rmw_gix(ocelot, val, in ocelot_port_vlan_filtering()
634 ocelot_port_set_pvid(ocelot, port, ocelot_port->pvid_vlan); in ocelot_port_vlan_filtering()
635 ocelot_port_manage_port_tag(ocelot, port); in ocelot_port_vlan_filtering()
641 int ocelot_vlan_prepare(struct ocelot *ocelot, int port, u16 vid, bool pvid, in ocelot_vlan_prepare() argument
646 if (ocelot_port_uses_native_vlan(ocelot, port)) { in ocelot_vlan_prepare()
653 if (ocelot_port_num_untagged_vlans(ocelot, port) > 1) { in ocelot_vlan_prepare()
670 int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, in ocelot_vlan_add() argument
682 err = ocelot_vlan_member_add(ocelot, port, vid, untagged); in ocelot_vlan_add()
688 ocelot_port_set_pvid(ocelot, port, in ocelot_vlan_add()
689 ocelot_bridge_vlan_find(ocelot, vid)); in ocelot_vlan_add()
692 ocelot_port_manage_port_tag(ocelot, port); in ocelot_vlan_add()
698 int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid) in ocelot_vlan_del() argument
700 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_vlan_del()
710 err = ocelot_vlan_member_del(ocelot, port, vid); in ocelot_vlan_del()
716 ocelot_port_set_pvid(ocelot, port, NULL); in ocelot_vlan_del()
719 ocelot_port_manage_port_tag(ocelot, port); in ocelot_vlan_del()
725 static void ocelot_vlan_init(struct ocelot *ocelot) in ocelot_vlan_init() argument
727 unsigned long all_ports = GENMASK(ocelot->num_phys_ports - 1, 0); in ocelot_vlan_init()
731 ocelot_write(ocelot, ANA_TABLES_VLANACCESS_CMD_INIT, in ocelot_vlan_init()
733 ocelot_vlant_wait_for_completion(ocelot); in ocelot_vlan_init()
737 ocelot_vlant_set_mask(ocelot, vid, 0); in ocelot_vlan_init()
743 ocelot_vlant_set_mask(ocelot, OCELOT_STANDALONE_PVID, all_ports); in ocelot_vlan_init()
748 ocelot_write(ocelot, all_ports, ANA_VLANMASK); in ocelot_vlan_init()
750 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_vlan_init()
751 ocelot_write_gix(ocelot, 0, REW_PORT_VLAN_CFG, port); in ocelot_vlan_init()
752 ocelot_write_gix(ocelot, 0, REW_TAG_CFG, port); in ocelot_vlan_init()
756 static u32 ocelot_read_eq_avail(struct ocelot *ocelot, int port) in ocelot_read_eq_avail() argument
758 return ocelot_read_rix(ocelot, QSYS_SW_STATUS, port); in ocelot_read_eq_avail()
761 static int ocelot_port_flush(struct ocelot *ocelot, int port) in ocelot_port_flush() argument
767 ocelot_rmw_rix(ocelot, QSYS_PORT_MODE_DEQUEUE_DIS, in ocelot_port_flush()
772 ocelot_fields_read(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, &pause_ena); in ocelot_port_flush()
773 ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, 0); in ocelot_port_flush()
776 ocelot_fields_write(ocelot, port, in ocelot_port_flush()
790 ocelot_rmw_rix(ocelot, 0, SYS_FRONT_PORT_MODE_HDX_MODE, in ocelot_port_flush()
794 ocelot_rmw_gix(ocelot, REW_PORT_CFG_FLUSH_ENA, REW_PORT_CFG_FLUSH_ENA, in ocelot_port_flush()
798 ocelot_rmw_rix(ocelot, 0, QSYS_PORT_MODE_DEQUEUE_DIS, QSYS_PORT_MODE, in ocelot_port_flush()
803 100, 2000000, false, ocelot, port); in ocelot_port_flush()
806 ocelot_rmw_gix(ocelot, 0, REW_PORT_CFG_FLUSH_ENA, REW_PORT_CFG, port); in ocelot_port_flush()
809 ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, pause_ena); in ocelot_port_flush()
814 int ocelot_port_configure_serdes(struct ocelot *ocelot, int port, in ocelot_port_configure_serdes() argument
817 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_configure_serdes()
818 struct device *dev = ocelot->dev; in ocelot_port_configure_serdes()
853 void ocelot_phylink_mac_config(struct ocelot *ocelot, int port, in ocelot_phylink_mac_config() argument
857 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_phylink_mac_config()
879 void ocelot_phylink_mac_link_down(struct ocelot *ocelot, int port, in ocelot_phylink_mac_link_down() argument
884 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_phylink_mac_link_down()
892 if (ocelot->ops->cut_through_fwd) { in ocelot_phylink_mac_link_down()
893 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_phylink_mac_link_down()
894 ocelot->ops->cut_through_fwd(ocelot); in ocelot_phylink_mac_link_down()
895 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_phylink_mac_link_down()
898 ocelot_fields_write(ocelot, port, QSYS_SWITCH_PORT_MODE_PORT_ENA, 0); in ocelot_phylink_mac_link_down()
900 err = ocelot_port_flush(ocelot, port); in ocelot_phylink_mac_link_down()
902 dev_err(ocelot->dev, "failed to flush port %d: %d\n", in ocelot_phylink_mac_link_down()
917 void ocelot_phylink_mac_link_up(struct ocelot *ocelot, int port, in ocelot_phylink_mac_link_up() argument
925 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_phylink_mac_link_up()
972 dev_err(ocelot->dev, "Unsupported speed on port %d: %d\n", in ocelot_phylink_mac_link_up()
989 ocelot_write_rix(ocelot, mac_fc_cfg, SYS_MAC_FC_CFG, port); in ocelot_phylink_mac_link_up()
991 ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port); in ocelot_phylink_mac_link_up()
994 if (port != ocelot->npi) in ocelot_phylink_mac_link_up()
995 ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, in ocelot_phylink_mac_link_up()
1007 if (ocelot->ops->cut_through_fwd) { in ocelot_phylink_mac_link_up()
1008 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_phylink_mac_link_up()
1011 * below also calls ocelot->ops->cut_through_fwd(), in ocelot_phylink_mac_link_up()
1014 ocelot_port_update_active_preemptible_tcs(ocelot, port); in ocelot_phylink_mac_link_up()
1015 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_phylink_mac_link_up()
1019 ocelot_fields_write(ocelot, port, in ocelot_phylink_mac_link_up()
1024 static int ocelot_rx_frame_word(struct ocelot *ocelot, u8 grp, bool ifh, in ocelot_rx_frame_word() argument
1029 val = ocelot_read_rix(ocelot, QS_XTR_RD, grp); in ocelot_rx_frame_word()
1035 val = ocelot_read_rix(ocelot, QS_XTR_RD, grp); in ocelot_rx_frame_word()
1048 val = ocelot_read_rix(ocelot, QS_XTR_RD, grp); in ocelot_rx_frame_word()
1050 *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp); in ocelot_rx_frame_word()
1056 *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp); in ocelot_rx_frame_word()
1066 static int ocelot_xtr_poll_xfh(struct ocelot *ocelot, int grp, u32 *xfh) in ocelot_xtr_poll_xfh() argument
1071 err = ocelot_rx_frame_word(ocelot, grp, true, &xfh[i]); in ocelot_xtr_poll_xfh()
1079 void ocelot_ptp_rx_timestamp(struct ocelot *ocelot, struct sk_buff *skb, in ocelot_ptp_rx_timestamp() argument
1086 ocelot_ptp_gettime64(&ocelot->ptp_info, &ts); in ocelot_ptp_rx_timestamp()
1102 int ocelot_xtr_poll_frame(struct ocelot *ocelot, int grp, struct sk_buff **nskb) in ocelot_xtr_poll_frame() argument
1112 err = ocelot_xtr_poll_xfh(ocelot, grp, xfh); in ocelot_xtr_poll_frame()
1120 if (WARN_ON(src_port >= ocelot->num_phys_ports)) in ocelot_xtr_poll_frame()
1123 dev = ocelot->ops->port_to_netdev(ocelot, src_port); in ocelot_xtr_poll_frame()
1138 sz = ocelot_rx_frame_word(ocelot, grp, false, &val); in ocelot_xtr_poll_frame()
1148 sz = ocelot_rx_frame_word(ocelot, grp, false, &val); in ocelot_xtr_poll_frame()
1162 if (ocelot->ptp) in ocelot_xtr_poll_frame()
1163 ocelot_ptp_rx_timestamp(ocelot, skb, timestamp); in ocelot_xtr_poll_frame()
1168 if (ocelot->ports[src_port]->bridge) in ocelot_xtr_poll_frame()
1183 bool ocelot_can_inject(struct ocelot *ocelot, int grp) in ocelot_can_inject() argument
1185 u32 val = ocelot_read(ocelot, QS_INJ_STATUS); in ocelot_can_inject()
1208 void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp, in ocelot_port_inject_frame() argument
1214 ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) | in ocelot_port_inject_frame()
1220 ocelot_write_rix(ocelot, ifh[i], QS_INJ_WR, grp); in ocelot_port_inject_frame()
1225 ocelot_write_rix(ocelot, ((u32 *)skb->data)[i], QS_INJ_WR, grp); in ocelot_port_inject_frame()
1229 ocelot_write_rix(ocelot, 0, QS_INJ_WR, grp); in ocelot_port_inject_frame()
1234 ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) | in ocelot_port_inject_frame()
1240 ocelot_write_rix(ocelot, 0, QS_INJ_WR, grp); in ocelot_port_inject_frame()
1248 void ocelot_drain_cpu_queue(struct ocelot *ocelot, int grp) in ocelot_drain_cpu_queue() argument
1250 while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)) in ocelot_drain_cpu_queue()
1251 ocelot_read_rix(ocelot, QS_XTR_RD, grp); in ocelot_drain_cpu_queue()
1255 int ocelot_fdb_add(struct ocelot *ocelot, int port, const unsigned char *addr, in ocelot_fdb_add() argument
1259 vid = ocelot_vlan_unaware_pvid(ocelot, bridge); in ocelot_fdb_add()
1261 return ocelot_mact_learn(ocelot, port, addr, vid, ENTRYTYPE_LOCKED); in ocelot_fdb_add()
1265 int ocelot_fdb_del(struct ocelot *ocelot, int port, const unsigned char *addr, in ocelot_fdb_del() argument
1269 vid = ocelot_vlan_unaware_pvid(ocelot, bridge); in ocelot_fdb_del()
1271 return ocelot_mact_forget(ocelot, addr, vid); in ocelot_fdb_del()
1275 /* Caller must hold &ocelot->mact_lock */
1276 static int ocelot_mact_read(struct ocelot *ocelot, int port, int row, int col, in ocelot_mact_read() argument
1283 ocelot_field_write(ocelot, ANA_TABLES_MACTINDX_M_INDEX, row); in ocelot_mact_read()
1284 ocelot_field_write(ocelot, ANA_TABLES_MACTINDX_BUCKET, col); in ocelot_mact_read()
1287 ocelot_write(ocelot, in ocelot_mact_read()
1291 if (ocelot_mact_wait_for_completion(ocelot)) in ocelot_mact_read()
1295 val = ocelot_read(ocelot, ANA_TABLES_MACACCESS); in ocelot_mact_read()
1307 macl = ocelot_read(ocelot, ANA_TABLES_MACLDATA); in ocelot_mact_read()
1308 mach = ocelot_read(ocelot, ANA_TABLES_MACHDATA); in ocelot_mact_read()
1323 int ocelot_mact_flush(struct ocelot *ocelot, int port) in ocelot_mact_flush() argument
1327 mutex_lock(&ocelot->mact_lock); in ocelot_mact_flush()
1330 ocelot_write(ocelot, ANA_ANAGEFIL_PID_EN | ANA_ANAGEFIL_PID_VAL(port), in ocelot_mact_flush()
1334 ocelot_write(ocelot, in ocelot_mact_flush()
1338 err = ocelot_mact_wait_for_completion(ocelot); in ocelot_mact_flush()
1340 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_flush()
1345 ocelot_write(ocelot, in ocelot_mact_flush()
1349 err = ocelot_mact_wait_for_completion(ocelot); in ocelot_mact_flush()
1352 ocelot_write(ocelot, 0, ANA_ANAGEFIL); in ocelot_mact_flush()
1354 mutex_unlock(&ocelot->mact_lock); in ocelot_mact_flush()
1360 int ocelot_fdb_dump(struct ocelot *ocelot, int port, in ocelot_fdb_dump() argument
1369 mutex_lock(&ocelot->mact_lock); in ocelot_fdb_dump()
1372 for (i = 0; i < ocelot->num_mact_rows; i++) { in ocelot_fdb_dump()
1377 err = ocelot_mact_read(ocelot, port, i, j, &entry); in ocelot_fdb_dump()
1400 mutex_unlock(&ocelot->mact_lock); in ocelot_fdb_dump()
1406 int ocelot_trap_add(struct ocelot *ocelot, int port, in ocelot_trap_add() argument
1415 block_vcap_is2 = &ocelot->block[VCAP_IS2]; in ocelot_trap_add()
1442 err = ocelot_vcap_filter_add(ocelot, trap, NULL); in ocelot_trap_add()
1444 err = ocelot_vcap_filter_replace(ocelot, trap); in ocelot_trap_add()
1455 int ocelot_trap_del(struct ocelot *ocelot, int port, unsigned long cookie) in ocelot_trap_del() argument
1460 block_vcap_is2 = &ocelot->block[VCAP_IS2]; in ocelot_trap_del()
1469 return ocelot_vcap_filter_del(ocelot, trap); in ocelot_trap_del()
1471 return ocelot_vcap_filter_replace(ocelot, trap); in ocelot_trap_del()
1474 static u32 ocelot_get_bond_mask(struct ocelot *ocelot, struct net_device *bond) in ocelot_get_bond_mask() argument
1479 lockdep_assert_held(&ocelot->fwd_domain_lock); in ocelot_get_bond_mask()
1481 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_get_bond_mask()
1482 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_get_bond_mask()
1497 int ocelot_bond_get_id(struct ocelot *ocelot, struct net_device *bond) in ocelot_bond_get_id() argument
1499 int bond_mask = ocelot_get_bond_mask(ocelot, bond); in ocelot_bond_get_id()
1518 static u32 ocelot_dsa_8021q_cpu_assigned_ports(struct ocelot *ocelot, in ocelot_dsa_8021q_cpu_assigned_ports() argument
1524 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_dsa_8021q_cpu_assigned_ports()
1525 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_dsa_8021q_cpu_assigned_ports()
1535 mask &= ~ocelot_get_bond_mask(ocelot, cpu->bond); in ocelot_dsa_8021q_cpu_assigned_ports()
1543 u32 ocelot_port_assigned_dsa_8021q_cpu_mask(struct ocelot *ocelot, int port) in ocelot_port_assigned_dsa_8021q_cpu_mask() argument
1545 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_assigned_dsa_8021q_cpu_mask()
1552 return ocelot_get_bond_mask(ocelot, cpu_port->bond); in ocelot_port_assigned_dsa_8021q_cpu_mask()
1558 u32 ocelot_get_bridge_fwd_mask(struct ocelot *ocelot, int src_port) in ocelot_get_bridge_fwd_mask() argument
1560 struct ocelot_port *ocelot_port = ocelot->ports[src_port]; in ocelot_get_bridge_fwd_mask()
1572 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_get_bridge_fwd_mask()
1573 ocelot_port = ocelot->ports[port]; in ocelot_get_bridge_fwd_mask()
1587 static void ocelot_apply_bridge_fwd_mask(struct ocelot *ocelot, bool joining) in ocelot_apply_bridge_fwd_mask() argument
1591 lockdep_assert_held(&ocelot->fwd_domain_lock); in ocelot_apply_bridge_fwd_mask()
1597 if (joining && ocelot->ops->cut_through_fwd) in ocelot_apply_bridge_fwd_mask()
1598 ocelot->ops->cut_through_fwd(ocelot); in ocelot_apply_bridge_fwd_mask()
1603 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_apply_bridge_fwd_mask()
1604 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_apply_bridge_fwd_mask()
1614 mask = ocelot_dsa_8021q_cpu_assigned_ports(ocelot, in ocelot_apply_bridge_fwd_mask()
1619 mask = ocelot_get_bridge_fwd_mask(ocelot, port); in ocelot_apply_bridge_fwd_mask()
1622 mask |= ocelot_port_assigned_dsa_8021q_cpu_mask(ocelot, in ocelot_apply_bridge_fwd_mask()
1626 mask &= ~ocelot_get_bond_mask(ocelot, bond); in ocelot_apply_bridge_fwd_mask()
1632 mask = ocelot_port_assigned_dsa_8021q_cpu_mask(ocelot, in ocelot_apply_bridge_fwd_mask()
1636 ocelot_write_rix(ocelot, mask, ANA_PGID_PGID, PGID_SRC + port); in ocelot_apply_bridge_fwd_mask()
1646 if (!joining && ocelot->ops->cut_through_fwd) in ocelot_apply_bridge_fwd_mask()
1647 ocelot->ops->cut_through_fwd(ocelot); in ocelot_apply_bridge_fwd_mask()
1657 static void ocelot_update_pgid_cpu(struct ocelot *ocelot) in ocelot_update_pgid_cpu() argument
1662 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_update_pgid_cpu()
1663 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_update_pgid_cpu()
1672 pgid_cpu = BIT(ocelot->num_phys_ports); in ocelot_update_pgid_cpu()
1674 ocelot_write_rix(ocelot, pgid_cpu, ANA_PGID_PGID, PGID_CPU); in ocelot_update_pgid_cpu()
1677 void ocelot_port_setup_dsa_8021q_cpu(struct ocelot *ocelot, int cpu) in ocelot_port_setup_dsa_8021q_cpu() argument
1679 struct ocelot_port *cpu_port = ocelot->ports[cpu]; in ocelot_port_setup_dsa_8021q_cpu()
1682 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_setup_dsa_8021q_cpu()
1687 ocelot_vlan_member_add(ocelot, cpu, vid, true); in ocelot_port_setup_dsa_8021q_cpu()
1689 ocelot_update_pgid_cpu(ocelot); in ocelot_port_setup_dsa_8021q_cpu()
1691 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_setup_dsa_8021q_cpu()
1695 void ocelot_port_teardown_dsa_8021q_cpu(struct ocelot *ocelot, int cpu) in ocelot_port_teardown_dsa_8021q_cpu() argument
1697 struct ocelot_port *cpu_port = ocelot->ports[cpu]; in ocelot_port_teardown_dsa_8021q_cpu()
1700 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_teardown_dsa_8021q_cpu()
1705 ocelot_vlan_member_del(ocelot, cpu_port->index, vid); in ocelot_port_teardown_dsa_8021q_cpu()
1707 ocelot_update_pgid_cpu(ocelot); in ocelot_port_teardown_dsa_8021q_cpu()
1709 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_teardown_dsa_8021q_cpu()
1713 void ocelot_port_assign_dsa_8021q_cpu(struct ocelot *ocelot, int port, in ocelot_port_assign_dsa_8021q_cpu() argument
1716 struct ocelot_port *cpu_port = ocelot->ports[cpu]; in ocelot_port_assign_dsa_8021q_cpu()
1718 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_assign_dsa_8021q_cpu()
1720 ocelot->ports[port]->dsa_8021q_cpu = cpu_port; in ocelot_port_assign_dsa_8021q_cpu()
1721 ocelot_apply_bridge_fwd_mask(ocelot, true); in ocelot_port_assign_dsa_8021q_cpu()
1723 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_assign_dsa_8021q_cpu()
1727 void ocelot_port_unassign_dsa_8021q_cpu(struct ocelot *ocelot, int port) in ocelot_port_unassign_dsa_8021q_cpu() argument
1729 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_unassign_dsa_8021q_cpu()
1731 ocelot->ports[port]->dsa_8021q_cpu = NULL; in ocelot_port_unassign_dsa_8021q_cpu()
1732 ocelot_apply_bridge_fwd_mask(ocelot, true); in ocelot_port_unassign_dsa_8021q_cpu()
1734 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_unassign_dsa_8021q_cpu()
1738 void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state) in ocelot_bridge_stp_state_set() argument
1740 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_bridge_stp_state_set()
1743 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_bridge_stp_state_set()
1751 ocelot_rmw_gix(ocelot, learn_ena, ANA_PORT_PORT_CFG_LEARN_ENA, in ocelot_bridge_stp_state_set()
1754 ocelot_apply_bridge_fwd_mask(ocelot, state == BR_STATE_FORWARDING); in ocelot_bridge_stp_state_set()
1756 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_bridge_stp_state_set()
1760 void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs) in ocelot_set_ageing_time() argument
1770 ocelot_rmw(ocelot, age_period, ANA_AUTOAGE_AGE_PERIOD_M, ANA_AUTOAGE); in ocelot_set_ageing_time()
1774 static struct ocelot_multicast *ocelot_multicast_get(struct ocelot *ocelot, in ocelot_multicast_get() argument
1780 list_for_each_entry(mc, &ocelot->multicast, list) { in ocelot_multicast_get()
1797 static struct ocelot_pgid *ocelot_pgid_alloc(struct ocelot *ocelot, int index, in ocelot_pgid_alloc() argument
1809 list_add_tail(&pgid->list, &ocelot->pgids); in ocelot_pgid_alloc()
1814 static void ocelot_pgid_free(struct ocelot *ocelot, struct ocelot_pgid *pgid) in ocelot_pgid_free() argument
1823 static struct ocelot_pgid *ocelot_mdb_get_pgid(struct ocelot *ocelot, in ocelot_mdb_get_pgid() argument
1836 return ocelot_pgid_alloc(ocelot, 0, mc->ports); in ocelot_mdb_get_pgid()
1838 list_for_each_entry(pgid, &ocelot->pgids, list) { in ocelot_mdb_get_pgid()
1849 for_each_nonreserved_multicast_dest_pgid(ocelot, index) { in ocelot_mdb_get_pgid()
1852 list_for_each_entry(pgid, &ocelot->pgids, list) { in ocelot_mdb_get_pgid()
1860 return ocelot_pgid_alloc(ocelot, index, mc->ports); in ocelot_mdb_get_pgid()
1881 int ocelot_port_mdb_add(struct ocelot *ocelot, int port, in ocelot_port_mdb_add() argument
1891 vid = ocelot_vlan_unaware_pvid(ocelot, bridge); in ocelot_port_mdb_add()
1893 mc = ocelot_multicast_get(ocelot, mdb->addr, vid); in ocelot_port_mdb_add()
1896 mc = devm_kzalloc(ocelot->dev, sizeof(*mc), GFP_KERNEL); in ocelot_port_mdb_add()
1904 list_add_tail(&mc->list, &ocelot->multicast); in ocelot_port_mdb_add()
1909 ocelot_pgid_free(ocelot, mc->pgid); in ocelot_port_mdb_add()
1911 ocelot_mact_forget(ocelot, addr, vid); in ocelot_port_mdb_add()
1916 pgid = ocelot_mdb_get_pgid(ocelot, mc); in ocelot_port_mdb_add()
1918 dev_err(ocelot->dev, in ocelot_port_mdb_add()
1921 devm_kfree(ocelot->dev, mc); in ocelot_port_mdb_add()
1930 ocelot_write_rix(ocelot, pgid->ports, ANA_PGID_PGID, in ocelot_port_mdb_add()
1933 return ocelot_mact_learn(ocelot, pgid->index, addr, vid, in ocelot_port_mdb_add()
1938 int ocelot_port_mdb_del(struct ocelot *ocelot, int port, in ocelot_port_mdb_del() argument
1948 vid = ocelot_vlan_unaware_pvid(ocelot, bridge); in ocelot_port_mdb_del()
1950 mc = ocelot_multicast_get(ocelot, mdb->addr, vid); in ocelot_port_mdb_del()
1955 ocelot_mact_forget(ocelot, addr, vid); in ocelot_port_mdb_del()
1957 ocelot_pgid_free(ocelot, mc->pgid); in ocelot_port_mdb_del()
1961 devm_kfree(ocelot->dev, mc); in ocelot_port_mdb_del()
1966 pgid = ocelot_mdb_get_pgid(ocelot, mc); in ocelot_port_mdb_del()
1975 ocelot_write_rix(ocelot, pgid->ports, ANA_PGID_PGID, in ocelot_port_mdb_del()
1978 return ocelot_mact_learn(ocelot, pgid->index, addr, vid, in ocelot_port_mdb_del()
1983 int ocelot_port_bridge_join(struct ocelot *ocelot, int port, in ocelot_port_bridge_join() argument
1987 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_bridge_join()
1990 err = ocelot_single_vlan_aware_bridge(ocelot, extack); in ocelot_port_bridge_join()
1994 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_bridge_join()
1999 ocelot_apply_bridge_fwd_mask(ocelot, true); in ocelot_port_bridge_join()
2001 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_bridge_join()
2006 return ocelot_add_vlan_unaware_pvid(ocelot, port, bridge); in ocelot_port_bridge_join()
2010 void ocelot_port_bridge_leave(struct ocelot *ocelot, int port, in ocelot_port_bridge_leave() argument
2013 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_bridge_leave()
2015 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_bridge_leave()
2018 ocelot_del_vlan_unaware_pvid(ocelot, port, bridge); in ocelot_port_bridge_leave()
2023 ocelot_port_set_pvid(ocelot, port, NULL); in ocelot_port_bridge_leave()
2024 ocelot_port_manage_port_tag(ocelot, port); in ocelot_port_bridge_leave()
2025 ocelot_apply_bridge_fwd_mask(ocelot, false); in ocelot_port_bridge_leave()
2027 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_bridge_leave()
2031 static void ocelot_set_aggr_pgids(struct ocelot *ocelot) in ocelot_set_aggr_pgids() argument
2033 unsigned long visited = GENMASK(ocelot->num_phys_ports - 1, 0); in ocelot_set_aggr_pgids()
2037 for_each_unicast_dest_pgid(ocelot, port) in ocelot_set_aggr_pgids()
2038 ocelot_write_rix(ocelot, BIT(port), ANA_PGID_PGID, port); in ocelot_set_aggr_pgids()
2040 for_each_aggr_pgid(ocelot, i) in ocelot_set_aggr_pgids()
2041 ocelot_write_rix(ocelot, GENMASK(ocelot->num_phys_ports - 1, 0), in ocelot_set_aggr_pgids()
2052 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_set_aggr_pgids()
2053 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_set_aggr_pgids()
2062 for (lag = 0; lag < ocelot->num_phys_ports; lag++) { in ocelot_set_aggr_pgids()
2063 struct net_device *bond = ocelot->ports[lag]->bond; in ocelot_set_aggr_pgids()
2071 bond_mask = ocelot_get_bond_mask(ocelot, bond); in ocelot_set_aggr_pgids()
2073 for_each_set_bit(port, &bond_mask, ocelot->num_phys_ports) { in ocelot_set_aggr_pgids()
2074 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_set_aggr_pgids()
2077 ocelot_write_rix(ocelot, bond_mask, in ocelot_set_aggr_pgids()
2084 for_each_aggr_pgid(ocelot, i) { in ocelot_set_aggr_pgids()
2087 ac = ocelot_read_rix(ocelot, ANA_PGID_PGID, i); in ocelot_set_aggr_pgids()
2094 ocelot_write_rix(ocelot, ac, ANA_PGID_PGID, i); in ocelot_set_aggr_pgids()
2100 for (port = lag; port < ocelot->num_phys_ports; port++) { in ocelot_set_aggr_pgids()
2101 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_set_aggr_pgids()
2117 static void ocelot_setup_logical_port_ids(struct ocelot *ocelot) in ocelot_setup_logical_port_ids() argument
2121 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_setup_logical_port_ids()
2122 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_setup_logical_port_ids()
2130 int lag = ocelot_bond_get_id(ocelot, bond); in ocelot_setup_logical_port_ids()
2132 ocelot_rmw_gix(ocelot, in ocelot_setup_logical_port_ids()
2137 ocelot_rmw_gix(ocelot, in ocelot_setup_logical_port_ids()
2145 static int ocelot_migrate_mc(struct ocelot *ocelot, struct ocelot_multicast *mc, in ocelot_migrate_mc() argument
2152 dev_dbg(ocelot->dev, in ocelot_migrate_mc()
2159 ocelot_pgid_free(ocelot, mc->pgid); in ocelot_migrate_mc()
2161 ocelot_mact_forget(ocelot, addr, vid); in ocelot_migrate_mc()
2166 pgid = ocelot_mdb_get_pgid(ocelot, mc); in ocelot_migrate_mc()
2168 dev_err(ocelot->dev, in ocelot_migrate_mc()
2171 devm_kfree(ocelot->dev, mc); in ocelot_migrate_mc()
2180 ocelot_write_rix(ocelot, pgid->ports, ANA_PGID_PGID, in ocelot_migrate_mc()
2183 return ocelot_mact_learn(ocelot, pgid->index, addr, vid, in ocelot_migrate_mc()
2187 int ocelot_migrate_mdbs(struct ocelot *ocelot, unsigned long from_mask, in ocelot_migrate_mdbs() argument
2193 list_for_each_entry(mc, &ocelot->multicast, list) { in ocelot_migrate_mdbs()
2197 err = ocelot_migrate_mc(ocelot, mc, from_mask, to_mask); in ocelot_migrate_mdbs()
2216 static void ocelot_migrate_lag_fdbs(struct ocelot *ocelot, in ocelot_migrate_lag_fdbs() argument
2223 lockdep_assert_held(&ocelot->fwd_domain_lock); in ocelot_migrate_lag_fdbs()
2225 list_for_each_entry(fdb, &ocelot->lag_fdbs, list) { in ocelot_migrate_lag_fdbs()
2229 err = ocelot_mact_forget(ocelot, fdb->addr, fdb->vid); in ocelot_migrate_lag_fdbs()
2231 dev_err(ocelot->dev, in ocelot_migrate_lag_fdbs()
2236 err = ocelot_mact_learn(ocelot, lag, fdb->addr, fdb->vid, in ocelot_migrate_lag_fdbs()
2239 dev_err(ocelot->dev, in ocelot_migrate_lag_fdbs()
2246 int ocelot_port_lag_join(struct ocelot *ocelot, int port, in ocelot_port_lag_join() argument
2257 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_lag_join()
2259 ocelot->ports[port]->bond = bond; in ocelot_port_lag_join()
2261 ocelot_setup_logical_port_ids(ocelot); in ocelot_port_lag_join()
2262 ocelot_apply_bridge_fwd_mask(ocelot, true); in ocelot_port_lag_join()
2263 ocelot_set_aggr_pgids(ocelot); in ocelot_port_lag_join()
2265 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_lag_join()
2271 void ocelot_port_lag_leave(struct ocelot *ocelot, int port, in ocelot_port_lag_leave() argument
2276 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_lag_leave()
2278 old_lag_id = ocelot_bond_get_id(ocelot, bond); in ocelot_port_lag_leave()
2280 ocelot->ports[port]->bond = NULL; in ocelot_port_lag_leave()
2282 ocelot_setup_logical_port_ids(ocelot); in ocelot_port_lag_leave()
2283 ocelot_apply_bridge_fwd_mask(ocelot, false); in ocelot_port_lag_leave()
2284 ocelot_set_aggr_pgids(ocelot); in ocelot_port_lag_leave()
2286 new_lag_id = ocelot_bond_get_id(ocelot, bond); in ocelot_port_lag_leave()
2289 ocelot_migrate_lag_fdbs(ocelot, bond, new_lag_id); in ocelot_port_lag_leave()
2291 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_lag_leave()
2295 void ocelot_port_lag_change(struct ocelot *ocelot, int port, bool lag_tx_active) in ocelot_port_lag_change() argument
2297 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_lag_change()
2299 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_port_lag_change()
2304 ocelot_set_aggr_pgids(ocelot); in ocelot_port_lag_change()
2306 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_port_lag_change()
2310 int ocelot_lag_fdb_add(struct ocelot *ocelot, struct net_device *bond, in ocelot_lag_fdb_add() argument
2321 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_add()
2324 vid = ocelot_vlan_unaware_pvid(ocelot, bridge); in ocelot_lag_fdb_add()
2330 lag = ocelot_bond_get_id(ocelot, bond); in ocelot_lag_fdb_add()
2332 err = ocelot_mact_learn(ocelot, lag, addr, vid, ENTRYTYPE_LOCKED); in ocelot_lag_fdb_add()
2334 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_add()
2339 list_add_tail(&fdb->list, &ocelot->lag_fdbs); in ocelot_lag_fdb_add()
2340 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_add()
2346 int ocelot_lag_fdb_del(struct ocelot *ocelot, struct net_device *bond, in ocelot_lag_fdb_del() argument
2352 mutex_lock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_del()
2355 vid = ocelot_vlan_unaware_pvid(ocelot, bridge); in ocelot_lag_fdb_del()
2357 list_for_each_entry_safe(fdb, tmp, &ocelot->lag_fdbs, list) { in ocelot_lag_fdb_del()
2362 ocelot_mact_forget(ocelot, addr, vid); in ocelot_lag_fdb_del()
2364 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_del()
2370 mutex_unlock(&ocelot->fwd_domain_lock); in ocelot_lag_fdb_del()
2382 void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu) in ocelot_port_set_maxlen() argument
2384 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_set_maxlen()
2389 if (port == ocelot->npi) { in ocelot_port_set_maxlen()
2392 if (ocelot->npi_inj_prefix == OCELOT_TAG_PREFIX_SHORT) in ocelot_port_set_maxlen()
2394 else if (ocelot->npi_inj_prefix == OCELOT_TAG_PREFIX_LONG) in ocelot_port_set_maxlen()
2403 ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_START, in ocelot_port_set_maxlen()
2405 ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_STOP, in ocelot_port_set_maxlen()
2409 atop_tot = (ocelot->packet_buffer_size - 9 * maxlen) / in ocelot_port_set_maxlen()
2412 ocelot_write_rix(ocelot, ocelot->ops->wm_enc(atop), SYS_ATOP, port); in ocelot_port_set_maxlen()
2413 ocelot_write(ocelot, ocelot->ops->wm_enc(atop_tot), SYS_ATOP_TOT_CFG); in ocelot_port_set_maxlen()
2417 int ocelot_get_max_mtu(struct ocelot *ocelot, int port) in ocelot_get_max_mtu() argument
2421 if (port == ocelot->npi) { in ocelot_get_max_mtu()
2424 if (ocelot->npi_inj_prefix == OCELOT_TAG_PREFIX_SHORT) in ocelot_get_max_mtu()
2426 else if (ocelot->npi_inj_prefix == OCELOT_TAG_PREFIX_LONG) in ocelot_get_max_mtu()
2434 static void ocelot_port_set_learning(struct ocelot *ocelot, int port, in ocelot_port_set_learning() argument
2437 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_set_learning()
2443 ocelot_rmw_gix(ocelot, val, ANA_PORT_PORT_CFG_LEARN_ENA, in ocelot_port_set_learning()
2449 static void ocelot_port_set_ucast_flood(struct ocelot *ocelot, int port, in ocelot_port_set_ucast_flood() argument
2457 ocelot_rmw_rix(ocelot, val, BIT(port), ANA_PGID_PGID, PGID_UC); in ocelot_port_set_ucast_flood()
2460 static void ocelot_port_set_mcast_flood(struct ocelot *ocelot, int port, in ocelot_port_set_mcast_flood() argument
2468 ocelot_rmw_rix(ocelot, val, BIT(port), ANA_PGID_PGID, PGID_MC); in ocelot_port_set_mcast_flood()
2469 ocelot_rmw_rix(ocelot, val, BIT(port), ANA_PGID_PGID, PGID_MCIPV4); in ocelot_port_set_mcast_flood()
2470 ocelot_rmw_rix(ocelot, val, BIT(port), ANA_PGID_PGID, PGID_MCIPV6); in ocelot_port_set_mcast_flood()
2473 static void ocelot_port_set_bcast_flood(struct ocelot *ocelot, int port, in ocelot_port_set_bcast_flood() argument
2481 ocelot_rmw_rix(ocelot, val, BIT(port), ANA_PGID_PGID, PGID_BC); in ocelot_port_set_bcast_flood()
2484 int ocelot_port_pre_bridge_flags(struct ocelot *ocelot, int port, in ocelot_port_pre_bridge_flags() argument
2495 void ocelot_port_bridge_flags(struct ocelot *ocelot, int port, in ocelot_port_bridge_flags() argument
2499 ocelot_port_set_learning(ocelot, port, in ocelot_port_bridge_flags()
2503 ocelot_port_set_ucast_flood(ocelot, port, in ocelot_port_bridge_flags()
2507 ocelot_port_set_mcast_flood(ocelot, port, in ocelot_port_bridge_flags()
2511 ocelot_port_set_bcast_flood(ocelot, port, in ocelot_port_bridge_flags()
2516 int ocelot_port_get_default_prio(struct ocelot *ocelot, int port) in ocelot_port_get_default_prio() argument
2518 int val = ocelot_read_gix(ocelot, ANA_PORT_QOS_CFG, port); in ocelot_port_get_default_prio()
2524 int ocelot_port_set_default_prio(struct ocelot *ocelot, int port, u8 prio) in ocelot_port_set_default_prio() argument
2529 ocelot_rmw_gix(ocelot, in ocelot_port_set_default_prio()
2539 int ocelot_port_get_dscp_prio(struct ocelot *ocelot, int port, u8 dscp) in ocelot_port_get_dscp_prio() argument
2541 int qos_cfg = ocelot_read_gix(ocelot, ANA_PORT_QOS_CFG, port); in ocelot_port_get_dscp_prio()
2542 int dscp_cfg = ocelot_read_rix(ocelot, ANA_DSCP_CFG, dscp); in ocelot_port_get_dscp_prio()
2551 dscp_cfg = ocelot_read_rix(ocelot, ANA_DSCP_CFG, dscp); in ocelot_port_get_dscp_prio()
2564 int ocelot_port_add_dscp_prio(struct ocelot *ocelot, int port, u8 dscp, u8 prio) in ocelot_port_add_dscp_prio() argument
2579 ocelot_rmw_gix(ocelot, ANA_PORT_QOS_CFG_QOS_DSCP_ENA, mask, in ocelot_port_add_dscp_prio()
2585 ocelot_write_rix(ocelot, val, ANA_DSCP_CFG, dscp); in ocelot_port_add_dscp_prio()
2591 int ocelot_port_del_dscp_prio(struct ocelot *ocelot, int port, u8 dscp, u8 prio) in ocelot_port_del_dscp_prio() argument
2593 int dscp_cfg = ocelot_read_rix(ocelot, ANA_DSCP_CFG, dscp); in ocelot_port_del_dscp_prio()
2608 ocelot_write_rix(ocelot, 0, ANA_DSCP_CFG, dscp); in ocelot_port_del_dscp_prio()
2611 int dscp_cfg = ocelot_read_rix(ocelot, ANA_DSCP_CFG, i); in ocelot_port_del_dscp_prio()
2626 ocelot_rmw_gix(ocelot, 0, mask, ANA_PORT_QOS_CFG, port); in ocelot_port_del_dscp_prio()
2632 struct ocelot_mirror *ocelot_mirror_get(struct ocelot *ocelot, int to, in ocelot_mirror_get() argument
2635 struct ocelot_mirror *m = ocelot->mirror; in ocelot_mirror_get()
2654 ocelot->mirror = m; in ocelot_mirror_get()
2657 ocelot_write(ocelot, BIT(to), ANA_MIRRORPORTS); in ocelot_mirror_get()
2662 void ocelot_mirror_put(struct ocelot *ocelot) in ocelot_mirror_put() argument
2664 struct ocelot_mirror *m = ocelot->mirror; in ocelot_mirror_put()
2669 ocelot_write(ocelot, 0, ANA_MIRRORPORTS); in ocelot_mirror_put()
2670 ocelot->mirror = NULL; in ocelot_mirror_put()
2674 int ocelot_port_mirror_add(struct ocelot *ocelot, int from, int to, in ocelot_port_mirror_add() argument
2677 struct ocelot_mirror *m = ocelot_mirror_get(ocelot, to, extack); in ocelot_port_mirror_add()
2683 ocelot_rmw_gix(ocelot, ANA_PORT_PORT_CFG_SRC_MIRROR_ENA, in ocelot_port_mirror_add()
2687 ocelot_rmw(ocelot, BIT(from), BIT(from), in ocelot_port_mirror_add()
2695 void ocelot_port_mirror_del(struct ocelot *ocelot, int from, bool ingress) in ocelot_port_mirror_del() argument
2698 ocelot_rmw_gix(ocelot, 0, ANA_PORT_PORT_CFG_SRC_MIRROR_ENA, in ocelot_port_mirror_del()
2701 ocelot_rmw(ocelot, 0, BIT(from), ANA_EMIRRORPORTS); in ocelot_port_mirror_del()
2704 ocelot_mirror_put(ocelot); in ocelot_port_mirror_del()
2708 static void ocelot_port_reset_mqprio(struct ocelot *ocelot, int port) in ocelot_port_reset_mqprio() argument
2710 struct net_device *dev = ocelot->ops->port_to_netdev(ocelot, port); in ocelot_port_reset_mqprio()
2713 ocelot_port_change_fp(ocelot, port, 0); in ocelot_port_reset_mqprio()
2716 int ocelot_port_mqprio(struct ocelot *ocelot, int port, in ocelot_port_mqprio() argument
2719 struct net_device *dev = ocelot->ops->port_to_netdev(ocelot, port); in ocelot_port_mqprio()
2726 ocelot_port_reset_mqprio(ocelot, port); in ocelot_port_mqprio()
2750 ocelot_port_change_fp(ocelot, port, mqprio->preemptible_tcs); in ocelot_port_mqprio()
2755 ocelot_port_reset_mqprio(ocelot, port); in ocelot_port_mqprio()
2760 void ocelot_init_port(struct ocelot *ocelot, int port) in ocelot_init_port() argument
2762 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_init_port()
2784 ocelot_port_set_maxlen(ocelot, port, ETH_DATA_LEN); in ocelot_init_port()
2796 ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, 1); in ocelot_init_port()
2799 ocelot_rmw_gix(ocelot, ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA, in ocelot_init_port()
2804 ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q), in ocelot_init_port()
2809 ocelot_port_set_learning(ocelot, port, false); in ocelot_init_port()
2815 ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_LEARNAUTO | in ocelot_init_port()
2821 ocelot_vcap_enable(ocelot, port); in ocelot_init_port()
2829 static void ocelot_cpu_port_init(struct ocelot *ocelot) in ocelot_cpu_port_init() argument
2831 int cpu = ocelot->num_phys_ports; in ocelot_cpu_port_init()
2834 ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu); in ocelot_cpu_port_init()
2839 ocelot_write_rix(ocelot, BIT(cpu), ANA_PGID_PGID, PGID_CPU); in ocelot_cpu_port_init()
2840 ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_RECV_ENA | in ocelot_cpu_port_init()
2845 ocelot_fields_write(ocelot, cpu, QSYS_SWITCH_PORT_MODE_PORT_ENA, 1); in ocelot_cpu_port_init()
2847 ocelot_fields_write(ocelot, cpu, SYS_PORT_MODE_INCL_XTR_HDR, in ocelot_cpu_port_init()
2849 ocelot_fields_write(ocelot, cpu, SYS_PORT_MODE_INCL_INJ_HDR, in ocelot_cpu_port_init()
2853 ocelot_write_gix(ocelot, in ocelot_cpu_port_init()
2860 static void ocelot_detect_features(struct ocelot *ocelot) in ocelot_detect_features() argument
2864 /* For Ocelot, Felix, Seville, Serval etc, SYS:MMGT:MMGT:FREECNT holds in ocelot_detect_features()
2868 mmgt = ocelot_read(ocelot, SYS_MMGT); in ocelot_detect_features()
2869 ocelot->packet_buffer_size = 240 * SYS_MMGT_FREECNT(mmgt); in ocelot_detect_features()
2871 eq_ctrl = ocelot_read(ocelot, QSYS_EQ_CTRL); in ocelot_detect_features()
2872 ocelot->num_frame_refs = QSYS_MMGT_EQ_CTRL_FP_FREE_CNT(eq_ctrl); in ocelot_detect_features()
2875 static int ocelot_mem_init_status(struct ocelot *ocelot) in ocelot_mem_init_status() argument
2880 err = regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], in ocelot_mem_init_status()
2886 int ocelot_reset(struct ocelot *ocelot) in ocelot_reset() argument
2891 err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1); in ocelot_reset()
2895 err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1); in ocelot_reset()
2902 err = readx_poll_timeout(ocelot_mem_init_status, ocelot, val, !val, in ocelot_reset()
2907 err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1); in ocelot_reset()
2911 return regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1); in ocelot_reset()
2915 int ocelot_init(struct ocelot *ocelot) in ocelot_init() argument
2920 if (ocelot->ops->reset) { in ocelot_init()
2921 ret = ocelot->ops->reset(ocelot); in ocelot_init()
2923 dev_err(ocelot->dev, "Switch reset failed\n"); in ocelot_init()
2928 mutex_init(&ocelot->mact_lock); in ocelot_init()
2929 mutex_init(&ocelot->fwd_domain_lock); in ocelot_init()
2930 spin_lock_init(&ocelot->ptp_clock_lock); in ocelot_init()
2931 spin_lock_init(&ocelot->ts_id_lock); in ocelot_init()
2933 ocelot->owq = alloc_ordered_workqueue("ocelot-owq", 0); in ocelot_init()
2934 if (!ocelot->owq) in ocelot_init()
2937 ret = ocelot_stats_init(ocelot); in ocelot_init()
2941 INIT_LIST_HEAD(&ocelot->multicast); in ocelot_init()
2942 INIT_LIST_HEAD(&ocelot->pgids); in ocelot_init()
2943 INIT_LIST_HEAD(&ocelot->vlans); in ocelot_init()
2944 INIT_LIST_HEAD(&ocelot->lag_fdbs); in ocelot_init()
2945 ocelot_detect_features(ocelot); in ocelot_init()
2946 ocelot_mact_init(ocelot); in ocelot_init()
2947 ocelot_vlan_init(ocelot); in ocelot_init()
2948 ocelot_vcap_init(ocelot); in ocelot_init()
2949 ocelot_cpu_port_init(ocelot); in ocelot_init()
2951 if (ocelot->ops->psfp_init) in ocelot_init()
2952 ocelot->ops->psfp_init(ocelot); in ocelot_init()
2954 if (ocelot->mm_supported) { in ocelot_init()
2955 ret = ocelot_mm_init(ocelot); in ocelot_init()
2960 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_init()
2962 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port) | in ocelot_init()
2968 ocelot_write(ocelot, ETH_P_8021AD, SYS_VLAN_ETYPE_CFG); in ocelot_init()
2971 ocelot_write(ocelot, ANA_AGGR_CFG_AC_SMAC_ENA | in ocelot_init()
2982 ocelot_write(ocelot, in ocelot_init()
2987 regmap_field_write(ocelot->regfields[ANA_ADVLEARN_VLAN_CHK], 1); in ocelot_init()
2990 ocelot_write(ocelot, SYS_FRM_AGING_AGE_TX_ENA | in ocelot_init()
2994 for (i = 0; i < ocelot->num_flooding_pgids; i++) in ocelot_init()
2995 ocelot_write_rix(ocelot, ANA_FLOODING_FLD_MULTICAST(PGID_MC) | in ocelot_init()
2999 ocelot_write(ocelot, ANA_FLOODING_IPMC_FLD_MC6_DATA(PGID_MCIPV6) | in ocelot_init()
3005 for (port = 0; port < ocelot->num_phys_ports; port++) { in ocelot_init()
3007 ocelot_write_rix(ocelot, BIT(port), ANA_PGID_PGID, port); in ocelot_init()
3009 ocelot_write_gix(ocelot, in ocelot_init()
3014 ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_SRC + port); in ocelot_init()
3017 for_each_nonreserved_multicast_dest_pgid(ocelot, i) { in ocelot_init()
3018 u32 val = ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports - 1, 0)); in ocelot_init()
3020 ocelot_write_rix(ocelot, val, ANA_PGID_PGID, i); in ocelot_init()
3023 ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_BLACKHOLE); in ocelot_init()
3026 ocelot_rmw_rix(ocelot, ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports)), in ocelot_init()
3027 ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports)), in ocelot_init()
3029 ocelot_rmw_rix(ocelot, ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports)), in ocelot_init()
3030 ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports)), in ocelot_init()
3032 ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV4); in ocelot_init()
3033 ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV6); in ocelot_init()
3038 ocelot_write_rix(ocelot, QS_INJ_GRP_CFG_BYTE_SWAP | in ocelot_init()
3040 ocelot_write_rix(ocelot, QS_XTR_GRP_CFG_BYTE_SWAP | in ocelot_init()
3042 ocelot_write(ocelot, ANA_CPUQ_CFG_CPUQ_MIRROR(2) | in ocelot_init()
3052 ocelot_write_rix(ocelot, ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL(6) | in ocelot_init()
3059 ocelot_stats_deinit(ocelot); in ocelot_init()
3061 destroy_workqueue(ocelot->owq); in ocelot_init()
3066 void ocelot_deinit(struct ocelot *ocelot) in ocelot_deinit() argument
3068 ocelot_stats_deinit(ocelot); in ocelot_deinit()
3069 destroy_workqueue(ocelot->owq); in ocelot_deinit()
3073 void ocelot_deinit_port(struct ocelot *ocelot, int port) in ocelot_deinit_port() argument
3075 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_deinit_port()