Lines Matching +full:sparx5 +full:- +full:switch

1 // SPDX-License-Identifier: GPL-2.0+
2 /* Microchip Sparx5 Switch driver
10 static int sparx5_vlant_set_mask(struct sparx5 *sparx5, u16 vid) in sparx5_vlant_set_mask() argument
15 bitmap_to_arr32(mask, sparx5->vlan_mask[vid], SPX5_PORTS); in sparx5_vlant_set_mask()
18 spx5_wr(mask[0], sparx5, ANA_L3_VLAN_MASK_CFG(vid)); in sparx5_vlant_set_mask()
19 if (is_sparx5(sparx5)) { in sparx5_vlant_set_mask()
20 spx5_wr(mask[1], sparx5, ANA_L3_VLAN_MASK_CFG1(vid)); in sparx5_vlant_set_mask()
21 spx5_wr(mask[2], sparx5, ANA_L3_VLAN_MASK_CFG2(vid)); in sparx5_vlant_set_mask()
27 void sparx5_vlan_init(struct sparx5 *sparx5) in sparx5_vlan_init() argument
33 sparx5, in sparx5_vlan_init()
40 sparx5, in sparx5_vlan_init()
44 void sparx5_vlan_port_setup(struct sparx5 *sparx5, int portno) in sparx5_vlan_port_setup() argument
46 struct sparx5_port *port = sparx5->ports[portno]; in sparx5_vlan_port_setup()
50 ANA_CL_VLAN_CTRL_PORT_VID_SET(port->pvid), in sparx5_vlan_port_setup()
53 sparx5, in sparx5_vlan_port_setup()
54 ANA_CL_VLAN_CTRL(port->portno)); in sparx5_vlan_port_setup()
60 struct sparx5 *sparx5 = port->sparx5; in sparx5_vlan_vid_add() local
64 if (untagged && port->vid != vid) { in sparx5_vlan_vid_add()
65 if (port->vid) { in sparx5_vlan_vid_add()
66 netdev_err(port->ndev, in sparx5_vlan_vid_add()
68 port->vid); in sparx5_vlan_vid_add()
69 return -EBUSY; in sparx5_vlan_vid_add()
71 port->vid = vid; in sparx5_vlan_vid_add()
75 set_bit(port->portno, sparx5->vlan_mask[vid]); in sparx5_vlan_vid_add()
76 ret = sparx5_vlant_set_mask(sparx5, vid); in sparx5_vlan_vid_add()
82 port->pvid = vid; in sparx5_vlan_vid_add()
84 sparx5_vlan_port_apply(sparx5, port); in sparx5_vlan_vid_add()
91 struct sparx5 *sparx5 = port->sparx5; in sparx5_vlan_vid_del() local
102 clear_bit(port->portno, sparx5->vlan_mask[vid]); in sparx5_vlan_vid_del()
103 ret = sparx5_vlant_set_mask(sparx5, vid); in sparx5_vlan_vid_del()
108 if (port->pvid == vid) in sparx5_vlan_vid_del()
109 port->pvid = 0; in sparx5_vlan_vid_del()
112 if (port->vid == vid) in sparx5_vlan_vid_del()
113 port->vid = 0; in sparx5_vlan_vid_del()
115 sparx5_vlan_port_apply(sparx5, port); in sparx5_vlan_vid_del()
122 struct sparx5 *sparx5 = port->sparx5; in sparx5_pgid_update_mask() local
126 if (port->portno < 32) { in sparx5_pgid_update_mask()
127 mask = BIT(port->portno); in sparx5_pgid_update_mask()
129 spx5_rmw(val, mask, sparx5, ANA_AC_PGID_CFG(pgid)); in sparx5_pgid_update_mask()
130 } else if (port->portno < 64) { in sparx5_pgid_update_mask()
131 mask = BIT(port->portno - 32); in sparx5_pgid_update_mask()
133 spx5_rmw(val, mask, sparx5, ANA_AC_PGID_CFG1(pgid)); in sparx5_pgid_update_mask()
134 } else if (port->portno < SPX5_PORTS) { in sparx5_pgid_update_mask()
135 mask = BIT(port->portno - 64); in sparx5_pgid_update_mask()
137 spx5_rmw(val, mask, sparx5, ANA_AC_PGID_CFG2(pgid)); in sparx5_pgid_update_mask()
139 netdev_err(port->ndev, "Invalid port no: %d\n", port->portno); in sparx5_pgid_update_mask()
143 void sparx5_pgid_clear(struct sparx5 *spx5, int pgid) in sparx5_pgid_clear()
152 void sparx5_pgid_read_mask(struct sparx5 *spx5, int pgid, u32 portmask[3]) in sparx5_pgid_read_mask()
161 void sparx5_update_fwd(struct sparx5 *sparx5) in sparx5_update_fwd() argument
168 bitmap_to_arr32(mask, sparx5->bridge_fwd_mask, SPX5_PORTS); in sparx5_update_fwd()
171 for (port = sparx5_get_pgid(sparx5, PGID_UC_FLOOD); in sparx5_update_fwd()
172 port <= sparx5_get_pgid(sparx5, PGID_BCAST); port++) { in sparx5_update_fwd()
173 spx5_wr(mask[0], sparx5, ANA_AC_PGID_CFG(port)); in sparx5_update_fwd()
174 if (is_sparx5(sparx5)) { in sparx5_update_fwd()
175 spx5_wr(mask[1], sparx5, ANA_AC_PGID_CFG1(port)); in sparx5_update_fwd()
176 spx5_wr(mask[2], sparx5, ANA_AC_PGID_CFG2(port)); in sparx5_update_fwd()
181 for (port = 0; port < sparx5->data->consts->n_ports; port++) { in sparx5_update_fwd()
182 if (test_bit(port, sparx5->bridge_fwd_mask)) { in sparx5_update_fwd()
184 bitmap_copy(workmask, sparx5->bridge_fwd_mask, SPX5_PORTS); in sparx5_update_fwd()
187 spx5_wr(mask[0], sparx5, ANA_AC_SRC_CFG(port)); in sparx5_update_fwd()
188 if (is_sparx5(sparx5)) { in sparx5_update_fwd()
189 spx5_wr(mask[1], sparx5, ANA_AC_SRC_CFG1(port)); in sparx5_update_fwd()
190 spx5_wr(mask[2], sparx5, ANA_AC_SRC_CFG2(port)); in sparx5_update_fwd()
193 spx5_wr(0, sparx5, ANA_AC_SRC_CFG(port)); in sparx5_update_fwd()
194 if (is_sparx5(sparx5)) { in sparx5_update_fwd()
195 spx5_wr(0, sparx5, ANA_AC_SRC_CFG1(port)); in sparx5_update_fwd()
196 spx5_wr(0, sparx5, ANA_AC_SRC_CFG2(port)); in sparx5_update_fwd()
202 bitmap_and(workmask, sparx5->bridge_fwd_mask, in sparx5_update_fwd()
203 sparx5->bridge_lrn_mask, SPX5_PORTS); in sparx5_update_fwd()
207 spx5_wr(mask[0], sparx5, ANA_L2_AUTO_LRN_CFG); in sparx5_update_fwd()
208 if (is_sparx5(sparx5)) { in sparx5_update_fwd()
209 spx5_wr(mask[1], sparx5, ANA_L2_AUTO_LRN_CFG1); in sparx5_update_fwd()
210 spx5_wr(mask[2], sparx5, ANA_L2_AUTO_LRN_CFG2); in sparx5_update_fwd()
214 void sparx5_vlan_port_apply(struct sparx5 *sparx5, in sparx5_vlan_port_apply() argument
221 val = ANA_CL_VLAN_CTRL_VLAN_AWARE_ENA_SET(port->vlan_aware) | in sparx5_vlan_port_apply()
222 ANA_CL_VLAN_CTRL_VLAN_POP_CNT_SET(port->vlan_aware) | in sparx5_vlan_port_apply()
223 ANA_CL_VLAN_CTRL_PORT_VID_SET(port->pvid); in sparx5_vlan_port_apply()
224 spx5_wr(val, sparx5, ANA_CL_VLAN_CTRL(port->portno)); in sparx5_vlan_port_apply()
227 if (port->vlan_aware && !port->pvid) in sparx5_vlan_port_apply()
228 /* If port is vlan-aware and tagged, drop untagged and in sparx5_vlan_port_apply()
234 spx5_wr(val, sparx5, in sparx5_vlan_port_apply()
235 ANA_CL_VLAN_FILTER_CTRL(port->portno, 0)); in sparx5_vlan_port_apply()
239 if (port->vlan_aware) { in sparx5_vlan_port_apply()
240 if (port->vid) in sparx5_vlan_port_apply()
246 spx5_wr(val, sparx5, REW_TAG_CTRL(port->portno)); in sparx5_vlan_port_apply()
249 spx5_rmw(REW_PORT_VLAN_CFG_PORT_VID_SET(port->vid), in sparx5_vlan_port_apply()
251 sparx5, in sparx5_vlan_port_apply()
252 REW_PORT_VLAN_CFG(port->portno)); in sparx5_vlan_port_apply()