1212
1313#include <linux/bitfield.h>
1414#include <linux/delay.h>
15+ #include <linux/dsa/mv88e6xxx.h>
1516#include <linux/etherdevice.h>
1617#include <linux/ethtool.h>
1718#include <linux/if_bridge.h>
@@ -1677,6 +1678,30 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
16771678 return 0 ;
16781679}
16791680
1681+ static int mv88e6xxx_port_commit_pvid (struct mv88e6xxx_chip * chip , int port )
1682+ {
1683+ struct dsa_port * dp = dsa_to_port (chip -> ds , port );
1684+ struct mv88e6xxx_port * p = & chip -> ports [port ];
1685+ u16 pvid = MV88E6XXX_VID_STANDALONE ;
1686+ bool drop_untagged = false;
1687+ int err ;
1688+
1689+ if (dp -> bridge_dev ) {
1690+ if (br_vlan_enabled (dp -> bridge_dev )) {
1691+ pvid = p -> bridge_pvid .vid ;
1692+ drop_untagged = !p -> bridge_pvid .valid ;
1693+ } else {
1694+ pvid = MV88E6XXX_VID_BRIDGED ;
1695+ }
1696+ }
1697+
1698+ err = mv88e6xxx_port_set_pvid (chip , port , pvid );
1699+ if (err )
1700+ return err ;
1701+
1702+ return mv88e6xxx_port_drop_untagged (chip , port , drop_untagged );
1703+ }
1704+
16801705static int mv88e6xxx_port_vlan_filtering (struct dsa_switch * ds , int port ,
16811706 bool vlan_filtering ,
16821707 struct netlink_ext_ack * extack )
@@ -1690,7 +1715,16 @@ static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
16901715 return - EOPNOTSUPP ;
16911716
16921717 mv88e6xxx_reg_lock (chip );
1718+
16931719 err = mv88e6xxx_port_set_8021q_mode (chip , port , mode );
1720+ if (err )
1721+ goto unlock ;
1722+
1723+ err = mv88e6xxx_port_commit_pvid (chip , port );
1724+ if (err )
1725+ goto unlock ;
1726+
1727+ unlock :
16941728 mv88e6xxx_reg_unlock (chip );
16951729
16961730 return err ;
@@ -1725,11 +1759,15 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
17251759 u16 fid ;
17261760 int err ;
17271761
1728- /* Null VLAN ID corresponds to the port private database */
1762+ /* Ports have two private address databases: one for when the port is
1763+ * standalone and one for when the port is under a bridge and the
1764+ * 802.1Q mode is disabled. When the port is standalone, DSA wants its
1765+ * address database to remain 100% empty, so we never load an ATU entry
1766+ * into a standalone port's database. Therefore, translate the null
1767+ * VLAN ID into the port's database used for VLAN-unaware bridging.
1768+ */
17291769 if (vid == 0 ) {
1730- err = mv88e6xxx_port_get_fid (chip , port , & fid );
1731- if (err )
1732- return err ;
1770+ fid = MV88E6XXX_FID_BRIDGED ;
17331771 } else {
17341772 err = mv88e6xxx_vtu_get (chip , vid , & vlan );
17351773 if (err )
@@ -2123,6 +2161,7 @@ static int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
21232161 struct mv88e6xxx_chip * chip = ds -> priv ;
21242162 bool untagged = vlan -> flags & BRIDGE_VLAN_INFO_UNTAGGED ;
21252163 bool pvid = vlan -> flags & BRIDGE_VLAN_INFO_PVID ;
2164+ struct mv88e6xxx_port * p = & chip -> ports [port ];
21262165 bool warn ;
21272166 u8 member ;
21282167 int err ;
@@ -2156,13 +2195,21 @@ static int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
21562195 }
21572196
21582197 if (pvid ) {
2159- err = mv88e6xxx_port_set_pvid (chip , port , vlan -> vid );
2160- if (err ) {
2161- dev_err (ds -> dev , "p%d: failed to set PVID %d\n" ,
2162- port , vlan -> vid );
2198+ p -> bridge_pvid .vid = vlan -> vid ;
2199+ p -> bridge_pvid .valid = true;
2200+
2201+ err = mv88e6xxx_port_commit_pvid (chip , port );
2202+ if (err )
2203+ goto out ;
2204+ } else if (vlan -> vid && p -> bridge_pvid .vid == vlan -> vid ) {
2205+ /* The old pvid was reinstalled as a non-pvid VLAN */
2206+ p -> bridge_pvid .valid = false;
2207+
2208+ err = mv88e6xxx_port_commit_pvid (chip , port );
2209+ if (err )
21632210 goto out ;
2164- }
21652211 }
2212+
21662213out :
21672214 mv88e6xxx_reg_unlock (chip );
21682215
@@ -2212,6 +2259,7 @@ static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
22122259 const struct switchdev_obj_port_vlan * vlan )
22132260{
22142261 struct mv88e6xxx_chip * chip = ds -> priv ;
2262+ struct mv88e6xxx_port * p = & chip -> ports [port ];
22152263 int err = 0 ;
22162264 u16 pvid ;
22172265
@@ -2229,7 +2277,9 @@ static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
22292277 goto unlock ;
22302278
22312279 if (vlan -> vid == pvid ) {
2232- err = mv88e6xxx_port_set_pvid (chip , port , 0 );
2280+ p -> bridge_pvid .valid = false;
2281+
2282+ err = mv88e6xxx_port_commit_pvid (chip , port );
22332283 if (err )
22342284 goto unlock ;
22352285 }
@@ -2393,7 +2443,16 @@ static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
23932443 int err ;
23942444
23952445 mv88e6xxx_reg_lock (chip );
2446+
23962447 err = mv88e6xxx_bridge_map (chip , br );
2448+ if (err )
2449+ goto unlock ;
2450+
2451+ err = mv88e6xxx_port_commit_pvid (chip , port );
2452+ if (err )
2453+ goto unlock ;
2454+
2455+ unlock :
23972456 mv88e6xxx_reg_unlock (chip );
23982457
23992458 return err ;
@@ -2403,11 +2462,20 @@ static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
24032462 struct net_device * br )
24042463{
24052464 struct mv88e6xxx_chip * chip = ds -> priv ;
2465+ int err ;
24062466
24072467 mv88e6xxx_reg_lock (chip );
2468+
24082469 if (mv88e6xxx_bridge_map (chip , br ) ||
24092470 mv88e6xxx_port_vlan_map (chip , port ))
24102471 dev_err (ds -> dev , "failed to remap in-chip Port VLAN\n" );
2472+
2473+ err = mv88e6xxx_port_commit_pvid (chip , port );
2474+ if (err )
2475+ dev_err (ds -> dev ,
2476+ "port %d failed to restore standalone pvid: %pe\n" ,
2477+ port , ERR_PTR (err ));
2478+
24112479 mv88e6xxx_reg_unlock (chip );
24122480}
24132481
@@ -2853,6 +2921,20 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
28532921 if (err )
28542922 return err ;
28552923
2924+ /* Associate MV88E6XXX_VID_BRIDGED with MV88E6XXX_FID_BRIDGED in the
2925+ * ATU by virtue of the fact that mv88e6xxx_atu_new() will pick it as
2926+ * the first free FID after MV88E6XXX_FID_STANDALONE. This will be used
2927+ * as the private PVID on ports under a VLAN-unaware bridge.
2928+ * Shared (DSA and CPU) ports must also be members of it, to translate
2929+ * the VID from the DSA tag into MV88E6XXX_FID_BRIDGED, instead of
2930+ * relying on their port default FID.
2931+ */
2932+ err = mv88e6xxx_port_vlan_join (chip , port , MV88E6XXX_VID_BRIDGED ,
2933+ MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED ,
2934+ false);
2935+ if (err )
2936+ return err ;
2937+
28562938 if (chip -> info -> ops -> port_set_jumbo_size ) {
28572939 err = chip -> info -> ops -> port_set_jumbo_size (chip , port , 10218 );
28582940 if (err )
@@ -2925,7 +3007,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
29253007 * database, and allow bidirectional communication between the
29263008 * CPU and DSA port(s), and the other ports.
29273009 */
2928- err = mv88e6xxx_port_set_fid (chip , port , 0 );
3010+ err = mv88e6xxx_port_set_fid (chip , port , MV88E6XXX_FID_STANDALONE );
29293011 if (err )
29303012 return err ;
29313013
@@ -3115,6 +3197,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
31153197 }
31163198 }
31173199
3200+ err = mv88e6xxx_vtu_setup (chip );
3201+ if (err )
3202+ goto unlock ;
3203+
31183204 /* Setup Switch Port Registers */
31193205 for (i = 0 ; i < mv88e6xxx_num_ports (chip ); i ++ ) {
31203206 if (dsa_is_unused_port (ds , i ))
@@ -3144,10 +3230,6 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
31443230 if (err )
31453231 goto unlock ;
31463232
3147- err = mv88e6xxx_vtu_setup (chip );
3148- if (err )
3149- goto unlock ;
3150-
31513233 err = mv88e6xxx_pvt_setup (chip );
31523234 if (err )
31533235 goto unlock ;
0 commit comments