@@ -1880,19 +1880,17 @@ static int sja1105_crosschip_bridge_join(struct dsa_switch *ds,
1880
1880
if (dsa_to_port (ds , port )-> bridge_dev != br )
1881
1881
continue ;
1882
1882
1883
- other_priv -> expect_dsa_8021q = true;
1884
- rc = dsa_8021q_crosschip_bridge_join (ds , port , other_ds ,
1885
- other_port ,
1886
- & priv -> crosschip_links );
1887
- other_priv -> expect_dsa_8021q = false;
1883
+ rc = dsa_8021q_crosschip_bridge_join (priv -> dsa_8021q_ctx ,
1884
+ port ,
1885
+ other_priv -> dsa_8021q_ctx ,
1886
+ other_port );
1888
1887
if (rc )
1889
1888
return rc ;
1890
1889
1891
- priv -> expect_dsa_8021q = true;
1892
- rc = dsa_8021q_crosschip_bridge_join (other_ds , other_port , ds ,
1893
- port ,
1894
- & other_priv -> crosschip_links );
1895
- priv -> expect_dsa_8021q = false;
1890
+ rc = dsa_8021q_crosschip_bridge_join (other_priv -> dsa_8021q_ctx ,
1891
+ other_port ,
1892
+ priv -> dsa_8021q_ctx ,
1893
+ port );
1896
1894
if (rc )
1897
1895
return rc ;
1898
1896
}
@@ -1919,15 +1917,13 @@ static void sja1105_crosschip_bridge_leave(struct dsa_switch *ds,
1919
1917
if (dsa_to_port (ds , port )-> bridge_dev != br )
1920
1918
continue ;
1921
1919
1922
- other_priv -> expect_dsa_8021q = true;
1923
- dsa_8021q_crosschip_bridge_leave (ds , port , other_ds , other_port ,
1924
- & priv -> crosschip_links );
1925
- other_priv -> expect_dsa_8021q = false;
1920
+ dsa_8021q_crosschip_bridge_leave (priv -> dsa_8021q_ctx , port ,
1921
+ other_priv -> dsa_8021q_ctx ,
1922
+ other_port );
1926
1923
1927
- priv -> expect_dsa_8021q = true;
1928
- dsa_8021q_crosschip_bridge_leave (other_ds , other_port , ds , port ,
1929
- & other_priv -> crosschip_links );
1930
- priv -> expect_dsa_8021q = false;
1924
+ dsa_8021q_crosschip_bridge_leave (other_priv -> dsa_8021q_ctx ,
1925
+ other_port ,
1926
+ priv -> dsa_8021q_ctx , port );
1931
1927
}
1932
1928
}
1933
1929
@@ -1936,7 +1932,7 @@ static int sja1105_setup_8021q_tagging(struct dsa_switch *ds, bool enabled)
1936
1932
struct sja1105_private * priv = ds -> priv ;
1937
1933
int rc ;
1938
1934
1939
- rc = dsa_8021q_setup (priv -> ds , enabled );
1935
+ rc = dsa_8021q_setup (priv -> dsa_8021q_ctx , enabled );
1940
1936
if (rc )
1941
1937
return rc ;
1942
1938
@@ -2142,12 +2138,12 @@ struct sja1105_crosschip_vlan {
2142
2138
bool untagged ;
2143
2139
int port ;
2144
2140
int other_port ;
2145
- struct dsa_switch * other_ds ;
2141
+ struct dsa_8021q_context * other_ctx ;
2146
2142
};
2147
2143
2148
2144
struct sja1105_crosschip_switch {
2149
2145
struct list_head list ;
2150
- struct dsa_switch * other_ds ;
2146
+ struct dsa_8021q_context * other_ctx ;
2151
2147
};
2152
2148
2153
2149
static int sja1105_commit_pvid (struct sja1105_private * priv )
@@ -2323,8 +2319,8 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv,
2323
2319
2324
2320
INIT_LIST_HEAD (& crosschip_vlans );
2325
2321
2326
- list_for_each_entry (c , & priv -> crosschip_links , list ) {
2327
- struct sja1105_private * other_priv = c -> other_ds -> priv ;
2322
+ list_for_each_entry (c , & priv -> dsa_8021q_ctx -> crosschip_links , list ) {
2323
+ struct sja1105_private * other_priv = c -> other_ctx -> ds -> priv ;
2328
2324
2329
2325
if (other_priv -> vlan_state == SJA1105_VLAN_FILTERING_FULL )
2330
2326
continue ;
@@ -2334,7 +2330,7 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv,
2334
2330
*/
2335
2331
if (!dsa_is_user_port (priv -> ds , c -> port ))
2336
2332
continue ;
2337
- if (!dsa_is_user_port (c -> other_ds , c -> other_port ))
2333
+ if (!dsa_is_user_port (c -> other_ctx -> ds , c -> other_port ))
2338
2334
continue ;
2339
2335
2340
2336
/* Search for VLANs on the remote port */
@@ -2369,7 +2365,7 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv,
2369
2365
tmp -> untagged == v -> untagged &&
2370
2366
tmp -> port == c -> port &&
2371
2367
tmp -> other_port == v -> port &&
2372
- tmp -> other_ds == c -> other_ds ) {
2368
+ tmp -> other_ctx == c -> other_ctx ) {
2373
2369
already_added = true;
2374
2370
break ;
2375
2371
}
@@ -2387,14 +2383,14 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv,
2387
2383
tmp -> vid = v -> vid ;
2388
2384
tmp -> port = c -> port ;
2389
2385
tmp -> other_port = v -> port ;
2390
- tmp -> other_ds = c -> other_ds ;
2386
+ tmp -> other_ctx = c -> other_ctx ;
2391
2387
tmp -> untagged = v -> untagged ;
2392
2388
list_add (& tmp -> list , & crosschip_vlans );
2393
2389
}
2394
2390
}
2395
2391
2396
2392
list_for_each_entry (tmp , & crosschip_vlans , list ) {
2397
- struct sja1105_private * other_priv = tmp -> other_ds -> priv ;
2393
+ struct sja1105_private * other_priv = tmp -> other_ctx -> ds -> priv ;
2398
2394
int upstream = dsa_upstream_port (priv -> ds , tmp -> port );
2399
2395
int match , subvlan ;
2400
2396
u16 rx_vid ;
@@ -2411,7 +2407,7 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv,
2411
2407
goto out ;
2412
2408
}
2413
2409
2414
- rx_vid = dsa_8021q_rx_vid_subvlan (tmp -> other_ds ,
2410
+ rx_vid = dsa_8021q_rx_vid_subvlan (tmp -> other_ctx -> ds ,
2415
2411
tmp -> other_port ,
2416
2412
subvlan );
2417
2413
@@ -2486,11 +2482,11 @@ static int sja1105_notify_crosschip_switches(struct sja1105_private *priv)
2486
2482
2487
2483
INIT_LIST_HEAD (& crosschip_switches );
2488
2484
2489
- list_for_each_entry (c , & priv -> crosschip_links , list ) {
2485
+ list_for_each_entry (c , & priv -> dsa_8021q_ctx -> crosschip_links , list ) {
2490
2486
bool already_added = false;
2491
2487
2492
2488
list_for_each_entry (s , & crosschip_switches , list ) {
2493
- if (s -> other_ds == c -> other_ds ) {
2489
+ if (s -> other_ctx == c -> other_ctx ) {
2494
2490
already_added = true;
2495
2491
break ;
2496
2492
}
@@ -2505,12 +2501,12 @@ static int sja1105_notify_crosschip_switches(struct sja1105_private *priv)
2505
2501
rc = - ENOMEM ;
2506
2502
goto out ;
2507
2503
}
2508
- s -> other_ds = c -> other_ds ;
2504
+ s -> other_ctx = c -> other_ctx ;
2509
2505
list_add (& s -> list , & crosschip_switches );
2510
2506
}
2511
2507
2512
2508
list_for_each_entry (s , & crosschip_switches , list ) {
2513
- struct sja1105_private * other_priv = s -> other_ds -> priv ;
2509
+ struct sja1105_private * other_priv = s -> other_ctx -> ds -> priv ;
2514
2510
2515
2511
rc = sja1105_build_vlan_table (other_priv , false);
2516
2512
if (rc )
@@ -2611,16 +2607,6 @@ static int sja1105_build_vlan_table(struct sja1105_private *priv, bool notify)
2611
2607
return rc ;
2612
2608
}
2613
2609
2614
- /* Select the list to which we should add this VLAN. */
2615
- static struct list_head * sja1105_classify_vlan (struct sja1105_private * priv ,
2616
- u16 vid )
2617
- {
2618
- if (priv -> expect_dsa_8021q )
2619
- return & priv -> dsa_8021q_vlans ;
2620
-
2621
- return & priv -> bridge_vlans ;
2622
- }
2623
-
2624
2610
static int sja1105_vlan_prepare (struct dsa_switch * ds , int port ,
2625
2611
const struct switchdev_obj_port_vlan * vlan )
2626
2612
{
@@ -2635,7 +2621,7 @@ static int sja1105_vlan_prepare(struct dsa_switch *ds, int port,
2635
2621
* configuration done by dsa_8021q.
2636
2622
*/
2637
2623
for (vid = vlan -> vid_begin ; vid <= vlan -> vid_end ; vid ++ ) {
2638
- if (! priv -> expect_dsa_8021q && vid_is_dsa_8021q (vid )) {
2624
+ if (vid_is_dsa_8021q (vid )) {
2639
2625
dev_err (ds -> dev , "Range 1024-3071 reserved for dsa_8021q operation\n" );
2640
2626
return - EBUSY ;
2641
2627
}
@@ -2755,6 +2741,54 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, int port, bool enabled)
2755
2741
return sja1105_setup_8021q_tagging (ds , want_tagging );
2756
2742
}
2757
2743
2744
+ /* Returns number of VLANs added (0 or 1) on success,
2745
+ * or a negative error code.
2746
+ */
2747
+ static int sja1105_vlan_add_one (struct dsa_switch * ds , int port , u16 vid ,
2748
+ u16 flags , struct list_head * vlan_list )
2749
+ {
2750
+ bool untagged = flags & BRIDGE_VLAN_INFO_UNTAGGED ;
2751
+ bool pvid = flags & BRIDGE_VLAN_INFO_PVID ;
2752
+ struct sja1105_bridge_vlan * v ;
2753
+
2754
+ list_for_each_entry (v , vlan_list , list )
2755
+ if (v -> port == port && v -> vid == vid &&
2756
+ v -> untagged == untagged && v -> pvid == pvid )
2757
+ /* Already added */
2758
+ return 0 ;
2759
+
2760
+ v = kzalloc (sizeof (* v ), GFP_KERNEL );
2761
+ if (!v ) {
2762
+ dev_err (ds -> dev , "Out of memory while storing VLAN\n" );
2763
+ return - ENOMEM ;
2764
+ }
2765
+
2766
+ v -> port = port ;
2767
+ v -> vid = vid ;
2768
+ v -> untagged = untagged ;
2769
+ v -> pvid = pvid ;
2770
+ list_add (& v -> list , vlan_list );
2771
+
2772
+ return 1 ;
2773
+ }
2774
+
2775
+ /* Returns number of VLANs deleted (0 or 1) */
2776
+ static int sja1105_vlan_del_one (struct dsa_switch * ds , int port , u16 vid ,
2777
+ struct list_head * vlan_list )
2778
+ {
2779
+ struct sja1105_bridge_vlan * v , * n ;
2780
+
2781
+ list_for_each_entry_safe (v , n , vlan_list , list ) {
2782
+ if (v -> port == port && v -> vid == vid ) {
2783
+ list_del (& v -> list );
2784
+ kfree (v );
2785
+ return 1 ;
2786
+ }
2787
+ }
2788
+
2789
+ return 0 ;
2790
+ }
2791
+
2758
2792
static void sja1105_vlan_add (struct dsa_switch * ds , int port ,
2759
2793
const struct switchdev_obj_port_vlan * vlan )
2760
2794
{
@@ -2764,38 +2798,12 @@ static void sja1105_vlan_add(struct dsa_switch *ds, int port,
2764
2798
int rc ;
2765
2799
2766
2800
for (vid = vlan -> vid_begin ; vid <= vlan -> vid_end ; vid ++ ) {
2767
- bool untagged = vlan -> flags & BRIDGE_VLAN_INFO_UNTAGGED ;
2768
- bool pvid = vlan -> flags & BRIDGE_VLAN_INFO_PVID ;
2769
- struct sja1105_bridge_vlan * v ;
2770
- struct list_head * vlan_list ;
2771
- bool already_added = false;
2772
-
2773
- vlan_list = sja1105_classify_vlan (priv , vid );
2774
-
2775
- list_for_each_entry (v , vlan_list , list ) {
2776
- if (v -> port == port && v -> vid == vid &&
2777
- v -> untagged == untagged && v -> pvid == pvid ) {
2778
- already_added = true;
2779
- break ;
2780
- }
2781
- }
2782
-
2783
- if (already_added )
2784
- continue ;
2785
-
2786
- v = kzalloc (sizeof (* v ), GFP_KERNEL );
2787
- if (!v ) {
2788
- dev_err (ds -> dev , "Out of memory while storing VLAN\n" );
2801
+ rc = sja1105_vlan_add_one (ds , port , vid , vlan -> flags ,
2802
+ & priv -> bridge_vlans );
2803
+ if (rc < 0 )
2789
2804
return ;
2790
- }
2791
-
2792
- v -> port = port ;
2793
- v -> vid = vid ;
2794
- v -> untagged = untagged ;
2795
- v -> pvid = pvid ;
2796
- list_add (& v -> list , vlan_list );
2797
-
2798
- vlan_table_changed = true;
2805
+ if (rc > 0 )
2806
+ vlan_table_changed = true;
2799
2807
}
2800
2808
2801
2809
if (!vlan_table_changed )
@@ -2812,21 +2820,12 @@ static int sja1105_vlan_del(struct dsa_switch *ds, int port,
2812
2820
struct sja1105_private * priv = ds -> priv ;
2813
2821
bool vlan_table_changed = false;
2814
2822
u16 vid ;
2823
+ int rc ;
2815
2824
2816
2825
for (vid = vlan -> vid_begin ; vid <= vlan -> vid_end ; vid ++ ) {
2817
- struct sja1105_bridge_vlan * v , * n ;
2818
- struct list_head * vlan_list ;
2819
-
2820
- vlan_list = sja1105_classify_vlan (priv , vid );
2821
-
2822
- list_for_each_entry_safe (v , n , vlan_list , list ) {
2823
- if (v -> port == port && v -> vid == vid ) {
2824
- list_del (& v -> list );
2825
- kfree (v );
2826
- vlan_table_changed = true;
2827
- break ;
2828
- }
2829
- }
2826
+ rc = sja1105_vlan_del_one (ds , port , vid , & priv -> bridge_vlans );
2827
+ if (rc > 0 )
2828
+ vlan_table_changed = true;
2830
2829
}
2831
2830
2832
2831
if (!vlan_table_changed )
@@ -2835,6 +2834,36 @@ static int sja1105_vlan_del(struct dsa_switch *ds, int port,
2835
2834
return sja1105_build_vlan_table (priv , true);
2836
2835
}
2837
2836
2837
+ static int sja1105_dsa_8021q_vlan_add (struct dsa_switch * ds , int port , u16 vid ,
2838
+ u16 flags )
2839
+ {
2840
+ struct sja1105_private * priv = ds -> priv ;
2841
+ int rc ;
2842
+
2843
+ rc = sja1105_vlan_add_one (ds , port , vid , flags , & priv -> dsa_8021q_vlans );
2844
+ if (rc <= 0 )
2845
+ return rc ;
2846
+
2847
+ return sja1105_build_vlan_table (priv , true);
2848
+ }
2849
+
2850
+ static int sja1105_dsa_8021q_vlan_del (struct dsa_switch * ds , int port , u16 vid )
2851
+ {
2852
+ struct sja1105_private * priv = ds -> priv ;
2853
+ int rc ;
2854
+
2855
+ rc = sja1105_vlan_del_one (ds , port , vid , & priv -> dsa_8021q_vlans );
2856
+ if (!rc )
2857
+ return 0 ;
2858
+
2859
+ return sja1105_build_vlan_table (priv , true);
2860
+ }
2861
+
2862
+ static const struct dsa_8021q_ops sja1105_dsa_8021q_ops = {
2863
+ .vlan_add = sja1105_dsa_8021q_vlan_add ,
2864
+ .vlan_del = sja1105_dsa_8021q_vlan_del ,
2865
+ };
2866
+
2838
2867
static int sja1105_best_effort_vlan_filtering_get (struct sja1105_private * priv ,
2839
2868
bool * be_vlan )
2840
2869
{
@@ -3497,7 +3526,15 @@ static int sja1105_probe(struct spi_device *spi)
3497
3526
mutex_init (& priv -> ptp_data .lock );
3498
3527
mutex_init (& priv -> mgmt_lock );
3499
3528
3500
- INIT_LIST_HEAD (& priv -> crosschip_links );
3529
+ priv -> dsa_8021q_ctx = devm_kzalloc (dev , sizeof (* priv -> dsa_8021q_ctx ),
3530
+ GFP_KERNEL );
3531
+ if (!priv -> dsa_8021q_ctx )
3532
+ return - ENOMEM ;
3533
+
3534
+ priv -> dsa_8021q_ctx -> ops = & sja1105_dsa_8021q_ops ;
3535
+ priv -> dsa_8021q_ctx -> ds = ds ;
3536
+
3537
+ INIT_LIST_HEAD (& priv -> dsa_8021q_ctx -> crosschip_links );
3501
3538
INIT_LIST_HEAD (& priv -> bridge_vlans );
3502
3539
INIT_LIST_HEAD (& priv -> dsa_8021q_vlans );
3503
3540
0 commit comments