@@ -2098,6 +2098,117 @@ yt921x_dsa_port_bridge_join(struct dsa_switch *ds, int port,
20982098 return res ;
20992099}
21002100
2101+ static int
2102+ yt921x_dsa_port_mst_state_set (struct dsa_switch * ds , int port ,
2103+ const struct switchdev_mst_state * st )
2104+ {
2105+ struct yt921x_priv * priv = to_yt921x_priv (ds );
2106+ u32 mask ;
2107+ u32 ctrl ;
2108+ int res ;
2109+
2110+ mask = YT921X_STP_PORTn_M (port );
2111+ switch (st -> state ) {
2112+ case BR_STATE_DISABLED :
2113+ ctrl = YT921X_STP_PORTn_DISABLED (port );
2114+ break ;
2115+ case BR_STATE_LISTENING :
2116+ case BR_STATE_LEARNING :
2117+ ctrl = YT921X_STP_PORTn_LEARNING (port );
2118+ break ;
2119+ case BR_STATE_FORWARDING :
2120+ default :
2121+ ctrl = YT921X_STP_PORTn_FORWARD (port );
2122+ break ;
2123+ case BR_STATE_BLOCKING :
2124+ ctrl = YT921X_STP_PORTn_BLOCKING (port );
2125+ break ;
2126+ }
2127+
2128+ mutex_lock (& priv -> reg_lock );
2129+ res = yt921x_reg_update_bits (priv , YT921X_STPn (st -> msti ), mask , ctrl );
2130+ mutex_unlock (& priv -> reg_lock );
2131+
2132+ return res ;
2133+ }
2134+
2135+ static int
2136+ yt921x_dsa_vlan_msti_set (struct dsa_switch * ds , struct dsa_bridge bridge ,
2137+ const struct switchdev_vlan_msti * msti )
2138+ {
2139+ struct yt921x_priv * priv = to_yt921x_priv (ds );
2140+ u64 mask64 ;
2141+ u64 ctrl64 ;
2142+ int res ;
2143+
2144+ if (!msti -> vid )
2145+ return - EINVAL ;
2146+ if (!msti -> msti || msti -> msti >= YT921X_MSTI_NUM )
2147+ return - EINVAL ;
2148+
2149+ mask64 = YT921X_VLAN_CTRL_STP_ID_M ;
2150+ ctrl64 = YT921X_VLAN_CTRL_STP_ID (msti -> msti );
2151+
2152+ mutex_lock (& priv -> reg_lock );
2153+ res = yt921x_reg64_update_bits (priv , YT921X_VLANn_CTRL (msti -> vid ),
2154+ mask64 , ctrl64 );
2155+ mutex_unlock (& priv -> reg_lock );
2156+
2157+ return res ;
2158+ }
2159+
2160+ static void
2161+ yt921x_dsa_port_stp_state_set (struct dsa_switch * ds , int port , u8 state )
2162+ {
2163+ struct yt921x_priv * priv = to_yt921x_priv (ds );
2164+ struct dsa_port * dp = dsa_to_port (ds , port );
2165+ struct device * dev = to_device (priv );
2166+ bool learning ;
2167+ u32 mask ;
2168+ u32 ctrl ;
2169+ int res ;
2170+
2171+ mask = YT921X_STP_PORTn_M (port );
2172+ learning = false;
2173+ switch (state ) {
2174+ case BR_STATE_DISABLED :
2175+ ctrl = YT921X_STP_PORTn_DISABLED (port );
2176+ break ;
2177+ case BR_STATE_LISTENING :
2178+ ctrl = YT921X_STP_PORTn_LEARNING (port );
2179+ break ;
2180+ case BR_STATE_LEARNING :
2181+ ctrl = YT921X_STP_PORTn_LEARNING (port );
2182+ learning = dp -> learning ;
2183+ break ;
2184+ case BR_STATE_FORWARDING :
2185+ default :
2186+ ctrl = YT921X_STP_PORTn_FORWARD (port );
2187+ learning = dp -> learning ;
2188+ break ;
2189+ case BR_STATE_BLOCKING :
2190+ ctrl = YT921X_STP_PORTn_BLOCKING (port );
2191+ break ;
2192+ }
2193+
2194+ mutex_lock (& priv -> reg_lock );
2195+ do {
2196+ res = yt921x_reg_update_bits (priv , YT921X_STPn (0 ), mask , ctrl );
2197+ if (res )
2198+ break ;
2199+
2200+ mask = YT921X_PORT_LEARN_DIS ;
2201+ ctrl = !learning ? YT921X_PORT_LEARN_DIS : 0 ;
2202+ res = yt921x_reg_update_bits (priv , YT921X_PORTn_LEARN (port ),
2203+ mask , ctrl );
2204+ } while (0 );
2205+ mutex_unlock (& priv -> reg_lock );
2206+
2207+ if (res )
2208+ dev_err (dev , "Failed to %s port %d: %i\n" , "set STP state for" ,
2209+ port , res );
2210+ }
2211+
21012212static int yt921x_port_down (struct yt921x_priv * priv , int port )
21022213{
21032214 u32 mask ;
@@ -2783,6 +2894,10 @@ static const struct dsa_switch_ops yt921x_dsa_switch_ops = {
27832894 .port_bridge_flags = yt921x_dsa_port_bridge_flags ,
27842895 .port_bridge_leave = yt921x_dsa_port_bridge_leave ,
27852896 .port_bridge_join = yt921x_dsa_port_bridge_join ,
2897+ /* mst */
2898+ .port_mst_state_set = yt921x_dsa_port_mst_state_set ,
2899+ .vlan_msti_set = yt921x_dsa_vlan_msti_set ,
2900+ .port_stp_state_set = yt921x_dsa_port_stp_state_set ,
27862901 /* port */
27872902 .get_tag_protocol = yt921x_dsa_get_tag_protocol ,
27882903 .phylink_get_caps = yt921x_dsa_phylink_get_caps ,
0 commit comments