ocelot.c (62a22bcbd30ed01a0f0331288aa0cca9d9aae23b) | ocelot.c (90e0aa8d108d22cb0dd646083fb3dfcc7a43a018) |
---|---|
1// SPDX-License-Identifier: (GPL-2.0 OR MIT) 2/* 3 * Microsemi Ocelot Switch driver 4 * 5 * Copyright (c) 2017 Microsemi Corporation 6 */ 7#include <linux/dsa/ocelot.h> 8#include <linux/if_bridge.h> --- 205 unchanged lines hidden (view full) --- 214 ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA; 215 216 ocelot_rmw_gix(ocelot, val, 217 ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA | 218 ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA, 219 ANA_PORT_DROP_CFG, port); 220} 221 | 1// SPDX-License-Identifier: (GPL-2.0 OR MIT) 2/* 3 * Microsemi Ocelot Switch driver 4 * 5 * Copyright (c) 2017 Microsemi Corporation 6 */ 7#include <linux/dsa/ocelot.h> 8#include <linux/if_bridge.h> --- 205 unchanged lines hidden (view full) --- 214 ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA; 215 216 ocelot_rmw_gix(ocelot, val, 217 ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA | 218 ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA, 219 ANA_PORT_DROP_CFG, port); 220} 221 |
222static int ocelot_vlan_member_set(struct ocelot *ocelot, u32 vlan_mask, u16 vid) | 222static struct ocelot_bridge_vlan *ocelot_bridge_vlan_find(struct ocelot *ocelot, 223 u16 vid) |
223{ | 224{ |
225 struct ocelot_bridge_vlan *vlan; 226 227 list_for_each_entry(vlan, &ocelot->vlans, list) 228 if (vlan->vid == vid) 229 return vlan; 230 231 return NULL; 232} 233 234static int ocelot_vlan_member_add(struct ocelot *ocelot, int port, u16 vid) 235{ 236 struct ocelot_bridge_vlan *vlan = ocelot_bridge_vlan_find(ocelot, vid); 237 unsigned long portmask; |
|
224 int err; 225 | 238 int err; 239 |
226 err = ocelot_vlant_set_mask(ocelot, vid, vlan_mask); 227 if (err) | 240 if (vlan) { 241 portmask = vlan->portmask | BIT(port); 242 243 err = ocelot_vlant_set_mask(ocelot, vid, portmask); 244 if (err) 245 return err; 246 247 vlan->portmask = portmask; 248 249 return 0; 250 } 251 252 vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); 253 if (!vlan) 254 return -ENOMEM; 255 256 portmask = BIT(port); 257 258 err = ocelot_vlant_set_mask(ocelot, vid, portmask); 259 if (err) { 260 kfree(vlan); |
228 return err; | 261 return err; |
262 } |
|
229 | 263 |
230 ocelot->vlan_mask[vid] = vlan_mask; | 264 vlan->vid = vid; 265 vlan->portmask = portmask; 266 INIT_LIST_HEAD(&vlan->list); 267 list_add_tail(&vlan->list, &ocelot->vlans); |
231 232 return 0; 233} 234 | 268 269 return 0; 270} 271 |
235static int ocelot_vlan_member_add(struct ocelot *ocelot, int port, u16 vid) 236{ 237 return ocelot_vlan_member_set(ocelot, 238 ocelot->vlan_mask[vid] | BIT(port), 239 vid); 240} 241 | |
242static int ocelot_vlan_member_del(struct ocelot *ocelot, int port, u16 vid) 243{ | 272static int ocelot_vlan_member_del(struct ocelot *ocelot, int port, u16 vid) 273{ |
244 return ocelot_vlan_member_set(ocelot, 245 ocelot->vlan_mask[vid] & ~BIT(port), 246 vid); | 274 struct ocelot_bridge_vlan *vlan = ocelot_bridge_vlan_find(ocelot, vid); 275 unsigned long portmask; 276 int err; 277 278 if (!vlan) 279 return 0; 280 281 portmask = vlan->portmask & ~BIT(port); 282 283 err = ocelot_vlant_set_mask(ocelot, vid, portmask); 284 if (err) 285 return err; 286 287 vlan->portmask = portmask; 288 if (vlan->portmask) 289 return 0; 290 291 list_del(&vlan->list); 292 kfree(vlan); 293 294 return 0; |
247} 248 249int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, 250 bool vlan_aware, struct netlink_ext_ack *extack) 251{ 252 struct ocelot_vcap_block *block = &ocelot->block[VCAP_IS1]; 253 struct ocelot_port *ocelot_port = ocelot->ports[port]; 254 struct ocelot_vcap_filter *filter; --- 109 unchanged lines hidden (view full) --- 364 365 /* Clear VLAN table, by default all ports are members of all VLANs */ 366 ocelot_write(ocelot, ANA_TABLES_VLANACCESS_CMD_INIT, 367 ANA_TABLES_VLANACCESS); 368 ocelot_vlant_wait_for_completion(ocelot); 369 370 /* Configure the port VLAN memberships */ 371 for (vid = 1; vid < VLAN_N_VID; vid++) | 295} 296 297int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, 298 bool vlan_aware, struct netlink_ext_ack *extack) 299{ 300 struct ocelot_vcap_block *block = &ocelot->block[VCAP_IS1]; 301 struct ocelot_port *ocelot_port = ocelot->ports[port]; 302 struct ocelot_vcap_filter *filter; --- 109 unchanged lines hidden (view full) --- 412 413 /* Clear VLAN table, by default all ports are members of all VLANs */ 414 ocelot_write(ocelot, ANA_TABLES_VLANACCESS_CMD_INIT, 415 ANA_TABLES_VLANACCESS); 416 ocelot_vlant_wait_for_completion(ocelot); 417 418 /* Configure the port VLAN memberships */ 419 for (vid = 1; vid < VLAN_N_VID; vid++) |
372 ocelot_vlan_member_set(ocelot, 0, vid); | 420 ocelot_vlant_set_mask(ocelot, vid, 0); |
373 374 /* Because VLAN filtering is enabled, we need VID 0 to get untagged 375 * traffic. It is added automatically if 8021q module is loaded, but 376 * we can't rely on it since module may be not loaded. 377 */ | 421 422 /* Because VLAN filtering is enabled, we need VID 0 to get untagged 423 * traffic. It is added automatically if 8021q module is loaded, but 424 * we can't rely on it since module may be not loaded. 425 */ |
378 ocelot_vlan_member_set(ocelot, all_ports, 0); | 426 ocelot_vlant_set_mask(ocelot, 0, all_ports); |
379 380 /* Set vlan ingress filter mask to all ports but the CPU port by 381 * default. 382 */ 383 ocelot_write(ocelot, all_ports, ANA_VLANMASK); 384 385 for (port = 0; port < ocelot->num_phys_ports; port++) { 386 ocelot_write_gix(ocelot, 0, REW_PORT_VLAN_CFG, port); --- 1735 unchanged lines hidden (view full) --- 2122 ocelot->owq = alloc_ordered_workqueue("ocelot-owq", 0); 2123 if (!ocelot->owq) { 2124 destroy_workqueue(ocelot->stats_queue); 2125 return -ENOMEM; 2126 } 2127 2128 INIT_LIST_HEAD(&ocelot->multicast); 2129 INIT_LIST_HEAD(&ocelot->pgids); | 427 428 /* Set vlan ingress filter mask to all ports but the CPU port by 429 * default. 430 */ 431 ocelot_write(ocelot, all_ports, ANA_VLANMASK); 432 433 for (port = 0; port < ocelot->num_phys_ports; port++) { 434 ocelot_write_gix(ocelot, 0, REW_PORT_VLAN_CFG, port); --- 1735 unchanged lines hidden (view full) --- 2170 ocelot->owq = alloc_ordered_workqueue("ocelot-owq", 0); 2171 if (!ocelot->owq) { 2172 destroy_workqueue(ocelot->stats_queue); 2173 return -ENOMEM; 2174 } 2175 2176 INIT_LIST_HEAD(&ocelot->multicast); 2177 INIT_LIST_HEAD(&ocelot->pgids); |
2178 INIT_LIST_HEAD(&ocelot->vlans); |
|
2130 ocelot_detect_features(ocelot); 2131 ocelot_mact_init(ocelot); 2132 ocelot_vlan_init(ocelot); 2133 ocelot_vcap_init(ocelot); 2134 ocelot_cpu_port_init(ocelot); 2135 2136 for (port = 0; port < ocelot->num_phys_ports; port++) { 2137 /* Clear all counters (5 groups) */ --- 120 unchanged lines hidden --- | 2179 ocelot_detect_features(ocelot); 2180 ocelot_mact_init(ocelot); 2181 ocelot_vlan_init(ocelot); 2182 ocelot_vcap_init(ocelot); 2183 ocelot_cpu_port_init(ocelot); 2184 2185 for (port = 0; port < ocelot->num_phys_ports; port++) { 2186 /* Clear all counters (5 groups) */ --- 120 unchanged lines hidden --- |