@@ -186,15 +186,15 @@ static int b53_do_vlan_op(struct b53_device *dev, u8 op)
186
186
return - EIO ;
187
187
}
188
188
189
- static void b53_set_vlan_entry (struct b53_device * dev , u16 vid , u16 members ,
190
- u16 untag )
189
+ static void b53_set_vlan_entry (struct b53_device * dev , u16 vid ,
190
+ struct b53_vlan * vlan )
191
191
{
192
192
if (is5325 (dev )) {
193
193
u32 entry = 0 ;
194
194
195
- if (members ) {
196
- entry = ((untag & VA_UNTAG_MASK_25 ) << VA_UNTAG_S_25 ) |
197
- members ;
195
+ if (vlan -> members ) {
196
+ entry = ((vlan -> untag & VA_UNTAG_MASK_25 ) <<
197
+ VA_UNTAG_S_25 ) | vlan -> members ;
198
198
if (dev -> core_rev >= 3 )
199
199
entry |= VA_VALID_25_R4 | vid << VA_VID_HIGH_S ;
200
200
else
@@ -207,23 +207,65 @@ static void b53_set_vlan_entry(struct b53_device *dev, u16 vid, u16 members,
207
207
} else if (is5365 (dev )) {
208
208
u16 entry = 0 ;
209
209
210
- if (members )
211
- entry = ((untag & VA_UNTAG_MASK_65 ) << VA_UNTAG_S_65 ) |
212
- members | VA_VALID_65 ;
210
+ if (vlan -> members )
211
+ entry = ((vlan -> untag & VA_UNTAG_MASK_65 ) <<
212
+ VA_UNTAG_S_65 ) | vlan -> members | VA_VALID_65 ;
213
213
214
214
b53_write16 (dev , B53_VLAN_PAGE , B53_VLAN_WRITE_65 , entry );
215
215
b53_write16 (dev , B53_VLAN_PAGE , B53_VLAN_TABLE_ACCESS_65 , vid |
216
216
VTA_RW_STATE_WR | VTA_RW_OP_EN );
217
217
} else {
218
218
b53_write16 (dev , B53_ARLIO_PAGE , dev -> vta_regs [1 ], vid );
219
219
b53_write32 (dev , B53_ARLIO_PAGE , dev -> vta_regs [2 ],
220
- (untag << VTE_UNTAG_S ) | members );
220
+ (vlan -> untag << VTE_UNTAG_S ) | vlan -> members );
221
221
222
222
b53_do_vlan_op (dev , VTA_CMD_WRITE );
223
223
}
224
+
225
+ dev_dbg (dev -> ds -> dev , "VID: %d, members: 0x%04x, untag: 0x%04x\n" ,
226
+ vid , vlan -> members , vlan -> untag );
227
+ }
228
+
229
+ static void b53_get_vlan_entry (struct b53_device * dev , u16 vid ,
230
+ struct b53_vlan * vlan )
231
+ {
232
+ if (is5325 (dev )) {
233
+ u32 entry = 0 ;
234
+
235
+ b53_write16 (dev , B53_VLAN_PAGE , B53_VLAN_TABLE_ACCESS_25 , vid |
236
+ VTA_RW_STATE_RD | VTA_RW_OP_EN );
237
+ b53_read32 (dev , B53_VLAN_PAGE , B53_VLAN_WRITE_25 , & entry );
238
+
239
+ if (dev -> core_rev >= 3 )
240
+ vlan -> valid = !!(entry & VA_VALID_25_R4 );
241
+ else
242
+ vlan -> valid = !!(entry & VA_VALID_25 );
243
+ vlan -> members = entry & VA_MEMBER_MASK ;
244
+ vlan -> untag = (entry >> VA_UNTAG_S_25 ) & VA_UNTAG_MASK_25 ;
245
+
246
+ } else if (is5365 (dev )) {
247
+ u16 entry = 0 ;
248
+
249
+ b53_write16 (dev , B53_VLAN_PAGE , B53_VLAN_TABLE_ACCESS_65 , vid |
250
+ VTA_RW_STATE_WR | VTA_RW_OP_EN );
251
+ b53_read16 (dev , B53_VLAN_PAGE , B53_VLAN_WRITE_65 , & entry );
252
+
253
+ vlan -> valid = !!(entry & VA_VALID_65 );
254
+ vlan -> members = entry & VA_MEMBER_MASK ;
255
+ vlan -> untag = (entry >> VA_UNTAG_S_65 ) & VA_UNTAG_MASK_65 ;
256
+ } else {
257
+ u32 entry = 0 ;
258
+
259
+ b53_write16 (dev , B53_ARLIO_PAGE , dev -> vta_regs [1 ], vid );
260
+ b53_do_vlan_op (dev , VTA_CMD_READ );
261
+ b53_read32 (dev , B53_ARLIO_PAGE , dev -> vta_regs [2 ], & entry );
262
+ vlan -> members = entry & VTE_MEMBERS ;
263
+ vlan -> untag = (entry >> VTE_UNTAG_S ) & VTE_MEMBERS ;
264
+ vlan -> valid = true;
265
+ }
224
266
}
225
267
226
- void b53_set_forwarding (struct b53_device * dev , int enable )
268
+ static void b53_set_forwarding (struct b53_device * dev , int enable )
227
269
{
228
270
u8 mgmt ;
229
271
@@ -237,7 +279,7 @@ void b53_set_forwarding(struct b53_device *dev, int enable)
237
279
b53_write8 (dev , B53_CTRL_PAGE , B53_SWITCH_MODE , mgmt );
238
280
}
239
281
240
- static void b53_enable_vlan (struct b53_device * dev , int enable )
282
+ static void b53_enable_vlan (struct b53_device * dev , bool enable )
241
283
{
242
284
u8 mgmt , vc0 , vc1 , vc4 = 0 , vc5 ;
243
285
@@ -271,12 +313,6 @@ static void b53_enable_vlan(struct b53_device *dev, int enable)
271
313
if (is5325 (dev ) || is5365 (dev ))
272
314
vc1 |= VC1_RX_MCST_TAG_EN ;
273
315
274
- if (!is5325 (dev ) && !is5365 (dev )) {
275
- if (dev -> allow_vid_4095 )
276
- vc5 |= VC5_VID_FFF_EN ;
277
- else
278
- vc5 &= ~VC5_VID_FFF_EN ;
279
- }
280
316
} else {
281
317
vc0 &= ~(VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID );
282
318
vc1 &= ~(VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN );
@@ -290,11 +326,11 @@ static void b53_enable_vlan(struct b53_device *dev, int enable)
290
326
291
327
if (is5325 (dev ) || is5365 (dev ))
292
328
vc1 &= ~VC1_RX_MCST_TAG_EN ;
293
-
294
- if (!is5325 (dev ) && !is5365 (dev ))
295
- vc5 &= ~VC5_VID_FFF_EN ;
296
329
}
297
330
331
+ if (!is5325 (dev ) && !is5365 (dev ))
332
+ vc5 &= ~VC5_VID_FFF_EN ;
333
+
298
334
b53_write8 (dev , B53_VLAN_PAGE , B53_VLAN_CTRL0 , vc0 );
299
335
b53_write8 (dev , B53_VLAN_PAGE , B53_VLAN_CTRL1 , vc1 );
300
336
@@ -373,6 +409,13 @@ static int b53_fast_age_port(struct b53_device *dev, int port)
373
409
return b53_flush_arl (dev , FAST_AGE_PORT );
374
410
}
375
411
412
+ static int b53_fast_age_vlan (struct b53_device * dev , u16 vid )
413
+ {
414
+ b53_write16 (dev , B53_CTRL_PAGE , B53_FAST_AGE_VID_CTRL , vid );
415
+
416
+ return b53_flush_arl (dev , FAST_AGE_VLAN );
417
+ }
418
+
376
419
static void b53_imp_vlan_setup (struct dsa_switch * ds , int cpu_port )
377
420
{
378
421
struct b53_device * dev = ds_to_priv (ds );
@@ -453,12 +496,13 @@ static void b53_enable_mib(struct b53_device *dev)
453
496
454
497
static int b53_configure_vlan (struct b53_device * dev )
455
498
{
499
+ struct b53_vlan vl = { 0 };
456
500
int i ;
457
501
458
502
/* clear all vlan entries */
459
503
if (is5325 (dev ) || is5365 (dev )) {
460
504
for (i = 1 ; i < dev -> num_vlans ; i ++ )
461
- b53_set_vlan_entry (dev , i , 0 , 0 );
505
+ b53_set_vlan_entry (dev , i , & vl );
462
506
} else {
463
507
b53_do_vlan_op (dev , VTA_CMD_CLEAR );
464
508
}
@@ -554,6 +598,7 @@ static int b53_reset_switch(struct b53_device *priv)
554
598
/* reset vlans */
555
599
priv -> enable_jumbo = false;
556
600
601
+ memset (priv -> vlans , 0 , sizeof (* priv -> vlans ) * priv -> num_vlans );
557
602
memset (priv -> ports , 0 , sizeof (* priv -> ports ) * priv -> num_ports );
558
603
559
604
return b53_switch_reset (priv );
@@ -818,6 +863,151 @@ static void b53_adjust_link(struct dsa_switch *ds, int port,
818
863
}
819
864
}
820
865
866
+ static int b53_vlan_filtering (struct dsa_switch * ds , int port ,
867
+ bool vlan_filtering )
868
+ {
869
+ return 0 ;
870
+ }
871
+
872
+ static int b53_vlan_prepare (struct dsa_switch * ds , int port ,
873
+ const struct switchdev_obj_port_vlan * vlan ,
874
+ struct switchdev_trans * trans )
875
+ {
876
+ struct b53_device * dev = ds_to_priv (ds );
877
+
878
+ if ((is5325 (dev ) || is5365 (dev )) && vlan -> vid_begin == 0 )
879
+ return - EOPNOTSUPP ;
880
+
881
+ if (vlan -> vid_end > dev -> num_vlans )
882
+ return - ERANGE ;
883
+
884
+ b53_enable_vlan (dev , true);
885
+
886
+ return 0 ;
887
+ }
888
+
889
+ static void b53_vlan_add (struct dsa_switch * ds , int port ,
890
+ const struct switchdev_obj_port_vlan * vlan ,
891
+ struct switchdev_trans * trans )
892
+ {
893
+ struct b53_device * dev = ds_to_priv (ds );
894
+ bool untagged = vlan -> flags & BRIDGE_VLAN_INFO_UNTAGGED ;
895
+ bool pvid = vlan -> flags & BRIDGE_VLAN_INFO_PVID ;
896
+ unsigned int cpu_port = dev -> cpu_port ;
897
+ struct b53_vlan * vl ;
898
+ u16 vid ;
899
+
900
+ for (vid = vlan -> vid_begin ; vid <= vlan -> vid_end ; ++ vid ) {
901
+ vl = & dev -> vlans [vid ];
902
+
903
+ b53_get_vlan_entry (dev , vid , vl );
904
+
905
+ vl -> members |= BIT (port ) | BIT (cpu_port );
906
+ if (untagged )
907
+ vl -> untag |= BIT (port ) | BIT (cpu_port );
908
+ else
909
+ vl -> untag &= ~(BIT (port ) | BIT (cpu_port ));
910
+
911
+ b53_set_vlan_entry (dev , vid , vl );
912
+ b53_fast_age_vlan (dev , vid );
913
+ }
914
+
915
+ if (pvid ) {
916
+ b53_write16 (dev , B53_VLAN_PAGE , B53_VLAN_PORT_DEF_TAG (port ),
917
+ vlan -> vid_end );
918
+ b53_write16 (dev , B53_VLAN_PAGE , B53_VLAN_PORT_DEF_TAG (cpu_port ),
919
+ vlan -> vid_end );
920
+ b53_fast_age_vlan (dev , vid );
921
+ }
922
+ }
923
+
924
+ static int b53_vlan_del (struct dsa_switch * ds , int port ,
925
+ const struct switchdev_obj_port_vlan * vlan )
926
+ {
927
+ struct b53_device * dev = ds_to_priv (ds );
928
+ bool untagged = vlan -> flags & BRIDGE_VLAN_INFO_UNTAGGED ;
929
+ unsigned int cpu_port = dev -> cpu_port ;
930
+ struct b53_vlan * vl ;
931
+ u16 vid ;
932
+ u16 pvid ;
933
+
934
+ b53_read16 (dev , B53_VLAN_PAGE , B53_VLAN_PORT_DEF_TAG (port ), & pvid );
935
+
936
+ for (vid = vlan -> vid_begin ; vid <= vlan -> vid_end ; ++ vid ) {
937
+ vl = & dev -> vlans [vid ];
938
+
939
+ b53_get_vlan_entry (dev , vid , vl );
940
+
941
+ vl -> members &= ~BIT (port );
942
+ if ((vl -> members & BIT (cpu_port )) == BIT (cpu_port ))
943
+ vl -> members = 0 ;
944
+
945
+ if (pvid == vid ) {
946
+ if (is5325 (dev ) || is5365 (dev ))
947
+ pvid = 1 ;
948
+ else
949
+ pvid = 0 ;
950
+ }
951
+
952
+ if (untagged ) {
953
+ vl -> untag &= ~(BIT (port ));
954
+ if ((vl -> untag & BIT (cpu_port )) == BIT (cpu_port ))
955
+ vl -> untag = 0 ;
956
+ }
957
+
958
+ b53_set_vlan_entry (dev , vid , vl );
959
+ b53_fast_age_vlan (dev , vid );
960
+ }
961
+
962
+ b53_write16 (dev , B53_VLAN_PAGE , B53_VLAN_PORT_DEF_TAG (port ), pvid );
963
+ b53_write16 (dev , B53_VLAN_PAGE , B53_VLAN_PORT_DEF_TAG (cpu_port ), pvid );
964
+ b53_fast_age_vlan (dev , pvid );
965
+
966
+ return 0 ;
967
+ }
968
+
969
+ static int b53_vlan_dump (struct dsa_switch * ds , int port ,
970
+ struct switchdev_obj_port_vlan * vlan ,
971
+ int (* cb )(struct switchdev_obj * obj ))
972
+ {
973
+ struct b53_device * dev = ds_to_priv (ds );
974
+ u16 vid , vid_start = 0 , pvid ;
975
+ struct b53_vlan * vl ;
976
+ int err = 0 ;
977
+
978
+ if (is5325 (dev ) || is5365 (dev ))
979
+ vid_start = 1 ;
980
+
981
+ b53_read16 (dev , B53_VLAN_PAGE , B53_VLAN_PORT_DEF_TAG (port ), & pvid );
982
+
983
+ /* Use our software cache for dumps, since we do not have any HW
984
+ * operation returning only the used/valid VLANs
985
+ */
986
+ for (vid = vid_start ; vid < dev -> num_vlans ; vid ++ ) {
987
+ vl = & dev -> vlans [vid ];
988
+
989
+ if (!vl -> valid )
990
+ continue ;
991
+
992
+ if (!(vl -> members & BIT (port )))
993
+ continue ;
994
+
995
+ vlan -> vid_begin = vlan -> vid_end = vid ;
996
+ vlan -> flags = 0 ;
997
+
998
+ if (vl -> untag & BIT (port ))
999
+ vlan -> flags |= BRIDGE_VLAN_INFO_UNTAGGED ;
1000
+ if (pvid == vid )
1001
+ vlan -> flags |= BRIDGE_VLAN_INFO_PVID ;
1002
+
1003
+ err = cb (& vlan -> obj );
1004
+ if (err )
1005
+ break ;
1006
+ }
1007
+
1008
+ return err ;
1009
+ }
1010
+
821
1011
/* Address Resolution Logic routines */
822
1012
static int b53_arl_op_wait (struct b53_device * dev )
823
1013
{
@@ -1096,8 +1286,9 @@ static void b53_br_leave(struct dsa_switch *ds, int port)
1096
1286
{
1097
1287
struct b53_device * dev = ds_to_priv (ds );
1098
1288
struct net_device * bridge = dev -> ports [port ].bridge_dev ;
1289
+ struct b53_vlan * vl = & dev -> vlans [0 ];
1099
1290
unsigned int i ;
1100
- u16 pvlan , reg ;
1291
+ u16 pvlan , reg , pvid ;
1101
1292
1102
1293
b53_read16 (dev , B53_PVLAN_PAGE , B53_PVLAN_PORT_MASK (port ), & pvlan );
1103
1294
@@ -1119,6 +1310,16 @@ static void b53_br_leave(struct dsa_switch *ds, int port)
1119
1310
b53_write16 (dev , B53_PVLAN_PAGE , B53_PVLAN_PORT_MASK (port ), pvlan );
1120
1311
dev -> ports [port ].vlan_ctl_mask = pvlan ;
1121
1312
dev -> ports [port ].bridge_dev = NULL ;
1313
+
1314
+ if (is5325 (dev ) || is5365 (dev ))
1315
+ pvid = 1 ;
1316
+ else
1317
+ pvid = 0 ;
1318
+
1319
+ b53_get_vlan_entry (dev , pvid , vl );
1320
+ vl -> members |= BIT (port ) | BIT (dev -> cpu_port );
1321
+ vl -> untag |= BIT (port ) | BIT (dev -> cpu_port );
1322
+ b53_set_vlan_entry (dev , pvid , vl );
1122
1323
}
1123
1324
1124
1325
static void b53_br_set_stp_state (struct dsa_switch * ds , int port ,
@@ -1187,6 +1388,11 @@ static struct dsa_switch_driver b53_switch_ops = {
1187
1388
.port_bridge_join = b53_br_join ,
1188
1389
.port_bridge_leave = b53_br_leave ,
1189
1390
.port_stp_state_set = b53_br_set_stp_state ,
1391
+ .port_vlan_filtering = b53_vlan_filtering ,
1392
+ .port_vlan_prepare = b53_vlan_prepare ,
1393
+ .port_vlan_add = b53_vlan_add ,
1394
+ .port_vlan_del = b53_vlan_del ,
1395
+ .port_vlan_dump = b53_vlan_dump ,
1190
1396
.port_fdb_prepare = b53_fdb_prepare ,
1191
1397
.port_fdb_dump = b53_fdb_dump ,
1192
1398
.port_fdb_add = b53_fdb_add ,
@@ -1446,6 +1652,12 @@ static int b53_switch_init(struct b53_device *dev)
1446
1652
if (!dev -> ports )
1447
1653
return - ENOMEM ;
1448
1654
1655
+ dev -> vlans = devm_kzalloc (dev -> dev ,
1656
+ sizeof (struct b53_vlan ) * dev -> num_vlans ,
1657
+ GFP_KERNEL );
1658
+ if (!dev -> vlans )
1659
+ return - ENOMEM ;
1660
+
1449
1661
dev -> reset_gpio = b53_switch_get_reset_gpio (dev );
1450
1662
if (dev -> reset_gpio >= 0 ) {
1451
1663
ret = devm_gpio_request_one (dev -> dev , dev -> reset_gpio ,
0 commit comments