All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Marangi <ansuelsmth@gmail.com>
To: Andrew Lunn <andrew@lunn.ch>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Vladimir Oltean <olteanv@gmail.com>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Christian Marangi <ansuelsmth@gmail.com>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [net-next PATCH] net: dsa: qca8k: add support for port_change_master
Date: Tue, 20 Jun 2023 08:37:47 +0200	[thread overview]
Message-ID: <20230620063747.19175-1-ansuelsmth@gmail.com> (raw)

Add support for port_change_master to permit assigning an alternative
CPU port if the switch have both CPU port connected or create a LAG on
both CPU port and assign the LAG as DSA master.

On port change master request, we check if the master is a LAG.
With LAG we compose the cpu_port_mask with the CPU port in the LAG, if
master is a simple dsa_port, we derive the index.

Finally we apply the new cpu_port_mask to the LOOKUP MEMBER to permit
the port to receive packet by the new CPU port setup for the port and
we reenable the target port previously disabled.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/net/dsa/qca/qca8k-8xxx.c | 54 ++++++++++++++++++++++++++++++++
 drivers/net/dsa/qca/qca8k.h      |  1 +
 2 files changed, 55 insertions(+)

diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
index dee7b6579916..435b69c1c552 100644
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
@@ -1713,6 +1713,59 @@ qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
 	return DSA_TAG_PROTO_QCA;
 }
 
+static int qca8k_port_change_master(struct dsa_switch *ds, int port,
+				    struct net_device *master,
+				    struct netlink_ext_ack *extack)
+{
+	struct qca8k_priv *priv = ds->priv;
+	u32 val, cpu_port_mask = 0;
+	struct dsa_port *dp;
+	int ret;
+
+	/* With LAG of CPU port, compose the mask for LOOKUP MEMBER */
+	if (netif_is_lag_master(master)) {
+		struct dsa_lag *lag;
+		int id;
+
+		id = dsa_lag_id(ds->dst, master);
+		lag = dsa_lag_by_id(ds->dst, id);
+
+		dsa_lag_foreach_port(dp, ds->dst, lag)
+			if (dsa_port_is_cpu(dp))
+				cpu_port_mask |= BIT(dp->index);
+	} else {
+		dp = dsa_port_from_netdev(master);
+		cpu_port_mask |= BIT(dp->index);
+	}
+
+	/* Disable port */
+	qca8k_port_set_status(priv, port, 0);
+
+	/* Connect it to new cpu port */
+	ret = qca8k_read(priv, QCA8K_PORT_LOOKUP_CTRL(port), &val);
+	if (ret)
+		return ret;
+
+	/* Reset connected CPU port in LOOKUP MEMBER */
+	val &= QCA8K_PORT_LOOKUP_USER_MEMBER;
+	/* Assign the new CPU port in LOOKUP MEMBER */
+	val |= cpu_port_mask;
+
+	ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
+			QCA8K_PORT_LOOKUP_MEMBER,
+			val);
+	if (ret)
+		return ret;
+
+	/* Fast Age the port to flush FDB table */
+	qca8k_port_fast_age(ds, port);
+
+	/* Reenable port */
+	qca8k_port_set_status(priv, port, 1);
+
+	return 0;
+}
+
 static void
 qca8k_master_change(struct dsa_switch *ds, const struct net_device *master,
 		    bool operational)
@@ -1996,6 +2049,7 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
 	.get_phy_flags		= qca8k_get_phy_flags,
 	.port_lag_join		= qca8k_port_lag_join,
 	.port_lag_leave		= qca8k_port_lag_leave,
+	.port_change_master	= qca8k_port_change_master,
 	.master_state_change	= qca8k_master_change,
 	.connect_tag_protocol	= qca8k_connect_tag_protocol,
 };
diff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h
index c5cc8a172d65..424f851db881 100644
--- a/drivers/net/dsa/qca/qca8k.h
+++ b/drivers/net/dsa/qca/qca8k.h
@@ -250,6 +250,7 @@
 #define   QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK		GENMASK(14, 8)
 #define   QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK		GENMASK(6, 0)
 #define QCA8K_PORT_LOOKUP_CTRL(_i)			(0x660 + (_i) * 0xc)
+#define   QCA8K_PORT_LOOKUP_USER_MEMBER			GENMASK(5, 1)
 #define   QCA8K_PORT_LOOKUP_MEMBER			GENMASK(6, 0)
 #define   QCA8K_PORT_LOOKUP_VLAN_MODE_MASK		GENMASK(9, 8)
 #define   QCA8K_PORT_LOOKUP_VLAN_MODE(x)		FIELD_PREP(QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, x)
-- 
2.40.1


             reply	other threads:[~2023-06-20 15:30 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-20  6:37 Christian Marangi [this message]
2023-06-20 11:22 ` [net-next PATCH] net: dsa: qca8k: add support for port_change_master Christian Marangi
2023-06-20 20:12 ` Vladimir Oltean
2023-06-20 13:04   ` Christian Marangi
2023-06-21 10:25     ` Vladimir Oltean
2023-06-20 18:52       ` Christian Marangi
2023-06-21 12:17         ` Vladimir Oltean
2023-06-21  4:08           ` Christian Marangi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230620063747.19175-1-ansuelsmth@gmail.com \
    --to=ansuelsmth@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=f.fainelli@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.