@@ -222,6 +222,33 @@ static void ocelot_port_set_pvid(struct ocelot *ocelot, int port,
222
222
ANA_PORT_DROP_CFG , port );
223
223
}
224
224
225
+ static int ocelot_vlan_member_set (struct ocelot * ocelot , u32 vlan_mask , u16 vid )
226
+ {
227
+ int err ;
228
+
229
+ err = ocelot_vlant_set_mask (ocelot , vid , vlan_mask );
230
+ if (err )
231
+ return err ;
232
+
233
+ ocelot -> vlan_mask [vid ] = vlan_mask ;
234
+
235
+ return 0 ;
236
+ }
237
+
238
+ static int ocelot_vlan_member_add (struct ocelot * ocelot , int port , u16 vid )
239
+ {
240
+ return ocelot_vlan_member_set (ocelot ,
241
+ ocelot -> vlan_mask [vid ] | BIT (port ),
242
+ vid );
243
+ }
244
+
245
+ static int ocelot_vlan_member_del (struct ocelot * ocelot , int port , u16 vid )
246
+ {
247
+ return ocelot_vlan_member_set (ocelot ,
248
+ ocelot -> vlan_mask [vid ] & ~BIT (port ),
249
+ vid );
250
+ }
251
+
225
252
int ocelot_port_vlan_filtering (struct ocelot * ocelot , int port ,
226
253
bool vlan_aware , struct netlink_ext_ack * extack )
227
254
{
@@ -278,13 +305,11 @@ EXPORT_SYMBOL(ocelot_vlan_prepare);
278
305
int ocelot_vlan_add (struct ocelot * ocelot , int port , u16 vid , bool pvid ,
279
306
bool untagged )
280
307
{
281
- int ret ;
308
+ int err ;
282
309
283
- /* Make the port a member of the VLAN */
284
- ocelot -> vlan_mask [vid ] |= BIT (port );
285
- ret = ocelot_vlant_set_mask (ocelot , vid , ocelot -> vlan_mask [vid ]);
286
- if (ret )
287
- return ret ;
310
+ err = ocelot_vlan_member_add (ocelot , port , vid );
311
+ if (err )
312
+ return err ;
288
313
289
314
/* Default ingress vlan classification */
290
315
if (pvid ) {
@@ -311,13 +336,11 @@ EXPORT_SYMBOL(ocelot_vlan_add);
311
336
int ocelot_vlan_del (struct ocelot * ocelot , int port , u16 vid )
312
337
{
313
338
struct ocelot_port * ocelot_port = ocelot -> ports [port ];
314
- int ret ;
339
+ int err ;
315
340
316
- /* Stop the port from being a member of the vlan */
317
- ocelot -> vlan_mask [vid ] &= ~BIT (port );
318
- ret = ocelot_vlant_set_mask (ocelot , vid , ocelot -> vlan_mask [vid ]);
319
- if (ret )
320
- return ret ;
341
+ err = ocelot_vlan_member_del (ocelot , port , vid );
342
+ if (err )
343
+ return err ;
321
344
322
345
/* Ingress */
323
346
if (ocelot_port -> pvid_vlan .vid == vid ) {
@@ -339,6 +362,7 @@ EXPORT_SYMBOL(ocelot_vlan_del);
339
362
340
363
static void ocelot_vlan_init (struct ocelot * ocelot )
341
364
{
365
+ unsigned long all_ports = GENMASK (ocelot -> num_phys_ports - 1 , 0 );
342
366
u16 port , vid ;
343
367
344
368
/* Clear VLAN table, by default all ports are members of all VLANs */
@@ -347,23 +371,19 @@ static void ocelot_vlan_init(struct ocelot *ocelot)
347
371
ocelot_vlant_wait_for_completion (ocelot );
348
372
349
373
/* Configure the port VLAN memberships */
350
- for (vid = 1 ; vid < VLAN_N_VID ; vid ++ ) {
351
- ocelot -> vlan_mask [vid ] = 0 ;
352
- ocelot_vlant_set_mask (ocelot , vid , ocelot -> vlan_mask [vid ]);
353
- }
374
+ for (vid = 1 ; vid < VLAN_N_VID ; vid ++ )
375
+ ocelot_vlan_member_set (ocelot , 0 , vid );
354
376
355
377
/* Because VLAN filtering is enabled, we need VID 0 to get untagged
356
378
* traffic. It is added automatically if 8021q module is loaded, but
357
379
* we can't rely on it since module may be not loaded.
358
380
*/
359
- ocelot -> vlan_mask [0 ] = GENMASK (ocelot -> num_phys_ports - 1 , 0 );
360
- ocelot_vlant_set_mask (ocelot , 0 , ocelot -> vlan_mask [0 ]);
381
+ ocelot_vlan_member_set (ocelot , all_ports , 0 );
361
382
362
383
/* Set vlan ingress filter mask to all ports but the CPU port by
363
384
* default.
364
385
*/
365
- ocelot_write (ocelot , GENMASK (ocelot -> num_phys_ports - 1 , 0 ),
366
- ANA_VLANMASK );
386
+ ocelot_write (ocelot , all_ports , ANA_VLANMASK );
367
387
368
388
for (port = 0 ; port < ocelot -> num_phys_ports ; port ++ ) {
369
389
ocelot_write_gix (ocelot , 0 , REW_PORT_VLAN_CFG , port );
0 commit comments