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

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
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -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_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) |
		   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
		   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT) |
		   MT7530_VLAN_ACC_ALL);

	/* Set PVID to 0 */
	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)
			   MT7530_PORT_SECURITY_MODE);
		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
			   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
@@ -1612,11 +1619,26 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
	if (pvid) {
		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 */
		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
			mt7530_rmw(priv, MT7530_PPBV1_P(port),
				   G0_PORT_VID_MASK,
				   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);
@@ -1642,6 +1664,12 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
	 */
	if (priv->ports[port].pvid == vlan->vid) {
		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);
	}
+7 −0
Original line number Diff line number Diff line
@@ -238,6 +238,7 @@ enum mt7530_port_mode {
#define  PVC_EG_TAG_MASK		PVC_EG_TAG(7)
#define  VLAN_ATTR(x)			(((x) & 0x3) << 6)
#define  VLAN_ATTR_MASK			VLAN_ATTR(3)
#define  ACC_FRM_MASK			GENMASK(1, 0)

enum mt7530_vlan_port_eg_tag {
	MT7530_VLAN_EG_DISABLED = 0,
@@ -249,6 +250,12 @@ enum mt7530_vlan_port_attr {
	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)

/* Register for port port-and-protocol based vlan 1 control */