Skip to content

Commit b4dcaee

Browse files
committed
Merge branch 'net-dsa-yt921x-add-stp-mst-support'
David Yang says: ==================== net: dsa: yt921x: Add STP/MST support Support for these features was deferred from the initial submission of the driver. v3: https://lore.kernel.org/[email protected] v2: https://lore.kernel.org/[email protected] v1: https://lore.kernel.org/[email protected] ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents a202701 + 633b1d0 commit b4dcaee

File tree

2 files changed

+137
-13
lines changed

2 files changed

+137
-13
lines changed

drivers/net/dsa/yt921x.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
21012212
static 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,

drivers/net/dsa/yt921x.h

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,13 @@
274274
#define YT921X_VLAN_IGR_FILTER_PORTn(port) BIT(port)
275275
#define YT921X_PORTn_ISOLATION(port) (0x180294 + 4 * (port))
276276
#define YT921X_PORT_ISOLATION_BLOCKn(port) BIT(port)
277+
#define YT921X_STPn(n) (0x18038c + 4 * (n))
278+
#define YT921X_STP_PORTn_M(port) GENMASK(2 * (port) + 1, 2 * (port))
279+
#define YT921X_STP_PORTn(port, x) ((x) << (2 * (port)))
280+
#define YT921X_STP_PORTn_DISABLED(port) YT921X_STP_PORTn(port, 0)
281+
#define YT921X_STP_PORTn_LEARNING(port) YT921X_STP_PORTn(port, 1)
282+
#define YT921X_STP_PORTn_BLOCKING(port) YT921X_STP_PORTn(port, 2)
283+
#define YT921X_STP_PORTn_FORWARD(port) YT921X_STP_PORTn(port, 3)
277284
#define YT921X_PORTn_LEARN(port) (0x1803d0 + 4 * (port))
278285
#define YT921X_PORT_LEARN_VID_LEARN_MULTI_EN BIT(22)
279286
#define YT921X_PORT_LEARN_VID_LEARN_MODE BIT(21)
@@ -382,23 +389,23 @@
382389
#define YT921X_FDB_HW_FLUSH_ON_LINKDOWN BIT(0)
383390

384391
#define YT921X_VLANn_CTRL(vlan) (0x188000 + 8 * (vlan))
385-
#define YT921X_VLAN_CTRL_UNTAG_PORTS_M GENMASK(50, 40)
392+
#define YT921X_VLAN_CTRL_UNTAG_PORTS_M GENMASK_ULL(50, 40)
386393
#define YT921X_VLAN_CTRL_UNTAG_PORTS(x) FIELD_PREP(YT921X_VLAN_CTRL_UNTAG_PORTS_M, (x))
387-
#define YT921X_VLAN_CTRL_UNTAG_PORTn(port) BIT((port) + 40)
388-
#define YT921X_VLAN_CTRL_STP_ID_M GENMASK(39, 36)
394+
#define YT921X_VLAN_CTRL_UNTAG_PORTn(port) BIT_ULL((port) + 40)
395+
#define YT921X_VLAN_CTRL_STP_ID_M GENMASK_ULL(39, 36)
389396
#define YT921X_VLAN_CTRL_STP_ID(x) FIELD_PREP(YT921X_VLAN_CTRL_STP_ID_M, (x))
390-
#define YT921X_VLAN_CTRL_SVLAN_EN BIT(35)
391-
#define YT921X_VLAN_CTRL_FID_M GENMASK(34, 23)
397+
#define YT921X_VLAN_CTRL_SVLAN_EN BIT_ULL(35)
398+
#define YT921X_VLAN_CTRL_FID_M GENMASK_ULL(34, 23)
392399
#define YT921X_VLAN_CTRL_FID(x) FIELD_PREP(YT921X_VLAN_CTRL_FID_M, (x))
393-
#define YT921X_VLAN_CTRL_LEARN_DIS BIT(22)
394-
#define YT921X_VLAN_CTRL_INT_PRI_EN BIT(21)
395-
#define YT921X_VLAN_CTRL_INT_PRI_M GENMASK(20, 18)
396-
#define YT921X_VLAN_CTRL_PORTS_M GENMASK(17, 7)
400+
#define YT921X_VLAN_CTRL_LEARN_DIS BIT_ULL(22)
401+
#define YT921X_VLAN_CTRL_INT_PRI_EN BIT_ULL(21)
402+
#define YT921X_VLAN_CTRL_INT_PRI_M GENMASK_ULL(20, 18)
403+
#define YT921X_VLAN_CTRL_PORTS_M GENMASK_ULL(17, 7)
397404
#define YT921X_VLAN_CTRL_PORTS(x) FIELD_PREP(YT921X_VLAN_CTRL_PORTS_M, (x))
398-
#define YT921X_VLAN_CTRL_PORTn(port) BIT((port) + 7)
399-
#define YT921X_VLAN_CTRL_BYPASS_1X_AC BIT(6)
400-
#define YT921X_VLAN_CTRL_METER_EN BIT(5)
401-
#define YT921X_VLAN_CTRL_METER_ID_M GENMASK(4, 0)
405+
#define YT921X_VLAN_CTRL_PORTn(port) BIT_ULL((port) + 7)
406+
#define YT921X_VLAN_CTRL_BYPASS_1X_AC BIT_ULL(6)
407+
#define YT921X_VLAN_CTRL_METER_EN BIT_ULL(5)
408+
#define YT921X_VLAN_CTRL_METER_ID_M GENMASK_ULL(4, 0)
402409

403410
#define YT921X_TPID_IGRn(x) (0x210000 + 4 * (x)) /* [0, 3] */
404411
#define YT921X_TPID_IGR_TPID_M GENMASK(15, 0)
@@ -449,6 +456,8 @@ enum yt921x_fdb_entry_status {
449456
YT921X_FDB_ENTRY_STATUS_STATIC = 7,
450457
};
451458

459+
#define YT921X_MSTI_NUM 16
460+
452461
#define YT9215_MAJOR 0x9002
453462
#define YT9218_MAJOR 0x9001
454463

0 commit comments

Comments
 (0)