Commit 8fbebef8 authored by DENG Qingfang's avatar DENG Qingfang Committed by David S. Miller

net: dsa: mt7530: drop untagged frames on VLAN-aware ports without PVID

The driver currently still accepts untagged frames on VLAN-aware ports
without PVID. Use PVC.ACC_FRM to drop untagged frames in that case.
Signed-off-by: default avatarDENG Qingfang <dqfext@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9b9311af
...@@ -1245,9 +1245,11 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port) ...@@ -1245,9 +1245,11 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK, mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
MT7530_PORT_FALLBACK_MODE); MT7530_PORT_FALLBACK_MODE);
mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK, mt7530_rmw(priv, MT7530_PVC_P(port),
VLAN_ATTR_MASK | PVC_EG_TAG_MASK | ACC_FRM_MASK,
VLAN_ATTR(MT7530_VLAN_TRANSPARENT) | VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT)); PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT) |
MT7530_VLAN_ACC_ALL);
/* Set PVID to 0 */ /* Set PVID to 0 */
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
...@@ -1285,6 +1287,11 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port) ...@@ -1285,6 +1287,11 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port)
MT7530_PORT_SECURITY_MODE); MT7530_PORT_SECURITY_MODE);
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
G0_PORT_VID(priv->ports[port].pvid)); G0_PORT_VID(priv->ports[port].pvid));
/* Only accept tagged frames if PVID is not set */
if (!priv->ports[port].pvid)
mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
MT7530_VLAN_ACC_TAGGED);
} }
/* Set the port as a user port which is to be able to recognize VID /* Set the port as a user port which is to be able to recognize VID
...@@ -1612,11 +1619,26 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port, ...@@ -1612,11 +1619,26 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
if (pvid) { if (pvid) {
priv->ports[port].pvid = vlan->vid; priv->ports[port].pvid = vlan->vid;
/* Accept all frames if PVID is set */
mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
MT7530_VLAN_ACC_ALL);
/* Only configure PVID if VLAN filtering is enabled */ /* Only configure PVID if VLAN filtering is enabled */
if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
mt7530_rmw(priv, MT7530_PPBV1_P(port), mt7530_rmw(priv, MT7530_PPBV1_P(port),
G0_PORT_VID_MASK, G0_PORT_VID_MASK,
G0_PORT_VID(vlan->vid)); G0_PORT_VID(vlan->vid));
} else if (vlan->vid && priv->ports[port].pvid == vlan->vid) {
/* This VLAN is overwritten without PVID, so unset it */
priv->ports[port].pvid = G0_PORT_VID_DEF;
/* Only accept tagged frames if the port is VLAN-aware */
if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
MT7530_VLAN_ACC_TAGGED);
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
G0_PORT_VID_DEF);
} }
mutex_unlock(&priv->reg_mutex); mutex_unlock(&priv->reg_mutex);
...@@ -1642,6 +1664,12 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port, ...@@ -1642,6 +1664,12 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
*/ */
if (priv->ports[port].pvid == vlan->vid) { if (priv->ports[port].pvid == vlan->vid) {
priv->ports[port].pvid = G0_PORT_VID_DEF; priv->ports[port].pvid = G0_PORT_VID_DEF;
/* Only accept tagged frames if the port is VLAN-aware */
if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
MT7530_VLAN_ACC_TAGGED);
mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
G0_PORT_VID_DEF); G0_PORT_VID_DEF);
} }
......
...@@ -238,6 +238,7 @@ enum mt7530_port_mode { ...@@ -238,6 +238,7 @@ enum mt7530_port_mode {
#define PVC_EG_TAG_MASK PVC_EG_TAG(7) #define PVC_EG_TAG_MASK PVC_EG_TAG(7)
#define VLAN_ATTR(x) (((x) & 0x3) << 6) #define VLAN_ATTR(x) (((x) & 0x3) << 6)
#define VLAN_ATTR_MASK VLAN_ATTR(3) #define VLAN_ATTR_MASK VLAN_ATTR(3)
#define ACC_FRM_MASK GENMASK(1, 0)
enum mt7530_vlan_port_eg_tag { enum mt7530_vlan_port_eg_tag {
MT7530_VLAN_EG_DISABLED = 0, MT7530_VLAN_EG_DISABLED = 0,
...@@ -249,6 +250,12 @@ enum mt7530_vlan_port_attr { ...@@ -249,6 +250,12 @@ enum mt7530_vlan_port_attr {
MT7530_VLAN_TRANSPARENT = 3, MT7530_VLAN_TRANSPARENT = 3,
}; };
enum mt7530_vlan_port_acc_frm {
MT7530_VLAN_ACC_ALL = 0,
MT7530_VLAN_ACC_TAGGED = 1,
MT7530_VLAN_ACC_UNTAGGED = 2,
};
#define STAG_VPID (((x) & 0xffff) << 16) #define STAG_VPID (((x) & 0xffff) << 16)
/* Register for port port-and-protocol based vlan 1 control */ /* Register for port port-and-protocol based vlan 1 control */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment