All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver
@ 2019-06-02 21:11 Vladimir Oltean
  2019-06-02 21:11 ` [PATCH net-next 01/11] net: dsa: sja1105: Shim declaration of struct sja1105_dyn_cmd Vladimir Oltean
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Vladimir Oltean @ 2019-06-02 21:11 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem; +Cc: netdev, Vladimir Oltean

This patch series adds:

- FDB switchdev support for the second generation of switches (P/Q/R/S).
  I could test/code these now that I got a board with a SJA1105Q.

- Management route support for SJA1105 P/Q/R/S. This is needed to send
  PTP/STP/management frames over the CPU port.

- Logic to hide private DSA VLANs from the 'bridge fdb' commands.

The new FDB code was also tested and still works on SJA1105T.

Vladimir Oltean (11):
  net: dsa: sja1105: Shim declaration of struct sja1105_dyn_cmd
  net: dsa: sja1105: Fix bit offsets of index field from L2 lookup
    entries
  net: dsa: sja1105: Add missing L2 Forwarding Table definitions for
    P/Q/R/S
  net: dsa: sja1105: Plug in support for TCAM searches via the dynamic
    interface
  net: dsa: sja1105: Make room for P/Q/R/S FDB operations
  net: dsa: sja1105: Add P/Q/R/S support for dynamic L2 lookup
    operations
  net: dsa: sja1105: Make dynamic_config_read return -ENOENT if not
    found
  net: dsa: sja1105: Add P/Q/R/S management route support via dynamic
    interface
  net: dsa: sja1105: Add FDB operations for P/Q/R/S series
  net: dsa: sja1105: Unset port from forwarding mask unconditionally on
    fdb_del
  net: dsa: sja1105: Hide the dsa_8021q VLANs from the bridge fdb
    command

 drivers/net/dsa/sja1105/sja1105.h             |  20 +-
 .../net/dsa/sja1105/sja1105_dynamic_config.c  | 144 +++++++++++++-
 .../net/dsa/sja1105/sja1105_dynamic_config.h  |  11 +-
 drivers/net/dsa/sja1105/sja1105_main.c        | 186 ++++++++++++++++--
 drivers/net/dsa/sja1105/sja1105_spi.c         |  12 ++
 .../net/dsa/sja1105/sja1105_static_config.c   |  18 +-
 .../net/dsa/sja1105/sja1105_static_config.h   |  26 +++
 7 files changed, 379 insertions(+), 38 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH net-next 01/11] net: dsa: sja1105: Shim declaration of struct sja1105_dyn_cmd
  2019-06-02 21:11 [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver Vladimir Oltean
@ 2019-06-02 21:11 ` Vladimir Oltean
  2019-06-04 20:55   ` Florian Fainelli
  2019-06-02 21:11 ` [PATCH net-next 02/11] net: dsa: sja1105: Fix bit offsets of index field from L2 lookup entries Vladimir Oltean
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 10+ messages in thread
From: Vladimir Oltean @ 2019-06-02 21:11 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem; +Cc: netdev, Vladimir Oltean

This structure is merely an implementation detail and should be hidden
from the sja1105_dynamic_config.h header, which provides to the rest of
the driver an abstract access to the dynamic configuration interface of
the switch.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
 drivers/net/dsa/sja1105/sja1105_dynamic_config.c | 8 ++++++++
 drivers/net/dsa/sja1105/sja1105_dynamic_config.h | 8 +-------
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
index e73ab28bf632..c981c12eb181 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
@@ -35,6 +35,14 @@
 #define SJA1105_MAX_DYN_CMD_SIZE				\
 	SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD
 
+struct sja1105_dyn_cmd {
+	u64 valid;
+	u64 rdwrset;
+	u64 errors;
+	u64 valident;
+	u64 index;
+};
+
 static void
 sja1105pqrs_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
 				  enum packing_op op)
diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h
index 77be59546a55..49c611eb02cb 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h
@@ -7,13 +7,7 @@
 #include "sja1105.h"
 #include <linux/packing.h>
 
-struct sja1105_dyn_cmd {
-	u64 valid;
-	u64 rdwrset;
-	u64 errors;
-	u64 valident;
-	u64 index;
-};
+struct sja1105_dyn_cmd;
 
 struct sja1105_dynamic_table_ops {
 	/* This returns size_t just to keep same prototype as the
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next 02/11] net: dsa: sja1105: Fix bit offsets of index field from L2 lookup entries
  2019-06-02 21:11 [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver Vladimir Oltean
  2019-06-02 21:11 ` [PATCH net-next 01/11] net: dsa: sja1105: Shim declaration of struct sja1105_dyn_cmd Vladimir Oltean
@ 2019-06-02 21:11 ` Vladimir Oltean
  2019-06-02 21:11 ` [PATCH net-next 03/11] net: dsa: sja1105: Add missing L2 Forwarding Table definitions for P/Q/R/S Vladimir Oltean
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2019-06-02 21:11 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem; +Cc: netdev, Vladimir Oltean

This was inadvertently copied from the SJA1105 E/T structure and not
tested.  Cross-checking with the P/Q/R/S documentation (UM11040) makes
it immediately obvious what the correct bit offsets for this field are.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
 drivers/net/dsa/sja1105/sja1105_dynamic_config.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
index c981c12eb181..0023b03a010d 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
@@ -62,7 +62,7 @@ sja1105pqrs_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
 	 * such that our API doesn't need to ask for a full-blown entry
 	 * structure when e.g. a delete is requested.
 	 */
-	sja1105_packing(buf, &cmd->index, 29, 20,
+	sja1105_packing(buf, &cmd->index, 15, 6,
 			SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, op);
 	/* TODO hostcmd */
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next 03/11] net: dsa: sja1105: Add missing L2 Forwarding Table definitions for P/Q/R/S
  2019-06-02 21:11 [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver Vladimir Oltean
  2019-06-02 21:11 ` [PATCH net-next 01/11] net: dsa: sja1105: Shim declaration of struct sja1105_dyn_cmd Vladimir Oltean
  2019-06-02 21:11 ` [PATCH net-next 02/11] net: dsa: sja1105: Fix bit offsets of index field from L2 lookup entries Vladimir Oltean
@ 2019-06-02 21:11 ` Vladimir Oltean
  2019-06-02 21:11 ` [PATCH net-next 04/11] net: dsa: sja1105: Plug in support for TCAM searches via the dynamic interface Vladimir Oltean
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2019-06-02 21:11 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem; +Cc: netdev, Vladimir Oltean

This appends to the L2 Forwarding and L2 Forwarding Parameters tables
(originally added for first-generation switches) the bits that are new
in the second generation.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
 .../net/dsa/sja1105/sja1105_static_config.c   | 18 ++++++++++---
 .../net/dsa/sja1105/sja1105_static_config.h   | 26 +++++++++++++++++++
 2 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.c b/drivers/net/dsa/sja1105/sja1105_static_config.c
index 7e90e62da389..6d65a7b09395 100644
--- a/drivers/net/dsa/sja1105/sja1105_static_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_static_config.c
@@ -236,10 +236,20 @@ size_t sja1105pqrs_l2_lookup_entry_packing(void *buf, void *entry_ptr,
 	const size_t size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
 	struct sja1105_l2_lookup_entry *entry = entry_ptr;
 
-	/* These are static L2 lookup entries, so the structure
-	 * should match UM11040 Table 16/17 definitions when
-	 * LOCKEDS is 1.
-	 */
+	if (entry->lockeds) {
+		sja1105_packing(buf, &entry->tsreg,    159, 159, size, op);
+		sja1105_packing(buf, &entry->mirrvlan, 158, 147, size, op);
+		sja1105_packing(buf, &entry->takets,   146, 146, size, op);
+		sja1105_packing(buf, &entry->mirr,     145, 145, size, op);
+		sja1105_packing(buf, &entry->retag,    144, 144, size, op);
+	} else {
+		sja1105_packing(buf, &entry->touched,  159, 159, size, op);
+		sja1105_packing(buf, &entry->age,      158, 144, size, op);
+	}
+	sja1105_packing(buf, &entry->mask_iotag,   143, 143, size, op);
+	sja1105_packing(buf, &entry->mask_vlanid,  142, 131, size, op);
+	sja1105_packing(buf, &entry->mask_macaddr, 130,  83, size, op);
+	sja1105_packing(buf, &entry->iotag,         82,  82, size, op);
 	sja1105_packing(buf, &entry->vlanid,        81,  70, size, op);
 	sja1105_packing(buf, &entry->macaddr,       69,  22, size, op);
 	sja1105_packing(buf, &entry->destports,     21,  17, size, op);
diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.h b/drivers/net/dsa/sja1105/sja1105_static_config.h
index 069ca8fd059c..d513b1c91b98 100644
--- a/drivers/net/dsa/sja1105/sja1105_static_config.h
+++ b/drivers/net/dsa/sja1105/sja1105_static_config.h
@@ -122,9 +122,35 @@ struct sja1105_l2_lookup_entry {
 	u64 destports;
 	u64 enfport;
 	u64 index;
+	/* P/Q/R/S only */
+	u64 mask_iotag;
+	u64 mask_vlanid;
+	u64 mask_macaddr;
+	u64 iotag;
+	bool lockeds;
+	union {
+		/* LOCKEDS=1: Static FDB entries */
+		struct {
+			u64 tsreg;
+			u64 mirrvlan;
+			u64 takets;
+			u64 mirr;
+			u64 retag;
+		};
+		/* LOCKEDS=0: Dynamically learned FDB entries */
+		struct {
+			u64 touched;
+			u64 age;
+		};
+	};
 };
 
 struct sja1105_l2_lookup_params_entry {
+	u64 start_dynspc;    /* P/Q/R/S only */
+	u64 drpnolearn;      /* P/Q/R/S only */
+	u64 use_static;      /* P/Q/R/S only */
+	u64 owr_dyn;         /* P/Q/R/S only */
+	u64 learn_once;      /* P/Q/R/S only */
 	u64 maxage;          /* Shared */
 	u64 dyn_tbsz;        /* E/T only */
 	u64 poly;            /* E/T only */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next 04/11] net: dsa: sja1105: Plug in support for TCAM searches via the dynamic interface
  2019-06-02 21:11 [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver Vladimir Oltean
                   ` (2 preceding siblings ...)
  2019-06-02 21:11 ` [PATCH net-next 03/11] net: dsa: sja1105: Add missing L2 Forwarding Table definitions for P/Q/R/S Vladimir Oltean
@ 2019-06-02 21:11 ` Vladimir Oltean
  2019-06-02 21:11 ` [PATCH net-next 05/11] net: dsa: sja1105: Make room for P/Q/R/S FDB operations Vladimir Oltean
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2019-06-02 21:11 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem; +Cc: netdev, Vladimir Oltean

Only a single dynamic configuration table of the SJA1105 P/Q/R/S
supports this operation: the FDB.

To keep the existing structure in place (sja1105_dynamic_config_read and
sja1105_dynamic_config_write) and not introduce any new function, a
convention is made for sja1105_dynamic_config_read that a negative index
argument denotes a search for the entry provided as argument.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
 .../net/dsa/sja1105/sja1105_dynamic_config.c  | 36 ++++++++++++++++++-
 .../net/dsa/sja1105/sja1105_dynamic_config.h  |  3 ++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
index 0023b03a010d..7e7efc2e8ee4 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
@@ -36,6 +36,7 @@
 	SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD
 
 struct sja1105_dyn_cmd {
+	bool search;
 	u64 valid;
 	u64 rdwrset;
 	u64 errors;
@@ -248,6 +249,7 @@ sja1105et_general_params_entry_packing(void *buf, void *entry_ptr,
 #define OP_READ		BIT(0)
 #define OP_WRITE	BIT(1)
 #define OP_DEL		BIT(2)
+#define OP_SEARCH	BIT(3)
 
 /* SJA1105E/T: First generation */
 struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
@@ -367,6 +369,24 @@ struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
 	[BLK_IDX_XMII_PARAMS] = {0},
 };
 
+/* Provides read access to the settings through the dynamic interface
+ * of the switch.
+ * @blk_idx	is used as key to select from the sja1105_dynamic_table_ops.
+ *		The selection is limited by the hardware in respect to which
+ *		configuration blocks can be read through the dynamic interface.
+ * @index	is used to retrieve a particular table entry. If negative,
+ *		(and if the @blk_idx supports the searching operation) a search
+ *		is performed by the @entry parameter.
+ * @entry	Type-casted to an unpacked structure that holds a table entry
+ *		of the type specified in @blk_idx.
+ *		Usually an output argument. If @index is negative, then this
+ *		argument is used as input/output: it should be pre-populated
+ *		with the element to search for. Entries which support the
+ *		search operation will have an "index" field (not the @index
+ *		argument to this function) and that is where the found index
+ *		will be returned (or left unmodified - thus negative - if not
+ *		found).
+ */
 int sja1105_dynamic_config_read(struct sja1105_private *priv,
 				enum sja1105_blk_idx blk_idx,
 				int index, void *entry)
@@ -385,6 +405,8 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv,
 
 	if (index >= ops->max_entry_count)
 		return -ERANGE;
+	if (index < 0 && !(ops->access & OP_SEARCH))
+		return -EOPNOTSUPP;
 	if (!(ops->access & OP_READ))
 		return -EOPNOTSUPP;
 	if (ops->packed_size > SJA1105_MAX_DYN_CMD_SIZE)
@@ -396,9 +418,19 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv,
 
 	cmd.valid = true; /* Trigger action on table entry */
 	cmd.rdwrset = SPI_READ; /* Action is read */
-	cmd.index = index;
+	if (index < 0) {
+		/* Avoid copying a signed negative number to an u64 */
+		cmd.index = 0;
+		cmd.search = true;
+	} else {
+		cmd.index = index;
+		cmd.search = false;
+	}
 	ops->cmd_packing(packed_buf, &cmd, PACK);
 
+	if (cmd.search)
+		ops->entry_packing(packed_buf, entry, PACK);
+
 	/* Send SPI write operation: read config table entry */
 	rc = sja1105_spi_send_packed_buf(priv, SPI_WRITE, ops->addr,
 					 packed_buf, ops->packed_size);
@@ -456,6 +488,8 @@ int sja1105_dynamic_config_write(struct sja1105_private *priv,
 
 	if (index >= ops->max_entry_count)
 		return -ERANGE;
+	if (index < 0)
+		return -ERANGE;
 	if (!(ops->access & OP_WRITE))
 		return -EOPNOTSUPP;
 	if (!keep && !(ops->access & OP_DEL))
diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h
index 49c611eb02cb..740dadf43f01 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h
@@ -7,6 +7,9 @@
 #include "sja1105.h"
 #include <linux/packing.h>
 
+/* Special index that can be used for sja1105_dynamic_config_read */
+#define SJA1105_SEARCH		-1
+
 struct sja1105_dyn_cmd;
 
 struct sja1105_dynamic_table_ops {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next 05/11] net: dsa: sja1105: Make room for P/Q/R/S FDB operations
  2019-06-02 21:11 [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver Vladimir Oltean
                   ` (3 preceding siblings ...)
  2019-06-02 21:11 ` [PATCH net-next 04/11] net: dsa: sja1105: Plug in support for TCAM searches via the dynamic interface Vladimir Oltean
@ 2019-06-02 21:11 ` Vladimir Oltean
  2019-06-02 21:11 ` [PATCH net-next 06/11] net: dsa: sja1105: Add P/Q/R/S support for dynamic L2 lookup operations Vladimir Oltean
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2019-06-02 21:11 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem; +Cc: netdev, Vladimir Oltean

The DSA callbacks were written with the E/T (first generation) in mind,
which is quite different.

For P/Q/R/S completely new implementations need to be provided, which
are held as function pointers in the priv->info structure.  We are
taking a slightly roundabout way for this (a function from
sja1105_main.c reads a structure defined in sja1105_spi.c that
points to a function defined in sja1105_main.c), but it is what it is.

The FDB dump callback works for both families, hence no function pointer
for that.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
 drivers/net/dsa/sja1105/sja1105.h             | 15 ++++-
 .../net/dsa/sja1105/sja1105_dynamic_config.c  |  2 +-
 drivers/net/dsa/sja1105/sja1105_main.c        | 56 ++++++++++++++-----
 drivers/net/dsa/sja1105/sja1105_spi.c         | 12 ++++
 4 files changed, 69 insertions(+), 16 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h
index b043bfc408f2..f55e95d1b731 100644
--- a/drivers/net/dsa/sja1105/sja1105.h
+++ b/drivers/net/dsa/sja1105/sja1105.h
@@ -55,6 +55,11 @@ struct sja1105_info {
 	const struct sja1105_regs *regs;
 	int (*reset_cmd)(const void *ctx, const void *data);
 	int (*setup_rgmii_delay)(const void *ctx, int port);
+	/* Prototypes from include/net/dsa.h */
+	int (*fdb_add_cmd)(struct dsa_switch *ds, int port,
+			   const unsigned char *addr, u16 vid);
+	int (*fdb_del_cmd)(struct dsa_switch *ds, int port,
+			   const unsigned char *addr, u16 vid);
 	const char *name;
 };
 
@@ -142,7 +147,15 @@ int sja1105_dynamic_config_write(struct sja1105_private *priv,
 				 enum sja1105_blk_idx blk_idx,
 				 int index, void *entry, bool keep);
 
-u8 sja1105_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid);
+u8 sja1105et_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid);
+int sja1105et_fdb_add(struct dsa_switch *ds, int port,
+		      const unsigned char *addr, u16 vid);
+int sja1105et_fdb_del(struct dsa_switch *ds, int port,
+		      const unsigned char *addr, u16 vid);
+int sja1105pqrs_fdb_add(struct dsa_switch *ds, int port,
+			const unsigned char *addr, u16 vid);
+int sja1105pqrs_fdb_del(struct dsa_switch *ds, int port,
+			const unsigned char *addr, u16 vid);
 
 /* Common implementations for the static and dynamic configs */
 size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr,
diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
index 7e7efc2e8ee4..3a8b0d0ab330 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
@@ -552,7 +552,7 @@ static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly)
  * is also received as argument in the Koopman notation that the switch
  * hardware stores it in.
  */
-u8 sja1105_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid)
+u8 sja1105et_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid)
 {
 	struct sja1105_l2_lookup_params_entry *l2_lookup_params =
 		priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS].entries;
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index cfdefd9f1905..c78d2def52f1 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -786,10 +786,10 @@ static inline int sja1105et_fdb_index(int bin, int way)
 	return bin * SJA1105ET_FDB_BIN_SIZE + way;
 }
 
-static int sja1105_is_fdb_entry_in_bin(struct sja1105_private *priv, int bin,
-				       const u8 *addr, u16 vid,
-				       struct sja1105_l2_lookup_entry *match,
-				       int *last_unused)
+static int sja1105et_is_fdb_entry_in_bin(struct sja1105_private *priv, int bin,
+					 const u8 *addr, u16 vid,
+					 struct sja1105_l2_lookup_entry *match,
+					 int *last_unused)
 {
 	int way;
 
@@ -818,8 +818,8 @@ static int sja1105_is_fdb_entry_in_bin(struct sja1105_private *priv, int bin,
 	return -1;
 }
 
-static int sja1105_fdb_add(struct dsa_switch *ds, int port,
-			   const unsigned char *addr, u16 vid)
+int sja1105et_fdb_add(struct dsa_switch *ds, int port,
+		      const unsigned char *addr, u16 vid)
 {
 	struct sja1105_l2_lookup_entry l2_lookup = {0};
 	struct sja1105_private *priv = ds->priv;
@@ -827,10 +827,10 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port,
 	int last_unused = -1;
 	int bin, way;
 
-	bin = sja1105_fdb_hash(priv, addr, vid);
+	bin = sja1105et_fdb_hash(priv, addr, vid);
 
-	way = sja1105_is_fdb_entry_in_bin(priv, bin, addr, vid,
-					  &l2_lookup, &last_unused);
+	way = sja1105et_is_fdb_entry_in_bin(priv, bin, addr, vid,
+					    &l2_lookup, &last_unused);
 	if (way >= 0) {
 		/* We have an FDB entry. Is our port in the destination
 		 * mask? If yes, we need to do nothing. If not, we need
@@ -874,17 +874,17 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port,
 					    true);
 }
 
-static int sja1105_fdb_del(struct dsa_switch *ds, int port,
-			   const unsigned char *addr, u16 vid)
+int sja1105et_fdb_del(struct dsa_switch *ds, int port,
+		      const unsigned char *addr, u16 vid)
 {
 	struct sja1105_l2_lookup_entry l2_lookup = {0};
 	struct sja1105_private *priv = ds->priv;
 	int index, bin, way;
 	bool keep;
 
-	bin = sja1105_fdb_hash(priv, addr, vid);
-	way = sja1105_is_fdb_entry_in_bin(priv, bin, addr, vid,
-					  &l2_lookup, NULL);
+	bin = sja1105et_fdb_hash(priv, addr, vid);
+	way = sja1105et_is_fdb_entry_in_bin(priv, bin, addr, vid,
+					    &l2_lookup, NULL);
 	if (way < 0)
 		return 0;
 	index = sja1105et_fdb_index(bin, way);
@@ -905,6 +905,34 @@ static int sja1105_fdb_del(struct dsa_switch *ds, int port,
 					    index, &l2_lookup, keep);
 }
 
+int sja1105pqrs_fdb_add(struct dsa_switch *ds, int port,
+			const unsigned char *addr, u16 vid)
+{
+	return -EOPNOTSUPP;
+}
+
+int sja1105pqrs_fdb_del(struct dsa_switch *ds, int port,
+			const unsigned char *addr, u16 vid)
+{
+	return -EOPNOTSUPP;
+}
+
+static int sja1105_fdb_add(struct dsa_switch *ds, int port,
+			   const unsigned char *addr, u16 vid)
+{
+	struct sja1105_private *priv = ds->priv;
+
+	return priv->info->fdb_add_cmd(ds, port, addr, vid);
+}
+
+static int sja1105_fdb_del(struct dsa_switch *ds, int port,
+			   const unsigned char *addr, u16 vid)
+{
+	struct sja1105_private *priv = ds->priv;
+
+	return priv->info->fdb_del_cmd(ds, port, addr, vid);
+}
+
 static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
 			    dsa_fdb_dump_cb_t *cb, void *data)
 {
diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c
index 2eb70b8acfc3..b1344ed1697f 100644
--- a/drivers/net/dsa/sja1105/sja1105_spi.c
+++ b/drivers/net/dsa/sja1105/sja1105_spi.c
@@ -541,6 +541,8 @@ struct sja1105_info sja1105e_info = {
 	.static_ops		= sja1105e_table_ops,
 	.dyn_ops		= sja1105et_dyn_ops,
 	.reset_cmd		= sja1105et_reset_cmd,
+	.fdb_add_cmd		= sja1105et_fdb_add,
+	.fdb_del_cmd		= sja1105et_fdb_del,
 	.regs			= &sja1105et_regs,
 	.name			= "SJA1105E",
 };
@@ -550,6 +552,8 @@ struct sja1105_info sja1105t_info = {
 	.static_ops		= sja1105t_table_ops,
 	.dyn_ops		= sja1105et_dyn_ops,
 	.reset_cmd		= sja1105et_reset_cmd,
+	.fdb_add_cmd		= sja1105et_fdb_add,
+	.fdb_del_cmd		= sja1105et_fdb_del,
 	.regs			= &sja1105et_regs,
 	.name			= "SJA1105T",
 };
@@ -559,6 +563,8 @@ struct sja1105_info sja1105p_info = {
 	.static_ops		= sja1105p_table_ops,
 	.dyn_ops		= sja1105pqrs_dyn_ops,
 	.reset_cmd		= sja1105pqrs_reset_cmd,
+	.fdb_add_cmd		= sja1105pqrs_fdb_add,
+	.fdb_del_cmd		= sja1105pqrs_fdb_del,
 	.regs			= &sja1105pqrs_regs,
 	.name			= "SJA1105P",
 };
@@ -568,6 +574,8 @@ struct sja1105_info sja1105q_info = {
 	.static_ops		= sja1105q_table_ops,
 	.dyn_ops		= sja1105pqrs_dyn_ops,
 	.reset_cmd		= sja1105pqrs_reset_cmd,
+	.fdb_add_cmd		= sja1105pqrs_fdb_add,
+	.fdb_del_cmd		= sja1105pqrs_fdb_del,
 	.regs			= &sja1105pqrs_regs,
 	.name			= "SJA1105Q",
 };
@@ -577,6 +585,8 @@ struct sja1105_info sja1105r_info = {
 	.static_ops		= sja1105r_table_ops,
 	.dyn_ops		= sja1105pqrs_dyn_ops,
 	.reset_cmd		= sja1105pqrs_reset_cmd,
+	.fdb_add_cmd		= sja1105pqrs_fdb_add,
+	.fdb_del_cmd		= sja1105pqrs_fdb_del,
 	.regs			= &sja1105pqrs_regs,
 	.name			= "SJA1105R",
 };
@@ -587,5 +597,7 @@ struct sja1105_info sja1105s_info = {
 	.dyn_ops		= sja1105pqrs_dyn_ops,
 	.regs			= &sja1105pqrs_regs,
 	.reset_cmd		= sja1105pqrs_reset_cmd,
+	.fdb_add_cmd		= sja1105pqrs_fdb_add,
+	.fdb_del_cmd		= sja1105pqrs_fdb_del,
 	.name			= "SJA1105S",
 };
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next 06/11] net: dsa: sja1105: Add P/Q/R/S support for dynamic L2 lookup operations
  2019-06-02 21:11 [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver Vladimir Oltean
                   ` (4 preceding siblings ...)
  2019-06-02 21:11 ` [PATCH net-next 05/11] net: dsa: sja1105: Make room for P/Q/R/S FDB operations Vladimir Oltean
@ 2019-06-02 21:11 ` Vladimir Oltean
  2019-06-02 21:11 ` [PATCH net-next 07/11] net: dsa: sja1105: Make dynamic_config_read return -ENOENT if not found Vladimir Oltean
  2019-06-04 18:51 ` [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver David Miller
  7 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2019-06-02 21:11 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem; +Cc: netdev, Vladimir Oltean

These are needed in order to implement the switchdev FDB callbacks.

Compared to the E/T generation, not only the ABI (bit offsets) is
different, but also the introduction of the HOSTCMD field which permits
O(1) TCAM search for an FDB entry.  Make use of the newly introduce
OP_SEARCH to permit that.  It will be used while adding and deleting an
FDB entry (to see whether it exists or not).

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
 .../net/dsa/sja1105/sja1105_dynamic_config.c  | 54 +++++++++++++++++--
 1 file changed, 50 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
index 3a8b0d0ab330..7db1f8258287 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
@@ -44,17 +44,63 @@ struct sja1105_dyn_cmd {
 	u64 index;
 };
 
+enum sja1105_hostcmd {
+	SJA1105_HOSTCMD_SEARCH = 1,
+	SJA1105_HOSTCMD_READ = 2,
+	SJA1105_HOSTCMD_WRITE = 3,
+	SJA1105_HOSTCMD_INVALIDATE = 4,
+};
+
 static void
 sja1105pqrs_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
 				  enum packing_op op)
 {
 	u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
 	const int size = SJA1105_SIZE_DYN_CMD;
+	u64 lockeds = 0;
+	u64 hostcmd;
 
 	sja1105_packing(p, &cmd->valid,    31, 31, size, op);
 	sja1105_packing(p, &cmd->rdwrset,  30, 30, size, op);
 	sja1105_packing(p, &cmd->errors,   29, 29, size, op);
+	sja1105_packing(p, &lockeds,       28, 28, size, op);
 	sja1105_packing(p, &cmd->valident, 27, 27, size, op);
+
+	/* VALIDENT is supposed to indicate "keep or not", but in SJA1105 E/T,
+	 * using it to delete a management route was unsupported. UM10944
+	 * said about it:
+	 *
+	 *   In case of a write access with the MGMTROUTE flag set,
+	 *   the flag will be ignored. It will always be found cleared
+	 *   for read accesses with the MGMTROUTE flag set.
+	 *
+	 * SJA1105 P/Q/R/S keeps the same behavior w.r.t. VALIDENT, but there
+	 * is now another flag called HOSTCMD which does more stuff (quoting
+	 * from UM11040):
+	 *
+	 *   A write request is accepted only when HOSTCMD is set to write host
+	 *   or invalid. A read request is accepted only when HOSTCMD is set to
+	 *   search host or read host.
+	 *
+	 * So it is possible to translate a RDWRSET/VALIDENT combination into
+	 * HOSTCMD so that we keep the dynamic command API in place, and
+	 * at the same time achieve compatibility with the management route
+	 * command structure.
+	 */
+	if (cmd->rdwrset == SPI_READ) {
+		if (cmd->search)
+			hostcmd = SJA1105_HOSTCMD_SEARCH;
+		else
+			hostcmd = SJA1105_HOSTCMD_READ;
+	} else {
+		/* SPI_WRITE */
+		if (cmd->valident)
+			hostcmd = SJA1105_HOSTCMD_WRITE;
+		else
+			hostcmd = SJA1105_HOSTCMD_INVALIDATE;
+	}
+	sja1105_packing(p, &hostcmd, 25, 23, size, op);
+
 	/* Hack - The hardware takes the 'index' field within
 	 * struct sja1105_l2_lookup_entry as the index on which this command
 	 * will operate. However it will ignore everything else, so 'index'
@@ -65,7 +111,6 @@ sja1105pqrs_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
 	 */
 	sja1105_packing(buf, &cmd->index, 15, 6,
 			SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, op);
-	/* TODO hostcmd */
 }
 
 static void
@@ -319,9 +364,9 @@ struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
 	[BLK_IDX_L2_LOOKUP] = {
 		.entry_packing = sja1105pqrs_l2_lookup_entry_packing,
 		.cmd_packing = sja1105pqrs_l2_lookup_cmd_packing,
-		.access = (OP_READ | OP_WRITE | OP_DEL),
+		.access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH),
 		.max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
-		.packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD,
+		.packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD,
 		.addr = 0x24,
 	},
 	[BLK_IDX_L2_POLICING] = {0},
@@ -403,7 +448,7 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv,
 
 	ops = &priv->info->dyn_ops[blk_idx];
 
-	if (index >= ops->max_entry_count)
+	if (index >= 0 && index >= ops->max_entry_count)
 		return -ERANGE;
 	if (index < 0 && !(ops->access & OP_SEARCH))
 		return -EOPNOTSUPP;
@@ -426,6 +471,7 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv,
 		cmd.index = index;
 		cmd.search = false;
 	}
+	cmd.valident = true;
 	ops->cmd_packing(packed_buf, &cmd, PACK);
 
 	if (cmd.search)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next 07/11] net: dsa: sja1105: Make dynamic_config_read return -ENOENT if not found
  2019-06-02 21:11 [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver Vladimir Oltean
                   ` (5 preceding siblings ...)
  2019-06-02 21:11 ` [PATCH net-next 06/11] net: dsa: sja1105: Add P/Q/R/S support for dynamic L2 lookup operations Vladimir Oltean
@ 2019-06-02 21:11 ` Vladimir Oltean
  2019-06-04 18:51 ` [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver David Miller
  7 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2019-06-02 21:11 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem; +Cc: netdev, Vladimir Oltean

Conceptually, if an entry is not found in the requested hardware table,
it is not an invalid request - so change the error returned
appropriately.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
 drivers/net/dsa/sja1105/sja1105_dynamic_config.c | 2 +-
 drivers/net/dsa/sja1105/sja1105_main.c           | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
index 7db1f8258287..02a67df4437e 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
@@ -502,7 +502,7 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv,
 		 * So don't error out in that case.
 		 */
 		if (!cmd.valident && blk_idx != BLK_IDX_MGMT_ROUTE)
-			return -EINVAL;
+			return -ENOENT;
 		cpu_relax();
 	} while (cmd.valid && --retries);
 
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index c78d2def52f1..dc9803efdbbd 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -948,7 +948,7 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
 		rc = sja1105_dynamic_config_read(priv, BLK_IDX_L2_LOOKUP,
 						 i, &l2_lookup);
 		/* No fdb entry at i, not an issue */
-		if (rc == -EINVAL)
+		if (rc == -ENOENT)
 			continue;
 		if (rc) {
 			dev_err(dev, "Failed to dump FDB: %d\n", rc);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver
  2019-06-02 21:11 [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver Vladimir Oltean
                   ` (6 preceding siblings ...)
  2019-06-02 21:11 ` [PATCH net-next 07/11] net: dsa: sja1105: Make dynamic_config_read return -ENOENT if not found Vladimir Oltean
@ 2019-06-04 18:51 ` David Miller
  7 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2019-06-04 18:51 UTC (permalink / raw)
  To: olteanv; +Cc: f.fainelli, vivien.didelot, andrew, netdev

From: Vladimir Oltean <olteanv@gmail.com>
Date: Mon,  3 Jun 2019 00:11:52 +0300

> This patch series adds:
> 
> - FDB switchdev support for the second generation of switches (P/Q/R/S).
>   I could test/code these now that I got a board with a SJA1105Q.
> 
> - Management route support for SJA1105 P/Q/R/S. This is needed to send
>   PTP/STP/management frames over the CPU port.
> 
> - Logic to hide private DSA VLANs from the 'bridge fdb' commands.
> 
> The new FDB code was also tested and still works on SJA1105T.

Series applied, thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next 01/11] net: dsa: sja1105: Shim declaration of struct sja1105_dyn_cmd
  2019-06-02 21:11 ` [PATCH net-next 01/11] net: dsa: sja1105: Shim declaration of struct sja1105_dyn_cmd Vladimir Oltean
@ 2019-06-04 20:55   ` Florian Fainelli
  0 siblings, 0 replies; 10+ messages in thread
From: Florian Fainelli @ 2019-06-04 20:55 UTC (permalink / raw)
  To: Vladimir Oltean, vivien.didelot, andrew, davem; +Cc: netdev



On 6/2/2019 2:11 PM, Vladimir Oltean wrote:
> This structure is merely an implementation detail and should be hidden
> from the sja1105_dynamic_config.h header, which provides to the rest of
> the driver an abstract access to the dynamic configuration interface of
> the switch.
> 
> Signed-off-by: Vladimir Oltean <olteanv@gmail.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-06-04 20:55 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-02 21:11 [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver Vladimir Oltean
2019-06-02 21:11 ` [PATCH net-next 01/11] net: dsa: sja1105: Shim declaration of struct sja1105_dyn_cmd Vladimir Oltean
2019-06-04 20:55   ` Florian Fainelli
2019-06-02 21:11 ` [PATCH net-next 02/11] net: dsa: sja1105: Fix bit offsets of index field from L2 lookup entries Vladimir Oltean
2019-06-02 21:11 ` [PATCH net-next 03/11] net: dsa: sja1105: Add missing L2 Forwarding Table definitions for P/Q/R/S Vladimir Oltean
2019-06-02 21:11 ` [PATCH net-next 04/11] net: dsa: sja1105: Plug in support for TCAM searches via the dynamic interface Vladimir Oltean
2019-06-02 21:11 ` [PATCH net-next 05/11] net: dsa: sja1105: Make room for P/Q/R/S FDB operations Vladimir Oltean
2019-06-02 21:11 ` [PATCH net-next 06/11] net: dsa: sja1105: Add P/Q/R/S support for dynamic L2 lookup operations Vladimir Oltean
2019-06-02 21:11 ` [PATCH net-next 07/11] net: dsa: sja1105: Make dynamic_config_read return -ENOENT if not found Vladimir Oltean
2019-06-04 18:51 ` [PATCH net-next 00/11] FDB updates for SJA1105 DSA driver David Miller

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.