All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver
@ 2016-05-05 22:40 Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 01/20] net: dsa: mv88e6xxx: factorize PHY access with PPU Vivien Didelot
                   ` (19 more replies)
  0 siblings, 20 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

This patchset merges all mv88e6* drivers supported by the shared
mv88e6xxx code into a single mv88e6xxx DSA switch driver.

Some flags are added to describe the capabilities of a switch model,
such as the presence of a PPU, EEPROM, some old or new registers, etc.

First these flags are used to conditionally support the same set of
functions in every driver, then specific driver files are removed in
favor of the common mv88e6xxx driver.

Only the merge of driver specific setup code assumes a few differences.
If these differences such as frames priorities are really needed for
some models, they can easily be brought back in a future patch.

Some inconsistencies might show up, such as the need for
MV88E6XXX_FLAG_PPU and MV88E6XXX_FLAG_PPU_ACTIVE flags. But this
patchset does not aim to fix them yet. A future patch can do that if
they end up being inconsistencies.

Vivien Didelot (20):
  net: dsa: mv88e6xxx: factorize PHY access with PPU
  net: dsa: mv88e6xxx: factorize PHY indirect access
  net: dsa: mv88e6xxx: factorize EEPROM access
  net: dsa: mv88e6xxx: factorize temperature access
  net: dsa: mv88e6xxx: factorize MAC address setting
  net: dsa: mv88e6xxx: factorize EEE access
  net: dsa: mv88e6xxx: factorize registers access
  net: dsa: mv88e6xxx: factorize bridge support
  net: dsa: mv88e6xxx: factorize VTU access
  net: dsa: mv88e6xxx: factorize ATU access
  net: dsa: mv88e6xxx: factorize switch reset
  net: dsa: mv88e6xxx: factorize global setup
  net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup
  net: dsa: mv88e6xxx: factorize VLAN Ethertype
  net: dsa: mv88e6xxx: factorize GLOBAL_MONITOR_CONTROL setup
  net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL_2 setup
  net: dsa: mv88e6xxx: factorize frames priorities
  net: dsa: mv88e6xxx: factorize switch setup
  net: dsa: mv88e6xxx: factorize tag protocol
  net: dsa: mv88e6xxx: factorize the switch driver

 arch/arm/configs/multi_v5_defconfig |    5 +-
 arch/arm/configs/mvebu_v7_defconfig |    2 +-
 arch/arm/configs/orion5x_defconfig  |    3 +-
 arch/tile/configs/tilegx_defconfig  |    3 +-
 arch/tile/configs/tilepro_defconfig |    3 +-
 drivers/net/dsa/Kconfig             |   41 +-
 drivers/net/dsa/Makefile            |   15 +-
 drivers/net/dsa/mv88e6123.c         |  130 ----
 drivers/net/dsa/mv88e6131.c         |  204 ------
 drivers/net/dsa/mv88e6171.c         |  151 ----
 drivers/net/dsa/mv88e6352.c         |  377 ----------
 drivers/net/dsa/mv88e6xxx.c         | 1348 +++++++++++++++++++++++++----------
 drivers/net/dsa/mv88e6xxx.h         |  190 ++---
 13 files changed, 1084 insertions(+), 1388 deletions(-)
 delete mode 100644 drivers/net/dsa/mv88e6123.c
 delete mode 100644 drivers/net/dsa/mv88e6131.c
 delete mode 100644 drivers/net/dsa/mv88e6171.c
 delete mode 100644 drivers/net/dsa/mv88e6352.c

-- 
2.8.2

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

* [RFC PATCH net-next 01/20] net: dsa: mv88e6xxx: factorize PHY access with PPU
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:54   ` Andrew Lunn
                     ` (2 more replies)
  2016-05-05 22:40 ` [RFC PATCH net-next 02/20] net: dsa: mv88e6xxx: factorize PHY indirect access Vivien Didelot
                   ` (18 subsequent siblings)
  19 siblings, 3 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Add a flags bitmap to the mv88e6xxx_info structure to help describing
features supported or not by a switch model.

Add a MV88E6XXX_FLAG_PPU flag to describe switch models with a PHY
Polling Unit. This allows to merge PPU specific PHY access code in the
share code. In the meantime, use unlocked register accesses.

Since the PPU code is shared, also remove NET_DSA_MV88E6XXX_NEED_PPU.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/Kconfig     |   5 --
 drivers/net/dsa/mv88e6131.c |  43 ++-------------
 drivers/net/dsa/mv88e6xxx.c | 130 +++++++++++++++++++++-----------------------
 drivers/net/dsa/mv88e6xxx.h |  25 ++++++---
 4 files changed, 86 insertions(+), 117 deletions(-)

diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 90ba003..4aaadce 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -13,15 +13,10 @@ config NET_DSA_MV88E6060
 	  This enables support for the Marvell 88E6060 ethernet switch
 	  chip.
 
-config NET_DSA_MV88E6XXX_NEED_PPU
-	bool
-	default n
-
 config NET_DSA_MV88E6131
 	tristate "Marvell 88E6085/6095/6095F/6131 ethernet switch chip support"
 	depends on NET_DSA
 	select NET_DSA_MV88E6XXX
-	select NET_DSA_MV88E6XXX_NEED_PPU
 	select NET_DSA_TAG_DSA
 	---help---
 	  This enables support for the Marvell 88E6085/6095/6095F/6131
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 357ab79..437faf8 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -24,24 +24,28 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.name = "Marvell 88E6095/88E6095F",
 		.num_databases = 256,
 		.num_ports = 11,
+		.flags = MV88E6XXX_FLAG_PPU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
 		.family = MV88E6XXX_FAMILY_6097,
 		.name = "Marvell 88E6085",
 		.num_databases = 4096,
 		.num_ports = 10,
+		.flags = MV88E6XXX_FLAG_PPU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
 		.family = MV88E6XXX_FAMILY_6185,
 		.name = "Marvell 88E6131",
 		.num_databases = 256,
 		.num_ports = 8,
+		.flags = MV88E6XXX_FLAG_PPU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
 		.family = MV88E6XXX_FAMILY_6185,
 		.name = "Marvell 88E6185",
 		.num_databases = 256,
 		.num_ports = 10,
+		.flags = MV88E6XXX_FLAG_PPU,
 	}
 };
 
@@ -128,8 +132,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
 	if (ret < 0)
 		return ret;
 
-	mv88e6xxx_ppu_state_init(ps);
-
 	ret = mv88e6xxx_switch_reset(ps, false);
 	if (ret < 0)
 		return ret;
@@ -141,46 +143,13 @@ static int mv88e6131_setup(struct dsa_switch *ds)
 	return mv88e6xxx_setup_ports(ds);
 }
 
-static int mv88e6131_port_to_phy_addr(struct dsa_switch *ds, int port)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-
-	if (port >= 0 && port < ps->info->num_ports)
-		return port;
-
-	return -EINVAL;
-}
-
-static int
-mv88e6131_phy_read(struct dsa_switch *ds, int port, int regnum)
-{
-	int addr = mv88e6131_port_to_phy_addr(ds, port);
-
-	if (addr < 0)
-		return addr;
-
-	return mv88e6xxx_phy_read_ppu(ds, addr, regnum);
-}
-
-static int
-mv88e6131_phy_write(struct dsa_switch *ds,
-			      int port, int regnum, u16 val)
-{
-	int addr = mv88e6131_port_to_phy_addr(ds, port);
-
-	if (addr < 0)
-		return addr;
-
-	return mv88e6xxx_phy_write_ppu(ds, addr, regnum, val);
-}
-
 struct dsa_switch_driver mv88e6131_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_DSA,
 	.probe			= mv88e6131_drv_probe,
 	.setup			= mv88e6131_setup,
 	.set_addr		= mv88e6xxx_set_addr_direct,
-	.phy_read		= mv88e6131_phy_read,
-	.phy_write		= mv88e6131_phy_write,
+	.phy_read		= mv88e6xxx_phy_read,
+	.phy_write		= mv88e6xxx_phy_write,
 	.get_strings		= mv88e6xxx_get_strings,
 	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
 	.get_sset_count		= mv88e6xxx_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 470cfc7..4e031aa 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -241,60 +241,39 @@ static int _mv88e6xxx_phy_write(struct mv88e6xxx_priv_state *ps, int addr,
 	return 0;
 }
 
-#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
-static int mv88e6xxx_ppu_disable(struct mv88e6xxx_priv_state *ps)
+static int _mv88e6xxx_ppu_enable(struct mv88e6xxx_priv_state *ps, bool enable)
 {
-	int ret;
 	unsigned long timeout;
+	int ret;
 
-	ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_CONTROL);
+	ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_CONTROL);
 	if (ret < 0)
 		return ret;
 
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
-				  ret & ~GLOBAL_CONTROL_PPU_ENABLE);
-	if (ret)
-		return ret;
-
-	timeout = jiffies + 1 * HZ;
-	while (time_before(jiffies, timeout)) {
-		ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATUS);
-		if (ret < 0)
-			return ret;
-
-		usleep_range(1000, 2000);
-		if ((ret & GLOBAL_STATUS_PPU_MASK) !=
-		    GLOBAL_STATUS_PPU_POLLING)
-			return 0;
-	}
-
-	return -ETIMEDOUT;
-}
-
-static int mv88e6xxx_ppu_enable(struct mv88e6xxx_priv_state *ps)
-{
-	int ret, err;
-	unsigned long timeout;
+	if (enable)
+		ret |= GLOBAL_CONTROL_PPU_ENABLE;
+	else
+		ret &= ~GLOBAL_CONTROL_PPU_ENABLE;
 
-	ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_CONTROL);
+	ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, ret);
 	if (ret < 0)
 		return ret;
 
-	err = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
-				  ret | GLOBAL_CONTROL_PPU_ENABLE);
-	if (err)
-		return err;
-
 	timeout = jiffies + 1 * HZ;
 	while (time_before(jiffies, timeout)) {
-		ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATUS);
+		ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATUS);
 		if (ret < 0)
 			return ret;
 
 		usleep_range(1000, 2000);
-		if ((ret & GLOBAL_STATUS_PPU_MASK) ==
-		    GLOBAL_STATUS_PPU_POLLING)
+
+		ret &= GLOBAL_STATUS_PPU_MASK;
+
+		if ((enable && ret == GLOBAL_STATUS_PPU_POLLING) ||
+		    (!enable && ret != GLOBAL_STATUS_PPU_POLLING)) {
+			ps->ppu_disabled = !enable;
 			return 0;
+		}
 	}
 
 	return -ETIMEDOUT;
@@ -305,9 +284,12 @@ static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
 	struct mv88e6xxx_priv_state *ps;
 
 	ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work);
+
 	if (mutex_trylock(&ps->ppu_mutex)) {
-		if (mv88e6xxx_ppu_enable(ps) == 0)
-			ps->ppu_disabled = 0;
+		mutex_lock(&ps->smi_mutex);
+		_mv88e6xxx_ppu_enable(ps, true);
+		mutex_unlock(&ps->smi_mutex);
+
 		mutex_unlock(&ps->ppu_mutex);
 	}
 }
@@ -319,9 +301,9 @@ static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
 	schedule_work(&ps->ppu_work);
 }
 
-static int mv88e6xxx_ppu_access_get(struct mv88e6xxx_priv_state *ps)
+static int _mv88e6xxx_ppu_access_get(struct mv88e6xxx_priv_state *ps)
 {
-	int ret;
+	int err;
 
 	mutex_lock(&ps->ppu_mutex);
 
@@ -330,29 +312,27 @@ static int mv88e6xxx_ppu_access_get(struct mv88e6xxx_priv_state *ps)
 	 * disabled, cancel the timer that is going to re-enable
 	 * it.
 	 */
-	if (!ps->ppu_disabled) {
-		ret = mv88e6xxx_ppu_disable(ps);
-		if (ret < 0) {
+	if (ps->ppu_disabled) {
+		del_timer(&ps->ppu_timer);
+	} else {
+		err = _mv88e6xxx_ppu_enable(ps, false);
+		if (err) {
 			mutex_unlock(&ps->ppu_mutex);
-			return ret;
+			return err;
 		}
-		ps->ppu_disabled = 1;
-	} else {
-		del_timer(&ps->ppu_timer);
-		ret = 0;
 	}
 
-	return ret;
+	return 0;
 }
 
-static void mv88e6xxx_ppu_access_put(struct mv88e6xxx_priv_state *ps)
+static void _mv88e6xxx_ppu_access_put(struct mv88e6xxx_priv_state *ps)
 {
 	/* Schedule a timer to re-enable the PHY polling unit. */
 	mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10));
 	mutex_unlock(&ps->ppu_mutex);
 }
 
-void mv88e6xxx_ppu_state_init(struct mv88e6xxx_priv_state *ps)
+static void mv88e6xxx_ppu_state_init(struct mv88e6xxx_priv_state *ps)
 {
 	mutex_init(&ps->ppu_mutex);
 	INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work);
@@ -361,35 +341,33 @@ void mv88e6xxx_ppu_state_init(struct mv88e6xxx_priv_state *ps)
 	ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer;
 }
 
-int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum)
+static int _mv88e6xxx_phy_read_ppu(struct mv88e6xxx_priv_state *ps, int addr,
+				   int regnum)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
-	ret = mv88e6xxx_ppu_access_get(ps);
+	ret = _mv88e6xxx_ppu_access_get(ps);
 	if (ret >= 0) {
-		ret = mv88e6xxx_reg_read(ps, addr, regnum);
-		mv88e6xxx_ppu_access_put(ps);
+		ret = _mv88e6xxx_reg_read(ps, addr, regnum);
+		_mv88e6xxx_ppu_access_put(ps);
 	}
 
 	return ret;
 }
 
-int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
-			    int regnum, u16 val)
+static int _mv88e6xxx_phy_write_ppu(struct mv88e6xxx_priv_state *ps, int addr,
+				    int regnum, u16 val)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
-	ret = mv88e6xxx_ppu_access_get(ps);
+	ret = _mv88e6xxx_ppu_access_get(ps);
 	if (ret >= 0) {
-		ret = mv88e6xxx_reg_write(ps, addr, regnum, val);
-		mv88e6xxx_ppu_access_put(ps);
+		ret = _mv88e6xxx_reg_write(ps, addr, regnum, val);
+		_mv88e6xxx_ppu_access_put(ps);
 	}
 
 	return ret;
 }
-#endif
 
 static bool mv88e6xxx_6065_family(struct mv88e6xxx_priv_state *ps)
 {
@@ -2599,6 +2577,9 @@ int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps)
 
 	INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
 
+	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
+		mv88e6xxx_ppu_state_init(ps);
+
 	return 0;
 }
 
@@ -2884,8 +2865,14 @@ mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
 		return 0xffff;
 
 	mutex_lock(&ps->smi_mutex);
-	ret = _mv88e6xxx_phy_read(ps, addr, regnum);
+
+	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
+		ret = _mv88e6xxx_phy_read_ppu(ps, addr, regnum);
+	else
+		ret = _mv88e6xxx_phy_read(ps, addr, regnum);
+
 	mutex_unlock(&ps->smi_mutex);
+
 	return ret;
 }
 
@@ -2894,15 +2881,22 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int addr = mv88e6xxx_port_to_phy_addr(ps, port);
-	int ret;
+	int err;
 
 	if (addr < 0)
 		return 0xffff;
 
+
 	mutex_lock(&ps->smi_mutex);
-	ret = _mv88e6xxx_phy_write(ps, addr, regnum, val);
+
+	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
+		err = _mv88e6xxx_phy_write_ppu(ps, addr, regnum, val);
+	else
+		err = _mv88e6xxx_phy_write(ps, addr, regnum, val);
+
 	mutex_unlock(&ps->smi_mutex);
-	return ret;
+
+	return err;
 }
 
 int
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 4f455d2..3e77985 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -350,12 +350,23 @@ enum mv88e6xxx_family {
 	MV88E6XXX_FAMILY_6352,	/* 6172 6176 6240 6352 */
 };
 
+enum mv88e6xxx_cap {
+	/* PHY Polling Unit.
+	 * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING.
+	 */
+	MV88E6XXX_CAP_PPU,
+};
+
+/* Bitmask of capabilities */
+#define MV88E6XXX_FLAG_PPU		BIT(MV88E6XXX_CAP_PPU)
+
 struct mv88e6xxx_info {
 	enum mv88e6xxx_family family;
 	u16 prod_num;
 	const char *name;
 	unsigned int num_databases;
 	unsigned int num_ports;
+	unsigned long flags;
 };
 
 struct mv88e6xxx_atu_entry {
@@ -403,15 +414,13 @@ struct mv88e6xxx_priv_state {
 	struct mii_bus *bus;
 	int sw_addr;
 
-#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
 	/* Handles automatic disabling and re-enabling of the PHY
 	 * polling unit.
 	 */
 	struct mutex		ppu_mutex;
-	int			ppu_disabled;
+	bool			ppu_disabled;
 	struct work_struct	ppu_work;
 	struct timer_list	ppu_timer;
-#endif
 
 	/* This mutex serialises access to the statistics unit.
 	 * Hold this mutex over snapshot + dump sequences.
@@ -449,6 +458,12 @@ struct mv88e6xxx_hw_stat {
 	enum stat_type type;
 };
 
+static inline bool mv88e6xxx_has(struct mv88e6xxx_priv_state *ps,
+				 unsigned long flags)
+{
+	return (ps->info->flags & flags) == flags;
+}
+
 int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps, bool ppu_active);
 const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
 				int sw_addr, void **priv,
@@ -468,10 +483,6 @@ int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val);
 int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum);
 int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
 				 u16 val);
-void mv88e6xxx_ppu_state_init(struct mv88e6xxx_priv_state *ps);
-int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum);
-int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
-			    int regnum, u16 val);
 void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
 void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
 				 uint64_t *data);
-- 
2.8.2

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

* [RFC PATCH net-next 02/20] net: dsa: mv88e6xxx: factorize PHY indirect access
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 01/20] net: dsa: mv88e6xxx: factorize PHY access with PPU Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 03/20] net: dsa: mv88e6xxx: factorize EEPROM access Vivien Didelot
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Some switch has dedicated SMI PHY Command and Data registers, used to
indirectly access the PHYs, instead of direct access.

Identify these switch models and make mv88e6xxx_phy_{read,write} generic
enough to support every models.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6171.c |  8 ++++++--
 drivers/net/dsa/mv88e6352.c | 10 ++++++++--
 drivers/net/dsa/mv88e6xxx.c | 37 ++++---------------------------------
 drivers/net/dsa/mv88e6xxx.h | 10 +++++++---
 4 files changed, 25 insertions(+), 40 deletions(-)

diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index f75164d..304e25e 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -24,24 +24,28 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.name = "Marvell 88E6171",
 		.num_databases = 4096,
 		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
 		.family = MV88E6XXX_FAMILY_6351,
 		.name = "Marvell 88E6175",
 		.num_databases = 4096,
 		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
 		.family = MV88E6XXX_FAMILY_6351,
 		.name = "Marvell 88E6350",
 		.num_databases = 4096,
 		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
 		.family = MV88E6XXX_FAMILY_6351,
 		.name = "Marvell 88E6351",
 		.num_databases = 4096,
 		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_SMI_PHY,
 	}
 };
 
@@ -120,8 +124,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
 	.probe			= mv88e6171_drv_probe,
 	.setup			= mv88e6171_setup,
 	.set_addr		= mv88e6xxx_set_addr_indirect,
-	.phy_read		= mv88e6xxx_phy_read_indirect,
-	.phy_write		= mv88e6xxx_phy_write_indirect,
+	.phy_read		= mv88e6xxx_phy_read,
+	.phy_write		= mv88e6xxx_phy_write,
 	.get_strings		= mv88e6xxx_get_strings,
 	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
 	.get_sset_count		= mv88e6xxx_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index c622a1d..df9f944 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -29,36 +29,42 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6320",
 		.num_databases = 4096,
 		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
 		.family = MV88E6XXX_FAMILY_6320,
 		.name = "Marvell 88E6321",
 		.num_databases = 4096,
 		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
 		.family = MV88E6XXX_FAMILY_6352,
 		.name = "Marvell 88E6172",
 		.num_databases = 4096,
 		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
 		.family = MV88E6XXX_FAMILY_6352,
 		.name = "Marvell 88E6176",
 		.num_databases = 4096,
 		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
 		.family = MV88E6XXX_FAMILY_6352,
 		.name = "Marvell 88E6240",
 		.num_databases = 4096,
 		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
 		.family = MV88E6XXX_FAMILY_6352,
 		.name = "Marvell 88E6352",
 		.num_databases = 4096,
 		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_SMI_PHY,
 	}
 };
 
@@ -338,8 +344,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
 	.probe			= mv88e6352_drv_probe,
 	.setup			= mv88e6352_setup,
 	.set_addr		= mv88e6xxx_set_addr_indirect,
-	.phy_read		= mv88e6xxx_phy_read_indirect,
-	.phy_write		= mv88e6xxx_phy_write_indirect,
+	.phy_read		= mv88e6xxx_phy_read,
+	.phy_write		= mv88e6xxx_phy_write,
 	.get_strings		= mv88e6xxx_get_strings,
 	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
 	.get_sset_count		= mv88e6xxx_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 4e031aa..e48271c 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2868,6 +2868,8 @@ mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
 
 	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
 		ret = _mv88e6xxx_phy_read_ppu(ps, addr, regnum);
+	else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY))
+		ret = _mv88e6xxx_phy_read_indirect(ps, addr, regnum);
 	else
 		ret = _mv88e6xxx_phy_read(ps, addr, regnum);
 
@@ -2891,6 +2893,8 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
 
 	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
 		err = _mv88e6xxx_phy_write_ppu(ps, addr, regnum, val);
+	else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY))
+		err = _mv88e6xxx_phy_write_indirect(ps, addr, regnum, val);
 	else
 		err = _mv88e6xxx_phy_write(ps, addr, regnum, val);
 
@@ -2899,39 +2903,6 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
 	return err;
 }
 
-int
-mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int addr = mv88e6xxx_port_to_phy_addr(ps, port);
-	int ret;
-
-	if (addr < 0)
-		return 0xffff;
-
-	mutex_lock(&ps->smi_mutex);
-	ret = _mv88e6xxx_phy_read_indirect(ps, addr, regnum);
-	mutex_unlock(&ps->smi_mutex);
-	return ret;
-}
-
-int
-mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
-			     u16 val)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int addr = mv88e6xxx_port_to_phy_addr(ps, port);
-	int ret;
-
-	if (addr < 0)
-		return addr;
-
-	mutex_lock(&ps->smi_mutex);
-	ret = _mv88e6xxx_phy_write_indirect(ps, addr, regnum, val);
-	mutex_unlock(&ps->smi_mutex);
-	return ret;
-}
-
 #ifdef CONFIG_NET_DSA_HWMON
 
 static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 3e77985..95cbb8b 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -355,10 +355,17 @@ enum mv88e6xxx_cap {
 	 * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING.
 	 */
 	MV88E6XXX_CAP_PPU,
+
+	/* SMI PHY Command and Data registers.
+	 * This requires an indirect access to PHY registers through
+	 * GLOBAL2_SMI_OP, otherwise direct access to PHY registers is done.
+	 */
+	MV88E6XXX_CAP_SMI_PHY,
 };
 
 /* Bitmask of capabilities */
 #define MV88E6XXX_FLAG_PPU		BIT(MV88E6XXX_CAP_PPU)
+#define MV88E6XXX_FLAG_SMI_PHY		BIT(MV88E6XXX_CAP_SMI_PHY)
 
 struct mv88e6xxx_info {
 	enum mv88e6xxx_family family;
@@ -480,9 +487,6 @@ int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr);
 int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr);
 int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum);
 int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val);
-int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum);
-int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
-				 u16 val);
 void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
 void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
 				 uint64_t *data);
-- 
2.8.2

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

* [RFC PATCH net-next 03/20] net: dsa: mv88e6xxx: factorize EEPROM access
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 01/20] net: dsa: mv88e6xxx: factorize PHY access with PPU Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 02/20] net: dsa: mv88e6xxx: factorize PHY indirect access Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 04/20] net: dsa: mv88e6xxx: factorize temperature access Vivien Didelot
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Add a MV88E6XXX_FLAG_EEPROM flag to describe switch models featuring an
EEPROM and distribute the EEPROM access routines to all models.

In the meantime, change the static functions to use a
mv88e6xxx_priv_state instead of a dsa_switch.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |   2 +
 drivers/net/dsa/mv88e6131.c |   2 +
 drivers/net/dsa/mv88e6171.c |   2 +
 drivers/net/dsa/mv88e6352.c | 225 +++-------------------------------------
 drivers/net/dsa/mv88e6xxx.c | 248 +++++++++++++++++++++++++++++++++++++++++---
 drivers/net/dsa/mv88e6xxx.h |  12 ++-
 6 files changed, 264 insertions(+), 227 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 5535a42..1fc8f0d 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -121,6 +121,8 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
 #ifdef CONFIG_NET_DSA_HWMON
 	.get_temp		= mv88e6xxx_get_temp,
 #endif
+	.get_eeprom		= mv88e6xxx_get_eeprom,
+	.set_eeprom		= mv88e6xxx_set_eeprom,
 	.get_regs_len		= mv88e6xxx_get_regs_len,
 	.get_regs		= mv88e6xxx_get_regs,
 };
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 437faf8..3796f6d 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -153,6 +153,8 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
 	.get_strings		= mv88e6xxx_get_strings,
 	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
 	.get_sset_count		= mv88e6xxx_get_sset_count,
+	.get_eeprom		= mv88e6xxx_get_eeprom,
+	.set_eeprom		= mv88e6xxx_set_eeprom,
 	.adjust_link		= mv88e6xxx_adjust_link,
 	.port_bridge_join	= mv88e6xxx_port_bridge_join,
 	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 304e25e..b8b6902 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -133,6 +133,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
 #ifdef CONFIG_NET_DSA_HWMON
 	.get_temp               = mv88e6xxx_get_temp,
 #endif
+	.get_eeprom		= mv88e6xxx_get_eeprom,
+	.set_eeprom		= mv88e6xxx_set_eeprom,
 	.get_regs_len		= mv88e6xxx_get_regs_len,
 	.get_regs		= mv88e6xxx_get_regs,
 	.port_bridge_join	= mv88e6xxx_port_bridge_join,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index df9f944..e6437de 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -29,42 +29,48 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6320",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY,
+		.flags = MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
 		.family = MV88E6XXX_FAMILY_6320,
 		.name = "Marvell 88E6321",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY,
+		.flags = MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
 		.family = MV88E6XXX_FAMILY_6352,
 		.name = "Marvell 88E6172",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY,
+		.flags = MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
 		.family = MV88E6XXX_FAMILY_6352,
 		.name = "Marvell 88E6176",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY,
+		.flags = MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
 		.family = MV88E6XXX_FAMILY_6352,
 		.name = "Marvell 88E6240",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY,
+		.flags = MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_SMI_PHY,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
 		.family = MV88E6XXX_FAMILY_6352,
 		.name = "Marvell 88E6352",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY,
+		.flags = MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_SMI_PHY,
 	}
 };
 
@@ -125,8 +131,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
 	if (ret < 0)
 		return ret;
 
-	mutex_init(&ps->eeprom_mutex);
-
 	ret = mv88e6xxx_switch_reset(ps, true);
 	if (ret < 0)
 		return ret;
@@ -138,207 +142,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
 	return mv88e6xxx_setup_ports(ds);
 }
 
-static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int ret;
-
-	mutex_lock(&ps->eeprom_mutex);
-
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
-				  GLOBAL2_EEPROM_OP_READ |
-				  (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
-	if (ret < 0)
-		goto error;
-
-	ret = mv88e6xxx_eeprom_busy_wait(ds);
-	if (ret < 0)
-		goto error;
-
-	ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA);
-error:
-	mutex_unlock(&ps->eeprom_mutex);
-	return ret;
-}
-
-static int mv88e6352_get_eeprom(struct dsa_switch *ds,
-				struct ethtool_eeprom *eeprom, u8 *data)
-{
-	int offset;
-	int len;
-	int ret;
-
-	offset = eeprom->offset;
-	len = eeprom->len;
-	eeprom->len = 0;
-
-	eeprom->magic = 0xc3ec4951;
-
-	ret = mv88e6xxx_eeprom_load_wait(ds);
-	if (ret < 0)
-		return ret;
-
-	if (offset & 1) {
-		int word;
-
-		word = mv88e6352_read_eeprom_word(ds, offset >> 1);
-		if (word < 0)
-			return word;
-
-		*data++ = (word >> 8) & 0xff;
-
-		offset++;
-		len--;
-		eeprom->len++;
-	}
-
-	while (len >= 2) {
-		int word;
-
-		word = mv88e6352_read_eeprom_word(ds, offset >> 1);
-		if (word < 0)
-			return word;
-
-		*data++ = word & 0xff;
-		*data++ = (word >> 8) & 0xff;
-
-		offset += 2;
-		len -= 2;
-		eeprom->len += 2;
-	}
-
-	if (len) {
-		int word;
-
-		word = mv88e6352_read_eeprom_word(ds, offset >> 1);
-		if (word < 0)
-			return word;
-
-		*data++ = word & 0xff;
-
-		offset++;
-		len--;
-		eeprom->len++;
-	}
-
-	return 0;
-}
-
-static int mv88e6352_eeprom_is_readonly(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int ret;
-
-	ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP);
-	if (ret < 0)
-		return ret;
-
-	if (!(ret & GLOBAL2_EEPROM_OP_WRITE_EN))
-		return -EROFS;
-
-	return 0;
-}
-
-static int mv88e6352_write_eeprom_word(struct dsa_switch *ds, int addr,
-				       u16 data)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int ret;
-
-	mutex_lock(&ps->eeprom_mutex);
-
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data);
-	if (ret < 0)
-		goto error;
-
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
-				  GLOBAL2_EEPROM_OP_WRITE |
-				  (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
-	if (ret < 0)
-		goto error;
-
-	ret = mv88e6xxx_eeprom_busy_wait(ds);
-error:
-	mutex_unlock(&ps->eeprom_mutex);
-	return ret;
-}
-
-static int mv88e6352_set_eeprom(struct dsa_switch *ds,
-				struct ethtool_eeprom *eeprom, u8 *data)
-{
-	int offset;
-	int ret;
-	int len;
-
-	if (eeprom->magic != 0xc3ec4951)
-		return -EINVAL;
-
-	ret = mv88e6352_eeprom_is_readonly(ds);
-	if (ret)
-		return ret;
-
-	offset = eeprom->offset;
-	len = eeprom->len;
-	eeprom->len = 0;
-
-	ret = mv88e6xxx_eeprom_load_wait(ds);
-	if (ret < 0)
-		return ret;
-
-	if (offset & 1) {
-		int word;
-
-		word = mv88e6352_read_eeprom_word(ds, offset >> 1);
-		if (word < 0)
-			return word;
-
-		word = (*data++ << 8) | (word & 0xff);
-
-		ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
-		if (ret < 0)
-			return ret;
-
-		offset++;
-		len--;
-		eeprom->len++;
-	}
-
-	while (len >= 2) {
-		int word;
-
-		word = *data++;
-		word |= *data++ << 8;
-
-		ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
-		if (ret < 0)
-			return ret;
-
-		offset += 2;
-		len -= 2;
-		eeprom->len += 2;
-	}
-
-	if (len) {
-		int word;
-
-		word = mv88e6352_read_eeprom_word(ds, offset >> 1);
-		if (word < 0)
-			return word;
-
-		word = (word & 0xff00) | *data++;
-
-		ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
-		if (ret < 0)
-			return ret;
-
-		offset++;
-		len--;
-		eeprom->len++;
-	}
-
-	return 0;
-}
-
 struct dsa_switch_driver mv88e6352_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
 	.probe			= mv88e6352_drv_probe,
@@ -358,8 +161,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
 	.set_temp_limit		= mv88e6xxx_set_temp_limit,
 	.get_temp_alarm		= mv88e6xxx_get_temp_alarm,
 #endif
-	.get_eeprom		= mv88e6352_get_eeprom,
-	.set_eeprom		= mv88e6352_set_eeprom,
+	.get_eeprom		= mv88e6xxx_get_eeprom,
+	.set_eeprom		= mv88e6xxx_set_eeprom,
 	.get_regs_len		= mv88e6xxx_get_regs_len,
 	.get_regs		= mv88e6xxx_get_regs,
 	.port_bridge_join	= mv88e6xxx_port_bridge_join,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index e48271c..233c265 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -786,38 +786,255 @@ static int _mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg, int offset,
 	return -ETIMEDOUT;
 }
 
-static int mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg,
-			  int offset, u16 mask)
+static int _mv88e6xxx_phy_wait(struct mv88e6xxx_priv_state *ps)
+{
+	return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_SMI_OP,
+			       GLOBAL2_SMI_OP_BUSY);
+}
+
+static int _mv88e6xxx_eeprom_load_wait(struct mv88e6xxx_priv_state *ps)
+{
+	return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
+			       GLOBAL2_EEPROM_OP_LOAD);
+}
+
+static int _mv88e6xxx_eeprom_busy_wait(struct mv88e6xxx_priv_state *ps)
+{
+	return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
+			       GLOBAL2_EEPROM_OP_BUSY);
+}
+
+static int _mv88e6xxx_read_eeprom_word(struct mv88e6xxx_priv_state *ps,
+				       int addr)
 {
 	int ret;
 
-	mutex_lock(&ps->smi_mutex);
-	ret = _mv88e6xxx_wait(ps, reg, offset, mask);
-	mutex_unlock(&ps->smi_mutex);
+	mutex_lock(&ps->eeprom_mutex);
+
+	ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
+				  GLOBAL2_EEPROM_OP_READ |
+				  (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
+	if (ret)
+		goto unlock;
+
+	ret = _mv88e6xxx_eeprom_busy_wait(ps);
+	if (ret)
+		goto unlock;
+
+	ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA);
+unlock:
+	mutex_unlock(&ps->eeprom_mutex);
 
 	return ret;
 }
 
-static int _mv88e6xxx_phy_wait(struct mv88e6xxx_priv_state *ps)
+static int _mv88e6xxx_get_eeprom(struct mv88e6xxx_priv_state *ps,
+				 struct ethtool_eeprom *eeprom, u8 *data)
 {
-	return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_SMI_OP,
-			       GLOBAL2_SMI_OP_BUSY);
+	int offset;
+	int len;
+	int ret;
+
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
+		return -EOPNOTSUPP;
+
+	offset = eeprom->offset;
+	len = eeprom->len;
+	eeprom->len = 0;
+
+	eeprom->magic = 0xc3ec4951;
+
+	ret = _mv88e6xxx_eeprom_load_wait(ps);
+	if (ret < 0)
+		return ret;
+
+	if (offset & 1) {
+		int word;
+
+		word = _mv88e6xxx_read_eeprom_word(ps, offset >> 1);
+		if (word < 0)
+			return word;
+
+		*data++ = (word >> 8) & 0xff;
+
+		offset++;
+		len--;
+		eeprom->len++;
+	}
+
+	while (len >= 2) {
+		int word;
+
+		word = _mv88e6xxx_read_eeprom_word(ps, offset >> 1);
+		if (word < 0)
+			return word;
+
+		*data++ = word & 0xff;
+		*data++ = (word >> 8) & 0xff;
+
+		offset += 2;
+		len -= 2;
+		eeprom->len += 2;
+	}
+
+	if (len) {
+		int word;
+
+		word = _mv88e6xxx_read_eeprom_word(ps, offset >> 1);
+		if (word < 0)
+			return word;
+
+		*data++ = word & 0xff;
+
+		offset++;
+		len--;
+		eeprom->len++;
+	}
+
+	return 0;
 }
 
-int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds)
+int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
+			 u8 *data)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int err;
+
+	mutex_lock(&ps->smi_mutex);
+	err = _mv88e6xxx_get_eeprom(ps, eeprom, data);
+	mutex_unlock(&ps->smi_mutex);
+
+	return err;
+}
+
+static int _mv88e6xxx_eeprom_is_readonly(struct mv88e6xxx_priv_state *ps)
+{
+	int ret;
+
+	ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP);
+	if (ret < 0)
+		return ret;
 
-	return mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
-			      GLOBAL2_EEPROM_OP_LOAD);
+	if (!(ret & GLOBAL2_EEPROM_OP_WRITE_EN))
+		return -EROFS;
+
+	return 0;
+}
+
+static int _mv88e6xxx_write_eeprom_word(struct mv88e6xxx_priv_state *ps,
+					int addr, u16 data)
+{
+	int err;
+
+	mutex_lock(&ps->eeprom_mutex);
+
+	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data);
+	if (err)
+		goto unlock;
+
+	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
+				   GLOBAL2_EEPROM_OP_WRITE |
+				   (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
+	if (err)
+		goto unlock;
+
+	err = _mv88e6xxx_eeprom_busy_wait(ps);
+unlock:
+	mutex_unlock(&ps->eeprom_mutex);
+
+	return err;
 }
 
-int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds)
+static int _mv88e6xxx_set_eeprom(struct mv88e6xxx_priv_state *ps,
+				 struct ethtool_eeprom *eeprom, u8 *data)
+{
+	int offset;
+	int ret;
+	int len;
+
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
+		return -EOPNOTSUPP;
+
+	if (eeprom->magic != 0xc3ec4951)
+		return -EINVAL;
+
+	ret = _mv88e6xxx_eeprom_is_readonly(ps);
+	if (ret)
+		return ret;
+
+	offset = eeprom->offset;
+	len = eeprom->len;
+	eeprom->len = 0;
+
+	ret = _mv88e6xxx_eeprom_load_wait(ps);
+	if (ret < 0)
+		return ret;
+
+	if (offset & 1) {
+		int word;
+
+		word = _mv88e6xxx_read_eeprom_word(ps, offset >> 1);
+		if (word < 0)
+			return word;
+
+		word = (*data++ << 8) | (word & 0xff);
+
+		ret = _mv88e6xxx_write_eeprom_word(ps, offset >> 1, word);
+		if (ret < 0)
+			return ret;
+
+		offset++;
+		len--;
+		eeprom->len++;
+	}
+
+	while (len >= 2) {
+		int word;
+
+		word = *data++;
+		word |= *data++ << 8;
+
+		ret = _mv88e6xxx_write_eeprom_word(ps, offset >> 1, word);
+		if (ret < 0)
+			return ret;
+
+		offset += 2;
+		len -= 2;
+		eeprom->len += 2;
+	}
+
+	if (len) {
+		int word;
+
+		word = _mv88e6xxx_read_eeprom_word(ps, offset >> 1);
+		if (word < 0)
+			return word;
+
+		word = (word & 0xff00) | *data++;
+
+		ret = _mv88e6xxx_write_eeprom_word(ps, offset >> 1, word);
+		if (ret < 0)
+			return ret;
+
+		offset++;
+		len--;
+		eeprom->len++;
+	}
+
+	return 0;
+}
+
+int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
+			 u8 *data)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int err;
 
-	return mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
-			      GLOBAL2_EEPROM_OP_BUSY);
+	mutex_lock(&ps->smi_mutex);
+	err = _mv88e6xxx_set_eeprom(ps, eeprom, data);
+	mutex_unlock(&ps->smi_mutex);
+
+	return err;
 }
 
 static int _mv88e6xxx_atu_wait(struct mv88e6xxx_priv_state *ps)
@@ -2577,6 +2794,9 @@ int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps)
 
 	INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
 
+	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
+		mutex_init(&ps->eeprom_mutex);
+
 	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
 		mv88e6xxx_ppu_state_init(ps);
 
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 95cbb8b..08cb5c4 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -351,6 +351,11 @@ enum mv88e6xxx_family {
 };
 
 enum mv88e6xxx_cap {
+	/* EEPROM Command and Data registers.
+	 * See GLOBAL2_EEPROM_OP and GLOBAL2_EEPROM_DATA.
+	 */
+	MV88E6XXX_CAP_EEPROM,
+
 	/* PHY Polling Unit.
 	 * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING.
 	 */
@@ -364,6 +369,7 @@ enum mv88e6xxx_cap {
 };
 
 /* Bitmask of capabilities */
+#define MV88E6XXX_FLAG_EEPROM		BIT(MV88E6XXX_CAP_EEPROM)
 #define MV88E6XXX_FLAG_PPU		BIT(MV88E6XXX_CAP_PPU)
 #define MV88E6XXX_FLAG_SMI_PHY		BIT(MV88E6XXX_CAP_SMI_PHY)
 
@@ -501,8 +507,10 @@ int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp);
 int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp);
 int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp);
 int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm);
-int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds);
-int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds);
+int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
+			 u8 *data);
+int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
+			 u8 *data);
 int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum);
 int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
 				 u16 val);
-- 
2.8.2

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

* [RFC PATCH net-next 04/20] net: dsa: mv88e6xxx: factorize temperature access
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (2 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 03/20] net: dsa: mv88e6xxx: factorize EEPROM access Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 23:40   ` Andrew Lunn
  2016-05-05 22:40 ` [RFC PATCH net-next 05/20] net: dsa: mv88e6xxx: factorize MAC address setting Vivien Didelot
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Add MV88E6XXX_FLAG_TEMP and MV88E6XXX_FLAG_TEMP_LIMIT flags to describe
switch models featuring a temperature access. Use them to centralize the
access to the temperature feature.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |  6 ++++++
 drivers/net/dsa/mv88e6131.c |  6 ++++++
 drivers/net/dsa/mv88e6171.c | 17 ++++++++++++-----
 drivers/net/dsa/mv88e6352.c | 24 ++++++++++++++++++------
 drivers/net/dsa/mv88e6xxx.c | 32 +++++++++++++++++++-------------
 drivers/net/dsa/mv88e6xxx.h |  8 ++++++++
 6 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 1fc8f0d..6f4f719 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -24,18 +24,21 @@ static const struct mv88e6xxx_info mv88e6123_table[] = {
 		.name = "Marvell 88E6123",
 		.num_databases = 4096,
 		.num_ports = 3,
+		.flags = MV88E6XXX_FLAG_TEMP,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
 		.family = MV88E6XXX_FAMILY_6165,
 		.name = "Marvell 88E6161",
 		.num_databases = 4096,
 		.num_ports = 6,
+		.flags = MV88E6XXX_FLAG_TEMP,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
 		.family = MV88E6XXX_FAMILY_6165,
 		.name = "Marvell 88E6165",
 		.num_databases = 4096,
 		.num_ports = 6,
+		.flags = MV88E6XXX_FLAG_TEMP,
 	}
 };
 
@@ -120,6 +123,9 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
 	.adjust_link		= mv88e6xxx_adjust_link,
 #ifdef CONFIG_NET_DSA_HWMON
 	.get_temp		= mv88e6xxx_get_temp,
+	.get_temp_limit		= mv88e6xxx_get_temp_limit,
+	.set_temp_limit		= mv88e6xxx_set_temp_limit,
+	.get_temp_alarm		= mv88e6xxx_get_temp_alarm,
 #endif
 	.get_eeprom		= mv88e6xxx_get_eeprom,
 	.set_eeprom		= mv88e6xxx_set_eeprom,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 3796f6d..e8eb9a6 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -155,6 +155,12 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
 	.get_sset_count		= mv88e6xxx_get_sset_count,
 	.get_eeprom		= mv88e6xxx_get_eeprom,
 	.set_eeprom		= mv88e6xxx_set_eeprom,
+#ifdef CONFIG_NET_DSA_HWMON
+	.get_temp		= mv88e6xxx_get_temp,
+	.get_temp_limit		= mv88e6xxx_get_temp_limit,
+	.set_temp_limit		= mv88e6xxx_set_temp_limit,
+	.get_temp_alarm		= mv88e6xxx_get_temp_alarm,
+#endif
 	.adjust_link		= mv88e6xxx_adjust_link,
 	.port_bridge_join	= mv88e6xxx_port_bridge_join,
 	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index b8b6902..bd2082e 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -24,28 +24,32 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.name = "Marvell 88E6171",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY,
+		.flags = MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_TEMP,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
 		.family = MV88E6XXX_FAMILY_6351,
 		.name = "Marvell 88E6175",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY,
+		.flags = MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_TEMP,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
 		.family = MV88E6XXX_FAMILY_6351,
 		.name = "Marvell 88E6350",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY,
+		.flags = MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_TEMP,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
 		.family = MV88E6XXX_FAMILY_6351,
 		.name = "Marvell 88E6351",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY,
+		.flags = MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_TEMP,
 	}
 };
 
@@ -131,7 +135,10 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
 	.get_sset_count		= mv88e6xxx_get_sset_count,
 	.adjust_link		= mv88e6xxx_adjust_link,
 #ifdef CONFIG_NET_DSA_HWMON
-	.get_temp               = mv88e6xxx_get_temp,
+	.get_temp		= mv88e6xxx_get_temp,
+	.get_temp_limit		= mv88e6xxx_get_temp_limit,
+	.set_temp_limit		= mv88e6xxx_set_temp_limit,
+	.get_temp_alarm		= mv88e6xxx_get_temp_alarm,
 #endif
 	.get_eeprom		= mv88e6xxx_get_eeprom,
 	.set_eeprom		= mv88e6xxx_set_eeprom,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index e6437de..f588e2f 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -30,7 +30,9 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_databases = 4096,
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_SMI_PHY,
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
 		.family = MV88E6XXX_FAMILY_6320,
@@ -38,7 +40,9 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_databases = 4096,
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_SMI_PHY,
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -46,7 +50,9 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_databases = 4096,
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_SMI_PHY,
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -54,7 +60,9 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_databases = 4096,
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_SMI_PHY,
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -62,7 +70,9 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_databases = 4096,
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_SMI_PHY,
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -70,7 +80,9 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_databases = 4096,
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_SMI_PHY,
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}
 };
 
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 233c265..5f7851e 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -3125,16 +3125,13 @@ mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
 
 #ifdef CONFIG_NET_DSA_HWMON
 
-static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
+static int _mv88e61xx_get_temp(struct mv88e6xxx_priv_state *ps, int *temp)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 	int val;
 
 	*temp = 0;
 
-	mutex_lock(&ps->smi_mutex);
-
 	ret = _mv88e6xxx_phy_write(ps, 0x0, 0x16, 0x6);
 	if (ret < 0)
 		goto error;
@@ -3166,19 +3163,18 @@ static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
 
 error:
 	_mv88e6xxx_phy_write(ps, 0x0, 0x16, 0x0);
-	mutex_unlock(&ps->smi_mutex);
+
 	return ret;
 }
 
-static int mv88e63xx_get_temp(struct dsa_switch *ds, int *temp)
+static int _mv88e63xx_get_temp(struct mv88e6xxx_priv_state *ps, int *temp)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
 	int ret;
 
 	*temp = 0;
 
-	ret = mv88e6xxx_phy_page_read(ds, phy, 6, 27);
+	ret = _mv88e6xxx_phy_page_read(ps, phy, 6, 27);
 	if (ret < 0)
 		return ret;
 
@@ -3190,11 +3186,21 @@ static int mv88e63xx_get_temp(struct dsa_switch *ds, int *temp)
 int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int err;
+
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP))
+		return -EOPNOTSUPP;
+
+	mutex_lock(&ps->smi_mutex);
 
 	if (mv88e6xxx_6320_family(ps) || mv88e6xxx_6352_family(ps))
-		return mv88e63xx_get_temp(ds, temp);
+		err = _mv88e63xx_get_temp(ps, temp);
+	else
+		err = _mv88e61xx_get_temp(ps, temp);
 
-	return mv88e61xx_get_temp(ds, temp);
+	mutex_unlock(&ps->smi_mutex);
+
+	return err;
 }
 
 int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
@@ -3203,7 +3209,7 @@ int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
 	int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
 	int ret;
 
-	if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps))
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT))
 		return -EOPNOTSUPP;
 
 	*temp = 0;
@@ -3223,7 +3229,7 @@ int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
 	int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
 	int ret;
 
-	if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps))
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT))
 		return -EOPNOTSUPP;
 
 	ret = mv88e6xxx_phy_page_read(ds, phy, 6, 26);
@@ -3240,7 +3246,7 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
 	int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
 	int ret;
 
-	if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps))
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT))
 		return -EOPNOTSUPP;
 
 	*alarm = false;
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 08cb5c4..e7c2e45 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -366,12 +366,20 @@ enum mv88e6xxx_cap {
 	 * GLOBAL2_SMI_OP, otherwise direct access to PHY registers is done.
 	 */
 	MV88E6XXX_CAP_SMI_PHY,
+
+	/* Internal temperature sensor.
+	 * Available from any enabled port's PHY register 26, page 6.
+	 */
+	MV88E6XXX_CAP_TEMP,
+	MV88E6XXX_CAP_TEMP_LIMIT,
 };
 
 /* Bitmask of capabilities */
 #define MV88E6XXX_FLAG_EEPROM		BIT(MV88E6XXX_CAP_EEPROM)
 #define MV88E6XXX_FLAG_PPU		BIT(MV88E6XXX_CAP_PPU)
 #define MV88E6XXX_FLAG_SMI_PHY		BIT(MV88E6XXX_CAP_SMI_PHY)
+#define MV88E6XXX_FLAG_TEMP		BIT(MV88E6XXX_CAP_TEMP)
+#define MV88E6XXX_FLAG_TEMP_LIMIT	BIT(MV88E6XXX_CAP_TEMP_LIMIT)
 
 struct mv88e6xxx_info {
 	enum mv88e6xxx_family family;
-- 
2.8.2

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

* [RFC PATCH net-next 05/20] net: dsa: mv88e6xxx: factorize MAC address setting
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (3 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 04/20] net: dsa: mv88e6xxx: factorize temperature access Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 06/20] net: dsa: mv88e6xxx: factorize EEE access Vivien Didelot
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Some switch models have a dedicated register for Switch MAC/WoF/WoL.
This register, when present, is used to indirectly set the switch MAC
address, instead of a direct write to 3 global registers.

Identify this feature and share a common mv88e6xxx_set_addr function.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |  11 +++--
 drivers/net/dsa/mv88e6131.c |   2 +-
 drivers/net/dsa/mv88e6171.c |   6 ++-
 drivers/net/dsa/mv88e6352.c |   8 ++-
 drivers/net/dsa/mv88e6xxx.c | 115 ++++++++++++++++++++++++--------------------
 drivers/net/dsa/mv88e6xxx.h |  11 ++++-
 6 files changed, 92 insertions(+), 61 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 6f4f719..57a6d76 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -24,21 +24,24 @@ static const struct mv88e6xxx_info mv88e6123_table[] = {
 		.name = "Marvell 88E6123",
 		.num_databases = 4096,
 		.num_ports = 3,
-		.flags = MV88E6XXX_FLAG_TEMP,
+		.flags = MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
 		.family = MV88E6XXX_FAMILY_6165,
 		.name = "Marvell 88E6161",
 		.num_databases = 4096,
 		.num_ports = 6,
-		.flags = MV88E6XXX_FLAG_TEMP,
+		.flags = MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
 		.family = MV88E6XXX_FAMILY_6165,
 		.name = "Marvell 88E6165",
 		.num_databases = 4096,
 		.num_ports = 6,
-		.flags = MV88E6XXX_FLAG_TEMP,
+		.flags = MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP,
 	}
 };
 
@@ -114,7 +117,7 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
 	.probe			= mv88e6123_drv_probe,
 	.setup			= mv88e6123_setup,
-	.set_addr		= mv88e6xxx_set_addr_indirect,
+	.set_addr		= mv88e6xxx_set_addr,
 	.phy_read		= mv88e6xxx_phy_read,
 	.phy_write		= mv88e6xxx_phy_write,
 	.get_strings		= mv88e6xxx_get_strings,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index e8eb9a6..519d1eb 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -147,7 +147,7 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_DSA,
 	.probe			= mv88e6131_drv_probe,
 	.setup			= mv88e6131_setup,
-	.set_addr		= mv88e6xxx_set_addr_direct,
+	.set_addr		= mv88e6xxx_set_addr,
 	.phy_read		= mv88e6xxx_phy_read,
 	.phy_write		= mv88e6xxx_phy_write,
 	.get_strings		= mv88e6xxx_get_strings,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index bd2082e..f947950 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -25,6 +25,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.num_databases = 4096,
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
@@ -33,6 +34,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.num_databases = 4096,
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
@@ -41,6 +43,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.num_databases = 4096,
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
@@ -49,6 +52,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.num_databases = 4096,
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP,
 	}
 };
@@ -127,7 +131,7 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
 	.probe			= mv88e6171_drv_probe,
 	.setup			= mv88e6171_setup,
-	.set_addr		= mv88e6xxx_set_addr_indirect,
+	.set_addr		= mv88e6xxx_set_addr,
 	.phy_read		= mv88e6xxx_phy_read,
 	.phy_write		= mv88e6xxx_phy_write,
 	.get_strings		= mv88e6xxx_get_strings,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index f588e2f..90732da 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -31,6 +31,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}, {
@@ -41,6 +42,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}, {
@@ -51,6 +53,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}, {
@@ -61,6 +64,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}, {
@@ -71,6 +75,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}, {
@@ -81,6 +86,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT,
 	}
@@ -158,7 +164,7 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
 	.probe			= mv88e6352_drv_probe,
 	.setup			= mv88e6352_setup,
-	.set_addr		= mv88e6xxx_set_addr_indirect,
+	.set_addr		= mv88e6xxx_set_addr,
 	.phy_read		= mv88e6xxx_phy_read,
 	.phy_write		= mv88e6xxx_phy_write,
 	.get_strings		= mv88e6xxx_get_strings,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 5f7851e..5483e69 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -173,58 +173,6 @@ int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr,
 	return ret;
 }
 
-int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int err;
-
-	err = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_01,
-				  (addr[0] << 8) | addr[1]);
-	if (err)
-		return err;
-
-	err = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_23,
-				  (addr[2] << 8) | addr[3]);
-	if (err)
-		return err;
-
-	return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_45,
-				   (addr[4] << 8) | addr[5]);
-}
-
-int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int ret;
-	int i;
-
-	for (i = 0; i < 6; i++) {
-		int j;
-
-		/* Write the MAC address byte. */
-		ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MAC,
-					  GLOBAL2_SWITCH_MAC_BUSY |
-					  (i << 8) | addr[i]);
-		if (ret)
-			return ret;
-
-		/* Wait for the write to complete. */
-		for (j = 0; j < 16; j++) {
-			ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2,
-						 GLOBAL2_SWITCH_MAC);
-			if (ret < 0)
-				return ret;
-
-			if ((ret & GLOBAL2_SWITCH_MAC_BUSY) == 0)
-				break;
-		}
-		if (j == 16)
-			return -ETIMEDOUT;
-	}
-
-	return 0;
-}
-
 static int _mv88e6xxx_phy_read(struct mv88e6xxx_priv_state *ps, int addr,
 			       int regnum)
 {
@@ -1131,6 +1079,69 @@ out:
 	return ret;
 }
 
+static int _mv88e6xxx_set_addr_direct(struct mv88e6xxx_priv_state *ps, u8 *addr)
+{
+	int err;
+
+	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_01,
+				   (addr[0] << 8) | addr[1]);
+	if (err)
+		return err;
+
+	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_23,
+				   (addr[2] << 8) | addr[3]);
+	if (err)
+		return err;
+
+	return _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_45,
+				    (addr[4] << 8) | addr[5]);
+}
+
+static int _mv88e6xxx_switch_mac_wait(struct mv88e6xxx_priv_state *ps)
+{
+	return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MAC,
+			       GLOBAL2_SWITCH_MAC_BUSY);
+}
+
+static int _mv88e6xxx_set_addr_indirect(struct mv88e6xxx_priv_state *ps,
+					u8 *addr)
+{
+	int i, err;
+
+	for (i = 0; i < 6; i++) {
+		/* Write the MAC address byte. */
+		err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MAC,
+					   GLOBAL2_SWITCH_MAC_BUSY |
+					   (i << 8) | addr[i]);
+		if (err)
+			break;
+
+		/* Wait for the write to complete. */
+		err = _mv88e6xxx_switch_mac_wait(ps);
+		if (err)
+			break;
+	}
+
+	return err;
+}
+
+int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int err;
+
+	mutex_lock(&ps->smi_mutex);
+
+	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SWITCH_MAC))
+		err = _mv88e6xxx_set_addr_indirect(ps, addr);
+	else
+		err = _mv88e6xxx_set_addr_direct(ps, addr);
+
+	mutex_unlock(&ps->smi_mutex);
+
+	return err;
+}
+
 static int _mv88e6xxx_atu_cmd(struct mv88e6xxx_priv_state *ps, u16 fid, u16 cmd)
 {
 	int ret;
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index e7c2e45..72b563e 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -367,6 +367,13 @@ enum mv88e6xxx_cap {
 	 */
 	MV88E6XXX_CAP_SMI_PHY,
 
+	/* Switch MAC/WoL/WoF register.
+	 * This requires an indirect access to set the switch MAC address
+	 * through GLOBAL2_SWITCH_MAC, otherwise GLOBAL_MAC_01, GLOBAL_MAC_23,
+	 * and GLOBAL_MAC_45 are used with a direct access.
+	 */
+	MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF,
+
 	/* Internal temperature sensor.
 	 * Available from any enabled port's PHY register 26, page 6.
 	 */
@@ -378,6 +385,7 @@ enum mv88e6xxx_cap {
 #define MV88E6XXX_FLAG_EEPROM		BIT(MV88E6XXX_CAP_EEPROM)
 #define MV88E6XXX_FLAG_PPU		BIT(MV88E6XXX_CAP_PPU)
 #define MV88E6XXX_FLAG_SMI_PHY		BIT(MV88E6XXX_CAP_SMI_PHY)
+#define MV88E6XXX_FLAG_SWITCH_MAC	BIT(MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF)
 #define MV88E6XXX_FLAG_TEMP		BIT(MV88E6XXX_CAP_TEMP)
 #define MV88E6XXX_FLAG_TEMP_LIMIT	BIT(MV88E6XXX_CAP_TEMP_LIMIT)
 
@@ -497,8 +505,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds);
 int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg);
 int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr,
 			int reg, u16 val);
-int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr);
-int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr);
+int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr);
 int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum);
 int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val);
 void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
-- 
2.8.2

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

* [RFC PATCH net-next 06/20] net: dsa: mv88e6xxx: factorize EEE access
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (4 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 05/20] net: dsa: mv88e6xxx: factorize MAC address setting Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 07/20] net: dsa: mv88e6xxx: factorize registers access Vivien Didelot
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Add a MV88E6XXX_FLAG_EEE flag to describe switch models featuring Energy
Efficient Ethernet. Use it to conditionally support such access in the
common code.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |  2 ++
 drivers/net/dsa/mv88e6131.c |  2 ++
 drivers/net/dsa/mv88e6171.c |  2 ++
 drivers/net/dsa/mv88e6352.c | 18 ++++++++++++------
 drivers/net/dsa/mv88e6xxx.c |  6 ++++++
 drivers/net/dsa/mv88e6xxx.h |  5 +++++
 6 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 57a6d76..e5335c2 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -120,6 +120,8 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
 	.set_addr		= mv88e6xxx_set_addr,
 	.phy_read		= mv88e6xxx_phy_read,
 	.phy_write		= mv88e6xxx_phy_write,
+	.set_eee		= mv88e6xxx_set_eee,
+	.get_eee		= mv88e6xxx_get_eee,
 	.get_strings		= mv88e6xxx_get_strings,
 	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
 	.get_sset_count		= mv88e6xxx_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 519d1eb..73cf879 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -150,6 +150,8 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
 	.set_addr		= mv88e6xxx_set_addr,
 	.phy_read		= mv88e6xxx_phy_read,
 	.phy_write		= mv88e6xxx_phy_write,
+	.set_eee		= mv88e6xxx_set_eee,
+	.get_eee		= mv88e6xxx_get_eee,
 	.get_strings		= mv88e6xxx_get_strings,
 	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
 	.get_sset_count		= mv88e6xxx_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index f947950..6953d12 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -134,6 +134,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
 	.set_addr		= mv88e6xxx_set_addr,
 	.phy_read		= mv88e6xxx_phy_read,
 	.phy_write		= mv88e6xxx_phy_write,
+	.set_eee		= mv88e6xxx_set_eee,
+	.get_eee		= mv88e6xxx_get_eee,
 	.get_strings		= mv88e6xxx_get_strings,
 	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
 	.get_sset_count		= mv88e6xxx_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 90732da..d4ebfb3 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -29,7 +29,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6320",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEPROM |
+		.flags = MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -40,7 +41,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6321",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEPROM |
+		.flags = MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -51,7 +53,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6172",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEPROM |
+		.flags = MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -62,7 +65,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6176",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEPROM |
+		.flags = MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -73,7 +77,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6240",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEPROM |
+		.flags = MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -84,7 +89,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6352",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEPROM |
+		.flags = MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 5483e69..1fbd6d2 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -1032,6 +1032,9 @@ int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int reg;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEE))
+		return -EOPNOTSUPP;
+
 	mutex_lock(&ps->smi_mutex);
 
 	reg = _mv88e6xxx_phy_read_indirect(ps, port, 16);
@@ -1060,6 +1063,9 @@ int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
 	int reg;
 	int ret;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEE))
+		return -EOPNOTSUPP;
+
 	mutex_lock(&ps->smi_mutex);
 
 	ret = _mv88e6xxx_phy_read_indirect(ps, port, 16);
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 72b563e..305bccf 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -351,6 +351,10 @@ enum mv88e6xxx_family {
 };
 
 enum mv88e6xxx_cap {
+	/* Energy Efficient Ethernet.
+	 */
+	MV88E6XXX_CAP_EEE,
+
 	/* EEPROM Command and Data registers.
 	 * See GLOBAL2_EEPROM_OP and GLOBAL2_EEPROM_DATA.
 	 */
@@ -382,6 +386,7 @@ enum mv88e6xxx_cap {
 };
 
 /* Bitmask of capabilities */
+#define MV88E6XXX_FLAG_EEE		BIT(MV88E6XXX_CAP_EEE)
 #define MV88E6XXX_FLAG_EEPROM		BIT(MV88E6XXX_CAP_EEPROM)
 #define MV88E6XXX_FLAG_PPU		BIT(MV88E6XXX_CAP_PPU)
 #define MV88E6XXX_FLAG_SMI_PHY		BIT(MV88E6XXX_CAP_SMI_PHY)
-- 
2.8.2

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

* [RFC PATCH net-next 07/20] net: dsa: mv88e6xxx: factorize registers access
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (5 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 06/20] net: dsa: mv88e6xxx: factorize EEE access Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 08/20] net: dsa: mv88e6xxx: factorize bridge support Vivien Didelot
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Only 6131 was not supporting the port registers access yet. Assume such
support and use the unlock access routines in the meantime.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6131.c | 2 ++
 drivers/net/dsa/mv88e6xxx.c | 6 +++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 73cf879..89cabbf 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -157,6 +157,8 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
 	.get_sset_count		= mv88e6xxx_get_sset_count,
 	.get_eeprom		= mv88e6xxx_get_eeprom,
 	.set_eeprom		= mv88e6xxx_set_eeprom,
+	.get_regs_len		= mv88e6xxx_get_regs_len,
+	.get_regs		= mv88e6xxx_get_regs,
 #ifdef CONFIG_NET_DSA_HWMON
 	.get_temp		= mv88e6xxx_get_temp,
 	.get_temp_limit		= mv88e6xxx_get_temp_limit,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 1fbd6d2..4ed6379 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -706,13 +706,17 @@ void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
 
 	memset(p, 0xff, 32 * sizeof(u16));
 
+	mutex_lock(&ps->smi_mutex);
+
 	for (i = 0; i < 32; i++) {
 		int ret;
 
-		ret = mv88e6xxx_reg_read(ps, REG_PORT(port), i);
+		ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), i);
 		if (ret >= 0)
 			p[i] = ret;
 	}
+
+	mutex_unlock(&ps->smi_mutex);
 }
 
 static int _mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg, int offset,
-- 
2.8.2

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

* [RFC PATCH net-next 08/20] net: dsa: mv88e6xxx: factorize bridge support
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (6 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 07/20] net: dsa: mv88e6xxx: factorize registers access Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 09/20] net: dsa: mv88e6xxx: factorize VTU access Vivien Didelot
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Add MV88E6XXX_FLAG_PORTSTATE and MV88E6XXX_FLAG_VLANTABLE flags to
identify switch models with required 802.1D operations.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |  3 +++
 drivers/net/dsa/mv88e6131.c | 13 +++++++++----
 drivers/net/dsa/mv88e6171.c | 24 ++++++++++++++++--------
 drivers/net/dsa/mv88e6352.c | 24 ++++++++++++++++++------
 drivers/net/dsa/mv88e6xxx.c |  9 +++++++++
 drivers/net/dsa/mv88e6xxx.h | 13 +++++++++++++
 6 files changed, 68 insertions(+), 18 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index e5335c2..05d5196 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -136,6 +136,9 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
 	.set_eeprom		= mv88e6xxx_set_eeprom,
 	.get_regs_len		= mv88e6xxx_get_regs_len,
 	.get_regs		= mv88e6xxx_get_regs,
+	.port_bridge_join	= mv88e6xxx_port_bridge_join,
+	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
+	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
 };
 
 MODULE_ALIAS("platform:mv88e6123");
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 89cabbf..125fbbb 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -24,28 +24,32 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.name = "Marvell 88E6095/88E6095F",
 		.num_databases = 256,
 		.num_ports = 11,
-		.flags = MV88E6XXX_FLAG_PPU,
+		.flags = MV88E6XXX_FLAG_PPU |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
 		.family = MV88E6XXX_FAMILY_6097,
 		.name = "Marvell 88E6085",
 		.num_databases = 4096,
 		.num_ports = 10,
-		.flags = MV88E6XXX_FLAG_PPU,
+		.flags = MV88E6XXX_FLAG_PPU |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
 		.family = MV88E6XXX_FAMILY_6185,
 		.name = "Marvell 88E6131",
 		.num_databases = 256,
 		.num_ports = 8,
-		.flags = MV88E6XXX_FLAG_PPU,
+		.flags = MV88E6XXX_FLAG_PPU |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
 		.family = MV88E6XXX_FAMILY_6185,
 		.name = "Marvell 88E6185",
 		.num_databases = 256,
 		.num_ports = 10,
-		.flags = MV88E6XXX_FLAG_PPU,
+		.flags = MV88E6XXX_FLAG_PPU |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}
 };
 
@@ -168,6 +172,7 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
 	.adjust_link		= mv88e6xxx_adjust_link,
 	.port_bridge_join	= mv88e6xxx_port_bridge_join,
 	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
+	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
 	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
 	.port_vlan_prepare	= mv88e6xxx_port_vlan_prepare,
 	.port_vlan_add		= mv88e6xxx_port_vlan_add,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 6953d12..8ba338d 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -24,36 +24,44 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.name = "Marvell 88E6171",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY |
+		.flags = MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP,
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
 		.family = MV88E6XXX_FAMILY_6351,
 		.name = "Marvell 88E6175",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY |
+		.flags = MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP,
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
 		.family = MV88E6XXX_FAMILY_6351,
 		.name = "Marvell 88E6350",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY |
+		.flags = MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP,
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
 		.family = MV88E6XXX_FAMILY_6351,
 		.name = "Marvell 88E6351",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_SMI_PHY |
+		.flags = MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP,
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}
 };
 
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index d4ebfb3..a67dcf9 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -31,10 +31,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT,
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
 		.family = MV88E6XXX_FAMILY_6320,
@@ -43,10 +45,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT,
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -55,10 +59,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT,
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -67,10 +73,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT,
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -79,10 +87,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT,
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -91,10 +101,12 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT,
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE,
 	}
 };
 
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 4ed6379..c6e4254e 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -1359,6 +1359,9 @@ void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int stp_state;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_PORTSTATE))
+		return;
+
 	switch (state) {
 	case BR_STATE_DISABLED:
 		stp_state = PORT_CONTROL_STATE_DISABLED;
@@ -2420,6 +2423,9 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int i, err = 0;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE))
+		return -EOPNOTSUPP;
+
 	mutex_lock(&ps->smi_mutex);
 
 	/* Assign the bridge and remap each port's VLANTable */
@@ -2444,6 +2450,9 @@ void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
 	struct net_device *bridge = ps->ports[port].bridge_dev;
 	int i;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE))
+		return;
+
 	mutex_lock(&ps->smi_mutex);
 
 	/* Unassign the bridge and remap each port's VLANTable */
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 305bccf..bf8475b 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -360,6 +360,11 @@ enum mv88e6xxx_cap {
 	 */
 	MV88E6XXX_CAP_EEPROM,
 
+	/* Port State Filtering for 802.1D Spanning Tree.
+	 * See PORT_CONTROL_STATE_* values in the PORT_CONTROL register.
+	 */
+	MV88E6XXX_CAP_PORTSTATE,
+
 	/* PHY Polling Unit.
 	 * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING.
 	 */
@@ -383,16 +388,24 @@ enum mv88e6xxx_cap {
 	 */
 	MV88E6XXX_CAP_TEMP,
 	MV88E6XXX_CAP_TEMP_LIMIT,
+
+	/* In-chip Port Based VLANs.
+	 * Each port VLANTable register (see PORT_BASE_VLAN) is used to restrict
+	 * the output (or egress) ports to which it is allowed to send frames.
+	 */
+	MV88E6XXX_CAP_VLANTABLE,
 };
 
 /* Bitmask of capabilities */
 #define MV88E6XXX_FLAG_EEE		BIT(MV88E6XXX_CAP_EEE)
 #define MV88E6XXX_FLAG_EEPROM		BIT(MV88E6XXX_CAP_EEPROM)
+#define MV88E6XXX_FLAG_PORTSTATE	BIT(MV88E6XXX_CAP_PORTSTATE)
 #define MV88E6XXX_FLAG_PPU		BIT(MV88E6XXX_CAP_PPU)
 #define MV88E6XXX_FLAG_SMI_PHY		BIT(MV88E6XXX_CAP_SMI_PHY)
 #define MV88E6XXX_FLAG_SWITCH_MAC	BIT(MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF)
 #define MV88E6XXX_FLAG_TEMP		BIT(MV88E6XXX_CAP_TEMP)
 #define MV88E6XXX_FLAG_TEMP_LIMIT	BIT(MV88E6XXX_CAP_TEMP_LIMIT)
+#define MV88E6XXX_FLAG_VLANTABLE	BIT(MV88E6XXX_CAP_VLANTABLE)
 
 struct mv88e6xxx_info {
 	enum mv88e6xxx_family family;
-- 
2.8.2

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

* [RFC PATCH net-next 09/20] net: dsa: mv88e6xxx: factorize VTU access
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (7 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 08/20] net: dsa: mv88e6xxx: factorize bridge support Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 10/20] net: dsa: mv88e6xxx: factorize ATU access Vivien Didelot
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Add a MV88E6XXX_FLAG_VTU flag to indentify switch models with a VLAN
Table Unit.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |  5 +++++
 drivers/net/dsa/mv88e6131.c | 12 ++++++++----
 drivers/net/dsa/mv88e6171.c | 12 ++++++++----
 drivers/net/dsa/mv88e6352.c | 18 ++++++++++++------
 drivers/net/dsa/mv88e6xxx.c | 16 ++++++++++++++++
 drivers/net/dsa/mv88e6xxx.h |  6 ++++++
 6 files changed, 55 insertions(+), 14 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 05d5196..3992f4f 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -139,6 +139,11 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
 	.port_bridge_join	= mv88e6xxx_port_bridge_join,
 	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
 	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
+	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
+	.port_vlan_prepare	= mv88e6xxx_port_vlan_prepare,
+	.port_vlan_add		= mv88e6xxx_port_vlan_add,
+	.port_vlan_del		= mv88e6xxx_port_vlan_del,
+	.port_vlan_dump		= mv88e6xxx_port_vlan_dump,
 };
 
 MODULE_ALIAS("platform:mv88e6123");
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 125fbbb..d99ebad 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -25,7 +25,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.num_databases = 256,
 		.num_ports = 11,
 		.flags = MV88E6XXX_FLAG_PPU |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
 		.family = MV88E6XXX_FAMILY_6097,
@@ -33,7 +34,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.num_databases = 4096,
 		.num_ports = 10,
 		.flags = MV88E6XXX_FLAG_PPU |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
 		.family = MV88E6XXX_FAMILY_6185,
@@ -41,7 +43,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.num_databases = 256,
 		.num_ports = 8,
 		.flags = MV88E6XXX_FLAG_PPU |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
 		.family = MV88E6XXX_FAMILY_6185,
@@ -49,7 +52,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.num_databases = 256,
 		.num_ports = 10,
 		.flags = MV88E6XXX_FLAG_PPU |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}
 };
 
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 8ba338d..bbea365 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -28,7 +28,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
 		.family = MV88E6XXX_FAMILY_6351,
@@ -39,7 +40,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
 		.family = MV88E6XXX_FAMILY_6351,
@@ -50,7 +52,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
 		.family = MV88E6XXX_FAMILY_6351,
@@ -61,7 +64,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}
 };
 
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index a67dcf9..0ed4172 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -36,7 +36,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
 		.family = MV88E6XXX_FAMILY_6320,
@@ -50,7 +51,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -64,7 +66,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -78,7 +81,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -92,7 +96,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}, {
 		.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
 		.family = MV88E6XXX_FAMILY_6352,
@@ -106,7 +111,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
 			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE,
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
 	}
 };
 
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index c6e4254e..805bd0f 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -1586,6 +1586,9 @@ int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
 	u16 pvid;
 	int err;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU))
+		return -EOPNOTSUPP;
+
 	mutex_lock(&ps->smi_mutex);
 
 	err = _mv88e6xxx_port_pvid_get(ps, port, &pvid);
@@ -2009,6 +2012,9 @@ int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
 		PORT_CONTROL_2_8021Q_DISABLED;
 	int ret;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU))
+		return -EOPNOTSUPP;
+
 	mutex_lock(&ps->smi_mutex);
 
 	ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_CONTROL_2);
@@ -2042,8 +2048,12 @@ int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
 				const struct switchdev_obj_port_vlan *vlan,
 				struct switchdev_trans *trans)
 {
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int err;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU))
+		return -EOPNOTSUPP;
+
 	/* If the requested port doesn't belong to the same bridge as the VLAN
 	 * members, do not support it (yet) and fallback to software VLAN.
 	 */
@@ -2084,6 +2094,9 @@ void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
 	bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
 	u16 vid;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU))
+		return;
+
 	mutex_lock(&ps->smi_mutex);
 
 	for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid)
@@ -2141,6 +2154,9 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
 	u16 pvid, vid;
 	int err = 0;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU))
+		return -EOPNOTSUPP;
+
 	mutex_lock(&ps->smi_mutex);
 
 	err = _mv88e6xxx_port_pvid_get(ps, port, &pvid);
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index bf8475b..9de6ae9 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -394,6 +394,11 @@ enum mv88e6xxx_cap {
 	 * the output (or egress) ports to which it is allowed to send frames.
 	 */
 	MV88E6XXX_CAP_VLANTABLE,
+
+	/* VLAN Table Unit.
+	 * The VTU is used to program 802.1Q VLANs. See GLOBAL_VTU_OP.
+	 */
+	MV88E6XXX_CAP_VTU,
 };
 
 /* Bitmask of capabilities */
@@ -406,6 +411,7 @@ enum mv88e6xxx_cap {
 #define MV88E6XXX_FLAG_TEMP		BIT(MV88E6XXX_CAP_TEMP)
 #define MV88E6XXX_FLAG_TEMP_LIMIT	BIT(MV88E6XXX_CAP_TEMP_LIMIT)
 #define MV88E6XXX_FLAG_VLANTABLE	BIT(MV88E6XXX_CAP_VLANTABLE)
+#define MV88E6XXX_FLAG_VTU		BIT(MV88E6XXX_CAP_VTU)
 
 struct mv88e6xxx_info {
 	enum mv88e6xxx_family family;
-- 
2.8.2

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

* [RFC PATCH net-next 10/20] net: dsa: mv88e6xxx: factorize ATU access
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (8 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 09/20] net: dsa: mv88e6xxx: factorize VTU access Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 11/20] net: dsa: mv88e6xxx: factorize switch reset Vivien Didelot
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Add a MV88E6XXX_FLAG_ATU flag to identify switch models with an Address
Translation Unit.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |  4 ++++
 drivers/net/dsa/mv88e6131.c | 12 ++++++++----
 drivers/net/dsa/mv88e6171.c | 12 ++++++++----
 drivers/net/dsa/mv88e6352.c | 18 ++++++++++++------
 drivers/net/dsa/mv88e6xxx.c | 14 ++++++++++++++
 drivers/net/dsa/mv88e6xxx.h |  6 ++++++
 6 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 3992f4f..c562c4a 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -144,6 +144,10 @@ struct dsa_switch_driver mv88e6123_switch_driver = {
 	.port_vlan_add		= mv88e6xxx_port_vlan_add,
 	.port_vlan_del		= mv88e6xxx_port_vlan_del,
 	.port_vlan_dump		= mv88e6xxx_port_vlan_dump,
+	.port_fdb_prepare       = mv88e6xxx_port_fdb_prepare,
+	.port_fdb_add           = mv88e6xxx_port_fdb_add,
+	.port_fdb_del           = mv88e6xxx_port_fdb_del,
+	.port_fdb_dump          = mv88e6xxx_port_fdb_dump,
 };
 
 MODULE_ALIAS("platform:mv88e6123");
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index d99ebad..655781f 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -24,7 +24,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.name = "Marvell 88E6095/88E6095F",
 		.num_databases = 256,
 		.num_ports = 11,
-		.flags = MV88E6XXX_FLAG_PPU |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PPU |
 			MV88E6XXX_FLAG_VLANTABLE |
 			MV88E6XXX_FLAG_VTU,
 	}, {
@@ -33,7 +34,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.name = "Marvell 88E6085",
 		.num_databases = 4096,
 		.num_ports = 10,
-		.flags = MV88E6XXX_FLAG_PPU |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PPU |
 			MV88E6XXX_FLAG_VLANTABLE |
 			MV88E6XXX_FLAG_VTU,
 	}, {
@@ -42,7 +44,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.name = "Marvell 88E6131",
 		.num_databases = 256,
 		.num_ports = 8,
-		.flags = MV88E6XXX_FLAG_PPU |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PPU |
 			MV88E6XXX_FLAG_VLANTABLE |
 			MV88E6XXX_FLAG_VTU,
 	}, {
@@ -51,7 +54,8 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.name = "Marvell 88E6185",
 		.num_databases = 256,
 		.num_ports = 10,
-		.flags = MV88E6XXX_FLAG_PPU |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PPU |
 			MV88E6XXX_FLAG_VLANTABLE |
 			MV88E6XXX_FLAG_VTU,
 	}
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index bbea365..66e581f 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -24,7 +24,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.name = "Marvell 88E6171",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_PORTSTATE |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -36,7 +37,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.name = "Marvell 88E6175",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_PORTSTATE |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -48,7 +50,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.name = "Marvell 88E6350",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_PORTSTATE |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -60,7 +63,8 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.name = "Marvell 88E6351",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_PORTSTATE |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 0ed4172..f10aaee 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -29,7 +29,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6320",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEE |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
@@ -44,7 +45,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6321",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEE |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
@@ -59,7 +61,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6172",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEE |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
@@ -74,7 +77,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6176",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEE |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
@@ -89,7 +93,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6240",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEE |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
@@ -104,7 +109,8 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 		.name = "Marvell 88E6352",
 		.num_databases = 4096,
 		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_EEE |
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
 			MV88E6XXX_FLAG_SMI_PHY |
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 805bd0f..810226d 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2265,6 +2265,11 @@ int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
 			       const struct switchdev_obj_port_fdb *fdb,
 			       struct switchdev_trans *trans)
 {
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
+		return -EOPNOTSUPP;
+
 	/* We don't need any dynamic resource from the kernel (yet),
 	 * so skip the prepare phase.
 	 */
@@ -2280,6 +2285,9 @@ void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
 		GLOBAL_ATU_DATA_STATE_UC_STATIC;
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
+		return;
+
 	mutex_lock(&ps->smi_mutex);
 	if (_mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid, state))
 		netdev_err(ds->ports[port], "failed to load MAC address\n");
@@ -2292,6 +2300,9 @@ int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
+		return -EOPNOTSUPP;
+
 	mutex_lock(&ps->smi_mutex);
 	ret = _mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid,
 				       GLOBAL_ATU_DATA_STATE_UNUSED);
@@ -2397,6 +2408,9 @@ int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
 	u16 fid;
 	int err;
 
+	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
+		return -EOPNOTSUPP;
+
 	mutex_lock(&ps->smi_mutex);
 
 	/* Dump port's default Filtering Information Database (VLAN ID 0) */
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 9de6ae9..e639de7 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -351,6 +351,11 @@ enum mv88e6xxx_family {
 };
 
 enum mv88e6xxx_cap {
+	/* Address Translation Unit.
+	 * The ATU is used to lookup and learn MAC addresses. See GLOBAL_ATU_OP.
+	 */
+	MV88E6XXX_CAP_ATU,
+
 	/* Energy Efficient Ethernet.
 	 */
 	MV88E6XXX_CAP_EEE,
@@ -402,6 +407,7 @@ enum mv88e6xxx_cap {
 };
 
 /* Bitmask of capabilities */
+#define MV88E6XXX_FLAG_ATU		BIT(MV88E6XXX_CAP_ATU)
 #define MV88E6XXX_FLAG_EEE		BIT(MV88E6XXX_CAP_EEE)
 #define MV88E6XXX_FLAG_EEPROM		BIT(MV88E6XXX_CAP_EEPROM)
 #define MV88E6XXX_FLAG_PORTSTATE	BIT(MV88E6XXX_CAP_PORTSTATE)
-- 
2.8.2

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

* [RFC PATCH net-next 11/20] net: dsa: mv88e6xxx: factorize switch reset
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (9 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 10/20] net: dsa: mv88e6xxx: factorize ATU access Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 12/20] net: dsa: mv88e6xxx: factorize global setup Vivien Didelot
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Add a MV88E6XXX_FLAG_PPU_ACTIVE flag to describe how to reset the
switch, and merge the reset call to the common setup code.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |   4 --
 drivers/net/dsa/mv88e6131.c |   4 --
 drivers/net/dsa/mv88e6171.c |   8 +--
 drivers/net/dsa/mv88e6352.c |  10 ++--
 drivers/net/dsa/mv88e6xxx.c | 137 +++++++++++++++++++++++---------------------
 drivers/net/dsa/mv88e6xxx.h |   3 +-
 6 files changed, 83 insertions(+), 83 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index c562c4a..f542fbf 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -102,10 +102,6 @@ static int mv88e6123_setup(struct dsa_switch *ds)
 	if (ret < 0)
 		return ret;
 
-	ret = mv88e6xxx_switch_reset(ps, false);
-	if (ret < 0)
-		return ret;
-
 	ret = mv88e6123_setup_global(ds);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 655781f..5b33d39 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -144,10 +144,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
 	if (ret < 0)
 		return ret;
 
-	ret = mv88e6xxx_switch_reset(ps, false);
-	if (ret < 0)
-		return ret;
-
 	ret = mv88e6131_setup_global(ds);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 66e581f..9724a25 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -26,6 +26,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_ATU |
 			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -39,6 +40,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_ATU |
 			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -52,6 +54,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_ATU |
 			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -65,6 +68,7 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
 		.num_ports = 7,
 		.flags = MV88E6XXX_FLAG_ATU |
 			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -132,10 +136,6 @@ static int mv88e6171_setup(struct dsa_switch *ds)
 	if (ret < 0)
 		return ret;
 
-	ret = mv88e6xxx_switch_reset(ps, true);
-	if (ret < 0)
-		return ret;
-
 	ret = mv88e6171_setup_global(ds);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index f10aaee..a9d4d47a 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -33,6 +33,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -49,6 +50,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -65,6 +67,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -81,6 +84,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -97,6 +101,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -113,6 +118,7 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
 			MV88E6XXX_FLAG_EEE |
 			MV88E6XXX_FLAG_EEPROM |
 			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
 			MV88E6XXX_FLAG_SMI_PHY |
 			MV88E6XXX_FLAG_SWITCH_MAC |
 			MV88E6XXX_FLAG_TEMP |
@@ -179,10 +185,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
 	if (ret < 0)
 		return ret;
 
-	ret = mv88e6xxx_switch_reset(ps, true);
-	if (ret < 0)
-		return ret;
-
 	ret = mv88e6352_setup_global(ds);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 810226d..b52e3d0 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2549,6 +2549,68 @@ restore_page_0:
 	return ret;
 }
 
+static int _mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps)
+{
+	bool ppu_active = mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU_ACTIVE);
+	u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
+	struct gpio_desc *gpiod = ps->ds->pd->reset;
+	unsigned long timeout;
+	int ret;
+	int i;
+
+	/* Set all ports to the disabled state. */
+	for (i = 0; i < ps->info->num_ports; i++) {
+		ret = _mv88e6xxx_reg_read(ps, REG_PORT(i), PORT_CONTROL);
+		if (ret < 0)
+			return ret;
+
+		ret = _mv88e6xxx_reg_write(ps, REG_PORT(i), PORT_CONTROL,
+					   ret & 0xfffc);
+		if (ret)
+			return ret;
+	}
+
+	/* Wait for transmit queues to drain. */
+	usleep_range(2000, 4000);
+
+	/* If there is a gpio connected to the reset pin, toggle it */
+	if (gpiod) {
+		gpiod_set_value_cansleep(gpiod, 1);
+		usleep_range(10000, 20000);
+		gpiod_set_value_cansleep(gpiod, 0);
+		usleep_range(10000, 20000);
+	}
+
+	/* Reset the switch. Keep the PPU active if requested. The PPU
+	 * needs to be active to support indirect phy register access
+	 * through global registers 0x18 and 0x19.
+	 */
+	if (ppu_active)
+		ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc000);
+	else
+		ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc400);
+	if (ret)
+		return ret;
+
+	/* Wait up to one second for reset to complete. */
+	timeout = jiffies + 1 * HZ;
+	while (time_before(jiffies, timeout)) {
+		ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, 0x00);
+		if (ret < 0)
+			return ret;
+
+		if ((ret & is_reset) == is_reset)
+			break;
+		usleep_range(1000, 2000);
+	}
+	if (time_after(jiffies, timeout))
+		ret = -ETIMEDOUT;
+	else
+		ret = 0;
+
+	return ret;
+}
+
 static int mv88e6xxx_power_on_serdes(struct mv88e6xxx_priv_state *ps)
 {
 	int ret;
@@ -2850,6 +2912,8 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
 
 int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps)
 {
+	int err;
+
 	mutex_init(&ps->smi_mutex);
 
 	INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
@@ -2860,7 +2924,13 @@ int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps)
 	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
 		mv88e6xxx_ppu_state_init(ps);
 
-	return 0;
+	mutex_lock(&ps->smi_mutex);
+
+	err = _mv88e6xxx_switch_reset(ps);
+
+	mutex_unlock(&ps->smi_mutex);
+
+	return err;
 }
 
 int mv88e6xxx_setup_global(struct dsa_switch *ds)
@@ -3036,71 +3106,6 @@ unlock:
 	return err;
 }
 
-int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps, bool ppu_active)
-{
-	u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
-	struct gpio_desc *gpiod = ps->ds->pd->reset;
-	unsigned long timeout;
-	int ret;
-	int i;
-
-	mutex_lock(&ps->smi_mutex);
-
-	/* Set all ports to the disabled state. */
-	for (i = 0; i < ps->info->num_ports; i++) {
-		ret = _mv88e6xxx_reg_read(ps, REG_PORT(i), PORT_CONTROL);
-		if (ret < 0)
-			goto unlock;
-
-		ret = _mv88e6xxx_reg_write(ps, REG_PORT(i), PORT_CONTROL,
-					   ret & 0xfffc);
-		if (ret)
-			goto unlock;
-	}
-
-	/* Wait for transmit queues to drain. */
-	usleep_range(2000, 4000);
-
-	/* If there is a gpio connected to the reset pin, toggle it */
-	if (gpiod) {
-		gpiod_set_value_cansleep(gpiod, 1);
-		usleep_range(10000, 20000);
-		gpiod_set_value_cansleep(gpiod, 0);
-		usleep_range(10000, 20000);
-	}
-
-	/* Reset the switch. Keep the PPU active if requested. The PPU
-	 * needs to be active to support indirect phy register access
-	 * through global registers 0x18 and 0x19.
-	 */
-	if (ppu_active)
-		ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc000);
-	else
-		ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc400);
-	if (ret)
-		goto unlock;
-
-	/* Wait up to one second for reset to complete. */
-	timeout = jiffies + 1 * HZ;
-	while (time_before(jiffies, timeout)) {
-		ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, 0x00);
-		if (ret < 0)
-			goto unlock;
-
-		if ((ret & is_reset) == is_reset)
-			break;
-		usleep_range(1000, 2000);
-	}
-	if (time_after(jiffies, timeout))
-		ret = -ETIMEDOUT;
-	else
-		ret = 0;
-unlock:
-	mutex_unlock(&ps->smi_mutex);
-
-	return ret;
-}
-
 int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index e639de7..7ca7230 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -374,6 +374,7 @@ enum mv88e6xxx_cap {
 	 * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING.
 	 */
 	MV88E6XXX_CAP_PPU,
+	MV88E6XXX_CAP_PPU_ACTIVE,
 
 	/* SMI PHY Command and Data registers.
 	 * This requires an indirect access to PHY registers through
@@ -412,6 +413,7 @@ enum mv88e6xxx_cap {
 #define MV88E6XXX_FLAG_EEPROM		BIT(MV88E6XXX_CAP_EEPROM)
 #define MV88E6XXX_FLAG_PORTSTATE	BIT(MV88E6XXX_CAP_PORTSTATE)
 #define MV88E6XXX_FLAG_PPU		BIT(MV88E6XXX_CAP_PPU)
+#define MV88E6XXX_FLAG_PPU_ACTIVE	BIT(MV88E6XXX_CAP_PPU_ACTIVE)
 #define MV88E6XXX_FLAG_SMI_PHY		BIT(MV88E6XXX_CAP_SMI_PHY)
 #define MV88E6XXX_FLAG_SWITCH_MAC	BIT(MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF)
 #define MV88E6XXX_FLAG_TEMP		BIT(MV88E6XXX_CAP_TEMP)
@@ -523,7 +525,6 @@ static inline bool mv88e6xxx_has(struct mv88e6xxx_priv_state *ps,
 	return (ps->info->flags & flags) == flags;
 }
 
-int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps, bool ppu_active);
 const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
 				int sw_addr, void **priv,
 				const struct mv88e6xxx_info *table,
-- 
2.8.2

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

* [RFC PATCH net-next 12/20] net: dsa: mv88e6xxx: factorize global setup
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (10 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 11/20] net: dsa: mv88e6xxx: factorize switch reset Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:40 ` [RFC PATCH net-next 13/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup Vivien Didelot
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Every driver is calling mv88e6xxx_setup_global after
mv88e6xxx_setup_common. Call the former in the latter.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |   4 --
 drivers/net/dsa/mv88e6131.c |   4 --
 drivers/net/dsa/mv88e6171.c |   4 --
 drivers/net/dsa/mv88e6352.c |   4 --
 drivers/net/dsa/mv88e6xxx.c | 109 +++++++++++++++++++++++---------------------
 drivers/net/dsa/mv88e6xxx.h |   1 -
 6 files changed, 56 insertions(+), 70 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index f542fbf..938d5ca 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -61,10 +61,6 @@ static int mv88e6123_setup_global(struct dsa_switch *ds)
 	int ret;
 	u32 reg;
 
-	ret = mv88e6xxx_setup_global(ds);
-	if (ret)
-		return ret;
-
 	/* Disable the PHY polling unit (since there won't be any
 	 * external PHYs to poll), don't discard packets with
 	 * excessive collisions, and mask all interrupt sources.
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 5b33d39..2c43348 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -77,10 +77,6 @@ static int mv88e6131_setup_global(struct dsa_switch *ds)
 	int ret;
 	u32 reg;
 
-	ret = mv88e6xxx_setup_global(ds);
-	if (ret)
-		return ret;
-
 	/* Enable the PHY polling unit, don't discard packets with
 	 * excessive collisions, use a weighted fair queueing scheme
 	 * to arbitrate between packet queues, set the maximum frame
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 9724a25..fcdb5a7 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -93,10 +93,6 @@ static int mv88e6171_setup_global(struct dsa_switch *ds)
 	int ret;
 	u32 reg;
 
-	ret = mv88e6xxx_setup_global(ds);
-	if (ret)
-		return ret;
-
 	/* Discard packets with excessive collisions, mask all
 	 * interrupt sources, enable PPU.
 	 */
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index a9d4d47a..94a2698 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -144,10 +144,6 @@ static int mv88e6352_setup_global(struct dsa_switch *ds)
 	int ret;
 	u32 reg;
 
-	ret = mv88e6xxx_setup_global(ds);
-	if (ret)
-		return ret;
-
 	/* Discard packets with excessive collisions,
 	 * mask all interrupt sources, enable PPU (bit 14, undocumented).
 	 */
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index b52e3d0..7ec532d 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2910,36 +2910,11 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
 	return 0;
 }
 
-int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps)
+static int _mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
 {
 	int err;
-
-	mutex_init(&ps->smi_mutex);
-
-	INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
-
-	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
-		mutex_init(&ps->eeprom_mutex);
-
-	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
-		mv88e6xxx_ppu_state_init(ps);
-
-	mutex_lock(&ps->smi_mutex);
-
-	err = _mv88e6xxx_switch_reset(ps);
-
-	mutex_unlock(&ps->smi_mutex);
-
-	return err;
-}
-
-int mv88e6xxx_setup_global(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int err;
 	int i;
 
-	mutex_lock(&ps->smi_mutex);
 	/* Set the default address aging time to 5 minutes, and
 	 * enable address learn messages to be sent to all message
 	 * ports.
@@ -2947,45 +2922,45 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_CONTROL,
 				   0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL);
 	if (err)
-		goto unlock;
+		return err;
 
 	/* Configure the IP ToS mapping registers. */
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000);
 	if (err)
-		goto unlock;
+		return err;
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000);
 	if (err)
-		goto unlock;
+		return err;
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555);
 	if (err)
-		goto unlock;
+		return err;
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555);
 	if (err)
-		goto unlock;
+		return err;
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa);
 	if (err)
-		goto unlock;
+		return err;
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa);
 	if (err)
-		goto unlock;
+		return err;
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff);
 	if (err)
-		goto unlock;
+		return err;
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff);
 	if (err)
-		goto unlock;
+		return err;
 
 	/* Configure the IEEE 802.1p priority mapping register. */
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41);
 	if (err)
-		goto unlock;
+		return err;
 
 	/* Send all frames with destination addresses matching
 	 * 01:80:c2:00:00:0x to the CPU port.
 	 */
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff);
 	if (err)
-		goto unlock;
+		return err;
 
 	/* Ignore removed tag data on doubly tagged packets, disable
 	 * flow control messages, force flow control priority to the
@@ -2996,15 +2971,15 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 				   0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 |
 				   GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI);
 	if (err)
-		goto unlock;
+		return err;
 
 	/* Program the DSA routing table. */
 	for (i = 0; i < 32; i++) {
 		int nexthop = 0x1f;
 
-		if (ds->pd->rtable &&
-		    i != ds->index && i < ds->dst->pd->nr_chips)
-			nexthop = ds->pd->rtable[i] & 0x1f;
+		if (ps->ds->pd->rtable &&
+		    i != ps->ds->index && i < ps->ds->dst->pd->nr_chips)
+			nexthop = ps->ds->pd->rtable[i] & 0x1f;
 
 		err = _mv88e6xxx_reg_write(
 			ps, REG_GLOBAL2,
@@ -3012,7 +2987,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 			GLOBAL2_DEVICE_MAPPING_UPDATE |
 			(i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) | nexthop);
 		if (err)
-			goto unlock;
+			return err;
 	}
 
 	/* Clear all trunk masks. */
@@ -3022,7 +2997,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 					   (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) |
 					   ((1 << ps->info->num_ports) - 1));
 		if (err)
-			goto unlock;
+			return err;
 	}
 
 	/* Clear all trunk mappings. */
@@ -3033,7 +3008,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 			GLOBAL2_TRUNK_MAPPING_UPDATE |
 			(i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT));
 		if (err)
-			goto unlock;
+			return err;
 	}
 
 	if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
@@ -3045,7 +3020,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 		err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2,
 					   GLOBAL2_MGMT_EN_2X, 0xffff);
 		if (err)
-			goto unlock;
+			return err;
 
 		/* Initialise cross-chip port VLAN table to reset
 		 * defaults.
@@ -3053,7 +3028,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 		err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2,
 					   GLOBAL2_PVT_ADDR, 0x9000);
 		if (err)
-			goto unlock;
+			return err;
 
 		/* Clear the priority override table. */
 		for (i = 0; i < 16; i++) {
@@ -3061,7 +3036,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 						   GLOBAL2_PRIO_OVERRIDE,
 						   0x8000 | (i << 8));
 			if (err)
-				goto unlock;
+				return err;
 		}
 	}
 
@@ -3078,7 +3053,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 						   GLOBAL2_INGRESS_OP,
 						   0x9000 | (i << 8));
 			if (err)
-				goto unlock;
+				return err;
 		}
 	}
 
@@ -3086,20 +3061,48 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_STATS_OP,
 				   GLOBAL_STATS_OP_FLUSH_ALL);
 	if (err)
-		goto unlock;
+		return err;
 
 	/* Wait for the flush to complete. */
 	err = _mv88e6xxx_stats_wait(ps);
-	if (err < 0)
-		goto unlock;
+	if (err)
+		return err;
 
 	/* Clear all ATU entries */
 	err = _mv88e6xxx_atu_flush(ps, 0, true);
-	if (err < 0)
-		goto unlock;
+	if (err)
+		return err;
 
 	/* Clear all the VTU and STU entries */
 	err = _mv88e6xxx_vtu_stu_flush(ps);
+	if (err < 0)
+		return err;
+
+	return err;
+}
+
+int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps)
+{
+	int err;
+
+	mutex_init(&ps->smi_mutex);
+
+	INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
+
+	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
+		mutex_init(&ps->eeprom_mutex);
+
+	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
+		mv88e6xxx_ppu_state_init(ps);
+
+	mutex_lock(&ps->smi_mutex);
+
+	err = _mv88e6xxx_switch_reset(ps);
+	if (err)
+		goto unlock;
+
+	err = _mv88e6xxx_setup_global(ps);
+
 unlock:
 	mutex_unlock(&ps->smi_mutex);
 
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 7ca7230..119271e 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -532,7 +532,6 @@ const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
 
 int mv88e6xxx_setup_ports(struct dsa_switch *ds);
 int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps);
-int mv88e6xxx_setup_global(struct dsa_switch *ds);
 int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg);
 int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr,
 			int reg, u16 val);
-- 
2.8.2

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

* [RFC PATCH net-next 13/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (11 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 12/20] net: dsa: mv88e6xxx: factorize global setup Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-06  0:55   ` Andrew Lunn
  2016-05-05 22:40 ` [RFC PATCH net-next 14/20] net: dsa: mv88e6xxx: factorize VLAN Ethertype Vivien Didelot
                   ` (6 subsequent siblings)
  19 siblings, 1 reply; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

All switch models configure the GLOBAL_CONTROL register with slightly
differences.

Assume a common setup to enable the PHY Polling Unit if present, discard
packets with excessive collisions, set the maximum frame size to 1632,
and mask all interrupt sources.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |  8 --------
 drivers/net/dsa/mv88e6131.c | 11 -----------
 drivers/net/dsa/mv88e6171.c |  9 ---------
 drivers/net/dsa/mv88e6352.c |  9 ---------
 drivers/net/dsa/mv88e6xxx.c | 14 ++++++++++++++
 5 files changed, 14 insertions(+), 37 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 938d5ca..077fe30 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -61,14 +61,6 @@ static int mv88e6123_setup_global(struct dsa_switch *ds)
 	int ret;
 	u32 reg;
 
-	/* Disable the PHY polling unit (since there won't be any
-	 * external PHYs to poll), don't discard packets with
-	 * excessive collisions, and mask all interrupt sources.
-	 */
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, 0x0000);
-	if (ret)
-		return ret;
-
 	/* Configure the upstream port, and configure the upstream
 	 * port as the port to which ingress and egress monitor frames
 	 * are to be sent.
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 2c43348..013668c 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -77,17 +77,6 @@ static int mv88e6131_setup_global(struct dsa_switch *ds)
 	int ret;
 	u32 reg;
 
-	/* Enable the PHY polling unit, don't discard packets with
-	 * excessive collisions, use a weighted fair queueing scheme
-	 * to arbitrate between packet queues, set the maximum frame
-	 * size to 1632, and mask all interrupt sources.
-	 */
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
-				  GLOBAL_CONTROL_PPU_ENABLE |
-				  GLOBAL_CONTROL_MAX_FRAME_1632);
-	if (ret)
-		return ret;
-
 	/* Set the VLAN ethertype to 0x8100. */
 	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CORE_TAG_TYPE, 0x8100);
 	if (ret)
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index fcdb5a7..f7dbf78 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -93,15 +93,6 @@ static int mv88e6171_setup_global(struct dsa_switch *ds)
 	int ret;
 	u32 reg;
 
-	/* Discard packets with excessive collisions, mask all
-	 * interrupt sources, enable PPU.
-	 */
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
-				  GLOBAL_CONTROL_PPU_ENABLE |
-				  GLOBAL_CONTROL_DISCARD_EXCESS);
-	if (ret)
-		return ret;
-
 	/* Configure the upstream port, and configure the upstream
 	 * port as the port to which ingress and egress monitor frames
 	 * are to be sent.
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 94a2698..54849f5 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -144,15 +144,6 @@ static int mv88e6352_setup_global(struct dsa_switch *ds)
 	int ret;
 	u32 reg;
 
-	/* Discard packets with excessive collisions,
-	 * mask all interrupt sources, enable PPU (bit 14, undocumented).
-	 */
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
-				  GLOBAL_CONTROL_PPU_ENABLE |
-				  GLOBAL_CONTROL_DISCARD_EXCESS);
-	if (ret)
-		return ret;
-
 	/* Configure the upstream port, and configure the upstream
 	 * port as the port to which ingress and egress monitor frames
 	 * are to be sent.
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 7ec532d..1cba078 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2912,9 +2912,23 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
 
 static int _mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
 {
+	u16 reg;
 	int err;
 	int i;
 
+	/* Enable the PHY Polling Unit if present, discard packets with
+	 * excessive collisions, set the maximum frame size to 1632, and mask
+	 * all interrupt sources.
+	 */
+	reg = GLOBAL_CONTROL_DISCARD_EXCESS | GLOBAL_CONTROL_MAX_FRAME_1632;
+	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU) ||
+	    mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU_ACTIVE))
+		reg |= GLOBAL_CONTROL_PPU_ENABLE;
+
+	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, reg);
+	if (err)
+		return err;
+
 	/* Set the default address aging time to 5 minutes, and
 	 * enable address learn messages to be sent to all message
 	 * ports.
-- 
2.8.2

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

* [RFC PATCH net-next 14/20] net: dsa: mv88e6xxx: factorize VLAN Ethertype
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (12 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 13/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-06  0:57   ` Andrew Lunn
  2016-05-05 22:40 ` [RFC PATCH net-next 15/20] net: dsa: mv88e6xxx: factorize GLOBAL_MONITOR_CONTROL setup Vivien Didelot
                   ` (5 subsequent siblings)
  19 siblings, 1 reply; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Only the 6131 driver was setting the VLAN Ethertype to 0x8100. Set it to
all models.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6131.c | 9 ++++-----
 drivers/net/dsa/mv88e6xxx.c | 8 ++++++++
 drivers/net/dsa/mv88e6xxx.h | 7 +++++++
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 013668c..4c0b1e9 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -25,6 +25,7 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.num_databases = 256,
 		.num_ports = 11,
 		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_CORE_TAG_TYPE |
 			MV88E6XXX_FLAG_PPU |
 			MV88E6XXX_FLAG_VLANTABLE |
 			MV88E6XXX_FLAG_VTU,
@@ -35,6 +36,7 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.num_databases = 4096,
 		.num_ports = 10,
 		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_CORE_TAG_TYPE |
 			MV88E6XXX_FLAG_PPU |
 			MV88E6XXX_FLAG_VLANTABLE |
 			MV88E6XXX_FLAG_VTU,
@@ -45,6 +47,7 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.num_databases = 256,
 		.num_ports = 8,
 		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_CORE_TAG_TYPE |
 			MV88E6XXX_FLAG_PPU |
 			MV88E6XXX_FLAG_VLANTABLE |
 			MV88E6XXX_FLAG_VTU,
@@ -55,6 +58,7 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
 		.num_databases = 256,
 		.num_ports = 10,
 		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_CORE_TAG_TYPE |
 			MV88E6XXX_FLAG_PPU |
 			MV88E6XXX_FLAG_VLANTABLE |
 			MV88E6XXX_FLAG_VTU,
@@ -77,11 +81,6 @@ static int mv88e6131_setup_global(struct dsa_switch *ds)
 	int ret;
 	u32 reg;
 
-	/* Set the VLAN ethertype to 0x8100. */
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CORE_TAG_TYPE, 0x8100);
-	if (ret)
-		return ret;
-
 	/* Disable ARP mirroring, and configure the upstream port as
 	 * the port to which ingress and egress monitor frames are to
 	 * be sent.
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 1cba078..f7fca3e 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2929,6 +2929,14 @@ static int _mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
 	if (err)
 		return err;
 
+	/* Set the VLAN ethertype to 0x8100. */
+	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_CORE_TAG_TYPE)) {
+		err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CORE_TAG_TYPE,
+					   0x8100);
+		if (err)
+			return err;
+	}
+
 	/* Set the default address aging time to 5 minutes, and
 	 * enable address learn messages to be sent to all message
 	 * ports.
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 119271e..c8677dd 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -365,6 +365,12 @@ enum mv88e6xxx_cap {
 	 */
 	MV88E6XXX_CAP_EEPROM,
 
+	/* Core Tag Type.
+	 * Used with Double Tagged frames and ports in UseCoreTag mode.
+	 * See GLOBAL_CORE_TAG_TYPE.
+	 */
+	MV88E6XXX_CAP_CORE_TAG_TYPE,
+
 	/* Port State Filtering for 802.1D Spanning Tree.
 	 * See PORT_CONTROL_STATE_* values in the PORT_CONTROL register.
 	 */
@@ -411,6 +417,7 @@ enum mv88e6xxx_cap {
 #define MV88E6XXX_FLAG_ATU		BIT(MV88E6XXX_CAP_ATU)
 #define MV88E6XXX_FLAG_EEE		BIT(MV88E6XXX_CAP_EEE)
 #define MV88E6XXX_FLAG_EEPROM		BIT(MV88E6XXX_CAP_EEPROM)
+#define MV88E6XXX_FLAG_CORE_TAG_TYPE	BIT(MV88E6XXX_CAP_CORE_TAG_TYPE)
 #define MV88E6XXX_FLAG_PORTSTATE	BIT(MV88E6XXX_CAP_PORTSTATE)
 #define MV88E6XXX_FLAG_PPU		BIT(MV88E6XXX_CAP_PPU)
 #define MV88E6XXX_FLAG_PPU_ACTIVE	BIT(MV88E6XXX_CAP_PPU_ACTIVE)
-- 
2.8.2

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

* [RFC PATCH net-next 15/20] net: dsa: mv88e6xxx: factorize GLOBAL_MONITOR_CONTROL setup
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (13 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 14/20] net: dsa: mv88e6xxx: factorize VLAN Ethertype Vivien Didelot
@ 2016-05-05 22:40 ` Vivien Didelot
  2016-05-05 22:41 ` [RFC PATCH net-next 16/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL_2 setup Vivien Didelot
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:40 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

All switch drivers configure the GLOBAL_MONITOR_CONTROL register with
slightly changes.

Assume the setup of the upstream port, and configure it as the port to
which ingress and egress and ARP monitor frames are to be sent.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c | 14 --------------
 drivers/net/dsa/mv88e6131.c | 13 -------------
 drivers/net/dsa/mv88e6171.c | 15 ---------------
 drivers/net/dsa/mv88e6352.c | 14 --------------
 drivers/net/dsa/mv88e6xxx.c | 12 ++++++++++++
 5 files changed, 12 insertions(+), 56 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 077fe30..98eaee1 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -57,20 +57,6 @@ static const char *mv88e6123_drv_probe(struct device *dsa_dev,
 static int mv88e6123_setup_global(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	u32 upstream_port = dsa_upstream_port(ds);
-	int ret;
-	u32 reg;
-
-	/* Configure the upstream port, and configure the upstream
-	 * port as the port to which ingress and egress monitor frames
-	 * are to be sent.
-	 */
-	reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
-		upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
-		upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg);
-	if (ret)
-		return ret;
 
 	/* Disable remote management for now, and set the switch's
 	 * DSA device number.
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 4c0b1e9..c675070 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -77,20 +77,7 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev,
 static int mv88e6131_setup_global(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	u32 upstream_port = dsa_upstream_port(ds);
 	int ret;
-	u32 reg;
-
-	/* Disable ARP mirroring, and configure the upstream port as
-	 * the port to which ingress and egress monitor frames are to
-	 * be sent.
-	 */
-	reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
-		upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
-		GLOBAL_MONITOR_CONTROL_ARP_DISABLED;
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg);
-	if (ret)
-		return ret;
 
 	/* Disable cascade port functionality unless this device
 	 * is used in a cascade configuration, and set the switch's
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index f7dbf78..4c14f9f 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -89,21 +89,6 @@ static const char *mv88e6171_drv_probe(struct device *dsa_dev,
 static int mv88e6171_setup_global(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	u32 upstream_port = dsa_upstream_port(ds);
-	int ret;
-	u32 reg;
-
-	/* Configure the upstream port, and configure the upstream
-	 * port as the port to which ingress and egress monitor frames
-	 * are to be sent.
-	 */
-	reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
-		upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
-		upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT |
-		upstream_port << GLOBAL_MONITOR_CONTROL_MIRROR_SHIFT;
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg);
-	if (ret)
-		return ret;
 
 	/* Disable remote management for now, and set the switch's
 	 * DSA device number.
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 54849f5..52547d0 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -140,20 +140,6 @@ static const char *mv88e6352_drv_probe(struct device *dsa_dev,
 static int mv88e6352_setup_global(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	u32 upstream_port = dsa_upstream_port(ds);
-	int ret;
-	u32 reg;
-
-	/* Configure the upstream port, and configure the upstream
-	 * port as the port to which ingress and egress monitor frames
-	 * are to be sent.
-	 */
-	reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
-		upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
-		upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
-	ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg);
-	if (ret)
-		return ret;
 
 	/* Disable remote management for now, and set the switch's
 	 * DSA device number.
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index f7fca3e..de37f20 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2912,6 +2912,8 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
 
 static int _mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
 {
+	struct dsa_switch *ds = ps->ds;
+	u32 upstream_port = dsa_upstream_port(ds);
 	u16 reg;
 	int err;
 	int i;
@@ -2937,6 +2939,16 @@ static int _mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
 			return err;
 	}
 
+	/* Configure the upstream port, and configure it as the port to which
+	 * ingress and egress and ARP monitor frames are to be sent.
+	 */
+	reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
+		upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
+		upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
+	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg);
+	if (err)
+		return err;
+
 	/* Set the default address aging time to 5 minutes, and
 	 * enable address learn messages to be sent to all message
 	 * ports.
-- 
2.8.2

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

* [RFC PATCH net-next 16/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL_2 setup
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (14 preceding siblings ...)
  2016-05-05 22:40 ` [RFC PATCH net-next 15/20] net: dsa: mv88e6xxx: factorize GLOBAL_MONITOR_CONTROL setup Vivien Didelot
@ 2016-05-05 22:41 ` Vivien Didelot
  2016-05-05 22:41 ` [RFC PATCH net-next 17/20] net: dsa: mv88e6xxx: factorize frames priorities Vivien Didelot
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:41 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

All switch models setup the GLOBAL_CONTROL_2 register with slightly
differences.

Since the cascade mode is valid even in a single chip setup, factorize
such configuration.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c | 15 ---------------
 drivers/net/dsa/mv88e6131.c | 16 ----------------
 drivers/net/dsa/mv88e6171.c | 15 ---------------
 drivers/net/dsa/mv88e6352.c | 14 --------------
 drivers/net/dsa/mv88e6xxx.c |  7 +++++++
 5 files changed, 7 insertions(+), 60 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 98eaee1..9d3f672 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -54,17 +54,6 @@ static const char *mv88e6123_drv_probe(struct device *dsa_dev,
 				   ARRAY_SIZE(mv88e6123_table));
 }
 
-static int mv88e6123_setup_global(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-
-	/* Disable remote management for now, and set the switch's
-	 * DSA device number.
-	 */
-	return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2,
-				   ds->index & 0x1f);
-}
-
 static int mv88e6123_setup(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -76,10 +65,6 @@ static int mv88e6123_setup(struct dsa_switch *ds)
 	if (ret < 0)
 		return ret;
 
-	ret = mv88e6123_setup_global(ds);
-	if (ret < 0)
-		return ret;
-
 	return mv88e6xxx_setup_ports(ds);
 }
 
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index c675070..14d0722 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -77,22 +77,6 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev,
 static int mv88e6131_setup_global(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int ret;
-
-	/* Disable cascade port functionality unless this device
-	 * is used in a cascade configuration, and set the switch's
-	 * DSA device number.
-	 */
-	if (ds->dst->pd->nr_chips > 1)
-		ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2,
-					  GLOBAL_CONTROL_2_MULTIPLE_CASCADE |
-					  (ds->index & 0x1f));
-	else
-		ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2,
-					  GLOBAL_CONTROL_2_NO_CASCADE |
-					  (ds->index & 0x1f));
-	if (ret)
-		return ret;
 
 	/* Force the priority of IGMP/MLD snoop frames and ARP frames
 	 * to the highest setting.
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 4c14f9f..df7a810 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -86,17 +86,6 @@ static const char *mv88e6171_drv_probe(struct device *dsa_dev,
 				   ARRAY_SIZE(mv88e6171_table));
 }
 
-static int mv88e6171_setup_global(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-
-	/* Disable remote management for now, and set the switch's
-	 * DSA device number.
-	 */
-	return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2,
-				   ds->index & 0x1f);
-}
-
 static int mv88e6171_setup(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -108,10 +97,6 @@ static int mv88e6171_setup(struct dsa_switch *ds)
 	if (ret < 0)
 		return ret;
 
-	ret = mv88e6171_setup_global(ds);
-	if (ret < 0)
-		return ret;
-
 	return mv88e6xxx_setup_ports(ds);
 }
 
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 52547d0..b24bae1 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -137,16 +137,6 @@ static const char *mv88e6352_drv_probe(struct device *dsa_dev,
 				   ARRAY_SIZE(mv88e6352_table));
 }
 
-static int mv88e6352_setup_global(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-
-	/* Disable remote management for now, and set the switch's
-	 * DSA device number.
-	 */
-	return mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x1c, ds->index & 0x1f);
-}
-
 static int mv88e6352_setup(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -158,10 +148,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
 	if (ret < 0)
 		return ret;
 
-	ret = mv88e6352_setup_global(ds);
-	if (ret < 0)
-		return ret;
-
 	return mv88e6xxx_setup_ports(ds);
 }
 
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index de37f20..2c4594b 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2949,6 +2949,13 @@ static int _mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
 	if (err)
 		return err;
 
+	/* Disable remote management, and set the switch's DSA device number. */
+	err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2,
+				   GLOBAL_CONTROL_2_MULTIPLE_CASCADE |
+				   (ds->index & 0x1f));
+	if (err)
+		return err;
+
 	/* Set the default address aging time to 5 minutes, and
 	 * enable address learn messages to be sent to all message
 	 * ports.
-- 
2.8.2

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

* [RFC PATCH net-next 17/20] net: dsa: mv88e6xxx: factorize frames priorities
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (15 preceding siblings ...)
  2016-05-05 22:41 ` [RFC PATCH net-next 16/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL_2 setup Vivien Didelot
@ 2016-05-05 22:41 ` Vivien Didelot
  2016-05-05 22:41 ` [RFC PATCH net-next 18/20] net: dsa: mv88e6xxx: factorize switch setup Vivien Didelot
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:41 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

6131 is the only driver to setup the priority of IGMP/MLD snoop frames
and ARP frames to the highest setting. Drop such change until we figure
out a common configuration for all switch models.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6131.c | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 14d0722..4ab617a 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -74,20 +74,6 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev,
 				   ARRAY_SIZE(mv88e6131_table));
 }
 
-static int mv88e6131_setup_global(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-
-	/* Force the priority of IGMP/MLD snoop frames and ARP frames
-	 * to the highest setting.
-	 */
-	return mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE,
-				   GLOBAL2_PRIO_OVERRIDE_FORCE_SNOOP |
-				   7 << GLOBAL2_PRIO_OVERRIDE_SNOOP_SHIFT |
-				   GLOBAL2_PRIO_OVERRIDE_FORCE_ARP |
-				   7 << GLOBAL2_PRIO_OVERRIDE_ARP_SHIFT);
-}
-
 static int mv88e6131_setup(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -99,10 +85,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
 	if (ret < 0)
 		return ret;
 
-	ret = mv88e6131_setup_global(ds);
-	if (ret < 0)
-		return ret;
-
 	return mv88e6xxx_setup_ports(ds);
 }
 
-- 
2.8.2

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

* [RFC PATCH net-next 18/20] net: dsa: mv88e6xxx: factorize switch setup
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (16 preceding siblings ...)
  2016-05-05 22:41 ` [RFC PATCH net-next 17/20] net: dsa: mv88e6xxx: factorize frames priorities Vivien Didelot
@ 2016-05-05 22:41 ` Vivien Didelot
  2016-05-05 22:41 ` [RFC PATCH net-next 19/20] net: dsa: mv88e6xxx: factorize tag protocol Vivien Didelot
  2016-05-05 22:41 ` [RFC PATCH net-next 20/20] net: dsa: mv88e6xxx: factorize the switch driver Vivien Didelot
  19 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:41 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Provide a shared mv88e6xxx_setup function to the drivers.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c | 16 +----------
 drivers/net/dsa/mv88e6131.c | 16 +----------
 drivers/net/dsa/mv88e6171.c | 16 +----------
 drivers/net/dsa/mv88e6352.c | 16 +----------
 drivers/net/dsa/mv88e6xxx.c | 69 ++++++++++++++++++++++-----------------------
 drivers/net/dsa/mv88e6xxx.h |  3 +-
 6 files changed, 38 insertions(+), 98 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 9d3f672..bad4b8d 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -54,24 +54,10 @@ static const char *mv88e6123_drv_probe(struct device *dsa_dev,
 				   ARRAY_SIZE(mv88e6123_table));
 }
 
-static int mv88e6123_setup(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int ret;
-
-	ps->ds = ds;
-
-	ret = mv88e6xxx_setup_common(ps);
-	if (ret < 0)
-		return ret;
-
-	return mv88e6xxx_setup_ports(ds);
-}
-
 struct dsa_switch_driver mv88e6123_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
 	.probe			= mv88e6123_drv_probe,
-	.setup			= mv88e6123_setup,
+	.setup			= mv88e6xxx_setup,
 	.set_addr		= mv88e6xxx_set_addr,
 	.phy_read		= mv88e6xxx_phy_read,
 	.phy_write		= mv88e6xxx_phy_write,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 4ab617a..cf7d710 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -74,24 +74,10 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev,
 				   ARRAY_SIZE(mv88e6131_table));
 }
 
-static int mv88e6131_setup(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int ret;
-
-	ps->ds = ds;
-
-	ret = mv88e6xxx_setup_common(ps);
-	if (ret < 0)
-		return ret;
-
-	return mv88e6xxx_setup_ports(ds);
-}
-
 struct dsa_switch_driver mv88e6131_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_DSA,
 	.probe			= mv88e6131_drv_probe,
-	.setup			= mv88e6131_setup,
+	.setup			= mv88e6xxx_setup,
 	.set_addr		= mv88e6xxx_set_addr,
 	.phy_read		= mv88e6xxx_phy_read,
 	.phy_write		= mv88e6xxx_phy_write,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index df7a810..a5f32dc 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -86,24 +86,10 @@ static const char *mv88e6171_drv_probe(struct device *dsa_dev,
 				   ARRAY_SIZE(mv88e6171_table));
 }
 
-static int mv88e6171_setup(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int ret;
-
-	ps->ds = ds;
-
-	ret = mv88e6xxx_setup_common(ps);
-	if (ret < 0)
-		return ret;
-
-	return mv88e6xxx_setup_ports(ds);
-}
-
 struct dsa_switch_driver mv88e6171_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
 	.probe			= mv88e6171_drv_probe,
-	.setup			= mv88e6171_setup,
+	.setup			= mv88e6xxx_setup,
 	.set_addr		= mv88e6xxx_set_addr,
 	.phy_read		= mv88e6xxx_phy_read,
 	.phy_write		= mv88e6xxx_phy_write,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index b24bae1..d34eff5 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -137,24 +137,10 @@ static const char *mv88e6352_drv_probe(struct device *dsa_dev,
 				   ARRAY_SIZE(mv88e6352_table));
 }
 
-static int mv88e6352_setup(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int ret;
-
-	ps->ds = ds;
-
-	ret = mv88e6xxx_setup_common(ps);
-	if (ret < 0)
-		return ret;
-
-	return mv88e6xxx_setup_ports(ds);
-}
-
 struct dsa_switch_driver mv88e6352_switch_driver = {
 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
 	.probe			= mv88e6352_drv_probe,
-	.setup			= mv88e6352_setup,
+	.setup			= mv88e6xxx_setup,
 	.set_addr		= mv88e6xxx_set_addr,
 	.phy_read		= mv88e6xxx_phy_read,
 	.phy_write		= mv88e6xxx_phy_write,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 2c4594b..ad0513d 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2630,14 +2630,12 @@ static int mv88e6xxx_power_on_serdes(struct mv88e6xxx_priv_state *ps)
 	return ret;
 }
 
-static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
+static int _mv88e6xxx_setup_port(struct mv88e6xxx_priv_state *ps, int port)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	struct dsa_switch *ds = ps->ds;
 	int ret;
 	u16 reg;
 
-	mutex_lock(&ps->smi_mutex);
-
 	if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
 	    mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
 	    mv88e6xxx_6185_family(ps) || mv88e6xxx_6095_family(ps) ||
@@ -2666,7 +2664,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 		ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
 					   PORT_PCS_CTRL, reg);
 		if (ret)
-			goto abort;
+			return ret;
 	}
 
 	/* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
@@ -2730,7 +2728,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 		ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
 					   PORT_CONTROL, reg);
 		if (ret)
-			goto abort;
+			return ret;
 	}
 
 	/* If this port is connected to a SerDes, make sure the SerDes is not
@@ -2739,14 +2737,14 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 	if (mv88e6xxx_6352_family(ps)) {
 		ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_STATUS);
 		if (ret < 0)
-			goto abort;
+			return ret;
 		ret &= PORT_STATUS_CMODE_MASK;
 		if ((ret == PORT_STATUS_CMODE_100BASE_X) ||
 		    (ret == PORT_STATUS_CMODE_1000BASE_X) ||
 		    (ret == PORT_STATUS_CMODE_SGMII)) {
 			ret = mv88e6xxx_power_on_serdes(ps);
 			if (ret < 0)
-				goto abort;
+				return ret;
 		}
 	}
 
@@ -2783,7 +2781,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 		ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
 					   PORT_CONTROL_2, reg);
 		if (ret)
-			goto abort;
+			return ret;
 	}
 
 	/* Port Association Vector: when learning source addresses
@@ -2798,13 +2796,13 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 
 	ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_ASSOC_VECTOR, reg);
 	if (ret)
-		goto abort;
+		return ret;
 
 	/* Egress rate control 2: disable egress rate control. */
 	ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_RATE_CONTROL_2,
 				   0x0000);
 	if (ret)
-		goto abort;
+		return ret;
 
 	if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
 	    mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
@@ -2816,7 +2814,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 		ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
 					   PORT_PAUSE_CTRL, 0x0000);
 		if (ret)
-			goto abort;
+			return ret;
 
 		/* Port ATU control: disable limiting the number of
 		 * address database entries that this port is allowed
@@ -2830,7 +2828,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 		ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
 					   PORT_PRI_OVERRIDE, 0x0000);
 		if (ret)
-			goto abort;
+			return ret;
 
 		/* Port Ethertype: use the Ethertype DSA Ethertype
 		 * value.
@@ -2838,14 +2836,14 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 		ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
 					   PORT_ETH_TYPE, ETH_P_EDSA);
 		if (ret)
-			goto abort;
+			return ret;
 		/* Tag Remap: use an identity 802.1p prio -> switch
 		 * prio mapping.
 		 */
 		ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
 					   PORT_TAG_REGMAP_0123, 0x3210);
 		if (ret)
-			goto abort;
+			return ret;
 
 		/* Tag Remap 2: use an identity 802.1p prio -> switch
 		 * prio mapping.
@@ -2853,7 +2851,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 		ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
 					   PORT_TAG_REGMAP_4567, 0x7654);
 		if (ret)
-			goto abort;
+			return ret;
 	}
 
 	if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
@@ -2864,7 +2862,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 		ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
 					   PORT_RATE_CONTROL, 0x0001);
 		if (ret)
-			goto abort;
+			return ret;
 	}
 
 	/* Port Control 1: disable trunking, disable sending
@@ -2872,7 +2870,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 	 */
 	ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL_1, 0x0000);
 	if (ret)
-		goto abort;
+		return ret;
 
 	/* Port based VLAN map: give each port the same default address
 	 * database, and allow bidirectional communication between the
@@ -2880,33 +2878,20 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
 	 */
 	ret = _mv88e6xxx_port_fid_set(ps, port, 0);
 	if (ret)
-		goto abort;
+		return ret;
 
 	ret = _mv88e6xxx_port_based_vlan_map(ps, port);
 	if (ret)
-		goto abort;
+		return ret;
 
 	/* Default VLAN ID and priority: don't set a default VLAN
 	 * ID, and set the default packet priority to zero.
 	 */
 	ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_DEFAULT_VLAN,
 				   0x0000);
-abort:
-	mutex_unlock(&ps->smi_mutex);
-	return ret;
-}
-
-int mv88e6xxx_setup_ports(struct dsa_switch *ds)
-{
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int ret;
-	int i;
+	if (ret)
+		return ret;
 
-	for (i = 0; i < ps->info->num_ports; i++) {
-		ret = mv88e6xxx_setup_port(ds, i);
-		if (ret < 0)
-			return ret;
-	}
 	return 0;
 }
 
@@ -3122,9 +3107,13 @@ static int _mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
 	return err;
 }
 
-int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps)
+int mv88e6xxx_setup(struct dsa_switch *ds)
 {
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int err;
+	int i;
+
+	ps->ds = ds;
 
 	mutex_init(&ps->smi_mutex);
 
@@ -3143,6 +3132,14 @@ int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps)
 		goto unlock;
 
 	err = _mv88e6xxx_setup_global(ps);
+	if (err)
+		goto unlock;
+
+	for (i = 0; i < ps->info->num_ports; i++) {
+		err = _mv88e6xxx_setup_port(ps, i);
+		if (err)
+			goto unlock;
+	}
 
 unlock:
 	mutex_unlock(&ps->smi_mutex);
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index c8677dd..d13e290 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -537,8 +537,7 @@ const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
 				const struct mv88e6xxx_info *table,
 				unsigned int num);
 
-int mv88e6xxx_setup_ports(struct dsa_switch *ds);
-int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps);
+int mv88e6xxx_setup(struct dsa_switch *ds);
 int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg);
 int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr,
 			int reg, u16 val);
-- 
2.8.2

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

* [RFC PATCH net-next 19/20] net: dsa: mv88e6xxx: factorize tag protocol
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (17 preceding siblings ...)
  2016-05-05 22:41 ` [RFC PATCH net-next 18/20] net: dsa: mv88e6xxx: factorize switch setup Vivien Didelot
@ 2016-05-05 22:41 ` Vivien Didelot
  2016-05-06  1:09   ` Andrew Lunn
  2016-05-05 22:41 ` [RFC PATCH net-next 20/20] net: dsa: mv88e6xxx: factorize the switch driver Vivien Didelot
  19 siblings, 1 reply; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:41 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

6131 is the only driver to set the tag protocol to DSA_TAG_PROTO_DSA.
Since it works fine with DSA_TAG_PROTO_EDSA, change its value, like all
other mv88e6xxx drivers.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/Kconfig     | 2 +-
 drivers/net/dsa/mv88e6131.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 4aaadce..7e01dce 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -17,7 +17,7 @@ config NET_DSA_MV88E6131
 	tristate "Marvell 88E6085/6095/6095F/6131 ethernet switch chip support"
 	depends on NET_DSA
 	select NET_DSA_MV88E6XXX
-	select NET_DSA_TAG_DSA
+	select NET_DSA_TAG_EDSA
 	---help---
 	  This enables support for the Marvell 88E6085/6095/6095F/6131
 	  ethernet switch chips.
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index cf7d710..81640f6 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -75,7 +75,7 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev,
 }
 
 struct dsa_switch_driver mv88e6131_switch_driver = {
-	.tag_protocol		= DSA_TAG_PROTO_DSA,
+	.tag_protocol		= DSA_TAG_PROTO_EDSA,
 	.probe			= mv88e6131_drv_probe,
 	.setup			= mv88e6xxx_setup,
 	.set_addr		= mv88e6xxx_set_addr,
-- 
2.8.2

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

* [RFC PATCH net-next 20/20] net: dsa: mv88e6xxx: factorize the switch driver
  2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
                   ` (18 preceding siblings ...)
  2016-05-05 22:41 ` [RFC PATCH net-next 19/20] net: dsa: mv88e6xxx: factorize tag protocol Vivien Didelot
@ 2016-05-05 22:41 ` Vivien Didelot
  2016-05-06  1:14   ` Andrew Lunn
  19 siblings, 1 reply; 31+ messages in thread
From: Vivien Didelot @ 2016-05-05 22:41 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Now that all drivers support the same set of functions and the same
setup code, drop every model-specific DSA switch driver and replace them
with a common mv88e6xxx driver.

This merges the info tables into one, removes the function exports, the
model-specific files, and update the defconfigs.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 arch/arm/configs/multi_v5_defconfig |   5 +-
 arch/arm/configs/mvebu_v7_defconfig |   2 +-
 arch/arm/configs/orion5x_defconfig  |   3 +-
 arch/tile/configs/tilegx_defconfig  |   3 +-
 arch/tile/configs/tilepro_defconfig |   3 +-
 drivers/net/dsa/Kconfig             |  34 +--
 drivers/net/dsa/Makefile            |  15 +-
 drivers/net/dsa/mv88e6123.c         |  96 --------
 drivers/net/dsa/mv88e6131.c         | 117 ---------
 drivers/net/dsa/mv88e6171.c         | 129 ----------
 drivers/net/dsa/mv88e6352.c         | 181 --------------
 drivers/net/dsa/mv88e6xxx.c         | 461 +++++++++++++++++++++++++++++-------
 drivers/net/dsa/mv88e6xxx.h         |  94 ++------
 13 files changed, 406 insertions(+), 737 deletions(-)
 delete mode 100644 drivers/net/dsa/mv88e6123.c
 delete mode 100644 drivers/net/dsa/mv88e6131.c
 delete mode 100644 drivers/net/dsa/mv88e6171.c
 delete mode 100644 drivers/net/dsa/mv88e6352.c

diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
index e11d99d..690352d 100644
--- a/arch/arm/configs/multi_v5_defconfig
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -91,10 +91,7 @@ CONFIG_SATA_AHCI=y
 CONFIG_SATA_MV=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_DSA_MV88E6060=y
-CONFIG_NET_DSA_MV88E6131=y
-CONFIG_NET_DSA_MV88E6123=y
-CONFIG_NET_DSA_MV88E6171=y
-CONFIG_NET_DSA_MV88E6352=y
+CONFIG_NET_DSA_MV88E6XXX=y
 CONFIG_MV643XX_ETH=y
 CONFIG_R8169=y
 CONFIG_MARVELL_PHY=y
diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
index dc5797a..6492407 100644
--- a/arch/arm/configs/mvebu_v7_defconfig
+++ b/arch/arm/configs/mvebu_v7_defconfig
@@ -66,7 +66,7 @@ CONFIG_SATA_AHCI=y
 CONFIG_AHCI_MVEBU=y
 CONFIG_SATA_MV=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_DSA_MV88E6171=y
+CONFIG_NET_DSA_MV88E6XXX=y
 CONFIG_MV643XX_ETH=y
 CONFIG_MVNETA=y
 CONFIG_MVPP2=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 6a5bc27..27a70a7 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -85,8 +85,7 @@ CONFIG_ATA=y
 CONFIG_SATA_MV=y
 CONFIG_NETDEVICES=y
 CONFIG_MII=y
-CONFIG_NET_DSA_MV88E6131=y
-CONFIG_NET_DSA_MV88E6123=y
+CONFIG_NET_DSA_MV88E6XXX=y
 CONFIG_MV643XX_ETH=y
 CONFIG_MARVELL_PHY=y
 # CONFIG_INPUT_MOUSEDEV is not set
diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig
index 3f3dfb8..7189055 100644
--- a/arch/tile/configs/tilegx_defconfig
+++ b/arch/tile/configs/tilegx_defconfig
@@ -221,8 +221,7 @@ CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_TUN=y
 CONFIG_VETH=m
 CONFIG_NET_DSA_MV88E6060=y
-CONFIG_NET_DSA_MV88E6131=y
-CONFIG_NET_DSA_MV88E6123=y
+CONFIG_NET_DSA_MV88E6XXX=y
 CONFIG_SKY2=y
 CONFIG_PTP_1588_CLOCK_TILEGX=y
 # CONFIG_WLAN is not set
diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig
index ef9e27e..dc85468 100644
--- a/arch/tile/configs/tilepro_defconfig
+++ b/arch/tile/configs/tilepro_defconfig
@@ -340,8 +340,7 @@ CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_TUN=y
 CONFIG_VETH=m
 CONFIG_NET_DSA_MV88E6060=y
-CONFIG_NET_DSA_MV88E6131=y
-CONFIG_NET_DSA_MV88E6123=y
+CONFIG_NET_DSA_MV88E6XXX=y
 # CONFIG_NET_VENDOR_3COM is not set
 CONFIG_E1000E=y
 # CONFIG_WLAN is not set
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 7e01dce..b95fa9f 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -1,10 +1,6 @@
 menu "Distributed Switch Architecture drivers"
 	depends on HAVE_NET_DSA
 
-config NET_DSA_MV88E6XXX
-	tristate
-	default n
-
 config NET_DSA_MV88E6060
 	tristate "Marvell 88E6060 ethernet switch chip support"
 	depends on NET_DSA
@@ -13,42 +9,14 @@ config NET_DSA_MV88E6060
 	  This enables support for the Marvell 88E6060 ethernet switch
 	  chip.
 
-config NET_DSA_MV88E6131
+config NET_DSA_MV88E6XXX
 	tristate "Marvell 88E6085/6095/6095F/6131 ethernet switch chip support"
 	depends on NET_DSA
-	select NET_DSA_MV88E6XXX
 	select NET_DSA_TAG_EDSA
 	---help---
 	  This enables support for the Marvell 88E6085/6095/6095F/6131
 	  ethernet switch chips.
 
-config NET_DSA_MV88E6123
-	tristate "Marvell 88E6123/6161/6165 ethernet switch chip support"
-	depends on NET_DSA
-	select NET_DSA_MV88E6XXX
-	select NET_DSA_TAG_EDSA
-	---help---
-	  This enables support for the Marvell 88E6123/6161/6165
-	  ethernet switch chips.
-
-config NET_DSA_MV88E6171
-	tristate "Marvell 88E6171/6175/6350/6351 ethernet switch chip support"
-	depends on NET_DSA
-	select NET_DSA_MV88E6XXX
-	select NET_DSA_TAG_EDSA
-	---help---
-	  This enables support for the Marvell 88E6171/6175/6350/6351
-	  ethernet switches chips.
-
-config NET_DSA_MV88E6352
-	tristate "Marvell 88E6172/6176/6320/6321/6352 ethernet switch chip support"
-	depends on NET_DSA
-	select NET_DSA_MV88E6XXX
-	select NET_DSA_TAG_EDSA
-	---help---
-	  This enables support for the Marvell 88E6172, 88E6176, 88E6320,
-	  88E6321 and 88E6352 ethernet switch chips.
-
 config NET_DSA_BCM_SF2
 	tristate "Broadcom Starfighter 2 Ethernet switch support"
 	depends on HAS_IOMEM && NET_DSA
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index a6e0993..76b751d 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -1,16 +1,3 @@
 obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
-obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx_drv.o
-mv88e6xxx_drv-y += mv88e6xxx.o
-ifdef CONFIG_NET_DSA_MV88E6123
-mv88e6xxx_drv-y += mv88e6123.o
-endif
-ifdef CONFIG_NET_DSA_MV88E6131
-mv88e6xxx_drv-y += mv88e6131.o
-endif
-ifdef CONFIG_NET_DSA_MV88E6352
-mv88e6xxx_drv-y += mv88e6352.o
-endif
-ifdef CONFIG_NET_DSA_MV88E6171
-mv88e6xxx_drv-y += mv88e6171.o
-endif
+obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o
 obj-$(CONFIG_NET_DSA_BCM_SF2)	+= bcm_sf2.o
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
deleted file mode 100644
index bad4b8d..0000000
--- a/drivers/net/dsa/mv88e6123.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 switch chip support
- * Copyright (c) 2008-2009 Marvell Semiconductor
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/phy.h>
-#include <net/dsa.h>
-#include "mv88e6xxx.h"
-
-static const struct mv88e6xxx_info mv88e6123_table[] = {
-	{
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
-		.family = MV88E6XXX_FAMILY_6165,
-		.name = "Marvell 88E6123",
-		.num_databases = 4096,
-		.num_ports = 3,
-		.flags = MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
-		.family = MV88E6XXX_FAMILY_6165,
-		.name = "Marvell 88E6161",
-		.num_databases = 4096,
-		.num_ports = 6,
-		.flags = MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
-		.family = MV88E6XXX_FAMILY_6165,
-		.name = "Marvell 88E6165",
-		.num_databases = 4096,
-		.num_ports = 6,
-		.flags = MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP,
-	}
-};
-
-static const char *mv88e6123_drv_probe(struct device *dsa_dev,
-				       struct device *host_dev, int sw_addr,
-				       void **priv)
-{
-	return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
-				   mv88e6123_table,
-				   ARRAY_SIZE(mv88e6123_table));
-}
-
-struct dsa_switch_driver mv88e6123_switch_driver = {
-	.tag_protocol		= DSA_TAG_PROTO_EDSA,
-	.probe			= mv88e6123_drv_probe,
-	.setup			= mv88e6xxx_setup,
-	.set_addr		= mv88e6xxx_set_addr,
-	.phy_read		= mv88e6xxx_phy_read,
-	.phy_write		= mv88e6xxx_phy_write,
-	.set_eee		= mv88e6xxx_set_eee,
-	.get_eee		= mv88e6xxx_get_eee,
-	.get_strings		= mv88e6xxx_get_strings,
-	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
-	.get_sset_count		= mv88e6xxx_get_sset_count,
-	.adjust_link		= mv88e6xxx_adjust_link,
-#ifdef CONFIG_NET_DSA_HWMON
-	.get_temp		= mv88e6xxx_get_temp,
-	.get_temp_limit		= mv88e6xxx_get_temp_limit,
-	.set_temp_limit		= mv88e6xxx_set_temp_limit,
-	.get_temp_alarm		= mv88e6xxx_get_temp_alarm,
-#endif
-	.get_eeprom		= mv88e6xxx_get_eeprom,
-	.set_eeprom		= mv88e6xxx_set_eeprom,
-	.get_regs_len		= mv88e6xxx_get_regs_len,
-	.get_regs		= mv88e6xxx_get_regs,
-	.port_bridge_join	= mv88e6xxx_port_bridge_join,
-	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
-	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
-	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
-	.port_vlan_prepare	= mv88e6xxx_port_vlan_prepare,
-	.port_vlan_add		= mv88e6xxx_port_vlan_add,
-	.port_vlan_del		= mv88e6xxx_port_vlan_del,
-	.port_vlan_dump		= mv88e6xxx_port_vlan_dump,
-	.port_fdb_prepare       = mv88e6xxx_port_fdb_prepare,
-	.port_fdb_add           = mv88e6xxx_port_fdb_add,
-	.port_fdb_del           = mv88e6xxx_port_fdb_del,
-	.port_fdb_dump          = mv88e6xxx_port_fdb_dump,
-};
-
-MODULE_ALIAS("platform:mv88e6123");
-MODULE_ALIAS("platform:mv88e6161");
-MODULE_ALIAS("platform:mv88e6165");
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
deleted file mode 100644
index 81640f6..0000000
--- a/drivers/net/dsa/mv88e6131.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * net/dsa/mv88e6131.c - Marvell 88e6095/6095f/6131 switch chip support
- * Copyright (c) 2008-2009 Marvell Semiconductor
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/phy.h>
-#include <net/dsa.h>
-#include "mv88e6xxx.h"
-
-static const struct mv88e6xxx_info mv88e6131_table[] = {
-	{
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
-		.family = MV88E6XXX_FAMILY_6095,
-		.name = "Marvell 88E6095/88E6095F",
-		.num_databases = 256,
-		.num_ports = 11,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_CORE_TAG_TYPE |
-			MV88E6XXX_FLAG_PPU |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
-		.family = MV88E6XXX_FAMILY_6097,
-		.name = "Marvell 88E6085",
-		.num_databases = 4096,
-		.num_ports = 10,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_CORE_TAG_TYPE |
-			MV88E6XXX_FLAG_PPU |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
-		.family = MV88E6XXX_FAMILY_6185,
-		.name = "Marvell 88E6131",
-		.num_databases = 256,
-		.num_ports = 8,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_CORE_TAG_TYPE |
-			MV88E6XXX_FLAG_PPU |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
-		.family = MV88E6XXX_FAMILY_6185,
-		.name = "Marvell 88E6185",
-		.num_databases = 256,
-		.num_ports = 10,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_CORE_TAG_TYPE |
-			MV88E6XXX_FLAG_PPU |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}
-};
-
-static const char *mv88e6131_drv_probe(struct device *dsa_dev,
-				       struct device *host_dev, int sw_addr,
-				       void **priv)
-{
-	return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
-				   mv88e6131_table,
-				   ARRAY_SIZE(mv88e6131_table));
-}
-
-struct dsa_switch_driver mv88e6131_switch_driver = {
-	.tag_protocol		= DSA_TAG_PROTO_EDSA,
-	.probe			= mv88e6131_drv_probe,
-	.setup			= mv88e6xxx_setup,
-	.set_addr		= mv88e6xxx_set_addr,
-	.phy_read		= mv88e6xxx_phy_read,
-	.phy_write		= mv88e6xxx_phy_write,
-	.set_eee		= mv88e6xxx_set_eee,
-	.get_eee		= mv88e6xxx_get_eee,
-	.get_strings		= mv88e6xxx_get_strings,
-	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
-	.get_sset_count		= mv88e6xxx_get_sset_count,
-	.get_eeprom		= mv88e6xxx_get_eeprom,
-	.set_eeprom		= mv88e6xxx_set_eeprom,
-	.get_regs_len		= mv88e6xxx_get_regs_len,
-	.get_regs		= mv88e6xxx_get_regs,
-#ifdef CONFIG_NET_DSA_HWMON
-	.get_temp		= mv88e6xxx_get_temp,
-	.get_temp_limit		= mv88e6xxx_get_temp_limit,
-	.set_temp_limit		= mv88e6xxx_set_temp_limit,
-	.get_temp_alarm		= mv88e6xxx_get_temp_alarm,
-#endif
-	.adjust_link		= mv88e6xxx_adjust_link,
-	.port_bridge_join	= mv88e6xxx_port_bridge_join,
-	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
-	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
-	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
-	.port_vlan_prepare	= mv88e6xxx_port_vlan_prepare,
-	.port_vlan_add		= mv88e6xxx_port_vlan_add,
-	.port_vlan_del		= mv88e6xxx_port_vlan_del,
-	.port_vlan_dump		= mv88e6xxx_port_vlan_dump,
-	.port_fdb_prepare       = mv88e6xxx_port_fdb_prepare,
-	.port_fdb_add           = mv88e6xxx_port_fdb_add,
-	.port_fdb_del           = mv88e6xxx_port_fdb_del,
-	.port_fdb_dump          = mv88e6xxx_port_fdb_dump,
-};
-
-MODULE_ALIAS("platform:mv88e6085");
-MODULE_ALIAS("platform:mv88e6095");
-MODULE_ALIAS("platform:mv88e6095f");
-MODULE_ALIAS("platform:mv88e6131");
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
deleted file mode 100644
index a5f32dc..0000000
--- a/drivers/net/dsa/mv88e6171.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* net/dsa/mv88e6171.c - Marvell 88e6171 switch chip support
- * Copyright (c) 2008-2009 Marvell Semiconductor
- * Copyright (c) 2014 Claudio Leite <leitec@staticky.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/phy.h>
-#include <net/dsa.h>
-#include "mv88e6xxx.h"
-
-static const struct mv88e6xxx_info mv88e6171_table[] = {
-	{
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
-		.family = MV88E6XXX_FAMILY_6351,
-		.name = "Marvell 88E6171",
-		.num_databases = 4096,
-		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_PORTSTATE |
-			MV88E6XXX_FLAG_PPU_ACTIVE |
-			MV88E6XXX_FLAG_SMI_PHY |
-			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
-		.family = MV88E6XXX_FAMILY_6351,
-		.name = "Marvell 88E6175",
-		.num_databases = 4096,
-		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_PORTSTATE |
-			MV88E6XXX_FLAG_PPU_ACTIVE |
-			MV88E6XXX_FLAG_SMI_PHY |
-			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
-		.family = MV88E6XXX_FAMILY_6351,
-		.name = "Marvell 88E6350",
-		.num_databases = 4096,
-		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_PORTSTATE |
-			MV88E6XXX_FLAG_PPU_ACTIVE |
-			MV88E6XXX_FLAG_SMI_PHY |
-			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
-		.family = MV88E6XXX_FAMILY_6351,
-		.name = "Marvell 88E6351",
-		.num_databases = 4096,
-		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_PORTSTATE |
-			MV88E6XXX_FLAG_PPU_ACTIVE |
-			MV88E6XXX_FLAG_SMI_PHY |
-			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}
-};
-
-static const char *mv88e6171_drv_probe(struct device *dsa_dev,
-				       struct device *host_dev, int sw_addr,
-				       void **priv)
-{
-	return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
-				   mv88e6171_table,
-				   ARRAY_SIZE(mv88e6171_table));
-}
-
-struct dsa_switch_driver mv88e6171_switch_driver = {
-	.tag_protocol		= DSA_TAG_PROTO_EDSA,
-	.probe			= mv88e6171_drv_probe,
-	.setup			= mv88e6xxx_setup,
-	.set_addr		= mv88e6xxx_set_addr,
-	.phy_read		= mv88e6xxx_phy_read,
-	.phy_write		= mv88e6xxx_phy_write,
-	.set_eee		= mv88e6xxx_set_eee,
-	.get_eee		= mv88e6xxx_get_eee,
-	.get_strings		= mv88e6xxx_get_strings,
-	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
-	.get_sset_count		= mv88e6xxx_get_sset_count,
-	.adjust_link		= mv88e6xxx_adjust_link,
-#ifdef CONFIG_NET_DSA_HWMON
-	.get_temp		= mv88e6xxx_get_temp,
-	.get_temp_limit		= mv88e6xxx_get_temp_limit,
-	.set_temp_limit		= mv88e6xxx_set_temp_limit,
-	.get_temp_alarm		= mv88e6xxx_get_temp_alarm,
-#endif
-	.get_eeprom		= mv88e6xxx_get_eeprom,
-	.set_eeprom		= mv88e6xxx_set_eeprom,
-	.get_regs_len		= mv88e6xxx_get_regs_len,
-	.get_regs		= mv88e6xxx_get_regs,
-	.port_bridge_join	= mv88e6xxx_port_bridge_join,
-	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
-	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
-	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
-	.port_vlan_prepare	= mv88e6xxx_port_vlan_prepare,
-	.port_vlan_add		= mv88e6xxx_port_vlan_add,
-	.port_vlan_del		= mv88e6xxx_port_vlan_del,
-	.port_vlan_dump		= mv88e6xxx_port_vlan_dump,
-	.port_fdb_prepare	= mv88e6xxx_port_fdb_prepare,
-	.port_fdb_add		= mv88e6xxx_port_fdb_add,
-	.port_fdb_del		= mv88e6xxx_port_fdb_del,
-	.port_fdb_dump		= mv88e6xxx_port_fdb_dump,
-};
-
-MODULE_ALIAS("platform:mv88e6171");
-MODULE_ALIAS("platform:mv88e6175");
-MODULE_ALIAS("platform:mv88e6350");
-MODULE_ALIAS("platform:mv88e6351");
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
deleted file mode 100644
index d34eff5..0000000
--- a/drivers/net/dsa/mv88e6352.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * net/dsa/mv88e6352.c - Marvell 88e6352 switch chip support
- *
- * Copyright (c) 2014 Guenter Roeck
- *
- * Derived from mv88e6123_61_65.c
- * Copyright (c) 2008-2009 Marvell Semiconductor
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/platform_device.h>
-#include <linux/phy.h>
-#include <net/dsa.h>
-#include "mv88e6xxx.h"
-
-static const struct mv88e6xxx_info mv88e6352_table[] = {
-	{
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
-		.family = MV88E6XXX_FAMILY_6320,
-		.name = "Marvell 88E6320",
-		.num_databases = 4096,
-		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_EEE |
-			MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_PORTSTATE |
-			MV88E6XXX_FLAG_PPU_ACTIVE |
-			MV88E6XXX_FLAG_SMI_PHY |
-			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
-		.family = MV88E6XXX_FAMILY_6320,
-		.name = "Marvell 88E6321",
-		.num_databases = 4096,
-		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_EEE |
-			MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_PORTSTATE |
-			MV88E6XXX_FLAG_PPU_ACTIVE |
-			MV88E6XXX_FLAG_SMI_PHY |
-			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
-		.family = MV88E6XXX_FAMILY_6352,
-		.name = "Marvell 88E6172",
-		.num_databases = 4096,
-		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_EEE |
-			MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_PORTSTATE |
-			MV88E6XXX_FLAG_PPU_ACTIVE |
-			MV88E6XXX_FLAG_SMI_PHY |
-			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
-		.family = MV88E6XXX_FAMILY_6352,
-		.name = "Marvell 88E6176",
-		.num_databases = 4096,
-		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_EEE |
-			MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_PORTSTATE |
-			MV88E6XXX_FLAG_PPU_ACTIVE |
-			MV88E6XXX_FLAG_SMI_PHY |
-			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
-		.family = MV88E6XXX_FAMILY_6352,
-		.name = "Marvell 88E6240",
-		.num_databases = 4096,
-		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_EEE |
-			MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_PORTSTATE |
-			MV88E6XXX_FLAG_PPU_ACTIVE |
-			MV88E6XXX_FLAG_SMI_PHY |
-			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}, {
-		.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
-		.family = MV88E6XXX_FAMILY_6352,
-		.name = "Marvell 88E6352",
-		.num_databases = 4096,
-		.num_ports = 7,
-		.flags = MV88E6XXX_FLAG_ATU |
-			MV88E6XXX_FLAG_EEE |
-			MV88E6XXX_FLAG_EEPROM |
-			MV88E6XXX_FLAG_PORTSTATE |
-			MV88E6XXX_FLAG_PPU_ACTIVE |
-			MV88E6XXX_FLAG_SMI_PHY |
-			MV88E6XXX_FLAG_SWITCH_MAC |
-			MV88E6XXX_FLAG_TEMP |
-			MV88E6XXX_FLAG_TEMP_LIMIT |
-			MV88E6XXX_FLAG_VLANTABLE |
-			MV88E6XXX_FLAG_VTU,
-	}
-};
-
-static const char *mv88e6352_drv_probe(struct device *dsa_dev,
-				       struct device *host_dev, int sw_addr,
-				       void **priv)
-{
-	return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
-				   mv88e6352_table,
-				   ARRAY_SIZE(mv88e6352_table));
-}
-
-struct dsa_switch_driver mv88e6352_switch_driver = {
-	.tag_protocol		= DSA_TAG_PROTO_EDSA,
-	.probe			= mv88e6352_drv_probe,
-	.setup			= mv88e6xxx_setup,
-	.set_addr		= mv88e6xxx_set_addr,
-	.phy_read		= mv88e6xxx_phy_read,
-	.phy_write		= mv88e6xxx_phy_write,
-	.get_strings		= mv88e6xxx_get_strings,
-	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
-	.get_sset_count		= mv88e6xxx_get_sset_count,
-	.adjust_link		= mv88e6xxx_adjust_link,
-	.set_eee		= mv88e6xxx_set_eee,
-	.get_eee		= mv88e6xxx_get_eee,
-#ifdef CONFIG_NET_DSA_HWMON
-	.get_temp		= mv88e6xxx_get_temp,
-	.get_temp_limit		= mv88e6xxx_get_temp_limit,
-	.set_temp_limit		= mv88e6xxx_set_temp_limit,
-	.get_temp_alarm		= mv88e6xxx_get_temp_alarm,
-#endif
-	.get_eeprom		= mv88e6xxx_get_eeprom,
-	.set_eeprom		= mv88e6xxx_set_eeprom,
-	.get_regs_len		= mv88e6xxx_get_regs_len,
-	.get_regs		= mv88e6xxx_get_regs,
-	.port_bridge_join	= mv88e6xxx_port_bridge_join,
-	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
-	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
-	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
-	.port_vlan_prepare	= mv88e6xxx_port_vlan_prepare,
-	.port_vlan_add		= mv88e6xxx_port_vlan_add,
-	.port_vlan_del		= mv88e6xxx_port_vlan_del,
-	.port_vlan_dump		= mv88e6xxx_port_vlan_dump,
-	.port_fdb_prepare	= mv88e6xxx_port_fdb_prepare,
-	.port_fdb_add		= mv88e6xxx_port_fdb_add,
-	.port_fdb_del		= mv88e6xxx_port_fdb_del,
-	.port_fdb_dump		= mv88e6xxx_port_fdb_dump,
-};
-
-MODULE_ALIAS("platform:mv88e6172");
-MODULE_ALIAS("platform:mv88e6176");
-MODULE_ALIAS("platform:mv88e6320");
-MODULE_ALIAS("platform:mv88e6321");
-MODULE_ALIAS("platform:mv88e6352");
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index ad0513d..fabfbd1 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -386,8 +386,8 @@ static bool mv88e6xxx_has_stu(struct mv88e6xxx_priv_state *ps)
  * phy. However, in the case of a fixed link phy, we force the port
  * settings from the fixed link settings.
  */
-void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
-			   struct phy_device *phydev)
+static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
+				  struct phy_device *phydev)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	u32 reg;
@@ -633,7 +633,8 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_priv_state *ps,
 	return value;
 }
 
-void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
+static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
+				  uint8_t *data)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	struct mv88e6xxx_hw_stat *stat;
@@ -649,7 +650,7 @@ void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
 	}
 }
 
-int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
+static int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	struct mv88e6xxx_hw_stat *stat;
@@ -663,9 +664,8 @@ int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
 	return j;
 }
 
-void
-mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
-			    int port, uint64_t *data)
+static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
+					uint64_t *data)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	struct mv88e6xxx_hw_stat *stat;
@@ -690,13 +690,13 @@ mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
 	mutex_unlock(&ps->smi_mutex);
 }
 
-int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
+static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
 {
 	return 32 * sizeof(u16);
 }
 
-void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
-			struct ethtool_regs *regs, void *_p)
+static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
+			       struct ethtool_regs *regs, void *_p)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	u16 *p = _p;
@@ -846,8 +846,8 @@ static int _mv88e6xxx_get_eeprom(struct mv88e6xxx_priv_state *ps,
 	return 0;
 }
 
-int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
-			 u8 *data)
+static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
+				struct ethtool_eeprom *eeprom, u8 *data)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int err;
@@ -976,8 +976,8 @@ static int _mv88e6xxx_set_eeprom(struct mv88e6xxx_priv_state *ps,
 	return 0;
 }
 
-int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
-			 u8 *data)
+static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
+				struct ethtool_eeprom *eeprom, u8 *data)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int err;
@@ -1031,7 +1031,8 @@ static int _mv88e6xxx_phy_write_indirect(struct mv88e6xxx_priv_state *ps,
 	return _mv88e6xxx_phy_wait(ps);
 }
 
-int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
+static int mv88e6xxx_get_eee(struct dsa_switch *ds, int port,
+			     struct ethtool_eee *e)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int reg;
@@ -1060,8 +1061,8 @@ out:
 	return reg;
 }
 
-int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
-		      struct phy_device *phydev, struct ethtool_eee *e)
+static int mv88e6xxx_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);
 	int reg;
@@ -1354,7 +1355,8 @@ static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_priv_state *ps,
 	return _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_BASE_VLAN, reg);
 }
 
-void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
+					 u8 state)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int stp_state;
@@ -1577,9 +1579,9 @@ static int _mv88e6xxx_vtu_getnext(struct mv88e6xxx_priv_state *ps,
 	return 0;
 }
 
-int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
-			     struct switchdev_obj_port_vlan *vlan,
-			     int (*cb)(struct switchdev_obj *obj))
+static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
+				    struct switchdev_obj_port_vlan *vlan,
+				    int (*cb)(struct switchdev_obj *obj))
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	struct mv88e6xxx_vtu_stu_entry next;
@@ -2004,8 +2006,8 @@ static const char * const mv88e6xxx_port_8021q_mode_names[] = {
 	[PORT_CONTROL_2_8021Q_SECURE] = "Secure",
 };
 
-int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
-				  bool vlan_filtering)
+static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
+					 bool vlan_filtering)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	u16 old, new = vlan_filtering ? PORT_CONTROL_2_8021Q_SECURE :
@@ -2044,9 +2046,9 @@ unlock:
 	return ret;
 }
 
-int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
-				const struct switchdev_obj_port_vlan *vlan,
-				struct switchdev_trans *trans)
+static int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
+				       const struct switchdev_obj_port_vlan *vlan,
+				       struct switchdev_trans *trans)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int err;
@@ -2085,9 +2087,9 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_priv_state *ps, int port,
 	return _mv88e6xxx_vtu_loadpurge(ps, &vlan);
 }
 
-void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
-			     const struct switchdev_obj_port_vlan *vlan,
-			     struct switchdev_trans *trans)
+static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
+				    const struct switchdev_obj_port_vlan *vlan,
+				    struct switchdev_trans *trans)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
@@ -2147,8 +2149,8 @@ static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_priv_state *ps,
 	return _mv88e6xxx_atu_remove(ps, vlan.fid, port, false);
 }
 
-int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
-			    const struct switchdev_obj_port_vlan *vlan)
+static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
+				   const struct switchdev_obj_port_vlan *vlan)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	u16 pvid, vid;
@@ -2261,9 +2263,9 @@ static int _mv88e6xxx_port_fdb_load(struct mv88e6xxx_priv_state *ps, int port,
 	return _mv88e6xxx_atu_load(ps, &entry);
 }
 
-int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
-			       const struct switchdev_obj_port_fdb *fdb,
-			       struct switchdev_trans *trans)
+static int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
+				      const struct switchdev_obj_port_fdb *fdb,
+				      struct switchdev_trans *trans)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
@@ -2276,9 +2278,9 @@ int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
 	return 0;
 }
 
-void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
-			    const struct switchdev_obj_port_fdb *fdb,
-			    struct switchdev_trans *trans)
+static void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
+				   const struct switchdev_obj_port_fdb *fdb,
+				   struct switchdev_trans *trans)
 {
 	int state = is_multicast_ether_addr(fdb->addr) ?
 		GLOBAL_ATU_DATA_STATE_MC_STATIC :
@@ -2294,8 +2296,8 @@ void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
 	mutex_unlock(&ps->smi_mutex);
 }
 
-int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
-			   const struct switchdev_obj_port_fdb *fdb)
+static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
+				  const struct switchdev_obj_port_fdb *fdb)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
@@ -2397,9 +2399,9 @@ static int _mv88e6xxx_port_fdb_dump_one(struct mv88e6xxx_priv_state *ps,
 	return err;
 }
 
-int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
-			    struct switchdev_obj_port_fdb *fdb,
-			    int (*cb)(struct switchdev_obj *obj))
+static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
+				   struct switchdev_obj_port_fdb *fdb,
+				   int (*cb)(struct switchdev_obj *obj))
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	struct mv88e6xxx_vtu_stu_entry vlan = {
@@ -2447,8 +2449,8 @@ unlock:
 	return err;
 }
 
-int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
-			       struct net_device *bridge)
+static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
+				      struct net_device *bridge)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int i, err = 0;
@@ -2474,7 +2476,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
 	return err;
 }
 
-void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
+static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	struct net_device *bridge = ps->ports[port].bridge_dev;
@@ -3107,7 +3109,7 @@ static int _mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
 	return err;
 }
 
-int mv88e6xxx_setup(struct dsa_switch *ds)
+static int mv88e6xxx_setup(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int err;
@@ -3180,8 +3182,7 @@ static int mv88e6xxx_port_to_phy_addr(struct mv88e6xxx_priv_state *ps,
 	return -EINVAL;
 }
 
-int
-mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
+static int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int addr = mv88e6xxx_port_to_phy_addr(ps, port);
@@ -3204,8 +3205,8 @@ mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
 	return ret;
 }
 
-int
-mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
+static int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum,
+			       u16 val)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int addr = mv88e6xxx_port_to_phy_addr(ps, port);
@@ -3289,7 +3290,7 @@ static int _mv88e63xx_get_temp(struct mv88e6xxx_priv_state *ps, int *temp)
 	return 0;
 }
 
-int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
+static int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int err;
@@ -3309,7 +3310,7 @@ int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
 	return err;
 }
 
-int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
+static int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
@@ -3329,7 +3330,7 @@ int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
 	return 0;
 }
 
-int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
+static int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
@@ -3346,7 +3347,7 @@ int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
 					(ret & 0xe0ff) | (temp << 8));
 }
 
-int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
+static int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
@@ -3367,6 +3368,268 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
 }
 #endif /* CONFIG_NET_DSA_HWMON */
 
+static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+	[MV88E6085] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
+		.family = MV88E6XXX_FAMILY_6097,
+		.name = "Marvell 88E6085",
+		.num_databases = 4096,
+		.num_ports = 10,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_CORE_TAG_TYPE |
+			MV88E6XXX_FLAG_PPU |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6095] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
+		.family = MV88E6XXX_FAMILY_6095,
+		.name = "Marvell 88E6095/88E6095F",
+		.num_databases = 256,
+		.num_ports = 11,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_CORE_TAG_TYPE |
+			MV88E6XXX_FLAG_PPU |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6123] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
+		.family = MV88E6XXX_FAMILY_6165,
+		.name = "Marvell 88E6123",
+		.num_databases = 4096,
+		.num_ports = 3,
+		.flags = MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP,
+	},
+
+	[MV88E6131] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
+		.family = MV88E6XXX_FAMILY_6185,
+		.name = "Marvell 88E6131",
+		.num_databases = 256,
+		.num_ports = 8,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_CORE_TAG_TYPE |
+			MV88E6XXX_FLAG_PPU |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6161] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
+		.family = MV88E6XXX_FAMILY_6165,
+		.name = "Marvell 88E6161",
+		.num_databases = 4096,
+		.num_ports = 6,
+		.flags = MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP,
+	},
+
+	[MV88E6165] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
+		.family = MV88E6XXX_FAMILY_6165,
+		.name = "Marvell 88E6165",
+		.num_databases = 4096,
+		.num_ports = 6,
+		.flags = MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP,
+	},
+
+	[MV88E6171] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
+		.family = MV88E6XXX_FAMILY_6351,
+		.name = "Marvell 88E6171",
+		.num_databases = 4096,
+		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6172] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
+		.family = MV88E6XXX_FAMILY_6352,
+		.name = "Marvell 88E6172",
+		.num_databases = 4096,
+		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6175] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
+		.family = MV88E6XXX_FAMILY_6351,
+		.name = "Marvell 88E6175",
+		.num_databases = 4096,
+		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6176] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
+		.family = MV88E6XXX_FAMILY_6352,
+		.name = "Marvell 88E6176",
+		.num_databases = 4096,
+		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6185] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
+		.family = MV88E6XXX_FAMILY_6185,
+		.name = "Marvell 88E6185",
+		.num_databases = 256,
+		.num_ports = 10,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_CORE_TAG_TYPE |
+			MV88E6XXX_FLAG_PPU |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6240] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
+		.family = MV88E6XXX_FAMILY_6352,
+		.name = "Marvell 88E6240",
+		.num_databases = 4096,
+		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6320] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
+		.family = MV88E6XXX_FAMILY_6320,
+		.name = "Marvell 88E6320",
+		.num_databases = 4096,
+		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6321] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
+		.family = MV88E6XXX_FAMILY_6320,
+		.name = "Marvell 88E6321",
+		.num_databases = 4096,
+		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6350] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
+		.family = MV88E6XXX_FAMILY_6351,
+		.name = "Marvell 88E6350",
+		.num_databases = 4096,
+		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6351] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
+		.family = MV88E6XXX_FAMILY_6351,
+		.name = "Marvell 88E6351",
+		.num_databases = 4096,
+		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+
+	[MV88E6352] = {
+		.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
+		.family = MV88E6XXX_FAMILY_6352,
+		.name = "Marvell 88E6352",
+		.num_databases = 4096,
+		.num_ports = 7,
+		.flags = MV88E6XXX_FLAG_ATU |
+			MV88E6XXX_FLAG_EEE |
+			MV88E6XXX_FLAG_EEPROM |
+			MV88E6XXX_FLAG_PORTSTATE |
+			MV88E6XXX_FLAG_PPU_ACTIVE |
+			MV88E6XXX_FLAG_SMI_PHY |
+			MV88E6XXX_FLAG_SWITCH_MAC |
+			MV88E6XXX_FLAG_TEMP |
+			MV88E6XXX_FLAG_TEMP_LIMIT |
+			MV88E6XXX_FLAG_VLANTABLE |
+			MV88E6XXX_FLAG_VTU,
+	},
+};
+
 static const struct mv88e6xxx_info *
 mv88e6xxx_lookup_info(unsigned int prod_num, const struct mv88e6xxx_info *table,
 		      unsigned int num)
@@ -3380,10 +3643,9 @@ mv88e6xxx_lookup_info(unsigned int prod_num, const struct mv88e6xxx_info *table,
 	return NULL;
 }
 
-const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
-				int sw_addr, void **priv,
-				const struct mv88e6xxx_info *table,
-				unsigned int num)
+static const char *mv88e6xxx_probe(struct device *dsa_dev,
+				   struct device *host_dev, int sw_addr,
+				   void **priv)
 {
 	const struct mv88e6xxx_info *info;
 	struct mv88e6xxx_priv_state *ps;
@@ -3402,7 +3664,8 @@ const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
 	prod_num = (id & 0xfff0) >> 4;
 	rev = id & 0x000f;
 
-	info = mv88e6xxx_lookup_info(prod_num, table, num);
+	info = mv88e6xxx_lookup_info(prod_num, mv88e6xxx_table,
+				     ARRAY_SIZE(mv88e6xxx_table));
 	if (!info)
 		return NULL;
 
@@ -3424,41 +3687,73 @@ const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
 	return name;
 }
 
+struct dsa_switch_driver mv88e6xxx_switch_driver = {
+	.tag_protocol		= DSA_TAG_PROTO_EDSA,
+	.probe			= mv88e6xxx_probe,
+	.setup			= mv88e6xxx_setup,
+	.set_addr		= mv88e6xxx_set_addr,
+	.phy_read		= mv88e6xxx_phy_read,
+	.phy_write		= mv88e6xxx_phy_write,
+	.adjust_link		= mv88e6xxx_adjust_link,
+	.get_strings		= mv88e6xxx_get_strings,
+	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
+	.get_sset_count		= mv88e6xxx_get_sset_count,
+	.set_eee		= mv88e6xxx_set_eee,
+	.get_eee		= mv88e6xxx_get_eee,
+#ifdef CONFIG_NET_DSA_HWMON
+	.get_temp		= mv88e6xxx_get_temp,
+	.get_temp_limit		= mv88e6xxx_get_temp_limit,
+	.set_temp_limit		= mv88e6xxx_set_temp_limit,
+	.get_temp_alarm		= mv88e6xxx_get_temp_alarm,
+#endif
+	.get_eeprom		= mv88e6xxx_get_eeprom,
+	.set_eeprom		= mv88e6xxx_set_eeprom,
+	.get_regs_len		= mv88e6xxx_get_regs_len,
+	.get_regs		= mv88e6xxx_get_regs,
+	.port_bridge_join	= mv88e6xxx_port_bridge_join,
+	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
+	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
+	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
+	.port_vlan_prepare	= mv88e6xxx_port_vlan_prepare,
+	.port_vlan_add		= mv88e6xxx_port_vlan_add,
+	.port_vlan_del		= mv88e6xxx_port_vlan_del,
+	.port_vlan_dump		= mv88e6xxx_port_vlan_dump,
+	.port_fdb_prepare       = mv88e6xxx_port_fdb_prepare,
+	.port_fdb_add           = mv88e6xxx_port_fdb_add,
+	.port_fdb_del           = mv88e6xxx_port_fdb_del,
+	.port_fdb_dump          = mv88e6xxx_port_fdb_dump,
+};
+
 static int __init mv88e6xxx_init(void)
 {
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
-	register_switch_driver(&mv88e6131_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123)
-	register_switch_driver(&mv88e6123_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
-	register_switch_driver(&mv88e6352_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
-	register_switch_driver(&mv88e6171_switch_driver);
-#endif
+	register_switch_driver(&mv88e6xxx_switch_driver);
+
 	return 0;
 }
 module_init(mv88e6xxx_init);
 
 static void __exit mv88e6xxx_cleanup(void)
 {
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
-	unregister_switch_driver(&mv88e6171_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
-	unregister_switch_driver(&mv88e6352_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123)
-	unregister_switch_driver(&mv88e6123_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
-	unregister_switch_driver(&mv88e6131_switch_driver);
-#endif
+	unregister_switch_driver(&mv88e6xxx_switch_driver);
 }
 module_exit(mv88e6xxx_cleanup);
 
+MODULE_ALIAS("platform:mv88e6085");
+MODULE_ALIAS("platform:mv88e6095");
+MODULE_ALIAS("platform:mv88e6095f");
+MODULE_ALIAS("platform:mv88e6123");
+MODULE_ALIAS("platform:mv88e6131");
+MODULE_ALIAS("platform:mv88e6161");
+MODULE_ALIAS("platform:mv88e6165");
+MODULE_ALIAS("platform:mv88e6171");
+MODULE_ALIAS("platform:mv88e6172");
+MODULE_ALIAS("platform:mv88e6175");
+MODULE_ALIAS("platform:mv88e6176");
+MODULE_ALIAS("platform:mv88e6320");
+MODULE_ALIAS("platform:mv88e6321");
+MODULE_ALIAS("platform:mv88e6350");
+MODULE_ALIAS("platform:mv88e6351");
+MODULE_ALIAS("platform:mv88e6352");
 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
 MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index d13e290..25bbf77 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -338,6 +338,27 @@
 
 #define MV88E6XXX_N_FID		4096
 
+/* List of supported models */
+enum mv88e6xxx_model {
+	MV88E6085,
+	MV88E6095,
+	MV88E6123,
+	MV88E6131,
+	MV88E6161,
+	MV88E6165,
+	MV88E6171,
+	MV88E6172,
+	MV88E6175,
+	MV88E6176,
+	MV88E6185,
+	MV88E6240,
+	MV88E6320,
+	MV88E6321,
+	MV88E6350,
+	MV88E6351,
+	MV88E6352,
+};
+
 enum mv88e6xxx_family {
 	MV88E6XXX_FAMILY_NONE,
 	MV88E6XXX_FAMILY_6065,	/* 6031 6035 6061 6065 */
@@ -532,77 +553,4 @@ static inline bool mv88e6xxx_has(struct mv88e6xxx_priv_state *ps,
 	return (ps->info->flags & flags) == flags;
 }
 
-const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
-				int sw_addr, void **priv,
-				const struct mv88e6xxx_info *table,
-				unsigned int num);
-
-int mv88e6xxx_setup(struct dsa_switch *ds);
-int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg);
-int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr,
-			int reg, u16 val);
-int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr);
-int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum);
-int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val);
-void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
-void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
-				 uint64_t *data);
-int mv88e6xxx_get_sset_count(struct dsa_switch *ds);
-int mv88e6xxx_get_sset_count_basic(struct dsa_switch *ds);
-void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
-			   struct phy_device *phydev);
-int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port);
-void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
-			struct ethtool_regs *regs, void *_p);
-int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp);
-int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp);
-int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp);
-int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm);
-int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
-			 u8 *data);
-int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
-			 u8 *data);
-int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum);
-int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
-				 u16 val);
-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_port_bridge_join(struct dsa_switch *ds, int port,
-			       struct net_device *bridge);
-void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port);
-void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
-int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
-				  bool vlan_filtering);
-int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
-				const struct switchdev_obj_port_vlan *vlan,
-				struct switchdev_trans *trans);
-void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
-			     const struct switchdev_obj_port_vlan *vlan,
-			     struct switchdev_trans *trans);
-int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
-			    const struct switchdev_obj_port_vlan *vlan);
-int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
-			     struct switchdev_obj_port_vlan *vlan,
-			     int (*cb)(struct switchdev_obj *obj));
-int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
-			       const struct switchdev_obj_port_fdb *fdb,
-			       struct switchdev_trans *trans);
-void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
-			    const struct switchdev_obj_port_fdb *fdb,
-			    struct switchdev_trans *trans);
-int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
-			   const struct switchdev_obj_port_fdb *fdb);
-int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
-			    struct switchdev_obj_port_fdb *fdb,
-			    int (*cb)(struct switchdev_obj *obj));
-int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg);
-int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page,
-			     int reg, int val);
-
-extern struct dsa_switch_driver mv88e6131_switch_driver;
-extern struct dsa_switch_driver mv88e6123_switch_driver;
-extern struct dsa_switch_driver mv88e6352_switch_driver;
-extern struct dsa_switch_driver mv88e6171_switch_driver;
-
 #endif
-- 
2.8.2

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

* Re: [RFC PATCH net-next 01/20] net: dsa: mv88e6xxx: factorize PHY access with PPU
  2016-05-05 22:40 ` [RFC PATCH net-next 01/20] net: dsa: mv88e6xxx: factorize PHY access with PPU Vivien Didelot
@ 2016-05-05 22:54   ` Andrew Lunn
  2016-05-05 22:59   ` Andrew Lunn
  2016-05-05 23:06   ` Andrew Lunn
  2 siblings, 0 replies; 31+ messages in thread
From: Andrew Lunn @ 2016-05-05 22:54 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli

On Thu, May 05, 2016 at 06:40:45PM -0400, Vivien Didelot wrote:
> Add a flags bitmap to the mv88e6xxx_info structure to help describing
> features supported or not by a switch model.
> 
> Add a MV88E6XXX_FLAG_PPU flag to describe switch models with a PHY
> Polling Unit. This allows to merge PPU specific PHY access code in the
> share code. In the meantime, use unlocked register accesses.
> 
> Since the PPU code is shared, also remove NET_DSA_MV88E6XXX_NEED_PPU.

> -#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
> -static int mv88e6xxx_ppu_disable(struct mv88e6xxx_priv_state *ps)
> +static int _mv88e6xxx_ppu_enable(struct mv88e6xxx_priv_state *ps, bool enable)
>  {
> -	int ret;

The change log does not say anything about refactoring
mv88e6xxx_ppu_disable() and mv88e6xxx_ppu_enable() into one function.
That should be in separate patch. Also, i don't see much value in this
refactoring. The names mv88e6xxx_ppu_disable() and
mv88e6xxx_ppu_enable() are much clearer than having one function which
takes a bool.

      Andrew

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

* Re: [RFC PATCH net-next 01/20] net: dsa: mv88e6xxx: factorize PHY access with PPU
  2016-05-05 22:40 ` [RFC PATCH net-next 01/20] net: dsa: mv88e6xxx: factorize PHY access with PPU Vivien Didelot
  2016-05-05 22:54   ` Andrew Lunn
@ 2016-05-05 22:59   ` Andrew Lunn
  2016-05-05 23:06   ` Andrew Lunn
  2 siblings, 0 replies; 31+ messages in thread
From: Andrew Lunn @ 2016-05-05 22:59 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli

> -static int mv88e6xxx_ppu_access_get(struct mv88e6xxx_priv_state *ps)
> +static int _mv88e6xxx_ppu_access_get(struct mv88e6xxx_priv_state *ps)

Hi Vivien

We agreed to stop adding _ to functions that assume the lock has been
taken. Now that we check the lock is held in lowest level function, it
quickly becomes clear if the locks are wrong. It either deadlocks, or
it prints a warning when there is an error.

Please don't rename these functions.

       Andrew

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

* Re: [RFC PATCH net-next 01/20] net: dsa: mv88e6xxx: factorize PHY access with PPU
  2016-05-05 22:40 ` [RFC PATCH net-next 01/20] net: dsa: mv88e6xxx: factorize PHY access with PPU Vivien Didelot
  2016-05-05 22:54   ` Andrew Lunn
  2016-05-05 22:59   ` Andrew Lunn
@ 2016-05-05 23:06   ` Andrew Lunn
  2 siblings, 0 replies; 31+ messages in thread
From: Andrew Lunn @ 2016-05-05 23:06 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli

>  {
>  	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
>  	int addr = mv88e6xxx_port_to_phy_addr(ps, port);
> -	int ret;
> +	int err;
>  
>  	if (addr < 0)
>  		return 0xffff;
>  
> +

We don't want an extra blank line. I'm surprised checkpatch did not
warn about this.

>  	mutex_lock(&ps->smi_mutex);
> -	ret = _mv88e6xxx_phy_write(ps, addr, regnum, val);
> +
> +	if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
> +		err = _mv88e6xxx_phy_write_ppu(ps, addr, regnum, val);
> +	else
> +		err = _mv88e6xxx_phy_write(ps, addr, regnum, val);
> +
>  	mutex_unlock(&ps->smi_mutex);
> -	return ret;
> +
> +	return err;

Please don't rename ret to err. This patch is about phy reading and
writing, and i don't expect to see anything else here. It makes it
harder to review.

	 Andrew

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

* Re: [RFC PATCH net-next 04/20] net: dsa: mv88e6xxx: factorize temperature access
  2016-05-05 22:40 ` [RFC PATCH net-next 04/20] net: dsa: mv88e6xxx: factorize temperature access Vivien Didelot
@ 2016-05-05 23:40   ` Andrew Lunn
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Lunn @ 2016-05-05 23:40 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli

>  int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
>  {
>  	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
> +	int err;
> +
> +	if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP))
> +		return -EOPNOTSUPP;
> +
> +	mutex_lock(&ps->smi_mutex);
>  
>  	if (mv88e6xxx_6320_family(ps) || mv88e6xxx_6352_family(ps))
> -		return mv88e63xx_get_temp(ds, temp);
> +		err = _mv88e63xx_get_temp(ps, temp);
> +	else
> +		err = _mv88e61xx_get_temp(ps, temp);

It seems like this should be done with a flag, rather than the family.

However, don't spend too much time on this. I plan to rip it all out
and put it in the correct place, in the Marvell PHY driver. The
temperature sensor is in the PHY, and other Marvell PHYs also have
this temperature sensor.

     Andrew

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

* Re: [RFC PATCH net-next 13/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup
  2016-05-05 22:40 ` [RFC PATCH net-next 13/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup Vivien Didelot
@ 2016-05-06  0:55   ` Andrew Lunn
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Lunn @ 2016-05-06  0:55 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli

On Thu, May 05, 2016 at 06:40:57PM -0400, Vivien Didelot wrote:
> All switch models configure the GLOBAL_CONTROL register with slightly
> differences.

And as far as i know, we have no idea why.
 
> Assume a common setup to enable the PHY Polling Unit if present, discard
> packets with excessive collisions, set the maximum frame size to 1632,
> and mask all interrupt sources.

This is a behaviour change, not just a refactor. It would be good to
say on which families it has been tested, and which have not.

    Andrew

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

* Re: [RFC PATCH net-next 14/20] net: dsa: mv88e6xxx: factorize VLAN Ethertype
  2016-05-05 22:40 ` [RFC PATCH net-next 14/20] net: dsa: mv88e6xxx: factorize VLAN Ethertype Vivien Didelot
@ 2016-05-06  0:57   ` Andrew Lunn
  2016-05-06 15:12     ` Vivien Didelot
  0 siblings, 1 reply; 31+ messages in thread
From: Andrew Lunn @ 2016-05-06  0:57 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli

On Thu, May 05, 2016 at 06:40:58PM -0400, Vivien Didelot wrote:
> Only the 6131 driver was setting the VLAN Ethertype to 0x8100. Set it to
> all models.
> 
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
> ---
>  drivers/net/dsa/mv88e6131.c | 9 ++++-----
>  drivers/net/dsa/mv88e6xxx.c | 8 ++++++++
>  drivers/net/dsa/mv88e6xxx.h | 7 +++++++
>  3 files changed, 19 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
> index 013668c..4c0b1e9 100644
> --- a/drivers/net/dsa/mv88e6131.c
> +++ b/drivers/net/dsa/mv88e6131.c
> @@ -25,6 +25,7 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
>  		.num_databases = 256,
>  		.num_ports = 11,
>  		.flags = MV88E6XXX_FLAG_ATU |
> +			MV88E6XXX_FLAG_CORE_TAG_TYPE |
>  			MV88E6XXX_FLAG_PPU |
>  			MV88E6XXX_FLAG_VLANTABLE |
>  			MV88E6XXX_FLAG_VTU,
> @@ -35,6 +36,7 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
>  		.num_databases = 4096,
>  		.num_ports = 10,
>  		.flags = MV88E6XXX_FLAG_ATU |
> +			MV88E6XXX_FLAG_CORE_TAG_TYPE |
>  			MV88E6XXX_FLAG_PPU |
>  			MV88E6XXX_FLAG_VLANTABLE |
>  			MV88E6XXX_FLAG_VTU,
> @@ -45,6 +47,7 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
>  		.num_databases = 256,
>  		.num_ports = 8,
>  		.flags = MV88E6XXX_FLAG_ATU |
> +			MV88E6XXX_FLAG_CORE_TAG_TYPE |
>  			MV88E6XXX_FLAG_PPU |
>  			MV88E6XXX_FLAG_VLANTABLE |
>  			MV88E6XXX_FLAG_VTU,
> @@ -55,6 +58,7 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
>  		.num_databases = 256,
>  		.num_ports = 10,
>  		.flags = MV88E6XXX_FLAG_ATU |
> +			MV88E6XXX_FLAG_CORE_TAG_TYPE |
>  			MV88E6XXX_FLAG_PPU |
>  			MV88E6XXX_FLAG_VLANTABLE |
>  			MV88E6XXX_FLAG_VTU,

Hi Vivien

Rather than repeating these flags again and again, could you add one
#define containing the flags, and then use that to initialise .flags.

	Andrew

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

* Re: [RFC PATCH net-next 19/20] net: dsa: mv88e6xxx: factorize tag protocol
  2016-05-05 22:41 ` [RFC PATCH net-next 19/20] net: dsa: mv88e6xxx: factorize tag protocol Vivien Didelot
@ 2016-05-06  1:09   ` Andrew Lunn
  2016-05-06 20:56     ` Vivien Didelot
  0 siblings, 1 reply; 31+ messages in thread
From: Andrew Lunn @ 2016-05-06  1:09 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli

On Thu, May 05, 2016 at 06:41:03PM -0400, Vivien Didelot wrote:
> 6131 is the only driver to set the tag protocol to DSA_TAG_PROTO_DSA.
> Since it works fine with DSA_TAG_PROTO_EDSA, change its value, like all
> other mv88e6xxx drivers.

Hi Vivien

You might as well remove net/dsa/tag_dsa.c as well, since it is now
unused. Please do that as a separate patch.

	Andrew

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

* Re: [RFC PATCH net-next 20/20] net: dsa: mv88e6xxx: factorize the switch driver
  2016-05-05 22:41 ` [RFC PATCH net-next 20/20] net: dsa: mv88e6xxx: factorize the switch driver Vivien Didelot
@ 2016-05-06  1:14   ` Andrew Lunn
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Lunn @ 2016-05-06  1:14 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli

> +config NET_DSA_MV88E6XXX
>  	tristate "Marvell 88E6085/6095/6095F/6131 ethernet switch chip support"
>  	depends on NET_DSA
> -	select NET_DSA_MV88E6XXX
>  	select NET_DSA_TAG_EDSA
>  	---help---
>  	  This enables support for the Marvell 88E6085/6095/6095F/6131
>  	  ethernet switch chips.

Hi Vivien

You should update the list of devices. We need some text in the
tristate and help which suggests this driver supports everything
except mv88e6060.

       Andrew

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

* Re: [RFC PATCH net-next 14/20] net: dsa: mv88e6xxx: factorize VLAN Ethertype
  2016-05-06  0:57   ` Andrew Lunn
@ 2016-05-06 15:12     ` Vivien Didelot
  0 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-06 15:12 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli

Hi Andrew,

Andrew Lunn <andrew@lunn.ch> writes:

>> @@ -55,6 +58,7 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
>>  		.num_databases = 256,
>>  		.num_ports = 10,
>>  		.flags = MV88E6XXX_FLAG_ATU |
>> +			MV88E6XXX_FLAG_CORE_TAG_TYPE |
>>  			MV88E6XXX_FLAG_PPU |
>>  			MV88E6XXX_FLAG_VLANTABLE |
>>  			MV88E6XXX_FLAG_VTU,
>
> Rather than repeating these flags again and again, could you add one
> #define containing the flags, and then use that to initialise .flags.

Hum OK, I wasn't sure, but looking at the final mv88e6xxx_info table, I
can see that models from the same family all have the same set of flags,
even if they don't have the same number of ports or databases.

I'll add one MV88E6XXX_FLAGS_xxxx per family.

Thanks,

        Vivien

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

* Re: [RFC PATCH net-next 19/20] net: dsa: mv88e6xxx: factorize tag protocol
  2016-05-06  1:09   ` Andrew Lunn
@ 2016-05-06 20:56     ` Vivien Didelot
  0 siblings, 0 replies; 31+ messages in thread
From: Vivien Didelot @ 2016-05-06 20:56 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli

Hi Andrew,

Andrew Lunn <andrew@lunn.ch> writes:

> On Thu, May 05, 2016 at 06:41:03PM -0400, Vivien Didelot wrote:
>> 6131 is the only driver to set the tag protocol to DSA_TAG_PROTO_DSA.
>> Since it works fine with DSA_TAG_PROTO_EDSA, change its value, like all
>> other mv88e6xxx drivers.
>
> You might as well remove net/dsa/tag_dsa.c as well, since it is now
> unused. Please do that as a separate patch.

Why not, but isn't it a bit out of the scope of this patchset?

Thanks,

        Vivien

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

end of thread, other threads:[~2016-05-06 20:56 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-05 22:40 [RFC PATCH net-next 00/20] net: dsa: mv88e6xxx: turn into monolithic driver Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 01/20] net: dsa: mv88e6xxx: factorize PHY access with PPU Vivien Didelot
2016-05-05 22:54   ` Andrew Lunn
2016-05-05 22:59   ` Andrew Lunn
2016-05-05 23:06   ` Andrew Lunn
2016-05-05 22:40 ` [RFC PATCH net-next 02/20] net: dsa: mv88e6xxx: factorize PHY indirect access Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 03/20] net: dsa: mv88e6xxx: factorize EEPROM access Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 04/20] net: dsa: mv88e6xxx: factorize temperature access Vivien Didelot
2016-05-05 23:40   ` Andrew Lunn
2016-05-05 22:40 ` [RFC PATCH net-next 05/20] net: dsa: mv88e6xxx: factorize MAC address setting Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 06/20] net: dsa: mv88e6xxx: factorize EEE access Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 07/20] net: dsa: mv88e6xxx: factorize registers access Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 08/20] net: dsa: mv88e6xxx: factorize bridge support Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 09/20] net: dsa: mv88e6xxx: factorize VTU access Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 10/20] net: dsa: mv88e6xxx: factorize ATU access Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 11/20] net: dsa: mv88e6xxx: factorize switch reset Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 12/20] net: dsa: mv88e6xxx: factorize global setup Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 13/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL setup Vivien Didelot
2016-05-06  0:55   ` Andrew Lunn
2016-05-05 22:40 ` [RFC PATCH net-next 14/20] net: dsa: mv88e6xxx: factorize VLAN Ethertype Vivien Didelot
2016-05-06  0:57   ` Andrew Lunn
2016-05-06 15:12     ` Vivien Didelot
2016-05-05 22:40 ` [RFC PATCH net-next 15/20] net: dsa: mv88e6xxx: factorize GLOBAL_MONITOR_CONTROL setup Vivien Didelot
2016-05-05 22:41 ` [RFC PATCH net-next 16/20] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL_2 setup Vivien Didelot
2016-05-05 22:41 ` [RFC PATCH net-next 17/20] net: dsa: mv88e6xxx: factorize frames priorities Vivien Didelot
2016-05-05 22:41 ` [RFC PATCH net-next 18/20] net: dsa: mv88e6xxx: factorize switch setup Vivien Didelot
2016-05-05 22:41 ` [RFC PATCH net-next 19/20] net: dsa: mv88e6xxx: factorize tag protocol Vivien Didelot
2016-05-06  1:09   ` Andrew Lunn
2016-05-06 20:56     ` Vivien Didelot
2016-05-05 22:41 ` [RFC PATCH net-next 20/20] net: dsa: mv88e6xxx: factorize the switch driver Vivien Didelot
2016-05-06  1:14   ` Andrew Lunn

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.