@@ -1880,19 +1880,17 @@ static int sja1105_crosschip_bridge_join(struct dsa_switch *ds,
18801880 if (dsa_to_port (ds , port )-> bridge_dev != br )
18811881 continue ;
18821882
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 );
18881887 if (rc )
18891888 return rc ;
18901889
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 );
18961894 if (rc )
18971895 return rc ;
18981896 }
@@ -1919,33 +1917,24 @@ static void sja1105_crosschip_bridge_leave(struct dsa_switch *ds,
19191917 if (dsa_to_port (ds , port )-> bridge_dev != br )
19201918 continue ;
19211919
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 );
19261923
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 );
19311927 }
19321928}
19331929
19341930static int sja1105_setup_8021q_tagging (struct dsa_switch * ds , bool enabled )
19351931{
19361932 struct sja1105_private * priv = ds -> priv ;
1937- int rc , i ;
1933+ int rc ;
19381934
1939- for (i = 0 ; i < SJA1105_NUM_PORTS ; i ++ ) {
1940- priv -> expect_dsa_8021q = true;
1941- rc = dsa_port_setup_8021q_tagging (ds , i , enabled );
1942- priv -> expect_dsa_8021q = false;
1943- if (rc < 0 ) {
1944- dev_err (ds -> dev , "Failed to setup VLAN tagging for port %d: %d\n" ,
1945- i , rc );
1946- return rc ;
1947- }
1948- }
1935+ rc = dsa_8021q_setup (priv -> dsa_8021q_ctx , enabled );
1936+ if (rc )
1937+ return rc ;
19491938
19501939 dev_info (ds -> dev , "%s switch tagging\n" ,
19511940 enabled ? "Enabled" : "Disabled" );
@@ -2149,12 +2138,12 @@ struct sja1105_crosschip_vlan {
21492138 bool untagged ;
21502139 int port ;
21512140 int other_port ;
2152- struct dsa_switch * other_ds ;
2141+ struct dsa_8021q_context * other_ctx ;
21532142};
21542143
21552144struct sja1105_crosschip_switch {
21562145 struct list_head list ;
2157- struct dsa_switch * other_ds ;
2146+ struct dsa_8021q_context * other_ctx ;
21582147};
21592148
21602149static int sja1105_commit_pvid (struct sja1105_private * priv )
@@ -2330,8 +2319,8 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv,
23302319
23312320 INIT_LIST_HEAD (& crosschip_vlans );
23322321
2333- list_for_each_entry (c , & priv -> crosschip_links , list ) {
2334- 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 ;
23352324
23362325 if (other_priv -> vlan_state == SJA1105_VLAN_FILTERING_FULL )
23372326 continue ;
@@ -2341,7 +2330,7 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv,
23412330 */
23422331 if (!dsa_is_user_port (priv -> ds , c -> port ))
23432332 continue ;
2344- if (!dsa_is_user_port (c -> other_ds , c -> other_port ))
2333+ if (!dsa_is_user_port (c -> other_ctx -> ds , c -> other_port ))
23452334 continue ;
23462335
23472336 /* Search for VLANs on the remote port */
@@ -2376,7 +2365,7 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv,
23762365 tmp -> untagged == v -> untagged &&
23772366 tmp -> port == c -> port &&
23782367 tmp -> other_port == v -> port &&
2379- tmp -> other_ds == c -> other_ds ) {
2368+ tmp -> other_ctx == c -> other_ctx ) {
23802369 already_added = true;
23812370 break ;
23822371 }
@@ -2394,14 +2383,14 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv,
23942383 tmp -> vid = v -> vid ;
23952384 tmp -> port = c -> port ;
23962385 tmp -> other_port = v -> port ;
2397- tmp -> other_ds = c -> other_ds ;
2386+ tmp -> other_ctx = c -> other_ctx ;
23982387 tmp -> untagged = v -> untagged ;
23992388 list_add (& tmp -> list , & crosschip_vlans );
24002389 }
24012390 }
24022391
24032392 list_for_each_entry (tmp , & crosschip_vlans , list ) {
2404- struct sja1105_private * other_priv = tmp -> other_ds -> priv ;
2393+ struct sja1105_private * other_priv = tmp -> other_ctx -> ds -> priv ;
24052394 int upstream = dsa_upstream_port (priv -> ds , tmp -> port );
24062395 int match , subvlan ;
24072396 u16 rx_vid ;
@@ -2418,7 +2407,7 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv,
24182407 goto out ;
24192408 }
24202409
2421- rx_vid = dsa_8021q_rx_vid_subvlan (tmp -> other_ds ,
2410+ rx_vid = dsa_8021q_rx_vid_subvlan (tmp -> other_ctx -> ds ,
24222411 tmp -> other_port ,
24232412 subvlan );
24242413
@@ -2493,11 +2482,11 @@ static int sja1105_notify_crosschip_switches(struct sja1105_private *priv)
24932482
24942483 INIT_LIST_HEAD (& crosschip_switches );
24952484
2496- list_for_each_entry (c , & priv -> crosschip_links , list ) {
2485+ list_for_each_entry (c , & priv -> dsa_8021q_ctx -> crosschip_links , list ) {
24972486 bool already_added = false;
24982487
24992488 list_for_each_entry (s , & crosschip_switches , list ) {
2500- if (s -> other_ds == c -> other_ds ) {
2489+ if (s -> other_ctx == c -> other_ctx ) {
25012490 already_added = true;
25022491 break ;
25032492 }
@@ -2512,12 +2501,12 @@ static int sja1105_notify_crosschip_switches(struct sja1105_private *priv)
25122501 rc = - ENOMEM ;
25132502 goto out ;
25142503 }
2515- s -> other_ds = c -> other_ds ;
2504+ s -> other_ctx = c -> other_ctx ;
25162505 list_add (& s -> list , & crosschip_switches );
25172506 }
25182507
25192508 list_for_each_entry (s , & crosschip_switches , list ) {
2520- struct sja1105_private * other_priv = s -> other_ds -> priv ;
2509+ struct sja1105_private * other_priv = s -> other_ctx -> ds -> priv ;
25212510
25222511 rc = sja1105_build_vlan_table (other_priv , false);
25232512 if (rc )
@@ -2618,16 +2607,6 @@ static int sja1105_build_vlan_table(struct sja1105_private *priv, bool notify)
26182607 return rc ;
26192608}
26202609
2621- /* Select the list to which we should add this VLAN. */
2622- static struct list_head * sja1105_classify_vlan (struct sja1105_private * priv ,
2623- u16 vid )
2624- {
2625- if (priv -> expect_dsa_8021q )
2626- return & priv -> dsa_8021q_vlans ;
2627-
2628- return & priv -> bridge_vlans ;
2629- }
2630-
26312610static int sja1105_vlan_prepare (struct dsa_switch * ds , int port ,
26322611 const struct switchdev_obj_port_vlan * vlan )
26332612{
@@ -2642,7 +2621,7 @@ static int sja1105_vlan_prepare(struct dsa_switch *ds, int port,
26422621 * configuration done by dsa_8021q.
26432622 */
26442623 for (vid = vlan -> vid_begin ; vid <= vlan -> vid_end ; vid ++ ) {
2645- if (! priv -> expect_dsa_8021q && vid_is_dsa_8021q (vid )) {
2624+ if (vid_is_dsa_8021q (vid )) {
26462625 dev_err (ds -> dev , "Range 1024-3071 reserved for dsa_8021q operation\n" );
26472626 return - EBUSY ;
26482627 }
@@ -2762,6 +2741,54 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, int port, bool enabled)
27622741 return sja1105_setup_8021q_tagging (ds , want_tagging );
27632742}
27642743
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+
27652792static void sja1105_vlan_add (struct dsa_switch * ds , int port ,
27662793 const struct switchdev_obj_port_vlan * vlan )
27672794{
@@ -2771,38 +2798,12 @@ static void sja1105_vlan_add(struct dsa_switch *ds, int port,
27712798 int rc ;
27722799
27732800 for (vid = vlan -> vid_begin ; vid <= vlan -> vid_end ; vid ++ ) {
2774- bool untagged = vlan -> flags & BRIDGE_VLAN_INFO_UNTAGGED ;
2775- bool pvid = vlan -> flags & BRIDGE_VLAN_INFO_PVID ;
2776- struct sja1105_bridge_vlan * v ;
2777- struct list_head * vlan_list ;
2778- bool already_added = false;
2779-
2780- vlan_list = sja1105_classify_vlan (priv , vid );
2781-
2782- list_for_each_entry (v , vlan_list , list ) {
2783- if (v -> port == port && v -> vid == vid &&
2784- v -> untagged == untagged && v -> pvid == pvid ) {
2785- already_added = true;
2786- break ;
2787- }
2788- }
2789-
2790- if (already_added )
2791- continue ;
2792-
2793- v = kzalloc (sizeof (* v ), GFP_KERNEL );
2794- if (!v ) {
2795- 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 )
27962804 return ;
2797- }
2798-
2799- v -> port = port ;
2800- v -> vid = vid ;
2801- v -> untagged = untagged ;
2802- v -> pvid = pvid ;
2803- list_add (& v -> list , vlan_list );
2804-
2805- vlan_table_changed = true;
2805+ if (rc > 0 )
2806+ vlan_table_changed = true;
28062807 }
28072808
28082809 if (!vlan_table_changed )
@@ -2819,21 +2820,12 @@ static int sja1105_vlan_del(struct dsa_switch *ds, int port,
28192820 struct sja1105_private * priv = ds -> priv ;
28202821 bool vlan_table_changed = false;
28212822 u16 vid ;
2823+ int rc ;
28222824
28232825 for (vid = vlan -> vid_begin ; vid <= vlan -> vid_end ; vid ++ ) {
2824- struct sja1105_bridge_vlan * v , * n ;
2825- struct list_head * vlan_list ;
2826-
2827- vlan_list = sja1105_classify_vlan (priv , vid );
2828-
2829- list_for_each_entry_safe (v , n , vlan_list , list ) {
2830- if (v -> port == port && v -> vid == vid ) {
2831- list_del (& v -> list );
2832- kfree (v );
2833- vlan_table_changed = true;
2834- break ;
2835- }
2836- }
2826+ rc = sja1105_vlan_del_one (ds , port , vid , & priv -> bridge_vlans );
2827+ if (rc > 0 )
2828+ vlan_table_changed = true;
28372829 }
28382830
28392831 if (!vlan_table_changed )
@@ -2842,6 +2834,36 @@ static int sja1105_vlan_del(struct dsa_switch *ds, int port,
28422834 return sja1105_build_vlan_table (priv , true);
28432835}
28442836
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+
28452867static int sja1105_best_effort_vlan_filtering_get (struct sja1105_private * priv ,
28462868 bool * be_vlan )
28472869{
@@ -3504,7 +3526,15 @@ static int sja1105_probe(struct spi_device *spi)
35043526 mutex_init (& priv -> ptp_data .lock );
35053527 mutex_init (& priv -> mgmt_lock );
35063528
3507- 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 );
35083538 INIT_LIST_HEAD (& priv -> bridge_vlans );
35093539 INIT_LIST_HEAD (& priv -> dsa_8021q_vlans );
35103540
0 commit comments