Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Pawel Dembicki and committed by
Jakub Kicinski
1e5b23e5 a8ea8d53

+85 -11
+85 -11
drivers/net/dsa/vitesse-vsc73xx-core.c
··· 164 164 #define VSC73XX_AGENCTRL 0xf0 165 165 #define VSC73XX_CAPRST 0xff 166 166 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 + 167 171 #define VSC73XX_MACACCESS_CPU_COPY BIT(14) 168 172 #define VSC73XX_MACACCESS_FWD_KILL BIT(13) 169 173 #define VSC73XX_MACACCESS_IGNORE_VLAN BIT(12) ··· 627 623 vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GMIIDELAY, 628 624 VSC73XX_GMIIDELAY_GMII0_GTXDELAY_2_0_NS | 629 625 VSC73XX_GMIIDELAY_GMII0_RXDELAY_2_0_NS); 630 - /* Enable reception of frames on all ports */ 631 - vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_RECVMASK, 632 - 0x5f); 633 626 /* IP multicast flood mask (table 144) */ 634 627 vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_IFLODMSK, 635 628 0xff); ··· 789 788 /* Allow backward dropping of frames from this port */ 790 789 vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 791 790 VSC73XX_SBACKWDROP, BIT(port), BIT(port)); 792 - 793 - /* Receive mask (disable forwarding) */ 794 - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 795 - VSC73XX_RECVMASK, BIT(port), 0); 796 791 } 797 792 798 793 static void vsc73xx_mac_link_up(struct phylink_config *config, ··· 840 843 /* Accept packets again */ 841 844 vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, 842 845 VSC73XX_ARBDISC, BIT(port), 0); 843 - 844 - /* Enable port (forwarding) in the receive mask */ 845 - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 846 - VSC73XX_RECVMASK, BIT(port), BIT(port)); 847 846 848 847 /* Disallow backward dropping of frames from this port */ 849 848 vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, ··· 1032 1039 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000; 1033 1040 } 1034 1041 1042 + static void vsc73xx_refresh_fwd_map(struct dsa_switch *ds, int port, u8 state) 1043 + { 1044 + struct dsa_port *other_dp, *dp = dsa_to_port(ds, port); 1045 + struct vsc73xx *vsc = ds->priv; 1046 + u16 mask; 1047 + 1048 + if (state != BR_STATE_FORWARDING) { 1049 + /* Ports that aren't in the forwarding state must not 1050 + * forward packets anywhere. 1051 + */ 1052 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1053 + VSC73XX_SRCMASKS + port, 1054 + VSC73XX_SRCMASKS_PORTS_MASK, 0); 1055 + 1056 + dsa_switch_for_each_available_port(other_dp, ds) { 1057 + if (other_dp == dp) 1058 + continue; 1059 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1060 + VSC73XX_SRCMASKS + other_dp->index, 1061 + BIT(port), 0); 1062 + } 1063 + 1064 + return; 1065 + } 1066 + 1067 + /* Forwarding ports must forward to the CPU and to other ports 1068 + * in the same bridge 1069 + */ 1070 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1071 + VSC73XX_SRCMASKS + CPU_PORT, BIT(port), BIT(port)); 1072 + 1073 + mask = BIT(CPU_PORT); 1074 + 1075 + dsa_switch_for_each_user_port(other_dp, ds) { 1076 + int other_port = other_dp->index; 1077 + 1078 + if (port == other_port || !dsa_port_bridge_same(dp, other_dp) || 1079 + other_dp->stp_state != BR_STATE_FORWARDING) 1080 + continue; 1081 + 1082 + mask |= BIT(other_port); 1083 + 1084 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1085 + VSC73XX_SRCMASKS + other_port, 1086 + BIT(port), BIT(port)); 1087 + } 1088 + 1089 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1090 + VSC73XX_SRCMASKS + port, 1091 + VSC73XX_SRCMASKS_PORTS_MASK, mask); 1092 + } 1093 + 1094 + /* FIXME: STP frames aren't forwarded at this moment. BPDU frames are 1095 + * forwarded only from and to PI/SI interface. For more info see chapter 1096 + * 2.7.1 (CPU Forwarding) in datasheet. 1097 + * This function is required for tag_8021q operations. 1098 + */ 1099 + static void vsc73xx_port_stp_state_set(struct dsa_switch *ds, int port, 1100 + u8 state) 1101 + { 1102 + struct vsc73xx *vsc = ds->priv; 1103 + u32 val; 1104 + 1105 + val = (state == BR_STATE_BLOCKING || state == BR_STATE_DISABLED) ? 1106 + 0 : BIT(port); 1107 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1108 + VSC73XX_RECVMASK, BIT(port), val); 1109 + 1110 + val = (state == BR_STATE_LEARNING || state == BR_STATE_FORWARDING) ? 1111 + BIT(port) : 0; 1112 + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, 1113 + VSC73XX_LEARNMASK, BIT(port), val); 1114 + 1115 + /* CPU Port should always forward packets when user ports are forwarding 1116 + * so let's configure it from other ports only. 1117 + */ 1118 + if (port != CPU_PORT) 1119 + vsc73xx_refresh_fwd_map(ds, port, state); 1120 + } 1121 + 1035 1122 static const struct phylink_mac_ops vsc73xx_phylink_mac_ops = { 1036 1123 .mac_config = vsc73xx_mac_config, 1037 1124 .mac_link_down = vsc73xx_mac_link_down, ··· 1130 1057 .port_disable = vsc73xx_port_disable, 1131 1058 .port_change_mtu = vsc73xx_change_mtu, 1132 1059 .port_max_mtu = vsc73xx_get_max_mtu, 1060 + .port_stp_state_set = vsc73xx_port_stp_state_set, 1133 1061 .phylink_get_caps = vsc73xx_phylink_get_caps, 1134 1062 }; 1135 1063