Skip to content

Commit 1e5b23e

Browse files
CHKDSK88kuba-moo
authored andcommitted
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>
1 parent a8ea8d5 commit 1e5b23e

1 file changed

Lines changed: 85 additions & 11 deletions

File tree

drivers/net/dsa/vitesse-vsc73xx-core.c

Lines changed: 85 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@
164164
#define VSC73XX_AGENCTRL 0xf0
165165
#define VSC73XX_CAPRST 0xff
166166

167+
#define VSC73XX_SRCMASKS_CPU_COPY BIT(27)
168+
#define VSC73XX_SRCMASKS_MIRROR BIT(26)
169+
#define VSC73XX_SRCMASKS_PORTS_MASK GENMASK(7, 0)
170+
167171
#define VSC73XX_MACACCESS_CPU_COPY BIT(14)
168172
#define VSC73XX_MACACCESS_FWD_KILL BIT(13)
169173
#define VSC73XX_MACACCESS_IGNORE_VLAN BIT(12)
@@ -623,9 +627,6 @@ static int vsc73xx_setup(struct dsa_switch *ds)
623627
vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GMIIDELAY,
624628
VSC73XX_GMIIDELAY_GMII0_GTXDELAY_2_0_NS |
625629
VSC73XX_GMIIDELAY_GMII0_RXDELAY_2_0_NS);
626-
/* Enable reception of frames on all ports */
627-
vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_RECVMASK,
628-
0x5f);
629630
/* IP multicast flood mask (table 144) */
630631
vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_IFLODMSK,
631632
0xff);
@@ -788,10 +789,6 @@ static void vsc73xx_mac_link_down(struct phylink_config *config,
788789
/* Allow backward dropping of frames from this port */
789790
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0,
790791
VSC73XX_SBACKWDROP, BIT(port), BIT(port));
791-
792-
/* Receive mask (disable forwarding) */
793-
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
794-
VSC73XX_RECVMASK, BIT(port), 0);
795792
}
796793

797794
static void vsc73xx_mac_link_up(struct phylink_config *config,
@@ -844,10 +841,6 @@ static void vsc73xx_mac_link_up(struct phylink_config *config,
844841
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0,
845842
VSC73XX_ARBDISC, BIT(port), 0);
846843

847-
/* Enable port (forwarding) in the receive mask */
848-
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
849-
VSC73XX_RECVMASK, BIT(port), BIT(port));
850-
851844
/* Disallow backward dropping of frames from this port */
852845
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0,
853846
VSC73XX_SBACKWDROP, BIT(port), 0);
@@ -1039,6 +1032,86 @@ static void vsc73xx_phylink_get_caps(struct dsa_switch *dsa, int port,
10391032
config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000;
10401033
}
10411034

1035+
static void vsc73xx_refresh_fwd_map(struct dsa_switch *ds, int port, u8 state)
1036+
{
1037+
struct dsa_port *other_dp, *dp = dsa_to_port(ds, port);
1038+
struct vsc73xx *vsc = ds->priv;
1039+
u16 mask;
1040+
1041+
if (state != BR_STATE_FORWARDING) {
1042+
/* Ports that aren't in the forwarding state must not
1043+
* forward packets anywhere.
1044+
*/
1045+
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
1046+
VSC73XX_SRCMASKS + port,
1047+
VSC73XX_SRCMASKS_PORTS_MASK, 0);
1048+
1049+
dsa_switch_for_each_available_port(other_dp, ds) {
1050+
if (other_dp == dp)
1051+
continue;
1052+
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
1053+
VSC73XX_SRCMASKS + other_dp->index,
1054+
BIT(port), 0);
1055+
}
1056+
1057+
return;
1058+
}
1059+
1060+
/* Forwarding ports must forward to the CPU and to other ports
1061+
* in the same bridge
1062+
*/
1063+
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
1064+
VSC73XX_SRCMASKS + CPU_PORT, BIT(port), BIT(port));
1065+
1066+
mask = BIT(CPU_PORT);
1067+
1068+
dsa_switch_for_each_user_port(other_dp, ds) {
1069+
int other_port = other_dp->index;
1070+
1071+
if (port == other_port || !dsa_port_bridge_same(dp, other_dp) ||
1072+
other_dp->stp_state != BR_STATE_FORWARDING)
1073+
continue;
1074+
1075+
mask |= BIT(other_port);
1076+
1077+
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
1078+
VSC73XX_SRCMASKS + other_port,
1079+
BIT(port), BIT(port));
1080+
}
1081+
1082+
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
1083+
VSC73XX_SRCMASKS + port,
1084+
VSC73XX_SRCMASKS_PORTS_MASK, mask);
1085+
}
1086+
1087+
/* FIXME: STP frames aren't forwarded at this moment. BPDU frames are
1088+
* forwarded only from and to PI/SI interface. For more info see chapter
1089+
* 2.7.1 (CPU Forwarding) in datasheet.
1090+
* This function is required for tag_8021q operations.
1091+
*/
1092+
static void vsc73xx_port_stp_state_set(struct dsa_switch *ds, int port,
1093+
u8 state)
1094+
{
1095+
struct vsc73xx *vsc = ds->priv;
1096+
u32 val;
1097+
1098+
val = (state == BR_STATE_BLOCKING || state == BR_STATE_DISABLED) ?
1099+
0 : BIT(port);
1100+
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
1101+
VSC73XX_RECVMASK, BIT(port), val);
1102+
1103+
val = (state == BR_STATE_LEARNING || state == BR_STATE_FORWARDING) ?
1104+
BIT(port) : 0;
1105+
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
1106+
VSC73XX_LEARNMASK, BIT(port), val);
1107+
1108+
/* CPU Port should always forward packets when user ports are forwarding
1109+
* so let's configure it from other ports only.
1110+
*/
1111+
if (port != CPU_PORT)
1112+
vsc73xx_refresh_fwd_map(ds, port, state);
1113+
}
1114+
10421115
static const struct phylink_mac_ops vsc73xx_phylink_mac_ops = {
10431116
.mac_config = vsc73xx_mac_config,
10441117
.mac_link_down = vsc73xx_mac_link_down,
@@ -1057,6 +1130,7 @@ static const struct dsa_switch_ops vsc73xx_ds_ops = {
10571130
.port_disable = vsc73xx_port_disable,
10581131
.port_change_mtu = vsc73xx_change_mtu,
10591132
.port_max_mtu = vsc73xx_get_max_mtu,
1133+
.port_stp_state_set = vsc73xx_port_stp_state_set,
10601134
.phylink_get_caps = vsc73xx_phylink_get_caps,
10611135
};
10621136

0 commit comments

Comments
 (0)