@@ -803,9 +803,15 @@ static void ksz_phylink_get_caps(struct dsa_switch *ds, int port,
803803 if (dev -> info -> supports_rgmii [port ])
804804 phy_interface_set_rgmii (config -> supported_interfaces );
805805
806- if (dev -> info -> internal_phy [port ])
806+ if (dev -> info -> internal_phy [port ]) {
807807 __set_bit (PHY_INTERFACE_MODE_INTERNAL ,
808808 config -> supported_interfaces );
809+ /* Compatibility for phylib's default interface type when the
810+ * phy-mode property is absent
811+ */
812+ __set_bit (PHY_INTERFACE_MODE_GMII ,
813+ config -> supported_interfaces );
814+ }
809815
810816 if (dev -> dev_ops -> get_caps )
811817 dev -> dev_ops -> get_caps (dev , port , config );
@@ -962,6 +968,7 @@ static void ksz_update_port_member(struct ksz_device *dev, int port)
962968static int ksz_setup (struct dsa_switch * ds )
963969{
964970 struct ksz_device * dev = ds -> priv ;
971+ struct ksz_port * p ;
965972 const u16 * regs ;
966973 int ret ;
967974
@@ -1001,6 +1008,14 @@ static int ksz_setup(struct dsa_switch *ds)
10011008 return ret ;
10021009 }
10031010
1011+ /* Start with learning disabled on standalone user ports, and enabled
1012+ * on the CPU port. In lack of other finer mechanisms, learning on the
1013+ * CPU port will avoid flooding bridge local addresses on the network
1014+ * in some cases.
1015+ */
1016+ p = & dev -> ports [dev -> cpu_port ];
1017+ p -> learning = true;
1018+
10041019 /* start switch */
10051020 regmap_update_bits (dev -> regmap [0 ], regs [S_START_CTRL ],
10061021 SW_START , SW_START );
@@ -1277,6 +1292,8 @@ void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
12771292 ksz_pread8 (dev , port , regs [P_STP_CTRL ], & data );
12781293 data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE );
12791294
1295+ p = & dev -> ports [port ];
1296+
12801297 switch (state ) {
12811298 case BR_STATE_DISABLED :
12821299 data |= PORT_LEARN_DISABLE ;
@@ -1286,9 +1303,13 @@ void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
12861303 break ;
12871304 case BR_STATE_LEARNING :
12881305 data |= PORT_RX_ENABLE ;
1306+ if (!p -> learning )
1307+ data |= PORT_LEARN_DISABLE ;
12891308 break ;
12901309 case BR_STATE_FORWARDING :
12911310 data |= (PORT_TX_ENABLE | PORT_RX_ENABLE );
1311+ if (!p -> learning )
1312+ data |= PORT_LEARN_DISABLE ;
12921313 break ;
12931314 case BR_STATE_BLOCKING :
12941315 data |= PORT_LEARN_DISABLE ;
@@ -1300,12 +1321,38 @@ void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
13001321
13011322 ksz_pwrite8 (dev , port , regs [P_STP_CTRL ], data );
13021323
1303- p = & dev -> ports [port ];
13041324 p -> stp_state = state ;
13051325
13061326 ksz_update_port_member (dev , port );
13071327}
13081328
1329+ static int ksz_port_pre_bridge_flags (struct dsa_switch * ds , int port ,
1330+ struct switchdev_brport_flags flags ,
1331+ struct netlink_ext_ack * extack )
1332+ {
1333+ if (flags .mask & ~BR_LEARNING )
1334+ return - EINVAL ;
1335+
1336+ return 0 ;
1337+ }
1338+
1339+ static int ksz_port_bridge_flags (struct dsa_switch * ds , int port ,
1340+ struct switchdev_brport_flags flags ,
1341+ struct netlink_ext_ack * extack )
1342+ {
1343+ struct ksz_device * dev = ds -> priv ;
1344+ struct ksz_port * p = & dev -> ports [port ];
1345+
1346+ if (flags .mask & BR_LEARNING ) {
1347+ p -> learning = !!(flags .val & BR_LEARNING );
1348+
1349+ /* Make the change take effect immediately */
1350+ ksz_port_stp_state_set (ds , port , p -> stp_state );
1351+ }
1352+
1353+ return 0 ;
1354+ }
1355+
13091356static enum dsa_tag_protocol ksz_get_tag_protocol (struct dsa_switch * ds ,
13101357 int port ,
13111358 enum dsa_tag_protocol mp )
@@ -1719,6 +1766,8 @@ static const struct dsa_switch_ops ksz_switch_ops = {
17191766 .port_bridge_join = ksz_port_bridge_join ,
17201767 .port_bridge_leave = ksz_port_bridge_leave ,
17211768 .port_stp_state_set = ksz_port_stp_state_set ,
1769+ .port_pre_bridge_flags = ksz_port_pre_bridge_flags ,
1770+ .port_bridge_flags = ksz_port_bridge_flags ,
17221771 .port_fast_age = ksz_port_fast_age ,
17231772 .port_vlan_filtering = ksz_port_vlan_filtering ,
17241773 .port_vlan_add = ksz_port_vlan_add ,
0 commit comments