Re: [PATCH v2 net-next 1/3] net: dsa: mediatek: add VLAN support for MT7530
Hi Sean, I love your patch! Perhaps something to improve: [auto build test WARNING on net-next/master] url: https://github.com/0day-ci/linux/commits/sean-wang-mediatek-com/add-VLAN-support-to-DSA-MT7530/20171215-214450 config: x86_64-randconfig-g0-12151942 (attached as .config) compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): drivers/net/dsa/mt7530.c: In function 'mt7530_port_vlan_add': drivers/net/dsa/mt7530.c:1131:6: warning: unused variable 'ret' [-Wunused-variable] int ret; ^ drivers/net/dsa/mt7530.c: At top level: >> drivers/net/dsa/mt7530.c:1324:2: warning: initialization from incompatible >> pointer type .port_vlan_prepare = mt7530_port_vlan_prepare, ^ drivers/net/dsa/mt7530.c:1324:2: warning: (near initialization for 'mt7530_switch_ops.port_vlan_prepare') drivers/net/dsa/mt7530.c:1325:2: warning: initialization from incompatible pointer type .port_vlan_add = mt7530_port_vlan_add, ^ drivers/net/dsa/mt7530.c:1325:2: warning: (near initialization for 'mt7530_switch_ops.port_vlan_add') Cyclomatic Complexity 3 include/linux/string.h:strncpy Cyclomatic Complexity 1 include/linux/err.h:ERR_PTR Cyclomatic Complexity 1 include/linux/err.h:PTR_ERR Cyclomatic Complexity 1 include/linux/err.h:IS_ERR Cyclomatic Complexity 3 include/linux/ktime.h:ktime_compare Cyclomatic Complexity 1 include/linux/ktime.h:ktime_add_us Cyclomatic Complexity 1 include/linux/device.h:devm_kzalloc Cyclomatic Complexity 1 include/linux/device.h:dev_get_drvdata Cyclomatic Complexity 1 include/linux/device.h:dev_set_drvdata Cyclomatic Complexity 5 include/linux/mii.h:mii_resolve_flowctrl_fdx Cyclomatic Complexity 1 include/linux/of.h:of_property_read_bool Cyclomatic Complexity 1 include/linux/phy.h:phy_is_pseudo_fixed_link Cyclomatic Complexity 1 include/linux/reset.h:reset_control_assert Cyclomatic Complexity 1 include/linux/reset.h:reset_control_deassert Cyclomatic Complexity 2 include/linux/reset.h:__devm_reset_control_get Cyclomatic Complexity 2 include/linux/reset.h:devm_reset_control_get_exclusive Cyclomatic Complexity 1 include/linux/reset.h:devm_reset_control_get Cyclomatic Complexity 1 include/net/dsa.h:dsa_to_port Cyclomatic Complexity 1 include/net/dsa.h:dsa_is_cpu_port Cyclomatic Complexity 1 include/net/dsa.h:dsa_is_user_port Cyclomatic Complexity 3 include/net/dsa.h:dsa_user_ports Cyclomatic Complexity 1 drivers/net/dsa/mt7530.h:mt7530_hw_vlan_entry_init Cyclomatic Complexity 1 drivers/net/dsa/mt7530.h:INIT_MT7530_DUMMY_POLL Cyclomatic Complexity 2 drivers/net/dsa/mt7530.c:mt7530_get_strings Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_get_sset_count Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_port_vlan_prepare Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mdio_module_init Cyclomatic Complexity 2 drivers/net/dsa/mt7530.c:mt7530_mii_read Cyclomatic Complexity 4 drivers/net/dsa/mt7530.c:mt7530_mii_write Cyclomatic Complexity 4 drivers/net/dsa/mt7530.c:core_read_mmd_indirect Cyclomatic Complexity 5 drivers/net/dsa/mt7530.c:core_write_mmd_indirect Cyclomatic Complexity 3 drivers/net/dsa/mt7530.c:mt7530_remove Cyclomatic Complexity 9 drivers/net/dsa/mt7530.c:mt7530_probe Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:_mt7530_read Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_read Cyclomatic Complexity 2 drivers/net/dsa/mt7530.c:mt7530_fdb_read Cyclomatic Complexity 3 drivers/net/dsa/mt7530.c:mt7530_get_ethtool_stats Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_write Cyclomatic Complexity 2 drivers/net/dsa/mt7530.c:mt7530_fdb_write Cyclomatic Complexity 3 drivers/net/dsa/mt7530.c:mt7530_hw_vlan_del Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_mib_reset Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_rmw Cyclomatic Complexity 2 drivers/net/dsa/mt7530.c:mt7530_hw_vlan_add Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_port_set_vlan_aware Cyclomatic Complexity 2 drivers/net/dsa/mt7530.c:mt7530_port_vlan_filtering Cyclomatic Complexity 5 drivers/net/dsa/mt7530.c:mt7530_stp_state_set Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_clear Cyclomatic Complexity 5 drivers/net/dsa/mt7530.c:mt7530_port_set_vlan_unaware Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_set Cyclomatic Complexity 2 drivers/net/dsa/mt7530.c:mt7530_port_set_status Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_cpu_port_enable Cyclomatic Complexity 8 drivers/net/dsa/mt7530.c:mt7530_port_bridge_leave Cyclomatic Complexity 7 drivers/net/dsa/mt7530.c:mt7530_port_bridge_join Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_port_disable Cyclomatic Complexity 1 drivers/net/dsa/mt7530.c:mt7530_port_enable
Re: [PATCH v2 net-next 1/3] net: dsa: mediatek: add VLAN support for MT7530
Hi Sean, I love your patch! Perhaps something to improve: [auto build test WARNING on net-next/master] url: https://github.com/0day-ci/linux/commits/sean-wang-mediatek-com/add-VLAN-support-to-DSA-MT7530/20171215-214450 reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) vim +1324 drivers/net/dsa/mt7530.c 1305 1306 static const struct dsa_switch_ops mt7530_switch_ops = { 1307 .get_tag_protocol = mtk_get_tag_protocol, 1308 .setup = mt7530_setup, 1309 .get_strings= mt7530_get_strings, 1310 .phy_read = mt7530_phy_read, 1311 .phy_write = mt7530_phy_write, 1312 .get_ethtool_stats = mt7530_get_ethtool_stats, 1313 .get_sset_count = mt7530_get_sset_count, 1314 .adjust_link= mt7530_adjust_link, 1315 .port_enable= mt7530_port_enable, 1316 .port_disable = mt7530_port_disable, 1317 .port_stp_state_set = mt7530_stp_state_set, 1318 .port_bridge_join = mt7530_port_bridge_join, 1319 .port_bridge_leave = mt7530_port_bridge_leave, 1320 .port_fdb_add = mt7530_port_fdb_add, 1321 .port_fdb_del = mt7530_port_fdb_del, 1322 .port_fdb_dump = mt7530_port_fdb_dump, 1323 .port_vlan_filtering= mt7530_port_vlan_filtering, > 1324 .port_vlan_prepare = mt7530_port_vlan_prepare, > 1325 .port_vlan_add = mt7530_port_vlan_add, 1326 .port_vlan_del = mt7530_port_vlan_del, 1327 }; 1328 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Re: [PATCH v2 net-next 1/3] net: dsa: mediatek: add VLAN support for MT7530
Hi Sean, I love your patch! Yet something to improve: [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/sean-wang-mediatek-com/add-VLAN-support-to-DSA-MT7530/20171215-214450 config: i386-randconfig-x019-201750 (attached as .config) compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): drivers/net/dsa/mt7530.c: In function 'mt7530_port_vlan_add': drivers/net/dsa/mt7530.c:1131:6: warning: unused variable 'ret' [-Wunused-variable] int ret; ^~~ drivers/net/dsa/mt7530.c: At top level: >> drivers/net/dsa/mt7530.c:1324:23: error: initialization from incompatible >> pointer type [-Werror=incompatible-pointer-types] .port_vlan_prepare = mt7530_port_vlan_prepare, ^~~~ drivers/net/dsa/mt7530.c:1324:23: note: (near initialization for 'mt7530_switch_ops.port_vlan_prepare') drivers/net/dsa/mt7530.c:1325:20: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] .port_vlan_add = mt7530_port_vlan_add, ^~~~ drivers/net/dsa/mt7530.c:1325:20: note: (near initialization for 'mt7530_switch_ops.port_vlan_add') cc1: some warnings being treated as errors vim +1324 drivers/net/dsa/mt7530.c 1121 1122 static void 1123 mt7530_port_vlan_add(struct dsa_switch *ds, int port, 1124 const struct switchdev_obj_port_vlan *vlan, 1125 struct switchdev_trans *trans) 1126 { 1127 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; 1128 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; 1129 struct mt7530_hw_vlan_entry new_entry; 1130 struct mt7530_priv *priv = ds->priv; > 1131 int ret; 1132 u16 vid; 1133 1134 /* The port is kept as VLAN-unaware if bridge with vlan_filtering not 1135 * being set. 1136 */ 1137 if (!priv->ports[port].vlan_filtering) 1138 return; 1139 1140 mutex_lock(>reg_mutex); 1141 1142 for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) { 1143 mt7530_hw_vlan_entry_init(_entry, port, untagged); 1144 mt7530_hw_vlan_update(priv, vid, _entry, 1145mt7530_hw_vlan_add); 1146 } 1147 1148 if (pvid) { 1149 mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, 1150 G0_PORT_VID(vlan->vid_end)); 1151 priv->ports[port].pvid = vlan->vid_end; 1152 } 1153 1154 mutex_unlock(>reg_mutex); 1155 } 1156 1157 static int 1158 mt7530_port_vlan_del(struct dsa_switch *ds, int port, 1159 const struct switchdev_obj_port_vlan *vlan) 1160 { 1161 struct mt7530_hw_vlan_entry target_entry; 1162 struct mt7530_priv *priv = ds->priv; 1163 u16 vid, pvid; 1164 1165 /* The port is kept as VLAN-unaware if bridge with vlan_filtering not 1166 * being set. 1167 */ 1168 if (!priv->ports[port].vlan_filtering) 1169 return 0; 1170 1171 mutex_lock(>reg_mutex); 1172 1173 pvid = priv->ports[port].pvid; 1174 for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) { 1175 mt7530_hw_vlan_entry_init(_entry, port, 0); 1176 mt7530_hw_vlan_update(priv, vid, _entry, 1177mt7530_hw_vlan_del); 1178 1179 /* PVID is being restored to the default whenever the PVID port 1180 * is being removed from the VLAN. 1181 */ 1182 if (pvid == vid) 1183 pvid = G0_PORT_VID_DEF; 1184 } 1185 1186 mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, pvid); 1187 priv->ports[port].pvid = pvid; 1188 1189 mutex_unlock(>reg_mutex); 1190 1191 return 0; 1192 } 1193 1194 static enum dsa_tag_protocol 1195 mtk_get_tag_protocol(struct dsa_switch *ds, int port) 1196 { 1197 struct mt7530_priv *priv = ds->priv; 1198 1199 if (port != MT7530_CPU_PORT) { 1200 dev_warn(priv->dev, 1201 "port not matched with tagging CPU port\n"); 1202 return DSA_TAG_PROTO_NONE; 1203 } else { 1204 return DSA_TAG_PROTO_MTK; 1205 } 1206 } 1207 1208 static int 1209 mt7530_setup(struct dsa_switch *ds) 1210 { 1211 struct mt7530_priv *priv = ds->priv; 1212 int ret,
[PATCH v2 net-next 1/3] net: dsa: mediatek: add VLAN support for MT7530
From: Sean WangMT7530 can treat each port as either VLAN-unaware port or VLAN-aware port through the implementation of port matrix mode or port security mode on the ingress port, respectively. On one hand, Each port has been acting as the VLAN-unaware one whenever the device is created in the initial or certain port joins or leaves into/from the bridge at the runtime. On the other hand, the patch just filling the required callbacks for VLAN operations is achieved via extending the port to be into port security mode when the port is configured as VLAN-aware port. Which mode can make the port be able to recognize VID from incoming packets and look up VLAN table to validate and judge which port it should be going to. And the range for VID from 1 to 4094 is valid for the hardware. Signed-off-by: Sean Wang --- drivers/net/dsa/mt7530.c | 291 ++- drivers/net/dsa/mt7530.h | 83 +- 2 files changed, 367 insertions(+), 7 deletions(-) diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index 2820d69..252e8ba 100644 --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c @@ -805,6 +805,69 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port, } static void +mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port) +{ + struct mt7530_priv *priv = ds->priv; + bool all_user_ports_removed = true; + int i; + + /* When a port is removed from the bridge, the port would be set up +* back to the default as is at initial boot which is a VLAN-unaware +* port. +*/ + mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK, + MT7530_PORT_MATRIX_MODE); + mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK, + VLAN_ATTR(MT7530_VLAN_TRANSPARENT)); + + priv->ports[port].vlan_filtering = false; + + for (i = 0; i < MT7530_NUM_PORTS; i++) { + if (dsa_is_user_port(ds, i) && + priv->ports[i].vlan_filtering) { + all_user_ports_removed = false; + break; + } + } + + /* CPU port also does the same thing until all user ports belonging to +* the CPU port get out of VLAN filtering mode. +*/ + if (all_user_ports_removed) { + mt7530_write(priv, MT7530_PCR_P(MT7530_CPU_PORT), +PCR_MATRIX(dsa_user_ports(priv->ds))); + mt7530_write(priv, MT7530_PVC_P(MT7530_CPU_PORT), +PORT_SPEC_TAG); + } +} + +static void +mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port) +{ + struct mt7530_priv *priv = ds->priv; + + /* The real fabric path would be decided on the membership in the +* entry of VLAN table. PCR_MATRIX set up here with ALL_MEMBERS +* means potential VLAN can be consisting of certain subset of all +* ports. +*/ + mt7530_rmw(priv, MT7530_PCR_P(port), + PCR_MATRIX_MASK, PCR_MATRIX(MT7530_ALL_MEMBERS)); + + /* Trapped into security mode allows packet forwarding through VLAN +* table lookup. +*/ + mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK, + MT7530_PORT_SECURITY_MODE); + + /* Set the port as a user port which is to be able to recognize VID +* from incoming packets before fetching entry within the VLAN table. +*/ + mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK, + VLAN_ATTR(MT7530_VLAN_USER)); +} + +static void mt7530_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *bridge) { @@ -817,8 +880,11 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port, /* Remove this port from the port matrix of the other ports * in the same bridge. If the port is disabled, port matrix * is kept and not being setup until the port becomes enabled. +* And the other port's port matrix cannot be broken when the +* other port is still a VLAN-aware port. */ - if (dsa_is_user_port(ds, i) && i != port) { + if (!priv->ports[i].vlan_filtering && + dsa_is_user_port(ds, i) && i != port) { if (dsa_to_port(ds, i)->bridge_dev != bridge) continue; if (priv->ports[i].enable) @@ -836,6 +902,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port, PCR_MATRIX(BIT(MT7530_CPU_PORT))); priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT)); + mt7530_port_set_vlan_unaware(ds, port); + mutex_unlock(>reg_mutex); } @@ -906,6 +974,223 @@ mt7530_port_fdb_dump(struct dsa_switch *ds, int port, return 0; } +static int