Commit 440d71e2 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'dsa-mt7530-fixes'



Arınç ÜNAL says:

====================
net: dsa: mt7530: fix multiple CPU ports, BPDU and LLDP handling

This patch series fixes all non-theoretical issues regarding multiple CPU
ports and the handling of LLDP frames and BPDUs.

I am adding me as a maintainer, I've got some code improvements on the way.
I will keep an eye on this driver and the patches submitted for it in the
future.

Arınç

v6:
- Change a small portion of the comment in the diff on "net: dsa: mt7530:
  set all CPU ports in MT7531_CPU_PMAP" with Russell's suggestion.
- Change the patch log of "net: dsa: mt7530: fix trapping frames on
  non-MT7621 SoC MT7530 switch" with Vladimir's suggestion.
- Group the code for trapping frames into a common function and call that.
- Add Vladimir and Russell's reviewed-by tags to where they're given.

v5:
- Change the comment in the diff on the first patch with Russell's words.
- Change the patch log of the first patch to state that the patch is just
  preparatory work for change "net: dsa: introduce
  preferred_default_local_cpu_port and use on MT7530" and not a fix to an
  existing problem on the code base.
- Remove the "net: dsa: mt7530: fix trapping frames with multiple CPU ports
  on MT7530" patch. It fixes a theoretical issue, therefore it is net-next
  material.
- Remove unnecessary information from the patch logs. Remove the enum
  renaming change.
- Strengthen the point of the "net: dsa: introduce
  preferred_default_local_cpu_port and use on MT7530" patch.

v4: Make the patch logs and my comments in the code easier to understand.
v3: Fix the from header on the patches. Write a cover letter.
v2: Add patches to fix the handling of LLDP frames and BPDUs.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9a43827e 94d12d88
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -13270,10 +13270,11 @@ F: drivers/memory/mtk-smi.c
F:	include/soc/mediatek/smi.h
MEDIATEK SWITCH DRIVER
M:	Sean Wang <sean.wang@mediatek.com>
M:	Arınç ÜNAL <arinc.unal@arinc9.com>
M:	Daniel Golle <daniel@makrotopia.org>
M:	Landen Chao <Landen.Chao@mediatek.com>
M:	DENG Qingfang <dqfext@gmail.com>
M:	Daniel Golle <daniel@makrotopia.org>
M:	Sean Wang <sean.wang@mediatek.com>
L:	netdev@vger.kernel.org
S:	Maintained
F:	drivers/net/dsa/mt7530-mdio.c
+38 −10
Original line number Diff line number Diff line
@@ -399,6 +399,20 @@ static void mt7530_pll_setup(struct mt7530_priv *priv)
	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
}

/* If port 6 is available as a CPU port, always prefer that as the default,
 * otherwise don't care.
 */
static struct dsa_port *
mt753x_preferred_default_local_cpu_port(struct dsa_switch *ds)
{
	struct dsa_port *cpu_dp = dsa_to_port(ds, 6);

	if (dsa_port_is_cpu(cpu_dp))
		return cpu_dp;

	return NULL;
}

/* Setup port 6 interface mode and TRGMII TX circuit */
static int
mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
@@ -985,6 +999,18 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
	mutex_unlock(&priv->reg_mutex);
}

static void
mt753x_trap_frames(struct mt7530_priv *priv)
{
	/* Trap BPDUs to the CPU port(s) */
	mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
		   MT753X_BPDU_CPU_ONLY);

	/* Trap LLDP frames with :0E MAC DA to the CPU port(s) */
	mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_PORT_FW_MASK,
		   MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY));
}

static int
mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
{
@@ -1007,9 +1033,16 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
		   UNU_FFP(BIT(port)));

	/* Set CPU port number */
	if (priv->id == ID_MT7621)
	if (priv->id == ID_MT7530 || priv->id == ID_MT7621)
		mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));

	/* Add the CPU port to the CPU port bitmap for MT7531 and the switch on
	 * the MT7988 SoC. Trapped frames will be forwarded to the CPU port that
	 * is affine to the inbound user port.
	 */
	if (priv->id == ID_MT7531 || priv->id == ID_MT7988)
		mt7530_set(priv, MT7531_CFC, MT7531_CPU_PMAP(BIT(port)));

	/* CPU port gets connected to all user ports of
	 * the switch.
	 */
@@ -2255,6 +2288,8 @@ mt7530_setup(struct dsa_switch *ds)

	priv->p6_interface = PHY_INTERFACE_MODE_NA;

	mt753x_trap_frames(priv);

	/* Enable and reset MIB counters */
	mt7530_mib_reset(ds);

@@ -2352,17 +2387,9 @@ static int
mt7531_setup_common(struct dsa_switch *ds)
{
	struct mt7530_priv *priv = ds->priv;
	struct dsa_port *cpu_dp;
	int ret, i;

	/* BPDU to CPU port */
	dsa_switch_for_each_cpu_port(cpu_dp, ds) {
		mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
			   BIT(cpu_dp->index));
		break;
	}
	mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
		   MT753X_BPDU_CPU_ONLY);
	mt753x_trap_frames(priv);

	/* Enable and reset MIB counters */
	mt7530_mib_reset(ds);
@@ -3085,6 +3112,7 @@ static int mt7988_setup(struct dsa_switch *ds)
const struct dsa_switch_ops mt7530_switch_ops = {
	.get_tag_protocol	= mtk_get_tag_protocol,
	.setup			= mt753x_setup,
	.preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port,
	.get_strings		= mt7530_get_strings,
	.get_ethtool_stats	= mt7530_get_ethtool_stats,
	.get_sset_count		= mt7530_get_sset_count,
+6 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ enum mt753x_id {
#define  MT7531_MIRROR_PORT_GET(x)	(((x) >> 16) & MIRROR_MASK)
#define  MT7531_MIRROR_PORT_SET(x)	(((x) & MIRROR_MASK) << 16)
#define  MT7531_CPU_PMAP_MASK		GENMASK(7, 0)
#define  MT7531_CPU_PMAP(x)		FIELD_PREP(MT7531_CPU_PMAP_MASK, x)

#define MT753X_MIRROR_REG(id)		((((id) == ID_MT7531) || ((id) == ID_MT7988)) ?	\
					 MT7531_CFC : MT7530_MFC)
@@ -66,6 +67,11 @@ enum mt753x_id {
#define MT753X_BPC			0x24
#define  MT753X_BPDU_PORT_FW_MASK	GENMASK(2, 0)

/* Register for :03 and :0E MAC DA frame control */
#define MT753X_RGAC2			0x2c
#define  MT753X_R0E_PORT_FW_MASK	GENMASK(18, 16)
#define  MT753X_R0E_PORT_FW(x)		FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x)

enum mt753x_bpdu_port_fw {
	MT753X_BPDU_FOLLOW_MFC,
	MT753X_BPDU_CPU_EXCLUDE = 4,
+8 −0
Original line number Diff line number Diff line
@@ -958,6 +958,14 @@ struct dsa_switch_ops {
			       struct phy_device *phy);
	void	(*port_disable)(struct dsa_switch *ds, int port);

	/*
	 * Compatibility between device trees defining multiple CPU ports and
	 * drivers which are not OK to use by default the numerically smallest
	 * CPU port of a switch for its local ports. This can return NULL,
	 * meaning "don't know/don't care".
	 */
	struct dsa_port *(*preferred_default_local_cpu_port)(struct dsa_switch *ds);

	/*
	 * Port's MAC EEE settings
	 */
+23 −1
Original line number Diff line number Diff line
@@ -403,6 +403,24 @@ static int dsa_tree_setup_default_cpu(struct dsa_switch_tree *dst)
	return 0;
}

static struct dsa_port *
dsa_switch_preferred_default_local_cpu_port(struct dsa_switch *ds)
{
	struct dsa_port *cpu_dp;

	if (!ds->ops->preferred_default_local_cpu_port)
		return NULL;

	cpu_dp = ds->ops->preferred_default_local_cpu_port(ds);
	if (!cpu_dp)
		return NULL;

	if (WARN_ON(!dsa_port_is_cpu(cpu_dp) || cpu_dp->ds != ds))
		return NULL;

	return cpu_dp;
}

/* Perform initial assignment of CPU ports to user ports and DSA links in the
 * fabric, giving preference to CPU ports local to each switch. Default to
 * using the first CPU port in the switch tree if the port does not have a CPU
@@ -410,12 +428,16 @@ static int dsa_tree_setup_default_cpu(struct dsa_switch_tree *dst)
 */
static int dsa_tree_setup_cpu_ports(struct dsa_switch_tree *dst)
{
	struct dsa_port *cpu_dp, *dp;
	struct dsa_port *preferred_cpu_dp, *cpu_dp, *dp;

	list_for_each_entry(cpu_dp, &dst->ports, list) {
		if (!dsa_port_is_cpu(cpu_dp))
			continue;

		preferred_cpu_dp = dsa_switch_preferred_default_local_cpu_port(cpu_dp->ds);
		if (preferred_cpu_dp && preferred_cpu_dp != cpu_dp)
			continue;

		/* Prefer a local CPU port */
		dsa_switch_for_each_port(dp, cpu_dp->ds) {
			/* Prefer the first local CPU port found */