linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/18] net: dsa: HW bridging, EEE support
@ 2015-03-21 15:46 Guenter Roeck
  2015-03-21 15:46 ` [PATCH 01/18] net: dsa: mv88e6xxx: Factor out common initialization code Guenter Roeck
                   ` (18 more replies)
  0 siblings, 19 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

Patch 1 to 7 of this series prepare the drivers using the mv88e6xxx code
for HW bridging support, without adding the code itself. For the most part
this factors out common port initialization code. There is no functional
change except for patch 3, which disables the message port bit for the
CPU port to prevent packet duplication if HW bridging is configured.

Patch 8 adds the infrastructure for hardware bridging support to the
mv88e6xxx code.

Patch 9 wires the MV88E6352 driver to support hardware bridging.

Patches 10 to 12 add support for ndo_fdb functions to the dsa subsystem, and
wire up the MV88E6352 driver to support those functions.

Patches 13 to 16 add EEE support and HW bridging support to the mv88e6171
driver. This set of patches is from Andrew, applied on top of the first
set of patches.

Patch 17 and 18 add HW bridging support to the mv88e6131 driver. This code
is untested and therefore marked RFT.

The series applies to net-next as of 3/20/2015.

Thanks a lot to Andrew Lunn for testing and valuable feedback.

---
Changes from RFT:
- Various bug fixes
  - Fixed packet duplication seen when HW bridging is enabled
- Cleanup; use more defines and restructure patches
- Added ndo_fdb functions
- New patches adding support for HW bridging and EEE support
  to the mv88e6171 driver.

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

* [PATCH 01/18] net: dsa: mv88e6xxx: Factor out common initialization code
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 02/18] net: dsa: mv88e6xxx: Provide function for common port initialization Guenter Roeck
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

Code used and needed in mv886xxx.c should be initialized there as well,
so factor it out from the individual initialization files.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6123_61_65.c |  7 +++----
 drivers/net/dsa/mv88e6171.c       |  8 +++-----
 drivers/net/dsa/mv88e6352.c       |  7 ++++---
 drivers/net/dsa/mv88e6xxx.c       | 11 +++++++++++
 drivers/net/dsa/mv88e6xxx.h       |  1 +
 5 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
index e9c736e..6ebe570 100644
--- a/drivers/net/dsa/mv88e6123_61_65.c
+++ b/drivers/net/dsa/mv88e6123_61_65.c
@@ -293,13 +293,12 @@ static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p)
 
 static int mv88e6123_61_65_setup(struct dsa_switch *ds)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int i;
 	int ret;
 
-	mutex_init(&ps->smi_mutex);
-	mutex_init(&ps->stats_mutex);
-	mutex_init(&ps->phy_mutex);
+	ret = mv88e6xxx_setup_common(ds);
+	if (ret < 0)
+		return ret;
 
 	ret = mv88e6123_61_65_switch_reset(ds);
 	if (ret < 0)
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 9808c86..2f6662c 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -292,12 +292,12 @@ static int mv88e6171_setup_port(struct dsa_switch *ds, int p)
 
 static int mv88e6171_setup(struct dsa_switch *ds)
 {
-	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
 	int i;
 	int ret;
 
-	mutex_init(&ps->smi_mutex);
-	mutex_init(&ps->stats_mutex);
+	ret = mv88e6xxx_setup_common(ds);
+	if (ret < 0)
+		return ret;
 
 	ret = mv88e6171_switch_reset(ds);
 	if (ret < 0)
@@ -318,8 +318,6 @@ static int mv88e6171_setup(struct dsa_switch *ds)
 			return ret;
 	}
 
-	mutex_init(&ps->phy_mutex);
-
 	return 0;
 }
 
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 7bc5998..75cf9e1 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -385,9 +385,10 @@ static int mv88e6352_setup(struct dsa_switch *ds)
 	int ret;
 	int i;
 
-	mutex_init(&ps->smi_mutex);
-	mutex_init(&ps->stats_mutex);
-	mutex_init(&ps->phy_mutex);
+	ret = mv88e6xxx_setup_common(ds);
+	if (ret < 0)
+		return ret;
+
 	mutex_init(&ps->eeprom_mutex);
 
 	ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0;
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index c18ffc9..6496beb 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -700,6 +700,17 @@ int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
 	return 0;
 }
 
+int mv88e6xxx_setup_common(struct dsa_switch *ds)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+
+	mutex_init(&ps->smi_mutex);
+	mutex_init(&ps->stats_mutex);
+	mutex_init(&ps->phy_mutex);
+
+	return 0;
+}
+
 static int __init mv88e6xxx_init(void)
 {
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 5fd42ce..a02d95a 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -57,6 +57,7 @@ struct mv88e6xxx_hw_stat {
 	int reg;
 };
 
+int mv88e6xxx_setup_common(struct dsa_switch *ds);
 int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg);
 int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg);
 int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
-- 
2.1.0


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

* [PATCH 02/18] net: dsa: mv88e6xxx: Provide function for common port initialization
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
  2015-03-21 15:46 ` [PATCH 01/18] net: dsa: mv88e6xxx: Factor out common initialization code Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 22:41   ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 03/18] net: dsa: mv88e6xxx: Disable Message Port bit for CPU port Guenter Roeck
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

Provide mv88e6xxx_setup_port_common() for common port initialization.
Currently only write Port 1 Control and VLAN configuration since
this will be needed for hardware bridging. More can be added later
if desired/needed.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6xxx.c | 39 +++++++++++++++++++++++++++++++++++++++
 drivers/net/dsa/mv88e6xxx.h |  1 +
 2 files changed, 40 insertions(+)

diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 6496beb..3c2cb45 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -700,6 +700,45 @@ int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
 	return 0;
 }
 
+int mv88e6xxx_setup_port_common(struct dsa_switch *ds, int port)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int reg;
+
+	mutex_lock(&ps->smi_mutex);
+
+	/* Port Control 1: disable trunking.  Also, if this is the
+	 * CPU port, enable learn messages to be sent to this port.
+	 */
+	ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), 0x05,
+				   dsa_is_cpu_port(ds, port) ? 0x8000 : 0x0000);
+	if (ret)
+		goto abort;
+
+	/* Port based VLAN map: give each port its own address
+	 * database, allow the CPU port to talk to each of the 'real'
+	 * ports, and allow each of the 'real' ports to only talk to
+	 * the upstream port.
+	 */
+	reg = (port & 0xf) << 12;
+	if (dsa_is_cpu_port(ds, port))
+		reg |= ds->phys_port_mask;
+	else
+		reg |= 1 << dsa_upstream_port(ds);
+
+	ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), 0x06, reg);
+	if (ret)
+		goto abort;
+
+	/* Default VLAN ID and priority: don't set a default VLAN
+	 * ID, and set the default packet priority to zero.
+	 */
+	ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), 0x07, 0x0000);
+abort:
+	mutex_unlock(&ps->smi_mutex);
+	return ret;
+}
+
 int mv88e6xxx_setup_common(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index a02d95a..a4df496 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -57,6 +57,7 @@ struct mv88e6xxx_hw_stat {
 	int reg;
 };
 
+int mv88e6xxx_setup_port_common(struct dsa_switch *ds, int port);
 int mv88e6xxx_setup_common(struct dsa_switch *ds);
 int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg);
 int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg);
-- 
2.1.0


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

* [PATCH 03/18] net: dsa: mv88e6xxx: Disable Message Port bit for CPU port
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
  2015-03-21 15:46 ` [PATCH 01/18] net: dsa: mv88e6xxx: Factor out common initialization code Guenter Roeck
  2015-03-21 15:46 ` [PATCH 02/18] net: dsa: mv88e6xxx: Provide function for common port initialization Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 04/18] net: dsa: mv88e6xxx: Split mv88e6xxx_reg_read and mv88e6xxx_reg_write Guenter Roeck
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

Datasheet says that the Message Port bit should not be set for the CPU port.
Having it set causes DSA tagged packets to be sent to the CPU port roughly
every 30 seconds. Those packets are the same as real packets forwarded between
switch ports if the switch is configured for switching between multiple ports.
The packets are then bridged by the software bridge, resulting in duplicated
packets on the network.

Reported-by: Andrew Lunn <andrew@lunn.ch>
Cc: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6xxx.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 3c2cb45..d4447b7 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -707,11 +707,10 @@ int mv88e6xxx_setup_port_common(struct dsa_switch *ds, int port)
 
 	mutex_lock(&ps->smi_mutex);
 
-	/* Port Control 1: disable trunking.  Also, if this is the
-	 * CPU port, enable learn messages to be sent to this port.
+	/* Port Control 1: disable trunking, disable sending
+	 * learning messages to this port.
 	 */
-	ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), 0x05,
-				   dsa_is_cpu_port(ds, port) ? 0x8000 : 0x0000);
+	ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), 0x05, 0x0000);
 	if (ret)
 		goto abort;
 
-- 
2.1.0


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

* [PATCH 04/18] net: dsa: mv88e6xxx: Split mv88e6xxx_reg_read and mv88e6xxx_reg_write
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (2 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 03/18] net: dsa: mv88e6xxx: Disable Message Port bit for CPU port Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 05/18] net: dsa: mv88e6352: Use common port initialization code Guenter Roeck
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

Split mv88e6xxx_reg_read and mv88e6xxx_reg_write into two functions each,
one to acquire smi_mutex and one to get struct mii_bus *bus from
struct dsa_switch *ds and to call the actual read/write function.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6xxx.c | 35 ++++++++++++++++++++++++++---------
 1 file changed, 26 insertions(+), 9 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index d4447b7..c2c0460 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -72,19 +72,16 @@ int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg)
 	return ret & 0xffff;
 }
 
-int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
+/* Must be called with SMI mutex held */
+static int _mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
 	int ret;
 
 	if (bus == NULL)
 		return -EINVAL;
 
-	mutex_lock(&ps->smi_mutex);
 	ret = __mv88e6xxx_reg_read(bus, ds->pd->sw_addr, addr, reg);
-	mutex_unlock(&ps->smi_mutex);
-
 	if (ret < 0)
 		return ret;
 
@@ -94,6 +91,18 @@ int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
 	return ret;
 }
 
+int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int ret;
+
+	mutex_lock(&ps->smi_mutex);
+	ret = _mv88e6xxx_reg_read(ds, addr, reg);
+	mutex_unlock(&ps->smi_mutex);
+
+	return ret;
+}
+
 int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
 			  int reg, u16 val)
 {
@@ -125,11 +134,11 @@ int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
 	return 0;
 }
 
-int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
+/* Must be called with SMI mutex held */
+static int _mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg,
+				u16 val)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
-	int ret;
 
 	if (bus == NULL)
 		return -EINVAL;
@@ -137,8 +146,16 @@ int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
 	dev_dbg(ds->master_dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
 		addr, reg, val);
 
+	return __mv88e6xxx_reg_write(bus, ds->pd->sw_addr, addr, reg, val);
+}
+
+int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int ret;
+
 	mutex_lock(&ps->smi_mutex);
-	ret = __mv88e6xxx_reg_write(bus, ds->pd->sw_addr, addr, reg, val);
+	ret = _mv88e6xxx_reg_write(ds, addr, reg, val);
 	mutex_unlock(&ps->smi_mutex);
 
 	return ret;
-- 
2.1.0


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

* [PATCH 05/18] net: dsa: mv88e6352: Use common port initialization code
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (3 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 04/18] net: dsa: mv88e6xxx: Split mv88e6xxx_reg_read and mv88e6xxx_reg_write Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 06/18] net: dsa: mv88e6123_61_65: Use common port configuration Guenter Roeck
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

This prepares the driver for hardware bridging.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6352.c | 24 +-----------------------
 1 file changed, 1 insertion(+), 23 deletions(-)

diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 75cf9e1..f7e7c0f 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -215,28 +215,6 @@ static int mv88e6352_setup_port(struct dsa_switch *ds, int p)
 		val |= 0x000c;
 	REG_WRITE(addr, 0x04, val);
 
-	/* Port Control 1: disable trunking.  Also, if this is the
-	 * CPU port, enable learn messages to be sent to this port.
-	 */
-	REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000);
-
-	/* Port based VLAN map: give each port its own address
-	 * database, allow the CPU port to talk to each of the 'real'
-	 * ports, and allow each of the 'real' ports to only talk to
-	 * the upstream port.
-	 */
-	val = (p & 0xf) << 12;
-	if (dsa_is_cpu_port(ds, p))
-		val |= ds->phys_port_mask;
-	else
-		val |= 1 << dsa_upstream_port(ds);
-	REG_WRITE(addr, 0x06, val);
-
-	/* Default VLAN ID and priority: don't set a default VLAN
-	 * ID, and set the default packet priority to zero.
-	 */
-	REG_WRITE(addr, 0x07, 0x0000);
-
 	/* Port Control 2: don't force a good FCS, set the maximum
 	 * frame size to 10240 bytes, don't let the switch add or
 	 * strip 802.1q tags, don't discard tagged or untagged frames
@@ -281,7 +259,7 @@ static int mv88e6352_setup_port(struct dsa_switch *ds, int p)
 	 */
 	REG_WRITE(addr, 0x19, 0x7654);
 
-	return 0;
+	return mv88e6xxx_setup_port_common(ds, p);
 }
 
 #ifdef CONFIG_NET_DSA_HWMON
-- 
2.1.0


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

* [PATCH 06/18] net: dsa: mv88e6123_61_65: Use common port configuration
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (4 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 05/18] net: dsa: mv88e6352: Use common port initialization code Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 07/18] net: dsa: mv88e6171: " Guenter Roeck
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

This will simplify adding offloaded bridge support later on.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6123_61_65.c | 24 +-----------------------
 1 file changed, 1 insertion(+), 23 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
index 6ebe570..2d7e1ff 100644
--- a/drivers/net/dsa/mv88e6123_61_65.c
+++ b/drivers/net/dsa/mv88e6123_61_65.c
@@ -222,28 +222,6 @@ static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p)
 		val |= 0x000c;
 	REG_WRITE(addr, 0x04, val);
 
-	/* Port Control 1: disable trunking.  Also, if this is the
-	 * CPU port, enable learn messages to be sent to this port.
-	 */
-	REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000);
-
-	/* Port based VLAN map: give each port its own address
-	 * database, allow the CPU port to talk to each of the 'real'
-	 * ports, and allow each of the 'real' ports to only talk to
-	 * the upstream port.
-	 */
-	val = (p & 0xf) << 12;
-	if (dsa_is_cpu_port(ds, p))
-		val |= ds->phys_port_mask;
-	else
-		val |= 1 << dsa_upstream_port(ds);
-	REG_WRITE(addr, 0x06, val);
-
-	/* Default VLAN ID and priority: don't set a default VLAN
-	 * ID, and set the default packet priority to zero.
-	 */
-	REG_WRITE(addr, 0x07, 0x0000);
-
 	/* Port Control 2: don't force a good FCS, set the maximum
 	 * frame size to 10240 bytes, don't let the switch add or
 	 * strip 802.1q tags, don't discard tagged or untagged frames
@@ -288,7 +266,7 @@ static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p)
 	 */
 	REG_WRITE(addr, 0x19, 0x7654);
 
-	return 0;
+	return mv88e6xxx_setup_port_common(ds, p);
 }
 
 static int mv88e6123_61_65_setup(struct dsa_switch *ds)
-- 
2.1.0


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

* [PATCH 07/18] net: dsa: mv88e6171: Use common port configuration
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (5 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 06/18] net: dsa: mv88e6123_61_65: Use common port configuration Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support Guenter Roeck
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6171.c | 24 +-----------------------
 1 file changed, 1 insertion(+), 23 deletions(-)

diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 2f6662c..6ce6a3e 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -221,28 +221,6 @@ static int mv88e6171_setup_port(struct dsa_switch *ds, int p)
 		val |= 0x000c;
 	REG_WRITE(addr, 0x04, val);
 
-	/* Port Control 1: disable trunking.  Also, if this is the
-	 * CPU port, enable learn messages to be sent to this port.
-	 */
-	REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000);
-
-	/* Port based VLAN map: give each port its own address
-	 * database, allow the CPU port to talk to each of the 'real'
-	 * ports, and allow each of the 'real' ports to only talk to
-	 * the upstream port.
-	 */
-	val = (p & 0xf) << 12;
-	if (dsa_is_cpu_port(ds, p))
-		val |= ds->phys_port_mask;
-	else
-		val |= 1 << dsa_upstream_port(ds);
-	REG_WRITE(addr, 0x06, val);
-
-	/* Default VLAN ID and priority: don't set a default VLAN
-	 * ID, and set the default packet priority to zero.
-	 */
-	REG_WRITE(addr, 0x07, 0x0000);
-
 	/* Port Control 2: don't force a good FCS, set the maximum
 	 * frame size to 10240 bytes, don't let the switch add or
 	 * strip 802.1q tags, don't discard tagged or untagged frames
@@ -287,7 +265,7 @@ static int mv88e6171_setup_port(struct dsa_switch *ds, int p)
 	 */
 	REG_WRITE(addr, 0x19, 0x7654);
 
-	return 0;
+	return mv88e6xxx_setup_port_common(ds, p);
 }
 
 static int mv88e6171_setup(struct dsa_switch *ds)
-- 
2.1.0


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

* [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (6 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 07/18] net: dsa: mv88e6171: " Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-22 20:06   ` Andrew Lunn
  2015-03-21 15:46 ` [PATCH 09/18] net: dsa: mv88e6352: Add support for hardware bridging Guenter Roeck
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

Bridge support is similar for all chips supported by the mv88e6xxx code,
so add the code there.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6xxx.c | 271 ++++++++++++++++++++++++++++++++++++++++++--
 drivers/net/dsa/mv88e6xxx.h |  28 +++++
 2 files changed, 292 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index c2c0460..17aa74f 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/if_bridge.h>
 #include <linux/jiffies.h>
 #include <linux/list.h>
 #include <linux/module.h>
@@ -644,6 +645,31 @@ int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds)
 	return mv88e6xxx_wait(ds, REG_GLOBAL2, 0x14, 0x8000);
 }
 
+/* Must be called with SMI lock held */
+static int _mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset, u16 mask)
+{
+	unsigned long timeout = jiffies + HZ / 10;
+
+	while (time_before(jiffies, timeout)) {
+		int ret;
+
+		ret = _mv88e6xxx_reg_read(ds, reg, offset);
+		if (ret < 0)
+			return ret;
+		if (!(ret & mask))
+			return 0;
+
+		usleep_range(1000, 2000);
+	}
+	return -ETIMEDOUT;
+}
+
+/* Must be called with SMI lock held */
+static int _mv88e6xxx_atu_wait(struct dsa_switch *ds)
+{
+	return _mv88e6xxx_wait(ds, REG_GLOBAL, 0x0b, ATU_BUSY);
+}
+
 int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum)
 {
 	int ret;
@@ -717,10 +743,236 @@ int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
 	return 0;
 }
 
+static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, int fid, u16 cmd)
+{
+	int ret;
+
+	ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x01, fid);
+	if (ret < 0)
+		return ret;
+
+	ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x0b, cmd);
+	if (ret < 0)
+		return ret;
+
+	return _mv88e6xxx_atu_wait(ds);
+}
+
+static int _mv88e6xxx_flush_fid(struct dsa_switch *ds, int fid)
+{
+	int ret;
+
+	ret = _mv88e6xxx_atu_wait(ds);
+	if (ret < 0)
+		return ret;
+
+	return _mv88e6xxx_atu_cmd(ds, fid, ATU_CMD_FLUSH_NONSTATIC_FID);
+}
+
+static int mv88e6xxx_set_port_state(struct dsa_switch *ds, int port, u8 state)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int reg, ret;
+	u8 oldstate;
+
+	mutex_lock(&ps->smi_mutex);
+
+	reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), 0x04);
+	if (reg < 0)
+		goto abort;
+
+	oldstate = reg & PSTATE_MASK;
+	if (oldstate != state) {
+		/* Flush forwarding database if we're moving a port
+		 * from Learning or Forwarding state to Disabled or
+		 * Blocking or Listening state.
+		 */
+		if (oldstate >= PSTATE_LEARNING && state <= PSTATE_BLOCKING) {
+			ret = _mv88e6xxx_flush_fid(ds, ps->fid[port]);
+			if (ret)
+				goto abort;
+		}
+		reg = (reg & ~PSTATE_MASK) | state;
+		ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), 0x04, reg);
+	}
+
+abort:
+	mutex_unlock(&ps->smi_mutex);
+	return ret;
+}
+
+/* Must be called with smi lock held */
+static int _mv88e6xxx_update_port_config(struct dsa_switch *ds, int port)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	u8 fid = ps->fid[port];
+	u16 reg = fid << 12;
+
+	if (dsa_is_cpu_port(ds, port))
+		reg |= ds->phys_port_mask;
+	else
+		reg |= (ps->bridge_mask[fid] |
+		       (1 << dsa_upstream_port(ds))) & ~(1 << port);
+
+	return _mv88e6xxx_reg_write(ds, REG_PORT(port), 0x06, reg);
+}
+
+/* Must be called with smi lock held */
+static int _mv88e6xxx_update_bridge_config(struct dsa_switch *ds, int fid)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int port;
+	u32 mask;
+	int ret;
+
+	mask = ds->phys_port_mask;
+	while (mask) {
+		port = __ffs(mask);
+		mask &= ~(1 << port);
+		if (ps->fid[port] != fid)
+			continue;
+
+		ret = _mv88e6xxx_update_port_config(ds, port);
+		if (ret)
+			return ret;
+	}
+
+	return _mv88e6xxx_flush_fid(ds, fid);
+}
+
+/* Bridge handling functions */
+
+int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int ret = 0;
+	u32 nmask;
+	int fid;
+
+	/* If the bridge group is not empty, join that group.
+	 * Otherwise create a new group.
+	 */
+	fid = ps->fid[port];
+	nmask = br_port_mask & ~(1 << port);
+	if (nmask)
+		fid = ps->fid[__ffs(nmask)];
+
+	nmask = ps->bridge_mask[fid] | (1 << port);
+	if (nmask != br_port_mask) {
+		netdev_err(ds->ports[port],
+			   "join: Bridge port mask mismatch fid=%d mask=0x%x expected 0x%x\n",
+			   fid, br_port_mask, nmask);
+		return -EINVAL;
+	}
+
+	mutex_lock(&ps->smi_mutex);
+
+	ps->bridge_mask[fid] = br_port_mask;
+
+	if (fid != ps->fid[port]) {
+		ps->fid_mask |= 1 << ps->fid[port];
+		ps->fid[port] = fid;
+		ret = _mv88e6xxx_update_bridge_config(ds, fid);
+	}
+
+	mutex_unlock(&ps->smi_mutex);
+
+	return ret;
+}
+
+int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	u8 fid, newfid;
+	int ret;
+
+	fid = ps->fid[port];
+
+	if (ps->bridge_mask[fid] != br_port_mask) {
+		netdev_err(ds->ports[port],
+			   "leave: Bridge port mask mismatch fid=%d mask=0x%x expected 0x%x\n",
+			   fid, br_port_mask, ps->bridge_mask[fid]);
+		return -EINVAL;
+	}
+
+	/* If the port was the last port of a bridge, we are done.
+	 * Otherwise assign a new fid to the port, and fix up
+	 * the bridge configuration.
+	 */
+	if (br_port_mask == (1 << port))
+		return 0;
+
+	mutex_lock(&ps->smi_mutex);
+
+	newfid = __ffs(ps->fid_mask);
+	ps->fid[port] = newfid;
+	ps->fid_mask &= (1 << newfid);
+	ps->bridge_mask[fid] &= ~(1 << port);
+	ps->bridge_mask[newfid] = 1 << port;
+
+	ret = _mv88e6xxx_update_bridge_config(ds, fid);
+	if (!ret)
+		ret = _mv88e6xxx_update_bridge_config(ds, newfid);
+
+	mutex_unlock(&ps->smi_mutex);
+
+	return ret;
+}
+
+int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int stp_state;
+
+	switch (state) {
+	case BR_STATE_DISABLED:
+		stp_state = PSTATE_DISABLED;
+		break;
+	case BR_STATE_BLOCKING:
+	case BR_STATE_LISTENING:
+		stp_state = PSTATE_BLOCKING;
+		break;
+	case BR_STATE_LEARNING:
+		stp_state = PSTATE_LEARNING;
+		break;
+	case BR_STATE_FORWARDING:
+	default:
+		stp_state = PSTATE_FORWARDING;
+		break;
+	}
+
+	netdev_dbg(ds->ports[port], "port state %d [%d]\n", state, stp_state);
+
+	/* mv88e6xxx_port_stp_update may be called with softirqs disabled,
+	 * so we can not update the port state directly but need to schedule it.
+	 */
+	ps->port_state[port] = stp_state;
+	set_bit(port, &ps->port_state_update_mask);
+	schedule_work(&ps->bridge_work);
+
+	return 0;
+}
+
+static void mv88e6xxx_bridge_work(struct work_struct *work)
+{
+	struct mv88e6xxx_priv_state *ps;
+	struct dsa_switch *ds;
+	int port;
+
+	ps = container_of(work, struct mv88e6xxx_priv_state, bridge_work);
+	ds = ((struct dsa_switch *)ps) - 1;
+
+	while (ps->port_state_update_mask) {
+		port = __ffs(ps->port_state_update_mask);
+		clear_bit(port, &ps->port_state_update_mask);
+		mv88e6xxx_set_port_state(ds, port, ps->port_state[port]);
+	}
+}
+
 int mv88e6xxx_setup_port_common(struct dsa_switch *ds, int port)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int reg;
+	int ret, fid;
 
 	mutex_lock(&ps->smi_mutex);
 
@@ -736,13 +988,14 @@ int mv88e6xxx_setup_port_common(struct dsa_switch *ds, int port)
 	 * ports, and allow each of the 'real' ports to only talk to
 	 * the upstream port.
 	 */
-	reg = (port & 0xf) << 12;
-	if (dsa_is_cpu_port(ds, port))
-		reg |= ds->phys_port_mask;
-	else
-		reg |= 1 << dsa_upstream_port(ds);
+	fid = __ffs(ps->fid_mask);
+	ps->fid[port] = fid;
+	ps->fid_mask &= ~(1 << fid);
+
+	if (!dsa_is_cpu_port(ds, port))
+		ps->bridge_mask[fid] = 1 << port;
 
-	ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), 0x06, reg);
+	ret = _mv88e6xxx_update_port_config(ds, port);
 	if (ret)
 		goto abort;
 
@@ -763,6 +1016,10 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds)
 	mutex_init(&ps->stats_mutex);
 	mutex_init(&ps->phy_mutex);
 
+	ps->fid_mask = (1 << DSA_MAX_PORTS) - 1;
+
+	INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
+
 	return 0;
 }
 
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index a4df496..8e215eb 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -15,6 +15,20 @@
 #define REG_GLOBAL		0x1b
 #define REG_GLOBAL2		0x1c
 
+/* ATU commands */
+
+#define ATU_BUSY			0x8000
+
+#define ATU_CMD_FLUSH_NONSTATIC_FID	(ATU_BUSY | 0x6000)
+
+/* port states */
+
+#define PSTATE_MASK		0x03
+#define PSTATE_DISABLED		0x00
+#define PSTATE_BLOCKING		0x01
+#define PSTATE_LEARNING		0x02
+#define PSTATE_FORWARDING	0x03
+
 struct mv88e6xxx_priv_state {
 	/* When using multi-chip addressing, this mutex protects
 	 * access to the indirect access registers.  (In single-chip
@@ -49,6 +63,17 @@ struct mv88e6xxx_priv_state {
 	struct mutex eeprom_mutex;
 
 	int		id; /* switch product id */
+
+	/* hw bridging */
+
+	u32 fid_mask;
+	u8 fid[DSA_MAX_PORTS];
+	u16 bridge_mask[DSA_MAX_PORTS];
+
+	unsigned long port_state_update_mask;
+	u8 port_state[DSA_MAX_PORTS];
+
+	struct work_struct bridge_work;
 };
 
 struct mv88e6xxx_hw_stat {
@@ -93,6 +118,9 @@ int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
 int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
 int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
 		      struct phy_device *phydev, struct ethtool_eee *e);
+int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask);
+int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask);
+int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state);
 
 extern struct dsa_switch_driver mv88e6131_switch_driver;
 extern struct dsa_switch_driver mv88e6123_61_65_switch_driver;
-- 
2.1.0


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

* [PATCH 09/18] net: dsa: mv88e6352: Add support for hardware bridging
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (7 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 10/18] net: dsa: Add basic framework to support ndo_fdb functions Guenter Roeck
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6352.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index f7e7c0f..51acd16 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -708,6 +708,9 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
 	.set_eeprom		= mv88e6352_set_eeprom,
 	.get_regs_len		= mv88e6xxx_get_regs_len,
 	.get_regs		= mv88e6xxx_get_regs,
+	.port_join_bridge	= mv88e6xxx_join_bridge,
+	.port_leave_bridge	= mv88e6xxx_leave_bridge,
+	.port_stp_update	= mv88e6xxx_port_stp_update,
 };
 
 MODULE_ALIAS("platform:mv88e6352");
-- 
2.1.0


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

* [PATCH 10/18] net: dsa: Add basic framework to support ndo_fdb functions
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (8 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 09/18] net: dsa: mv88e6352: Add support for hardware bridging Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 11/18] net: dsa: mv88e6xxx: Add support for fdb_add, fdb_del, and fdb_getnext Guenter Roeck
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

Provide callbacks for ndo_fdb_add, ndo_fdb_del, and ndo_fdb_dump.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 include/net/dsa.h |   6 ++++
 net/dsa/slave.c   | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 47917e5..fbca63b 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -296,6 +296,12 @@ struct dsa_switch_driver {
 				     u32 br_port_mask);
 	int	(*port_stp_update)(struct dsa_switch *ds, int port,
 				   u8 state);
+	int	(*fdb_add)(struct dsa_switch *ds, int port,
+			   const unsigned char *addr, u16 vid);
+	int	(*fdb_del)(struct dsa_switch *ds, int port,
+			   const unsigned char *addr, u16 vid);
+	int	(*fdb_getnext)(struct dsa_switch *ds, int port,
+			       unsigned char *addr, bool *is_static);
 };
 
 void register_switch_driver(struct dsa_switch_driver *type);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index f0af7aa..8ccfdbc 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -201,6 +201,105 @@ out:
 	return 0;
 }
 
+static int dsa_slave_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
+			     struct net_device *dev,
+			     const unsigned char *addr, u16 vid, u16 nlm_flags)
+{
+	struct dsa_slave_priv *p = netdev_priv(dev);
+	struct dsa_switch *ds = p->parent;
+	int ret = -EOPNOTSUPP;
+
+	if (ds->drv->fdb_add)
+		ret = ds->drv->fdb_add(ds, p->port, addr, vid);
+
+	return ret;
+}
+
+static int dsa_slave_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
+			     struct net_device *dev,
+			     const unsigned char *addr, u16 vid)
+{
+	struct dsa_slave_priv *p = netdev_priv(dev);
+	struct dsa_switch *ds = p->parent;
+	int ret = -EOPNOTSUPP;
+
+	if (ds->drv->fdb_del)
+		ret = ds->drv->fdb_del(ds, p->port, addr, vid);
+
+	return ret;
+}
+
+static int dsa_slave_fill_info(struct net_device *dev, struct sk_buff *skb,
+			       const unsigned char *addr, u16 vid,
+			       bool is_static,
+			       u32 portid, u32 seq, int type,
+			       unsigned int flags)
+{
+	struct nlmsghdr *nlh;
+	struct ndmsg *ndm;
+
+	nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags);
+	if (!nlh)
+		return -EMSGSIZE;
+
+	ndm = nlmsg_data(nlh);
+	ndm->ndm_family	 = AF_BRIDGE;
+	ndm->ndm_pad1    = 0;
+	ndm->ndm_pad2    = 0;
+	ndm->ndm_flags	 = NTF_EXT_LEARNED;
+	ndm->ndm_type	 = 0;
+	ndm->ndm_ifindex = dev->ifindex;
+	ndm->ndm_state   = is_static ? NUD_NOARP : NUD_REACHABLE;
+
+	if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr))
+		goto nla_put_failure;
+
+	if (vid && nla_put_u16(skb, NDA_VLAN, vid))
+		goto nla_put_failure;
+
+	nlmsg_end(skb, nlh);
+	return 0;
+
+nla_put_failure:
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
+}
+
+/* Dump information about entries, in response to GETNEIGH */
+static int dsa_slave_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
+			      struct net_device *dev,
+			      struct net_device *filter_dev, int idx)
+{
+	struct dsa_slave_priv *p = netdev_priv(dev);
+	struct dsa_switch *ds = p->parent;
+	unsigned char addr[ETH_ALEN] = { 0 };
+	int ret;
+
+	if (!ds->drv->fdb_getnext)
+		return -EOPNOTSUPP;
+
+	for (; ; idx++) {
+		bool is_static;
+
+		ret = ds->drv->fdb_getnext(ds, p->port, addr, &is_static);
+		if (ret < 0)
+			break;
+
+		if (idx < cb->args[0])
+			continue;
+
+		ret = dsa_slave_fill_info(dev, skb, addr, 0,
+					  is_static,
+					  NETLINK_CB(cb->skb).portid,
+					  cb->nlh->nlmsg_seq,
+					  RTM_NEWNEIGH, NLM_F_MULTI);
+		if (ret < 0)
+			break;
+	}
+
+	return idx;
+}
+
 static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
@@ -572,6 +671,9 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
 	.ndo_change_rx_flags	= dsa_slave_change_rx_flags,
 	.ndo_set_rx_mode	= dsa_slave_set_rx_mode,
 	.ndo_set_mac_address	= dsa_slave_set_mac_address,
+	.ndo_fdb_add		= dsa_slave_fdb_add,
+	.ndo_fdb_del		= dsa_slave_fdb_del,
+	.ndo_fdb_dump		= dsa_slave_fdb_dump,
 	.ndo_do_ioctl		= dsa_slave_ioctl,
 };
 
-- 
2.1.0


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

* [PATCH 11/18] net: dsa: mv88e6xxx: Add support for fdb_add, fdb_del, and fdb_getnext
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (9 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 10/18] net: dsa: Add basic framework to support ndo_fdb functions Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 12/18] net: dsa: mv88e6352: Add support for ndo_fdb functions Guenter Roeck
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

No vlan support at this time.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6xxx.c | 136 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/dsa/mv88e6xxx.h |  22 +++++++
 2 files changed, 158 insertions(+)

diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 17aa74f..0388022 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/etherdevice.h>
 #include <linux/if_bridge.h>
 #include <linux/jiffies.h>
 #include <linux/list.h>
@@ -953,6 +954,141 @@ int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state)
 	return 0;
 }
 
+static int __mv88e6xxx_write_addr(struct dsa_switch *ds,
+				  const unsigned char *addr)
+{
+	int i, ret;
+
+	for (i = 0; i < 3; i++) {
+		ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x0d + i,
+					(addr[i * 2] << 8) | addr[i * 2 + 1]);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int __mv88e6xxx_read_addr(struct dsa_switch *ds, unsigned char *addr)
+{
+	int i, ret;
+
+	for (i = 0; i < 3; i++) {
+		ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x0d + i);
+		if (ret < 0)
+			return ret;
+		addr[i * 2] = ret >> 8;
+		addr[i * 2 + 1] = ret & 0xff;
+	}
+
+	return 0;
+}
+
+static int __mv88e6xxx_port_fdb_cmd(struct dsa_switch *ds, int port,
+				    const unsigned char *addr, int state)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	u8 fid = ps->fid[port];
+	int ret;
+
+	ret = _mv88e6xxx_atu_wait(ds);
+	if (ret < 0)
+		return ret;
+
+	ret = __mv88e6xxx_write_addr(ds, addr);
+	if (ret < 0)
+		return ret;
+
+	ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x0c,
+				   (0x10 << port) | state);
+	if (ret)
+		return ret;
+
+	ret = _mv88e6xxx_atu_cmd(ds, fid, ATU_CMD_LOAD_FID);
+
+	return ret;
+}
+
+int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
+			   const unsigned char *addr, u16 vid)
+{
+	int state = is_multicast_ether_addr(addr) ?
+					FDB_STATE_MC_STATIC : FDB_STATE_STATIC;
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int ret;
+
+	mutex_lock(&ps->smi_mutex);
+	ret = __mv88e6xxx_port_fdb_cmd(ds, port, addr, state);
+	mutex_unlock(&ps->smi_mutex);
+
+	return ret;
+}
+
+int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
+			   const unsigned char *addr, u16 vid)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int ret;
+
+	mutex_lock(&ps->smi_mutex);
+	ret = __mv88e6xxx_port_fdb_cmd(ds, port, addr, FDB_STATE_UNUSED);
+	mutex_unlock(&ps->smi_mutex);
+
+	return ret;
+}
+
+static int __mv88e6xxx_port_getnext(struct dsa_switch *ds, int port,
+				    unsigned char *addr, bool *is_static)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	u8 fid = ps->fid[port];
+	int ret, state;
+
+	ret = _mv88e6xxx_atu_wait(ds);
+	if (ret < 0)
+		return ret;
+
+	ret = __mv88e6xxx_write_addr(ds, addr);
+	if (ret < 0)
+		return ret;
+
+	do {
+		ret = _mv88e6xxx_atu_cmd(ds, fid, ATU_CMD_GETNEXT_FID);
+		if (ret < 0)
+			return ret;
+
+		ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x0c);
+		if (ret < 0)
+			return ret;
+		state = ret & FDB_STATE_MASK;
+		if (state == FDB_STATE_UNUSED)
+			return -ENOENT;
+	} while (!(((ret >> 4) & 0xff) & (1 << port)));
+
+	ret = __mv88e6xxx_read_addr(ds, addr);
+	if (ret < 0)
+		return ret;
+
+	*is_static = state == (is_multicast_ether_addr(addr) ?
+			       FDB_STATE_MC_STATIC : FDB_STATE_STATIC);
+
+	return 0;
+}
+
+/* get next entry for port */
+int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port,
+			       unsigned char *addr, bool *is_static)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int ret;
+
+	mutex_lock(&ps->smi_mutex);
+	ret = __mv88e6xxx_port_getnext(ds, port, addr, is_static);
+	mutex_unlock(&ps->smi_mutex);
+
+	return ret;
+}
+
 static void mv88e6xxx_bridge_work(struct work_struct *work)
 {
 	struct mv88e6xxx_priv_state *ps;
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 8e215eb..48ecefc 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -29,6 +29,22 @@
 #define PSTATE_LEARNING		0x02
 #define PSTATE_FORWARDING	0x03
 
+/* ATU commands */
+
+#define ATU_BUSY			0x8000
+
+#define ATU_CMD_LOAD_FID		(ATU_BUSY | 0x3000)
+#define ATU_CMD_GETNEXT_FID		(ATU_BUSY | 0x4000)
+#define ATU_CMD_FLUSH_NONSTATIC_FID	(ATU_BUSY | 0x6000)
+
+/* FDB states */
+
+#define FDB_STATE_MASK			0x0f
+
+#define FDB_STATE_UNUSED		0x00
+#define FDB_STATE_MC_STATIC		0x07	/* static multicast */
+#define FDB_STATE_STATIC		0x0e	/* static unicast */
+
 struct mv88e6xxx_priv_state {
 	/* When using multi-chip addressing, this mutex protects
 	 * access to the indirect access registers.  (In single-chip
@@ -121,6 +137,12 @@ int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
 int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask);
 int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask);
 int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state);
+int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
+			   const unsigned char *addr, u16 vid);
+int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
+			   const unsigned char *addr, u16 vid);
+int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port,
+			       unsigned char *addr, bool *is_static);
 
 extern struct dsa_switch_driver mv88e6131_switch_driver;
 extern struct dsa_switch_driver mv88e6123_61_65_switch_driver;
-- 
2.1.0


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

* [PATCH 12/18] net: dsa: mv88e6352: Add support for ndo_fdb functions
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (10 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 11/18] net: dsa: mv88e6xxx: Add support for fdb_add, fdb_del, and fdb_getnext Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 13/18] net: dsa: Centralise getting switch id Guenter Roeck
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

Add support for manipulating switch fdb entries by pointing to the
ndo_fdb functions implemented for mv88e6xxxx.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6352.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 51acd16..7285bd0 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -711,6 +711,9 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
 	.port_join_bridge	= mv88e6xxx_join_bridge,
 	.port_leave_bridge	= mv88e6xxx_leave_bridge,
 	.port_stp_update	= mv88e6xxx_port_stp_update,
+	.fdb_add		= mv88e6xxx_port_fdb_add,
+	.fdb_del		= mv88e6xxx_port_fdb_del,
+	.fdb_getnext		= mv88e6xxx_port_fdb_getnext,
 };
 
 MODULE_ALIAS("platform:mv88e6352");
-- 
2.1.0


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

* [PATCH 13/18] net: dsa: Centralise getting switch id
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (11 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 12/18] net: dsa: mv88e6352: Add support for ndo_fdb functions Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 14/18] net: dsa: mv88e6171: Add defines for switch product IDs Guenter Roeck
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

From: Andrew Lunn <andrew@lunn.ch>

Get the switch id and save it away in the private mv88x6xxx structure
in a centralised piece of code, rather than each driver doing it itself.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6352.c | 2 --
 drivers/net/dsa/mv88e6xxx.c | 2 ++
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 7285bd0..41fe3a6 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -369,8 +369,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
 
 	mutex_init(&ps->eeprom_mutex);
 
-	ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0;
-
 	ret = mv88e6352_switch_reset(ds);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 0388022..13572cc 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -1152,6 +1152,8 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds)
 	mutex_init(&ps->stats_mutex);
 	mutex_init(&ps->phy_mutex);
 
+	ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0;
+
 	ps->fid_mask = (1 << DSA_MAX_PORTS) - 1;
 
 	INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
-- 
2.1.0


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

* [PATCH 14/18] net: dsa: mv88e6171: Add defines for switch product IDs
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (12 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 13/18] net: dsa: Centralise getting switch id Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 15/18] net: dsa: mv88e6171: Add EEE support to the mv88e6172 Guenter Roeck
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

From: Andrew Lunn <andrew@lunn.ch>

Make the code more readable by using defines for the switch IDs.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6171.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 6ce6a3e..54ebfed 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -17,6 +17,10 @@
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
+/* Switch product IDs */
+#define ID_6171	0x1710
+#define ID_6172	0x1720
+
 static char *mv88e6171_probe(struct device *host_dev, int sw_addr)
 {
 	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
@@ -27,9 +31,9 @@ static char *mv88e6171_probe(struct device *host_dev, int sw_addr)
 
 	ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
 	if (ret >= 0) {
-		if ((ret & 0xfff0) == 0x1710)
+		if ((ret & 0xfff0) == ID_6171)
 			return "Marvell 88E6171";
-		if ((ret & 0xfff0) == 0x1720)
+		if ((ret & 0xfff0) == ID_6172)
 			return "Marvell 88E6172";
 	}
 
-- 
2.1.0


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

* [PATCH 15/18] net: dsa: mv88e6171: Add EEE support to the mv88e6172
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (13 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 14/18] net: dsa: mv88e6171: Add defines for switch product IDs Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [PATCH 16/18] net: dsa: mv88e6171: Add support for hardware bridging Guenter Roeck
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

From: Andrew Lunn <andrew@lunn.ch>

The mv88e6172 has support for EEE. Check for the product ID and call
the common code if applicable.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6171.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 54ebfed..e1700cd 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -390,6 +390,28 @@ static int mv88e6171_get_sset_count(struct dsa_switch *ds)
 	return ARRAY_SIZE(mv88e6171_hw_stats);
 }
 
+static int mv88e6171_get_eee(struct dsa_switch *ds, int port,
+			     struct ethtool_eee *e)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+
+	if (ps->id == ID_6172)
+		return mv88e6xxx_get_eee(ds, port, e);
+
+	return -EOPNOTSUPP;
+}
+
+static int mv88e6171_set_eee(struct dsa_switch *ds, int port,
+			     struct phy_device *phydev, struct ethtool_eee *e)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+
+	if (ps->id == ID_6172)
+		return mv88e6xxx_set_eee(ds, port, phydev, e);
+
+	return -EOPNOTSUPP;
+}
+
 struct dsa_switch_driver mv88e6171_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
 	.priv_size		= sizeof(struct mv88e6xxx_priv_state),
@@ -402,6 +424,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
 	.get_strings		= mv88e6171_get_strings,
 	.get_ethtool_stats	= mv88e6171_get_ethtool_stats,
 	.get_sset_count		= mv88e6171_get_sset_count,
+	.set_eee		= mv88e6171_set_eee,
+	.get_eee		= mv88e6171_get_eee,
 #ifdef CONFIG_NET_DSA_HWMON
 	.get_temp               = mv88e6xxx_get_temp,
 #endif
-- 
2.1.0


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

* [PATCH 16/18] net: dsa: mv88e6171: Add support for hardware bridging
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (14 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 15/18] net: dsa: mv88e6171: Add EEE support to the mv88e6172 Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [RFT PATCH 17/18] net: dsa: mv88e6131: Use common initialization functions Guenter Roeck
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

From: Andrew Lunn <andrew@lunn.ch>

Wire up the common code for setting up hardware bridging
and access to the forwarding database.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6171.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index e1700cd..18cfead 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -431,6 +431,12 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
 #endif
 	.get_regs_len		= mv88e6xxx_get_regs_len,
 	.get_regs		= mv88e6xxx_get_regs,
+	.port_join_bridge       = mv88e6xxx_join_bridge,
+	.port_leave_bridge      = mv88e6xxx_leave_bridge,
+	.port_stp_update        = mv88e6xxx_port_stp_update,
+	.fdb_add		= mv88e6xxx_port_fdb_add,
+	.fdb_del		= mv88e6xxx_port_fdb_del,
+	.fdb_getnext		= mv88e6xxx_port_fdb_getnext,
 };
 
 MODULE_ALIAS("platform:mv88e6171");
-- 
2.1.0


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

* [RFT PATCH 17/18] net: dsa: mv88e6131: Use common initialization functions
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (15 preceding siblings ...)
  2015-03-21 15:46 ` [PATCH 16/18] net: dsa: mv88e6171: Add support for hardware bridging Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 15:46 ` [RFT PATCH 18/18] net: dsa: mv88e6131: Add HW bridging support Guenter Roeck
  2015-03-21 22:48 ` [PATCH 0/18] net: dsa: HW bridging, EEE support David Miller
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

Common initialization functions will be needed to enable
HW bridging support.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6131.c | 32 +++++---------------------------
 1 file changed, 5 insertions(+), 27 deletions(-)

diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 2540ef0..98a3668 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -208,28 +208,6 @@ static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
 		val |= 0x0100;
 	REG_WRITE(addr, 0x04, val);
 
-	/* Port Control 1: disable trunking.  Also, if this is the
-	 * CPU port, enable learn messages to be sent to this port.
-	 */
-	REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000);
-
-	/* Port based VLAN map: give each port its own address
-	 * database, allow the CPU port to talk to each of the 'real'
-	 * ports, and allow each of the 'real' ports to only talk to
-	 * the upstream port.
-	 */
-	val = (p & 0xf) << 12;
-	if (dsa_is_cpu_port(ds, p))
-		val |= ds->phys_port_mask;
-	else
-		val |= 1 << dsa_upstream_port(ds);
-	REG_WRITE(addr, 0x06, val);
-
-	/* Default VLAN ID and priority: don't set a default VLAN
-	 * ID, and set the default packet priority to zero.
-	 */
-	REG_WRITE(addr, 0x07, 0x0000);
-
 	/* Port Control 2: don't force a good FCS, don't use
 	 * VLAN-based, source address-based or destination
 	 * address-based priority overrides, don't let the switch
@@ -278,7 +256,7 @@ static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
 	 */
 	REG_WRITE(addr, 0x19, 0x7654);
 
-	return 0;
+	return mv88e6xxx_setup_port_common(ds, p);
 }
 
 static int mv88e6131_setup(struct dsa_switch *ds)
@@ -287,11 +265,11 @@ static int mv88e6131_setup(struct dsa_switch *ds)
 	int i;
 	int ret;
 
-	mutex_init(&ps->smi_mutex);
-	mv88e6xxx_ppu_state_init(ds);
-	mutex_init(&ps->stats_mutex);
+	ret = mv88e6xxx_setup_common(ds);
+	if (ret < 0)
+		return ret;
 
-	ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0;
+	mv88e6xxx_ppu_state_init(ds);
 
 	ret = mv88e6131_switch_reset(ds);
 	if (ret < 0)
-- 
2.1.0


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

* [RFT PATCH 18/18] net: dsa: mv88e6131: Add HW bridging support
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (16 preceding siblings ...)
  2015-03-21 15:46 ` [RFT PATCH 17/18] net: dsa: mv88e6131: Use common initialization functions Guenter Roeck
@ 2015-03-21 15:46 ` Guenter Roeck
  2015-03-21 22:48 ` [PATCH 0/18] net: dsa: HW bridging, EEE support David Miller
  18 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 15:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel,
	Guenter Roeck

HW bridging support for mv88e6131 and compatible chips is similar
to other chips of the series, so we can add support to it
by just setting the respective function vectors.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/net/dsa/mv88e6131.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 98a3668..60b8122 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -377,6 +377,12 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
 	.get_strings		= mv88e6131_get_strings,
 	.get_ethtool_stats	= mv88e6131_get_ethtool_stats,
 	.get_sset_count		= mv88e6131_get_sset_count,
+	.port_join_bridge	= mv88e6xxx_join_bridge,
+	.port_leave_bridge	= mv88e6xxx_leave_bridge,
+	.port_stp_update	= mv88e6xxx_port_stp_update,
+	.fdb_add		= mv88e6xxx_port_fdb_add,
+	.fdb_del		= mv88e6xxx_port_fdb_del,
+	.fdb_getnext		= mv88e6xxx_port_fdb_getnext,
 };
 
 MODULE_ALIAS("platform:mv88e6085");
-- 
2.1.0


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

* Re: [PATCH 02/18] net: dsa: mv88e6xxx: Provide function for common port initialization
  2015-03-21 15:46 ` [PATCH 02/18] net: dsa: mv88e6xxx: Provide function for common port initialization Guenter Roeck
@ 2015-03-21 22:41   ` Guenter Roeck
  0 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 22:41 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Andrew Lunn, Florian Fainelli, linux-kernel

On 03/21/2015 08:46 AM, Guenter Roeck wrote:
> Provide mv88e6xxx_setup_port_common() for common port initialization.
> Currently only write Port 1 Control and VLAN configuration since
> this will be needed for hardware bridging. More can be added later
> if desired/needed.
>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>   drivers/net/dsa/mv88e6xxx.c | 39 +++++++++++++++++++++++++++++++++++++++
>   drivers/net/dsa/mv88e6xxx.h |  1 +
>   2 files changed, 40 insertions(+)
>
> diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
> index 6496beb..3c2cb45 100644
> --- a/drivers/net/dsa/mv88e6xxx.c
> +++ b/drivers/net/dsa/mv88e6xxx.c
> @@ -700,6 +700,45 @@ int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
>   	return 0;
>   }
>
> +int mv88e6xxx_setup_port_common(struct dsa_switch *ds, int port)
> +{
> +	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
> +	int reg;
> +
> +	mutex_lock(&ps->smi_mutex);
> +
> +	/* Port Control 1: disable trunking.  Also, if this is the
> +	 * CPU port, enable learn messages to be sent to this port.
> +	 */
> +	ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), 0x05,
> +				   dsa_is_cpu_port(ds, port) ? 0x8000 : 0x0000);

This fails to compile. It is fixed in a later commit which is why I didn't see it.
Too much reordering, I guess. Sorry for that.

Just a heads up; I'll wait for comments before resubmitting.

Guenter


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

* Re: [PATCH 0/18] net: dsa: HW bridging, EEE support
  2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
                   ` (17 preceding siblings ...)
  2015-03-21 15:46 ` [RFT PATCH 18/18] net: dsa: mv88e6131: Add HW bridging support Guenter Roeck
@ 2015-03-21 22:48 ` David Miller
  2015-03-21 23:12   ` Guenter Roeck
  18 siblings, 1 reply; 33+ messages in thread
From: David Miller @ 2015-03-21 22:48 UTC (permalink / raw)
  To: linux; +Cc: netdev, andrew, f.fainelli, linux-kernel

From: Guenter Roeck <linux@roeck-us.net>
Date: Sat, 21 Mar 2015 08:46:37 -0700

> Patch 1 to 7 of this series prepare the drivers using the mv88e6xxx code
> for HW bridging support, without adding the code itself. For the most part
> this factors out common port initialization code. There is no functional
> change except for patch 3, which disables the message port bit for the
> CPU port to prevent packet duplication if HW bridging is configured.
> 
> Patch 8 adds the infrastructure for hardware bridging support to the
> mv88e6xxx code.
> 
> Patch 9 wires the MV88E6352 driver to support hardware bridging.
> 
> Patches 10 to 12 add support for ndo_fdb functions to the dsa subsystem, and
> wire up the MV88E6352 driver to support those functions.
> 
> Patches 13 to 16 add EEE support and HW bridging support to the mv88e6171
> driver. This set of patches is from Andrew, applied on top of the first
> set of patches.
> 
> Patch 17 and 18 add HW bridging support to the mv88e6131 driver. This code
> is untested and therefore marked RFT.
> 
> The series applies to net-next as of 3/20/2015.
> 
> Thanks a lot to Andrew Lunn for testing and valuable feedback.

Generally this series looks good.

But this driver would be so much easier to read and understand if it
used mnemonics instead of constants for the register offsets.

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

* Re: [PATCH 0/18] net: dsa: HW bridging, EEE support
  2015-03-21 22:48 ` [PATCH 0/18] net: dsa: HW bridging, EEE support David Miller
@ 2015-03-21 23:12   ` Guenter Roeck
  2015-03-21 23:26     ` Andrew Lunn
  2015-03-22  2:14     ` David Miller
  0 siblings, 2 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-21 23:12 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, andrew, f.fainelli, linux-kernel

On 03/21/2015 03:48 PM, David Miller wrote:
> From: Guenter Roeck <linux@roeck-us.net>
> Date: Sat, 21 Mar 2015 08:46:37 -0700
>
>> Patch 1 to 7 of this series prepare the drivers using the mv88e6xxx code
>> for HW bridging support, without adding the code itself. For the most part
>> this factors out common port initialization code. There is no functional
>> change except for patch 3, which disables the message port bit for the
>> CPU port to prevent packet duplication if HW bridging is configured.
>>
>> Patch 8 adds the infrastructure for hardware bridging support to the
>> mv88e6xxx code.
>>
>> Patch 9 wires the MV88E6352 driver to support hardware bridging.
>>
>> Patches 10 to 12 add support for ndo_fdb functions to the dsa subsystem, and
>> wire up the MV88E6352 driver to support those functions.
>>
>> Patches 13 to 16 add EEE support and HW bridging support to the mv88e6171
>> driver. This set of patches is from Andrew, applied on top of the first
>> set of patches.
>>
>> Patch 17 and 18 add HW bridging support to the mv88e6131 driver. This code
>> is untested and therefore marked RFT.
>>
>> The series applies to net-next as of 3/20/2015.
>>
>> Thanks a lot to Andrew Lunn for testing and valuable feedback.
>
> Generally this series looks good.
>
> But this driver would be so much easier to read and understand if it
> used mnemonics instead of constants for the register offsets.
>

Yes, agreed. It is on the to-do list. Should we be more aggressive ?
Since I'll have to resubmit anyway, we could start by adding defines
for all constants used in this patch set, not just some of them.

Guenter


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

* Re: [PATCH 0/18] net: dsa: HW bridging, EEE support
  2015-03-21 23:12   ` Guenter Roeck
@ 2015-03-21 23:26     ` Andrew Lunn
  2015-03-22  2:14     ` David Miller
  1 sibling, 0 replies; 33+ messages in thread
From: Andrew Lunn @ 2015-03-21 23:26 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: David Miller, netdev, f.fainelli, linux-kernel

> >But this driver would be so much easier to read and understand if it
> >used mnemonics instead of constants for the register offsets.
> >
> 
> Yes, agreed. It is on the to-do list. Should we be more aggressive ?
> Since I'll have to resubmit anyway, we could start by adding defines
> for all constants used in this patch set, not just some of them.

It may make more sense to remove a lot of the duplicate code first.  I
have patches which centralises all the switch reset and PHY access. It
should also be possible to centralise the statistics code. At a rough
guess, that is going to remove 50% of each driver. Quite a bit of the
remainder can also be centralised, but there is where the drivers
actually start to differ, and so will take more effort.

	 Andrew

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

* Re: [PATCH 0/18] net: dsa: HW bridging, EEE support
  2015-03-21 23:12   ` Guenter Roeck
  2015-03-21 23:26     ` Andrew Lunn
@ 2015-03-22  2:14     ` David Miller
  2015-03-22  2:31       ` Guenter Roeck
  1 sibling, 1 reply; 33+ messages in thread
From: David Miller @ 2015-03-22  2:14 UTC (permalink / raw)
  To: linux; +Cc: netdev, andrew, f.fainelli, linux-kernel

From: Guenter Roeck <linux@roeck-us.net>
Date: Sat, 21 Mar 2015 16:12:30 -0700

> Yes, agreed. It is on the to-do list. Should we be more aggressive ?
> Since I'll have to resubmit anyway, we could start by adding defines
> for all constants used in this patch set, not just some of them.

As long as you'll really take care of this afterwards, you can take
care of the defines after this series is integrated.

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

* Re: [PATCH 0/18] net: dsa: HW bridging, EEE support
  2015-03-22  2:14     ` David Miller
@ 2015-03-22  2:31       ` Guenter Roeck
  0 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-22  2:31 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, andrew, f.fainelli, linux-kernel

On 03/21/2015 07:14 PM, David Miller wrote:
> From: Guenter Roeck <linux@roeck-us.net>
> Date: Sat, 21 Mar 2015 16:12:30 -0700
>
>> Yes, agreed. It is on the to-do list. Should we be more aggressive ?
>> Since I'll have to resubmit anyway, we could start by adding defines
>> for all constants used in this patch set, not just some of them.
>
> As long as you'll really take care of this afterwards, you can take
> care of the defines after this series is integrated.
>
Definitely. But I agree with Andrew, I would prefer to do it
after this and Andrew's next set of patches has been accepted.

Guenter


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

* Re: [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support
  2015-03-21 15:46 ` [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support Guenter Roeck
@ 2015-03-22 20:06   ` Andrew Lunn
  2015-03-22 20:45     ` Guenter Roeck
  2015-03-22 22:24     ` David Miller
  0 siblings, 2 replies; 33+ messages in thread
From: Andrew Lunn @ 2015-03-22 20:06 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: netdev, David S. Miller, Florian Fainelli, linux-kernel

Hi Guenter

> +static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, int fid, u16 cmd)
> +{
> +	int ret;
> +
> +	ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x01, fid);
> +	if (ret < 0)
> +		return ret;

Please could you check this. I think register 0x01 here is wrong. I
think you want 0x0b, the ATU Operations register?

Thanks
	Andrew

> +
> +	ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x0b, cmd);
> +	if (ret < 0)
> +		return ret;
> +
> +	return _mv88e6xxx_atu_wait(ds);
> +}
> +

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

* Re: [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support
  2015-03-22 20:06   ` Andrew Lunn
@ 2015-03-22 20:45     ` Guenter Roeck
  2015-03-22 20:59       ` Andrew Lunn
  2015-03-22 22:24     ` David Miller
  1 sibling, 1 reply; 33+ messages in thread
From: Guenter Roeck @ 2015-03-22 20:45 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, David S. Miller, Florian Fainelli, linux-kernel

On 03/22/2015 01:06 PM, Andrew Lunn wrote:
> Hi Guenter
>
>> +static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, int fid, u16 cmd)
>> +{
>> +	int ret;
>> +
>> +	ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x01, fid);
>> +	if (ret < 0)
>> +		return ret;
>
> Please could you check this. I think register 0x01 here is wrong. I
> think you want 0x0b, the ATU Operations register?
>
The ATU operation is initiated below (and does write to register 0x0b).
Register 0x01 is FID[11..0] for ATU, which is what we want to write here.

Guenter

> Thanks
> 	Andrew
>
>> +
>> +	ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x0b, cmd);
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	return _mv88e6xxx_atu_wait(ds);
>> +}
>> +
>


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

* Re: [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support
  2015-03-22 20:45     ` Guenter Roeck
@ 2015-03-22 20:59       ` Andrew Lunn
  2015-03-22 22:39         ` Guenter Roeck
  0 siblings, 1 reply; 33+ messages in thread
From: Andrew Lunn @ 2015-03-22 20:59 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: netdev, David S. Miller, Florian Fainelli, linux-kernel

On Sun, Mar 22, 2015 at 01:45:49PM -0700, Guenter Roeck wrote:
> On 03/22/2015 01:06 PM, Andrew Lunn wrote:
> >Hi Guenter
> >
> >>+static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, int fid, u16 cmd)
> >>+{
> >>+	int ret;
> >>+
> >>+	ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x01, fid);
> >>+	if (ret < 0)
> >>+		return ret;
> >
> >Please could you check this. I think register 0x01 here is wrong. I
> >think you want 0x0b, the ATU Operations register?
> >
> The ATU operation is initiated below (and does write to register 0x0b).
> Register 0x01 is FID[11..0] for ATU, which is what we want to write here.

http://lxr.free-electrons.com/source/drivers/net/dsa/mv88e6xxx.c#L156

156 int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
157 {
158         REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
159         REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
160         REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
161 
162         return 0;
163 }

So maybe the meaning of these registers has changed between different
versions of the chips? Only 6131 uses mv88e6xxx_set_addr_direct, all
the others use indirect method. So maybe the 6131 is going to need
something different here in _mv88e6xxx_atu_cmd()?

	  Andrew


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

* Re: [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support
  2015-03-22 20:06   ` Andrew Lunn
  2015-03-22 20:45     ` Guenter Roeck
@ 2015-03-22 22:24     ` David Miller
  2015-03-22 22:45       ` Guenter Roeck
  1 sibling, 1 reply; 33+ messages in thread
From: David Miller @ 2015-03-22 22:24 UTC (permalink / raw)
  To: andrew; +Cc: linux, netdev, f.fainelli, linux-kernel

From: Andrew Lunn <andrew@lunn.ch>
Date: Sun, 22 Mar 2015 21:06:00 +0100

> Hi Guenter
> 
>> +static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, int fid, u16 cmd)
>> +{
>> +	int ret;
>> +
>> +	ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x01, fid);
>> +	if (ret < 0)
>> +		return ret;
> 
> Please could you check this. I think register 0x01 here is wrong. I
> think you want 0x0b, the ATU Operations register?

Just want to mention that register mnenomics would have made this
bug more obvious :-)

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

* Re: [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support
  2015-03-22 20:59       ` Andrew Lunn
@ 2015-03-22 22:39         ` Guenter Roeck
  2015-03-23  1:18           ` Andrew Lunn
  0 siblings, 1 reply; 33+ messages in thread
From: Guenter Roeck @ 2015-03-22 22:39 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, David S. Miller, Florian Fainelli, linux-kernel

On 03/22/2015 01:59 PM, Andrew Lunn wrote:
> On Sun, Mar 22, 2015 at 01:45:49PM -0700, Guenter Roeck wrote:
>> On 03/22/2015 01:06 PM, Andrew Lunn wrote:
>>> Hi Guenter
>>>
>>>> +static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, int fid, u16 cmd)
>>>> +{
>>>> +	int ret;
>>>> +
>>>> +	ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x01, fid);
>>>> +	if (ret < 0)
>>>> +		return ret;
>>>
>>> Please could you check this. I think register 0x01 here is wrong. I
>>> think you want 0x0b, the ATU Operations register?
>>>
>> The ATU operation is initiated below (and does write to register 0x0b).
>> Register 0x01 is FID[11..0] for ATU, which is what we want to write here.
>
> http://lxr.free-electrons.com/source/drivers/net/dsa/mv88e6xxx.c#L156
>
> 156 int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
> 157 {
> 158         REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
> 159         REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
> 160         REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
> 161
> 162         return 0;
> 163 }
>
> So maybe the meaning of these registers has changed between different
> versions of the chips? Only 6131 uses mv88e6xxx_set_addr_direct, all
> the others use indirect method. So maybe the 6131 is going to need
> something different here in _mv88e6xxx_atu_cmd()?
>

Good catch. You are so right, the meaning of this register has changed.

a) 6165, 6171, 6172, 6176, 6240, 6532
b) 6060, 6152, 6155, 6182, 6185

		(a)		(b)
Global 0x01	ATU FID		Switch mac address bytes 0 & 1
Global 0x0a	Age time	Age time, FID (DBNum) bit 4..7
Global 0x0b	ATU cmd		ATU cmd, FID (DBNum) bit 0..3
Global2 0x0d	Switch mac add	undefined / unused

I don't know about the 6095 and the 6131, but I assume those chips
are similar to the the chips listed in (b) above.

So the HW bridging code as written won't work for the switches in
group (b), meaning I need to drop the related patches for now.
Guess we need to wait for someone who can test the code with that chip
before releasing it.

That also means that we'll have to move the list of switch IDs into
mv88e6xxx.h to be able to use it where needed (such as in mv88e6xxx_atu_cmd).

Guenter


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

* Re: [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support
  2015-03-22 22:24     ` David Miller
@ 2015-03-22 22:45       ` Guenter Roeck
  0 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-22 22:45 UTC (permalink / raw)
  To: David Miller, andrew; +Cc: netdev, f.fainelli, linux-kernel

On 03/22/2015 03:24 PM, David Miller wrote:
> From: Andrew Lunn <andrew@lunn.ch>
> Date: Sun, 22 Mar 2015 21:06:00 +0100
>
>> Hi Guenter
>>
>>> +static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, int fid, u16 cmd)
>>> +{
>>> +	int ret;
>>> +
>>> +	ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x01, fid);
>>> +	if (ret < 0)
>>> +		return ret;
>>
>> Please could you check this. I think register 0x01 here is wrong. I
>> think you want 0x0b, the ATU Operations register?
>
> Just want to mention that register mnenomics would have made this
> bug more obvious :-)
>

Andrew is working on introducing those definitions, which is how he
found the problem. It is not a bug per se, though, since the register
definition changed across chip generations. The code works fine for
the chips we tested it with (6171, 6172, and 6352).

Guenter


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

* Re: [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support
  2015-03-22 22:39         ` Guenter Roeck
@ 2015-03-23  1:18           ` Andrew Lunn
  2015-03-23  1:33             ` Guenter Roeck
  0 siblings, 1 reply; 33+ messages in thread
From: Andrew Lunn @ 2015-03-23  1:18 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: netdev, David S. Miller, Florian Fainelli, linux-kernel

> That also means that we'll have to move the list of switch IDs into
> mv88e6xxx.h to be able to use it where needed (such as in mv88e6xxx_atu_cmd).

I was thinking about doing that anyway. It would make it cleaner for
handling statistics counters.

	 Andrew

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

* Re: [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support
  2015-03-23  1:18           ` Andrew Lunn
@ 2015-03-23  1:33             ` Guenter Roeck
  0 siblings, 0 replies; 33+ messages in thread
From: Guenter Roeck @ 2015-03-23  1:33 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, David S. Miller, Florian Fainelli, linux-kernel

On 03/22/2015 06:18 PM, Andrew Lunn wrote:
>> That also means that we'll have to move the list of switch IDs into
>> mv88e6xxx.h to be able to use it where needed (such as in mv88e6xxx_atu_cmd).
>
> I was thinking about doing that anyway. It would make it cleaner for
> handling statistics counters.
>

Makes sense. actually, I would say it is just cleaner, period.

Guenter


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

end of thread, other threads:[~2015-03-23  1:33 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-21 15:46 [PATCH 0/18] net: dsa: HW bridging, EEE support Guenter Roeck
2015-03-21 15:46 ` [PATCH 01/18] net: dsa: mv88e6xxx: Factor out common initialization code Guenter Roeck
2015-03-21 15:46 ` [PATCH 02/18] net: dsa: mv88e6xxx: Provide function for common port initialization Guenter Roeck
2015-03-21 22:41   ` Guenter Roeck
2015-03-21 15:46 ` [PATCH 03/18] net: dsa: mv88e6xxx: Disable Message Port bit for CPU port Guenter Roeck
2015-03-21 15:46 ` [PATCH 04/18] net: dsa: mv88e6xxx: Split mv88e6xxx_reg_read and mv88e6xxx_reg_write Guenter Roeck
2015-03-21 15:46 ` [PATCH 05/18] net: dsa: mv88e6352: Use common port initialization code Guenter Roeck
2015-03-21 15:46 ` [PATCH 06/18] net: dsa: mv88e6123_61_65: Use common port configuration Guenter Roeck
2015-03-21 15:46 ` [PATCH 07/18] net: dsa: mv88e6171: " Guenter Roeck
2015-03-21 15:46 ` [PATCH 08/18] net: dsa: mv88e6xxx: Add Hardware bridging support Guenter Roeck
2015-03-22 20:06   ` Andrew Lunn
2015-03-22 20:45     ` Guenter Roeck
2015-03-22 20:59       ` Andrew Lunn
2015-03-22 22:39         ` Guenter Roeck
2015-03-23  1:18           ` Andrew Lunn
2015-03-23  1:33             ` Guenter Roeck
2015-03-22 22:24     ` David Miller
2015-03-22 22:45       ` Guenter Roeck
2015-03-21 15:46 ` [PATCH 09/18] net: dsa: mv88e6352: Add support for hardware bridging Guenter Roeck
2015-03-21 15:46 ` [PATCH 10/18] net: dsa: Add basic framework to support ndo_fdb functions Guenter Roeck
2015-03-21 15:46 ` [PATCH 11/18] net: dsa: mv88e6xxx: Add support for fdb_add, fdb_del, and fdb_getnext Guenter Roeck
2015-03-21 15:46 ` [PATCH 12/18] net: dsa: mv88e6352: Add support for ndo_fdb functions Guenter Roeck
2015-03-21 15:46 ` [PATCH 13/18] net: dsa: Centralise getting switch id Guenter Roeck
2015-03-21 15:46 ` [PATCH 14/18] net: dsa: mv88e6171: Add defines for switch product IDs Guenter Roeck
2015-03-21 15:46 ` [PATCH 15/18] net: dsa: mv88e6171: Add EEE support to the mv88e6172 Guenter Roeck
2015-03-21 15:46 ` [PATCH 16/18] net: dsa: mv88e6171: Add support for hardware bridging Guenter Roeck
2015-03-21 15:46 ` [RFT PATCH 17/18] net: dsa: mv88e6131: Use common initialization functions Guenter Roeck
2015-03-21 15:46 ` [RFT PATCH 18/18] net: dsa: mv88e6131: Add HW bridging support Guenter Roeck
2015-03-21 22:48 ` [PATCH 0/18] net: dsa: HW bridging, EEE support David Miller
2015-03-21 23:12   ` Guenter Roeck
2015-03-21 23:26     ` Andrew Lunn
2015-03-22  2:14     ` David Miller
2015-03-22  2:31       ` Guenter Roeck

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).