All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Clément Léger" <clement.leger@bootlin.com>
To: Andrew Lunn <andrew@lunn.ch>,
	Vivien Didelot <vivien.didelot@gmail.com>,
	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>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Geert Uytterhoeven <geert+renesas@glider.be>,
	Magnus Damm <magnus.damm@gmail.com>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	Russell King <linux@armlinux.org.uk>,
	Alexandre Torgue <alexandre.torgue@foss.st.com>,
	Giuseppe Cavallaro <peppe.cavallaro@st.com>,
	Jose Abreu <joabreu@synopsys.com>
Cc: "Clément Léger" <clement.leger@bootlin.com>,
	"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>,
	"Herve Codina" <herve.codina@bootlin.com>,
	"Miquèl Raynal" <miquel.raynal@bootlin.com>,
	"Milan Stevanovic" <milan.stevanovic@se.com>,
	"Jimmy Lalande" <jimmy.lalande@se.com>,
	"Pascal Eberhard" <pascal.eberhard@se.com>,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org, netdev@vger.kernel.org
Subject: [PATCH net-next v9 09/16] net: dsa: rzn1-a5psw: add FDB support
Date: Fri, 24 Jun 2022 16:39:54 +0200	[thread overview]
Message-ID: <20220624144001.95518-10-clement.leger@bootlin.com> (raw)
In-Reply-To: <20220624144001.95518-1-clement.leger@bootlin.com>

This commits add forwarding database support to the driver. It
implements fdb_add(), fdb_del() and fdb_dump().

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
---
 drivers/net/dsa/rzn1_a5psw.c | 168 +++++++++++++++++++++++++++++++++++
 drivers/net/dsa/rzn1_a5psw.h |  17 ++++
 2 files changed, 185 insertions(+)

diff --git a/drivers/net/dsa/rzn1_a5psw.c b/drivers/net/dsa/rzn1_a5psw.c
index 4c2401fbaf9a..3e910da98ae2 100644
--- a/drivers/net/dsa/rzn1_a5psw.c
+++ b/drivers/net/dsa/rzn1_a5psw.c
@@ -375,6 +375,171 @@ static void a5psw_port_fast_age(struct dsa_switch *ds, int port)
 	a5psw_port_fdb_flush(a5psw, port);
 }
 
+static int a5psw_lk_execute_lookup(struct a5psw *a5psw, union lk_data *lk_data,
+				   u16 *entry)
+{
+	u32 ctrl;
+	int ret;
+
+	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_LO, lk_data->lo);
+	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data->hi);
+
+	ctrl = A5PSW_LK_ADDR_CTRL_LOOKUP;
+	ret = a5psw_lk_execute_ctrl(a5psw, &ctrl);
+	if (ret)
+		return ret;
+
+	*entry = ctrl & A5PSW_LK_ADDR_CTRL_ADDRESS;
+
+	return 0;
+}
+
+static int a5psw_port_fdb_add(struct dsa_switch *ds, int port,
+			      const unsigned char *addr, u16 vid,
+			      struct dsa_db db)
+{
+	struct a5psw *a5psw = ds->priv;
+	union lk_data lk_data = {0};
+	bool inc_learncount = false;
+	int ret = 0;
+	u16 entry;
+	u32 reg;
+
+	ether_addr_copy(lk_data.entry.mac, addr);
+	lk_data.entry.port_mask = BIT(port);
+
+	mutex_lock(&a5psw->lk_lock);
+
+	/* Set the value to be written in the lookup table */
+	ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
+	if (ret)
+		goto lk_unlock;
+
+	lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
+	if (!lk_data.entry.valid) {
+		inc_learncount = true;
+		/* port_mask set to 0x1f when entry is not valid, clear it */
+		lk_data.entry.port_mask = 0;
+		lk_data.entry.prio = 0;
+	}
+
+	lk_data.entry.port_mask |= BIT(port);
+	lk_data.entry.is_static = 1;
+	lk_data.entry.valid = 1;
+
+	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
+
+	reg = A5PSW_LK_ADDR_CTRL_WRITE | entry;
+	ret = a5psw_lk_execute_ctrl(a5psw, &reg);
+	if (ret)
+		goto lk_unlock;
+
+	if (inc_learncount) {
+		reg = A5PSW_LK_LEARNCOUNT_MODE_INC;
+		a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
+	}
+
+lk_unlock:
+	mutex_unlock(&a5psw->lk_lock);
+
+	return ret;
+}
+
+static int a5psw_port_fdb_del(struct dsa_switch *ds, int port,
+			      const unsigned char *addr, u16 vid,
+			      struct dsa_db db)
+{
+	struct a5psw *a5psw = ds->priv;
+	union lk_data lk_data = {0};
+	bool clear = false;
+	u16 entry;
+	u32 reg;
+	int ret;
+
+	ether_addr_copy(lk_data.entry.mac, addr);
+
+	mutex_lock(&a5psw->lk_lock);
+
+	ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
+	if (ret)
+		goto lk_unlock;
+
+	lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
+
+	/* Our hardware does not associate any VID to the FDB entries so this
+	 * means that if two entries were added for the same mac but for
+	 * different VID, then, on the deletion of the first one, we would also
+	 * delete the second one. Since there is unfortunately nothing we can do
+	 * about that, do not return an error...
+	 */
+	if (!lk_data.entry.valid)
+		goto lk_unlock;
+
+	lk_data.entry.port_mask &= ~BIT(port);
+	/* If there is no more port in the mask, clear the entry */
+	if (lk_data.entry.port_mask == 0)
+		clear = true;
+
+	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
+
+	reg = entry;
+	if (clear)
+		reg |= A5PSW_LK_ADDR_CTRL_CLEAR;
+	else
+		reg |= A5PSW_LK_ADDR_CTRL_WRITE;
+
+	ret = a5psw_lk_execute_ctrl(a5psw, &reg);
+	if (ret)
+		goto lk_unlock;
+
+	/* Decrement LEARNCOUNT */
+	if (clear) {
+		reg = A5PSW_LK_LEARNCOUNT_MODE_DEC;
+		a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
+	}
+
+lk_unlock:
+	mutex_unlock(&a5psw->lk_lock);
+
+	return ret;
+}
+
+static int a5psw_port_fdb_dump(struct dsa_switch *ds, int port,
+			       dsa_fdb_dump_cb_t *cb, void *data)
+{
+	struct a5psw *a5psw = ds->priv;
+	union lk_data lk_data;
+	int i = 0, ret = 0;
+	u32 reg;
+
+	mutex_lock(&a5psw->lk_lock);
+
+	for (i = 0; i < A5PSW_TABLE_ENTRIES; i++) {
+		reg = A5PSW_LK_ADDR_CTRL_READ | A5PSW_LK_ADDR_CTRL_WAIT | i;
+
+		ret = a5psw_lk_execute_ctrl(a5psw, &reg);
+		if (ret)
+			goto out_unlock;
+
+		lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
+		/* If entry is not valid or does not contain the port, skip */
+		if (!lk_data.entry.valid ||
+		    !(lk_data.entry.port_mask & BIT(port)))
+			continue;
+
+		lk_data.lo = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_LO);
+
+		ret = cb(lk_data.entry.mac, 0, lk_data.entry.is_static, data);
+		if (ret)
+			goto out_unlock;
+	}
+
+out_unlock:
+	mutex_unlock(&a5psw->lk_lock);
+
+	return ret;
+}
+
 static u64 a5psw_read_stat(struct a5psw *a5psw, u32 offset, int port)
 {
 	u32 reg_lo, reg_hi;
@@ -591,6 +756,9 @@ static const struct dsa_switch_ops a5psw_switch_ops = {
 	.port_bridge_leave = a5psw_port_bridge_leave,
 	.port_stp_state_set = a5psw_port_stp_state_set,
 	.port_fast_age = a5psw_port_fast_age,
+	.port_fdb_add = a5psw_port_fdb_add,
+	.port_fdb_del = a5psw_port_fdb_del,
+	.port_fdb_dump = a5psw_port_fdb_dump,
 };
 
 static int a5psw_mdio_wait_busy(struct a5psw *a5psw)
diff --git a/drivers/net/dsa/rzn1_a5psw.h b/drivers/net/dsa/rzn1_a5psw.h
index 6b0ce2b15eca..c67abd49c013 100644
--- a/drivers/net/dsa/rzn1_a5psw.h
+++ b/drivers/net/dsa/rzn1_a5psw.h
@@ -211,6 +211,23 @@
 #define A5PSW_CTRL_TIMEOUT		1000
 #define A5PSW_TABLE_ENTRIES		8192
 
+struct fdb_entry {
+	u8 mac[ETH_ALEN];
+	u16 valid:1;
+	u16 is_static:1;
+	u16 prio:3;
+	u16 port_mask:5;
+	u16 reserved:6;
+} __packed;
+
+union lk_data {
+	struct {
+		u32 lo;
+		u32 hi;
+	};
+	struct fdb_entry entry;
+};
+
 /**
  * struct a5psw - switch struct
  * @base: Base address of the switch
-- 
2.36.1


  parent reply	other threads:[~2022-06-24 14:43 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-24 14:39 [PATCH net-next v9 00/16] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
2022-06-24 14:39 ` [PATCH net-next v9 01/16] net: dsa: allow port_bridge_join() to override extack message Clément Léger
2022-06-24 14:39 ` [PATCH net-next v9 02/16] net: dsa: add support for ethtool get_rmon_stats() Clément Léger
2022-06-24 14:39 ` [PATCH net-next v9 03/16] net: dsa: add Renesas RZ/N1 switch tag driver Clément Léger
2022-06-24 14:39 ` [PATCH net-next v9 04/16] dt-bindings: net: pcs: add bindings for Renesas RZ/N1 MII converter Clément Léger
2022-06-29 14:38   ` Geert Uytterhoeven
2022-06-24 14:39 ` [PATCH net-next v9 05/16] net: pcs: add Renesas MII converter driver Clément Léger
2022-06-25  2:35   ` Florian Fainelli
2022-06-28 16:42   ` Russell King (Oracle)
2022-06-28 16:49     ` Clément Léger
2022-06-24 14:39 ` [PATCH net-next v9 06/16] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch Clément Léger
2022-06-28 15:37   ` Geert Uytterhoeven
2022-06-28 16:18     ` Clément Léger
2022-06-24 14:39 ` [PATCH net-next v9 07/16] net: dsa: rzn1-a5psw: add Renesas RZ/N1 advanced 5 port switch driver Clément Léger
2022-06-25  2:37   ` Florian Fainelli
2022-06-24 14:39 ` [PATCH net-next v9 08/16] net: dsa: rzn1-a5psw: add statistics support Clément Léger
2022-06-24 14:39 ` Clément Léger [this message]
2022-06-25  2:37   ` [PATCH net-next v9 09/16] net: dsa: rzn1-a5psw: add FDB support Florian Fainelli
2022-06-24 14:39 ` [PATCH net-next v9 10/16] dt-bindings: net: snps,dwmac: add "power-domains" property Clément Léger
2022-06-24 14:39 ` [PATCH net-next v9 11/16] dt-bindings: net: snps,dwmac: add "renesas,rzn1" compatible Clément Léger
2022-06-24 14:39 ` [PATCH net-next v9 12/16] ARM: dts: r9a06g032: describe MII converter Clément Léger
2022-06-25  2:38   ` Florian Fainelli
2022-06-28 15:28   ` Geert Uytterhoeven
2022-06-24 14:39 ` [PATCH net-next v9 13/16] ARM: dts: r9a06g032: describe GMAC2 Clément Léger
2022-06-25  2:38   ` Florian Fainelli
2022-06-28 15:30   ` Geert Uytterhoeven
2022-06-24 14:39 ` [PATCH net-next v9 14/16] ARM: dts: r9a06g032: describe switch Clément Léger
2022-06-25  2:39   ` Florian Fainelli
2022-06-28 15:31   ` Geert Uytterhoeven
2022-06-24 14:40 ` [PATCH net-next v9 15/16] ARM: dts: r9a06g032-rzn1d400-db: add switch description Clément Léger
2022-06-25  2:40   ` Florian Fainelli
2022-06-28 15:34   ` Geert Uytterhoeven
2022-06-28 16:20     ` Clément Léger
2022-06-24 14:40 ` [PATCH net-next v9 16/16] MAINTAINERS: add Renesas RZ/N1 switch related driver entry Clément Léger
2022-06-24 21:43 ` [PATCH net-next v9 00/16] add support for Renesas RZ/N1 ethernet subsystem devices Vladimir Oltean
2022-06-27  7:38   ` Clément Léger
2022-06-27 10:50 ` patchwork-bot+netdevbpf
2022-06-27 11:11   ` Geert Uytterhoeven

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=20220624144001.95518-10-clement.leger@bootlin.com \
    --to=clement.leger@bootlin.com \
    --cc=alexandre.torgue@foss.st.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=f.fainelli@gmail.com \
    --cc=geert+renesas@glider.be \
    --cc=herve.codina@bootlin.com \
    --cc=hkallweit1@gmail.com \
    --cc=jimmy.lalande@se.com \
    --cc=joabreu@synopsys.com \
    --cc=krzk+dt@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=magnus.damm@gmail.com \
    --cc=milan.stevanovic@se.com \
    --cc=miquel.raynal@bootlin.com \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=pascal.eberhard@se.com \
    --cc=peppe.cavallaro@st.com \
    --cc=robh+dt@kernel.org \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=vivien.didelot@gmail.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.