mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-08 14:23:19 +00:00
net: dsa: vsc73xx: add port_stp_state_set function
This isn't a fully functional implementation of 802.1D, but port_stp_state_set is required for a future tag8021q operations. This implementation handles properly all states, but vsc73xx doesn't forward STP packets. Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com> Link: https://patch.msgid.link/20240713211620.1125910-2-paweldembicki@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
a8ea8d531d
commit
1e5b23e50f
@ -164,6 +164,10 @@
|
||||
#define VSC73XX_AGENCTRL 0xf0
|
||||
#define VSC73XX_CAPRST 0xff
|
||||
|
||||
#define VSC73XX_SRCMASKS_CPU_COPY BIT(27)
|
||||
#define VSC73XX_SRCMASKS_MIRROR BIT(26)
|
||||
#define VSC73XX_SRCMASKS_PORTS_MASK GENMASK(7, 0)
|
||||
|
||||
#define VSC73XX_MACACCESS_CPU_COPY BIT(14)
|
||||
#define VSC73XX_MACACCESS_FWD_KILL BIT(13)
|
||||
#define VSC73XX_MACACCESS_IGNORE_VLAN BIT(12)
|
||||
@ -623,9 +627,6 @@ static int vsc73xx_setup(struct dsa_switch *ds)
|
||||
vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GMIIDELAY,
|
||||
VSC73XX_GMIIDELAY_GMII0_GTXDELAY_2_0_NS |
|
||||
VSC73XX_GMIIDELAY_GMII0_RXDELAY_2_0_NS);
|
||||
/* Enable reception of frames on all ports */
|
||||
vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_RECVMASK,
|
||||
0x5f);
|
||||
/* IP multicast flood mask (table 144) */
|
||||
vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_IFLODMSK,
|
||||
0xff);
|
||||
@ -788,10 +789,6 @@ static void vsc73xx_mac_link_down(struct phylink_config *config,
|
||||
/* Allow backward dropping of frames from this port */
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0,
|
||||
VSC73XX_SBACKWDROP, BIT(port), BIT(port));
|
||||
|
||||
/* Receive mask (disable forwarding) */
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_RECVMASK, BIT(port), 0);
|
||||
}
|
||||
|
||||
static void vsc73xx_mac_link_up(struct phylink_config *config,
|
||||
@ -844,10 +841,6 @@ static void vsc73xx_mac_link_up(struct phylink_config *config,
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0,
|
||||
VSC73XX_ARBDISC, BIT(port), 0);
|
||||
|
||||
/* Enable port (forwarding) in the receive mask */
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_RECVMASK, BIT(port), BIT(port));
|
||||
|
||||
/* Disallow backward dropping of frames from this port */
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0,
|
||||
VSC73XX_SBACKWDROP, BIT(port), 0);
|
||||
@ -1039,6 +1032,86 @@ static void vsc73xx_phylink_get_caps(struct dsa_switch *dsa, int port,
|
||||
config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000;
|
||||
}
|
||||
|
||||
static void vsc73xx_refresh_fwd_map(struct dsa_switch *ds, int port, u8 state)
|
||||
{
|
||||
struct dsa_port *other_dp, *dp = dsa_to_port(ds, port);
|
||||
struct vsc73xx *vsc = ds->priv;
|
||||
u16 mask;
|
||||
|
||||
if (state != BR_STATE_FORWARDING) {
|
||||
/* Ports that aren't in the forwarding state must not
|
||||
* forward packets anywhere.
|
||||
*/
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_SRCMASKS + port,
|
||||
VSC73XX_SRCMASKS_PORTS_MASK, 0);
|
||||
|
||||
dsa_switch_for_each_available_port(other_dp, ds) {
|
||||
if (other_dp == dp)
|
||||
continue;
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_SRCMASKS + other_dp->index,
|
||||
BIT(port), 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Forwarding ports must forward to the CPU and to other ports
|
||||
* in the same bridge
|
||||
*/
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_SRCMASKS + CPU_PORT, BIT(port), BIT(port));
|
||||
|
||||
mask = BIT(CPU_PORT);
|
||||
|
||||
dsa_switch_for_each_user_port(other_dp, ds) {
|
||||
int other_port = other_dp->index;
|
||||
|
||||
if (port == other_port || !dsa_port_bridge_same(dp, other_dp) ||
|
||||
other_dp->stp_state != BR_STATE_FORWARDING)
|
||||
continue;
|
||||
|
||||
mask |= BIT(other_port);
|
||||
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_SRCMASKS + other_port,
|
||||
BIT(port), BIT(port));
|
||||
}
|
||||
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_SRCMASKS + port,
|
||||
VSC73XX_SRCMASKS_PORTS_MASK, mask);
|
||||
}
|
||||
|
||||
/* FIXME: STP frames aren't forwarded at this moment. BPDU frames are
|
||||
* forwarded only from and to PI/SI interface. For more info see chapter
|
||||
* 2.7.1 (CPU Forwarding) in datasheet.
|
||||
* This function is required for tag_8021q operations.
|
||||
*/
|
||||
static void vsc73xx_port_stp_state_set(struct dsa_switch *ds, int port,
|
||||
u8 state)
|
||||
{
|
||||
struct vsc73xx *vsc = ds->priv;
|
||||
u32 val;
|
||||
|
||||
val = (state == BR_STATE_BLOCKING || state == BR_STATE_DISABLED) ?
|
||||
0 : BIT(port);
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_RECVMASK, BIT(port), val);
|
||||
|
||||
val = (state == BR_STATE_LEARNING || state == BR_STATE_FORWARDING) ?
|
||||
BIT(port) : 0;
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_LEARNMASK, BIT(port), val);
|
||||
|
||||
/* CPU Port should always forward packets when user ports are forwarding
|
||||
* so let's configure it from other ports only.
|
||||
*/
|
||||
if (port != CPU_PORT)
|
||||
vsc73xx_refresh_fwd_map(ds, port, state);
|
||||
}
|
||||
|
||||
static const struct phylink_mac_ops vsc73xx_phylink_mac_ops = {
|
||||
.mac_config = vsc73xx_mac_config,
|
||||
.mac_link_down = vsc73xx_mac_link_down,
|
||||
@ -1057,6 +1130,7 @@ static const struct dsa_switch_ops vsc73xx_ds_ops = {
|
||||
.port_disable = vsc73xx_port_disable,
|
||||
.port_change_mtu = vsc73xx_change_mtu,
|
||||
.port_max_mtu = vsc73xx_get_max_mtu,
|
||||
.port_stp_state_set = vsc73xx_port_stp_state_set,
|
||||
.phylink_get_caps = vsc73xx_phylink_get_caps,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user