All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071
@ 2019-10-26 23:14 Anatolij Gustschin
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 1/5] net: phy: mv88e61xx: rework to enable detection of 88E6071 devices Anatolij Gustschin
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Anatolij Gustschin @ 2019-10-26 23:14 UTC (permalink / raw)
  To: u-boot

This series adds support for 88E6071 and compatible switches in the
mv88e61xx driver.

Changes in v4:

 patch 1
 - rework to drop Kconfig option for MV88E6020 family selection:
   detect switch ID in mv88e61xx_priv_reg_offs_pre_init() and
   initialize the required port and global register offsets
   depending on the detected ID
 - patch 4 v3 is not required any more, drop it
 - add switch ID detection for 6020, 6070, 6220 and 6250
 - reword comments and fix spelling (s/initialised/initialized/)

 No changes in patches 2, 3, 4, 5

Changes in v3:

 - Add Reviewed-/Tested-by tags

 patch 1
  - drop DEVADDR_PORT to avoid macros with local variable
  - describe variables added to priv struct
  - reword comments in mv88e61xx_priv_reg_offs_pre_init()
  - add comment in get_phy_id() to explain why calling
    mv88e61xx_priv_reg_offs_pre_init() is required

 patch 2
  - remove unused PORT_REG_STATUS_SPEED_WIDTH macro

 patch 4
  - describe model numbers in numerical order

Changes in v2:
 - fix port init for 6096/6097 devices in patch 1/6
 - update commit description in patch 4/6

Anatolij Gustschin (5):
  net: phy: mv88e61xx: rework to enable detection of 88E6071 devices
  net: phy: mv88e61xx: add CPU port parameter init for 88E6071
  net: phy: mv88E61xx: fix ENERGY_DET init for mv88E6071
  net: phy: mv88e61xx: register phy_driver struct for 88E6071
  net: phy: fix switch vendor name

 drivers/net/phy/Kconfig     |   2 +-
 drivers/net/phy/mv88e61xx.c | 220 +++++++++++++++++++++++++++++-------
 2 files changed, 179 insertions(+), 43 deletions(-)

-- 
2.17.1

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

* [U-Boot] [PATCH v4 1/5] net: phy: mv88e61xx: rework to enable detection of 88E6071 devices
  2019-10-26 23:14 [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071 Anatolij Gustschin
@ 2019-10-26 23:14 ` Anatolij Gustschin
  2019-11-22 21:48   ` Joe Hershberger
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 2/5] net: phy: mv88e61xx: add CPU port parameter init for 88E6071 Anatolij Gustschin
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Anatolij Gustschin @ 2019-10-26 23:14 UTC (permalink / raw)
  To: u-boot

Extend the driver to init switch register offsets from variables
instead of compile time macros and enable detection of 88E6071 and
compatible devices. Ethernet transfer (e.g. tftp) does not work yet,
so enable the registration of the 'indirect mii' bus for easier PHY
register access by 'mii' command.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
 drivers/net/phy/mv88e61xx.c | 144 ++++++++++++++++++++++++++++++------
 1 file changed, 122 insertions(+), 22 deletions(-)

diff --git a/drivers/net/phy/mv88e61xx.c b/drivers/net/phy/mv88e61xx.c
index c1e2860329..56561c22ee 100644
--- a/drivers/net/phy/mv88e61xx.c
+++ b/drivers/net/phy/mv88e61xx.c
@@ -39,15 +39,11 @@
 
 #define PHY_AUTONEGOTIATE_TIMEOUT	5000
 
-#define PORT_COUNT			11
-#define PORT_MASK			((1 << PORT_COUNT) - 1)
+#define PORT_MASK(port_count)		((1 << (port_count)) - 1)
 
 /* Device addresses */
 #define DEVADDR_PHY(p)			(p)
-#define DEVADDR_PORT(p)			(0x10 + (p))
 #define DEVADDR_SERDES			0x0F
-#define DEVADDR_GLOBAL_1		0x1B
-#define DEVADDR_GLOBAL_2		0x1C
 
 /* SMI indirection registers for multichip addressing mode */
 #define SMI_CMD_REG			0x00
@@ -182,17 +178,26 @@
 #endif
 
 /* ID register values for different switch models */
+#define PORT_SWITCH_ID_6020		0x0200
+#define PORT_SWITCH_ID_6070		0x0700
+#define PORT_SWITCH_ID_6071		0x0710
 #define PORT_SWITCH_ID_6096		0x0980
 #define PORT_SWITCH_ID_6097		0x0990
 #define PORT_SWITCH_ID_6172		0x1720
 #define PORT_SWITCH_ID_6176		0x1760
+#define PORT_SWITCH_ID_6220		0x2200
 #define PORT_SWITCH_ID_6240		0x2400
+#define PORT_SWITCH_ID_6250		0x2500
 #define PORT_SWITCH_ID_6352		0x3520
 
 struct mv88e61xx_phy_priv {
 	struct mii_dev *mdio_bus;
 	int smi_addr;
 	int id;
+	int port_count;		/* Number of switch ports */
+	int port_reg_base;	/* Base of the switch port registers */
+	u8 global1;	/* Offset of Switch Global 1 registers */
+	u8 global2;	/* Offset of Switch Global 2 registers */
 };
 
 static inline int smi_cmd(int cmd, int addr, int reg)
@@ -329,11 +334,12 @@ static int mv88e61xx_reg_write(struct phy_device *phydev, int dev, int reg,
 
 static int mv88e61xx_phy_wait(struct phy_device *phydev)
 {
+	struct mv88e61xx_phy_priv *priv = phydev->priv;
 	int val;
 	u32 timeout = 100;
 
 	do {
-		val = mv88e61xx_reg_read(phydev, DEVADDR_GLOBAL_2,
+		val = mv88e61xx_reg_read(phydev, priv->global2,
 					 GLOBAL2_REG_PHY_CMD);
 		if (val >= 0 && (val & SMI_BUSY) == 0)
 			return 0;
@@ -347,13 +353,15 @@ static int mv88e61xx_phy_wait(struct phy_device *phydev)
 static int mv88e61xx_phy_read_indirect(struct mii_dev *smi_wrapper, int dev,
 		int devad, int reg)
 {
+	struct mv88e61xx_phy_priv *priv;
 	struct phy_device *phydev;
 	int res;
 
 	phydev = (struct phy_device *)smi_wrapper->priv;
+	priv = phydev->priv;
 
 	/* Issue command to read */
-	res = mv88e61xx_reg_write(phydev, DEVADDR_GLOBAL_2,
+	res = mv88e61xx_reg_write(phydev, priv->global2,
 				  GLOBAL2_REG_PHY_CMD,
 				  smi_cmd_read(dev, reg));
 
@@ -363,25 +371,27 @@ static int mv88e61xx_phy_read_indirect(struct mii_dev *smi_wrapper, int dev,
 		return res;
 
 	/* Read retrieved data */
-	return mv88e61xx_reg_read(phydev, DEVADDR_GLOBAL_2,
+	return mv88e61xx_reg_read(phydev, priv->global2,
 				  GLOBAL2_REG_PHY_DATA);
 }
 
 static int mv88e61xx_phy_write_indirect(struct mii_dev *smi_wrapper, int dev,
 		int devad, int reg, u16 data)
 {
+	struct mv88e61xx_phy_priv *priv;
 	struct phy_device *phydev;
 	int res;
 
 	phydev = (struct phy_device *)smi_wrapper->priv;
+	priv = phydev->priv;
 
 	/* Set the data to write */
-	res = mv88e61xx_reg_write(phydev, DEVADDR_GLOBAL_2,
+	res = mv88e61xx_reg_write(phydev, priv->global2,
 				  GLOBAL2_REG_PHY_DATA, data);
 	if (res < 0)
 		return res;
 	/* Issue the write command */
-	res = mv88e61xx_reg_write(phydev, DEVADDR_GLOBAL_2,
+	res = mv88e61xx_reg_write(phydev, priv->global2,
 				  GLOBAL2_REG_PHY_CMD,
 				  smi_cmd_write(dev, reg));
 	if (res < 0)
@@ -408,13 +418,18 @@ static int mv88e61xx_phy_write(struct phy_device *phydev, int phy,
 
 static int mv88e61xx_port_read(struct phy_device *phydev, u8 port, u8 reg)
 {
-	return mv88e61xx_reg_read(phydev, DEVADDR_PORT(port), reg);
+	struct mv88e61xx_phy_priv *priv = phydev->priv;
+
+	return mv88e61xx_reg_read(phydev, priv->port_reg_base + port, reg);
 }
 
 static int mv88e61xx_port_write(struct phy_device *phydev, u8 port, u8 reg,
 								u16 val)
 {
-	return mv88e61xx_reg_write(phydev, DEVADDR_PORT(port), reg, val);
+	struct mv88e61xx_phy_priv *priv = phydev->priv;
+
+	return mv88e61xx_reg_write(phydev, priv->port_reg_base + port,
+				   reg, val);
 }
 
 static int mv88e61xx_set_page(struct phy_device *phydev, u8 phy, u8 page)
@@ -515,12 +530,13 @@ static int mv88e61xx_parse_status(struct phy_device *phydev)
 
 static int mv88e61xx_switch_reset(struct phy_device *phydev)
 {
+	struct mv88e61xx_phy_priv *priv = phydev->priv;
 	int time;
 	int val;
 	u8 port;
 
 	/* Disable all ports */
-	for (port = 0; port < PORT_COUNT; port++) {
+	for (port = 0; port < priv->port_count; port++) {
 		val = mv88e61xx_port_read(phydev, port, PORT_REG_CTRL);
 		if (val < 0)
 			return val;
@@ -536,18 +552,18 @@ static int mv88e61xx_switch_reset(struct phy_device *phydev)
 	udelay(2000);
 
 	/* Reset switch */
-	val = mv88e61xx_reg_read(phydev, DEVADDR_GLOBAL_1, GLOBAL1_CTRL);
+	val = mv88e61xx_reg_read(phydev, priv->global1, GLOBAL1_CTRL);
 	if (val < 0)
 		return val;
 	val |= GLOBAL1_CTRL_SWRESET;
-	val = mv88e61xx_reg_write(phydev, DEVADDR_GLOBAL_1,
+	val = mv88e61xx_reg_write(phydev, priv->global1,
 				     GLOBAL1_CTRL, val);
 	if (val < 0)
 		return val;
 
 	/* Wait up to 1 second for switch reset complete */
 	for (time = 1000; time; time--) {
-		val = mv88e61xx_reg_read(phydev, DEVADDR_GLOBAL_1,
+		val = mv88e61xx_reg_read(phydev, priv->global1,
 					    GLOBAL1_CTRL);
 		if (val >= 0 && ((val & GLOBAL1_CTRL_SWRESET) == 0))
 			break;
@@ -732,22 +748,23 @@ static int mv88e61xx_fixed_port_setup(struct phy_device *phydev, u8 port)
 
 static int mv88e61xx_set_cpu_port(struct phy_device *phydev)
 {
+	struct mv88e61xx_phy_priv *priv = phydev->priv;
 	int val;
 
 	/* Set CPUDest */
-	val = mv88e61xx_reg_read(phydev, DEVADDR_GLOBAL_1, GLOBAL1_MON_CTRL);
+	val = mv88e61xx_reg_read(phydev, priv->global1, GLOBAL1_MON_CTRL);
 	if (val < 0)
 		return val;
 	val = bitfield_replace(val, GLOBAL1_MON_CTRL_CPUDEST_SHIFT,
 			       GLOBAL1_MON_CTRL_CPUDEST_WIDTH,
 			       CONFIG_MV88E61XX_CPU_PORT);
-	val = mv88e61xx_reg_write(phydev, DEVADDR_GLOBAL_1,
+	val = mv88e61xx_reg_write(phydev, priv->global1,
 				     GLOBAL1_MON_CTRL, val);
 	if (val < 0)
 		return val;
 
 	/* Allow CPU to route to any port */
-	val = PORT_MASK & ~(1 << CONFIG_MV88E61XX_CPU_PORT);
+	val = PORT_MASK(priv->port_count) & ~(1 << CONFIG_MV88E61XX_CPU_PORT);
 	val = mv88e61xx_port_set_vlan(phydev, CONFIG_MV88E61XX_CPU_PORT, val);
 	if (val < 0)
 		return val;
@@ -856,6 +873,48 @@ static int mv88e61xx_phy_config_port(struct phy_device *phydev, u8 phy)
 	return 0;
 }
 
+/*
+ * This function is used to pre-configure the required register
+ * offsets, so that the indirect register access to the PHY registers
+ * is possible. This is necessary to be able to read the PHY ID
+ * while driver probing or in get_phy_id(). The globalN register
+ * offsets must be initialized correctly for a detected switch,
+ * otherwise detection of the PHY ID won't work!
+ */
+static int mv88e61xx_priv_reg_offs_pre_init(struct phy_device *phydev)
+{
+	struct mv88e61xx_phy_priv *priv = phydev->priv;
+
+	/*
+	 * Initial 'port_reg_base' value must be an offset of existing
+	 * port register, then reading the ID should succeed. First, try
+	 * to read via port registers with device address 0x10 (88E6096
+	 * and compatible switches).
+	 */
+	priv->port_reg_base = 0x10;
+	priv->id = mv88e61xx_get_switch_id(phydev);
+	if (priv->id != 0xfff0) {
+		priv->global1 = 0x1B;
+		priv->global2 = 0x1C;
+		return 0;
+	}
+
+	/*
+	 * Now try via port registers with device address 0x08
+	 * (88E6020 and compatible switches).
+	 */
+	priv->port_reg_base = 0x08;
+	priv->id = mv88e61xx_get_switch_id(phydev);
+	if (priv->id != 0xfff0) {
+		priv->global1 = 0x0F;
+		priv->global2 = 0x07;
+		return 0;
+	}
+
+	debug("%s Unknown ID 0x%x\n", __func__, priv->id);
+	return -ENODEV;
+}
+
 static int mv88e61xx_probe(struct phy_device *phydev)
 {
 	struct mii_dev *smi_wrapper;
@@ -910,13 +969,43 @@ static int mv88e61xx_probe(struct phy_device *phydev)
 
 	phydev->priv = priv;
 
-	priv->id = mv88e61xx_get_switch_id(phydev);
+	res = mv88e61xx_priv_reg_offs_pre_init(phydev);
+	if (res < 0)
+		return res;
+
+	debug("%s ID 0x%x\n", __func__, priv->id);
+
+	switch (priv->id) {
+	case PORT_SWITCH_ID_6096:
+	case PORT_SWITCH_ID_6097:
+	case PORT_SWITCH_ID_6172:
+	case PORT_SWITCH_ID_6176:
+	case PORT_SWITCH_ID_6240:
+	case PORT_SWITCH_ID_6352:
+		priv->port_count = 11;
+		break;
+	case PORT_SWITCH_ID_6020:
+	case PORT_SWITCH_ID_6070:
+	case PORT_SWITCH_ID_6071:
+	case PORT_SWITCH_ID_6220:
+	case PORT_SWITCH_ID_6250:
+		priv->port_count = 7;
+		break;
+	default:
+		free(priv);
+		return -ENODEV;
+	}
+
+	res = mdio_register(smi_wrapper);
+	if (res)
+		printf("Failed to register SMI bus\n");
 
 	return 0;
 }
 
 static int mv88e61xx_phy_config(struct phy_device *phydev)
 {
+	struct mv88e61xx_phy_priv *priv = phydev->priv;
 	int res;
 	int i;
 	int ret = -1;
@@ -925,7 +1014,7 @@ static int mv88e61xx_phy_config(struct phy_device *phydev)
 	if (res < 0)
 		return res;
 
-	for (i = 0; i < PORT_COUNT; i++) {
+	for (i = 0; i < priv->port_count; i++) {
 		if ((1 << i) & CONFIG_MV88E61XX_PHY_PORTS) {
 			phydev->addr = i;
 
@@ -988,13 +1077,14 @@ static int mv88e61xx_phy_is_connected(struct phy_device *phydev)
 
 static int mv88e61xx_phy_startup(struct phy_device *phydev)
 {
+	struct mv88e61xx_phy_priv *priv = phydev->priv;
 	int i;
 	int link = 0;
 	int res;
 	int speed = phydev->speed;
 	int duplex = phydev->duplex;
 
-	for (i = 0; i < PORT_COUNT; i++) {
+	for (i = 0; i < priv->port_count; i++) {
 		if ((1 << i) & CONFIG_MV88E61XX_PHY_PORTS) {
 			phydev->addr = i;
 			if (!mv88e61xx_phy_is_connected(phydev))
@@ -1068,6 +1158,16 @@ int get_phy_id(struct mii_dev *bus, int smi_addr, int devad, u32 *phy_id)
 	temp_phy.priv = &temp_priv;
 	temp_mii.priv = &temp_phy;
 
+	/*
+	 * get_phy_id() can be called by framework before mv88e61xx driver
+	 * probing, in this case the global register offsets are not
+	 * initialized yet. Do this initialization here before indirect
+	 * PHY register access.
+	 */
+	val = mv88e61xx_priv_reg_offs_pre_init(&temp_phy);
+	if (val < 0)
+		return val;
+
 	val = mv88e61xx_phy_read_indirect(&temp_mii, 0, devad, MII_PHYSID1);
 	if (val < 0)
 		return -EIO;
-- 
2.17.1

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

* [U-Boot] [PATCH v4 2/5] net: phy: mv88e61xx: add CPU port parameter init for 88E6071
  2019-10-26 23:14 [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071 Anatolij Gustschin
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 1/5] net: phy: mv88e61xx: rework to enable detection of 88E6071 devices Anatolij Gustschin
@ 2019-10-26 23:14 ` Anatolij Gustschin
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 3/5] net: phy: mv88E61xx: fix ENERGY_DET init for mv88E6071 Anatolij Gustschin
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Anatolij Gustschin @ 2019-10-26 23:14 UTC (permalink / raw)
  To: u-boot

On 88E6071 chip the port status register bit field offsets
for duplex and link bits differ. Extend the driver to use
88E6071 specific offset values. The width of bit fields for
speed status differ, too. Adapt for proper port speed
detection on 88E6071.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Reviewed-by: Chris Packham <judge.packham@gmail.com>
Tested-by: Chris Packham <judge.packham@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
---
 drivers/net/phy/mv88e61xx.c | 42 ++++++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/drivers/net/phy/mv88e61xx.c b/drivers/net/phy/mv88e61xx.c
index 56561c22ee..b692db5514 100644
--- a/drivers/net/phy/mv88e61xx.c
+++ b/drivers/net/phy/mv88e61xx.c
@@ -84,11 +84,7 @@
 #define GLOBAL1_MON_CTRL_CPUDEST_SHIFT	4
 #define GLOBAL1_MON_CTRL_CPUDEST_WIDTH	4
 
-#define PORT_REG_STATUS_LINK		BIT(11)
-#define PORT_REG_STATUS_DUPLEX		BIT(10)
-
 #define PORT_REG_STATUS_SPEED_SHIFT	8
-#define PORT_REG_STATUS_SPEED_WIDTH	2
 #define PORT_REG_STATUS_SPEED_10	0
 #define PORT_REG_STATUS_SPEED_100	1
 #define PORT_REG_STATUS_SPEED_1000	2
@@ -107,6 +103,7 @@
 #define PORT_REG_PHYS_CTRL_DUPLEX_VALUE	BIT(3)
 #define PORT_REG_PHYS_CTRL_DUPLEX_FORCE	BIT(2)
 #define PORT_REG_PHYS_CTRL_SPD1000	BIT(1)
+#define PORT_REG_PHYS_CTRL_SPD100	BIT(0)
 #define PORT_REG_PHYS_CTRL_SPD_MASK	(BIT(1) | BIT(0))
 
 #define PORT_REG_CTRL_PSTATE_SHIFT	0
@@ -196,6 +193,9 @@ struct mv88e61xx_phy_priv {
 	int id;
 	int port_count;		/* Number of switch ports */
 	int port_reg_base;	/* Base of the switch port registers */
+	u16 port_stat_link_mask;/* Bitmask for port link status bits */
+	u16 port_stat_dup_mask; /* Bitmask for port duplex status bits */
+	u8 port_stat_speed_width;/* Width of speed status bitfield */
 	u8 global1;	/* Offset of Switch Global 1 registers */
 	u8 global2;	/* Offset of Switch Global 2 registers */
 };
@@ -644,6 +644,7 @@ static int mv88e61xx_port_set_vlan(struct phy_device *phydev, u8 port,
 
 static int mv88e61xx_read_port_config(struct phy_device *phydev, u8 port)
 {
+	struct mv88e61xx_phy_priv *priv = phydev->priv;
 	int res;
 	int val;
 	bool forced = false;
@@ -651,7 +652,7 @@ static int mv88e61xx_read_port_config(struct phy_device *phydev, u8 port)
 	val = mv88e61xx_port_read(phydev, port, PORT_REG_STATUS);
 	if (val < 0)
 		return val;
-	if (!(val & PORT_REG_STATUS_LINK)) {
+	if (!(val & priv->port_stat_link_mask)) {
 		/* Temporarily force link to read port configuration */
 		u32 timeout = 100;
 		forced = true;
@@ -674,7 +675,7 @@ static int mv88e61xx_read_port_config(struct phy_device *phydev, u8 port)
 				res = -EIO;
 				goto unforce;
 			}
-			if (val & PORT_REG_STATUS_LINK)
+			if (val & priv->port_stat_link_mask)
 				break;
 		} while (--timeout);
 
@@ -684,13 +685,13 @@ static int mv88e61xx_read_port_config(struct phy_device *phydev, u8 port)
 		}
 	}
 
-	if (val & PORT_REG_STATUS_DUPLEX)
+	if (val & priv->port_stat_dup_mask)
 		phydev->duplex = DUPLEX_FULL;
 	else
 		phydev->duplex = DUPLEX_HALF;
 
 	val = bitfield_extract(val, PORT_REG_STATUS_SPEED_SHIFT,
-			       PORT_REG_STATUS_SPEED_WIDTH);
+			       priv->port_stat_speed_width);
 	switch (val) {
 	case PORT_REG_STATUS_SPEED_1000:
 		phydev->speed = SPEED_1000;
@@ -723,6 +724,7 @@ unforce:
 
 static int mv88e61xx_fixed_port_setup(struct phy_device *phydev, u8 port)
 {
+	struct mv88e61xx_phy_priv *priv = phydev->priv;
 	int val;
 
 	val = mv88e61xx_port_read(phydev, port, PORT_REG_PHYS_CTRL);
@@ -730,13 +732,19 @@ static int mv88e61xx_fixed_port_setup(struct phy_device *phydev, u8 port)
 		return val;
 
 	val &= ~(PORT_REG_PHYS_CTRL_SPD_MASK |
-		 PORT_REG_PHYS_CTRL_FC_VALUE);
-	val |= PORT_REG_PHYS_CTRL_PCS_AN_EN |
-	       PORT_REG_PHYS_CTRL_PCS_AN_RST |
-	       PORT_REG_PHYS_CTRL_FC_FORCE |
+		 PORT_REG_PHYS_CTRL_FC_VALUE |
+		 PORT_REG_PHYS_CTRL_FC_FORCE);
+	val |= PORT_REG_PHYS_CTRL_FC_FORCE |
 	       PORT_REG_PHYS_CTRL_DUPLEX_VALUE |
-	       PORT_REG_PHYS_CTRL_DUPLEX_FORCE |
-	       PORT_REG_PHYS_CTRL_SPD1000;
+	       PORT_REG_PHYS_CTRL_DUPLEX_FORCE;
+
+	if (priv->id == PORT_SWITCH_ID_6071) {
+		val |= PORT_REG_PHYS_CTRL_SPD100;
+	} else {
+		val |= PORT_REG_PHYS_CTRL_PCS_AN_EN |
+		       PORT_REG_PHYS_CTRL_PCS_AN_RST |
+		       PORT_REG_PHYS_CTRL_SPD1000;
+	}
 
 	if (port == CONFIG_MV88E61XX_CPU_PORT)
 		val |= PORT_REG_PHYS_CTRL_LINK_VALUE |
@@ -983,6 +991,9 @@ static int mv88e61xx_probe(struct phy_device *phydev)
 	case PORT_SWITCH_ID_6240:
 	case PORT_SWITCH_ID_6352:
 		priv->port_count = 11;
+		priv->port_stat_link_mask = BIT(11);
+		priv->port_stat_dup_mask = BIT(10);
+		priv->port_stat_speed_width = 2;
 		break;
 	case PORT_SWITCH_ID_6020:
 	case PORT_SWITCH_ID_6070:
@@ -990,6 +1001,9 @@ static int mv88e61xx_probe(struct phy_device *phydev)
 	case PORT_SWITCH_ID_6220:
 	case PORT_SWITCH_ID_6250:
 		priv->port_count = 7;
+		priv->port_stat_link_mask = BIT(12);
+		priv->port_stat_dup_mask = BIT(9);
+		priv->port_stat_speed_width = 1;
 		break;
 	default:
 		free(priv);
-- 
2.17.1

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

* [U-Boot] [PATCH v4 3/5] net: phy: mv88E61xx: fix ENERGY_DET init for mv88E6071
  2019-10-26 23:14 [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071 Anatolij Gustschin
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 1/5] net: phy: mv88e61xx: rework to enable detection of 88E6071 devices Anatolij Gustschin
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 2/5] net: phy: mv88e61xx: add CPU port parameter init for 88E6071 Anatolij Gustschin
@ 2019-10-26 23:14 ` Anatolij Gustschin
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 4/5] net: phy: mv88e61xx: register phy_driver struct for 88E6071 Anatolij Gustschin
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Anatolij Gustschin @ 2019-10-26 23:14 UTC (permalink / raw)
  To: u-boot

On mv88E6071 the 'EDet' field offset, width and sense control
bits are different, adjust the driver to init the PHY control
register as needed. This fixes not working link detection and
tftp transfers.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Reviewed-by: Chris Packham <judge.packham@gmail.com>
Tested-by: Chris Packham <judge.packham@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
---
 drivers/net/phy/mv88e61xx.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/net/phy/mv88e61xx.c b/drivers/net/phy/mv88e61xx.c
index b692db5514..52b3272730 100644
--- a/drivers/net/phy/mv88e61xx.c
+++ b/drivers/net/phy/mv88e61xx.c
@@ -117,14 +117,12 @@
 
 #define SERDES_REG_CTRL_1_FORCE_LINK	BIT(10)
 
-#define PHY_REG_CTRL1_ENERGY_DET_SHIFT	8
-#define PHY_REG_CTRL1_ENERGY_DET_WIDTH	2
-
 /* Field values */
 #define PORT_REG_CTRL_PSTATE_DISABLED	0
 #define PORT_REG_CTRL_PSTATE_FORWARD	3
 
 #define PHY_REG_CTRL1_ENERGY_DET_OFF	0
+#define PHY_REG_CTRL1_ENERGY_DET_SENSE_PULSE	1
 #define PHY_REG_CTRL1_ENERGY_DET_SENSE_ONLY	2
 #define PHY_REG_CTRL1_ENERGY_DET_SENSE_XMIT	3
 
@@ -198,6 +196,9 @@ struct mv88e61xx_phy_priv {
 	u8 port_stat_speed_width;/* Width of speed status bitfield */
 	u8 global1;	/* Offset of Switch Global 1 registers */
 	u8 global2;	/* Offset of Switch Global 2 registers */
+	u8 phy_ctrl1_en_det_shift; /* 'EDet' bit field offset */
+	u8 phy_ctrl1_en_det_width; /* Width of 'EDet' bit field */
+	u8 phy_ctrl1_en_det_ctrl;  /* 'EDet' control value */
 };
 
 static inline int smi_cmd(int cmd, int addr, int reg)
@@ -846,6 +847,7 @@ static int mv88e61xx_phy_enable(struct phy_device *phydev, u8 phy)
 
 static int mv88e61xx_phy_setup(struct phy_device *phydev, u8 phy)
 {
+	struct mv88e61xx_phy_priv *priv = phydev->priv;
 	int val;
 
 	/*
@@ -855,9 +857,9 @@ static int mv88e61xx_phy_setup(struct phy_device *phydev, u8 phy)
 	val = mv88e61xx_phy_read(phydev, phy, PHY_REG_CTRL1);
 	if (val < 0)
 		return val;
-	val = bitfield_replace(val, PHY_REG_CTRL1_ENERGY_DET_SHIFT,
-			       PHY_REG_CTRL1_ENERGY_DET_WIDTH,
-			       PHY_REG_CTRL1_ENERGY_DET_SENSE_XMIT);
+	val = bitfield_replace(val, priv->phy_ctrl1_en_det_shift,
+			       priv->phy_ctrl1_en_det_width,
+			       priv->phy_ctrl1_en_det_ctrl);
 	val = mv88e61xx_phy_write(phydev, phy, PHY_REG_CTRL1, val);
 	if (val < 0)
 		return val;
@@ -994,6 +996,10 @@ static int mv88e61xx_probe(struct phy_device *phydev)
 		priv->port_stat_link_mask = BIT(11);
 		priv->port_stat_dup_mask = BIT(10);
 		priv->port_stat_speed_width = 2;
+		priv->phy_ctrl1_en_det_shift = 8;
+		priv->phy_ctrl1_en_det_width = 2;
+		priv->phy_ctrl1_en_det_ctrl =
+			PHY_REG_CTRL1_ENERGY_DET_SENSE_XMIT;
 		break;
 	case PORT_SWITCH_ID_6020:
 	case PORT_SWITCH_ID_6070:
@@ -1004,6 +1010,10 @@ static int mv88e61xx_probe(struct phy_device *phydev)
 		priv->port_stat_link_mask = BIT(12);
 		priv->port_stat_dup_mask = BIT(9);
 		priv->port_stat_speed_width = 1;
+		priv->phy_ctrl1_en_det_shift = 14;
+		priv->phy_ctrl1_en_det_width = 1;
+		priv->phy_ctrl1_en_det_ctrl =
+			PHY_REG_CTRL1_ENERGY_DET_SENSE_PULSE;
 		break;
 	default:
 		free(priv);
-- 
2.17.1

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

* [U-Boot] [PATCH v4 4/5] net: phy: mv88e61xx: register phy_driver struct for 88E6071
  2019-10-26 23:14 [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071 Anatolij Gustschin
                   ` (2 preceding siblings ...)
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 3/5] net: phy: mv88E61xx: fix ENERGY_DET init for mv88E6071 Anatolij Gustschin
@ 2019-10-26 23:14 ` Anatolij Gustschin
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 5/5] net: phy: fix switch vendor name Anatolij Gustschin
  2019-11-22 21:26 ` [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071 Anatolij Gustschin
  5 siblings, 0 replies; 8+ messages in thread
From: Anatolij Gustschin @ 2019-10-26 23:14 UTC (permalink / raw)
  To: u-boot

Support probing and init for 88E6071 switch.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Reviewed-by: Chris Packham <judge.packham@gmail.com>
Tested-by: Chris Packham <judge.packham@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
---
 drivers/net/phy/mv88e61xx.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/phy/mv88e61xx.c b/drivers/net/phy/mv88e61xx.c
index 52b3272730..f09e689a35 100644
--- a/drivers/net/phy/mv88e61xx.c
+++ b/drivers/net/phy/mv88e61xx.c
@@ -1154,10 +1154,22 @@ static struct phy_driver mv88e609x_driver = {
 	.shutdown = &genphy_shutdown,
 };
 
+static struct phy_driver mv88e6071_driver = {
+	.name = "Marvell MV88E6071",
+	.uid = 0x1410db0,
+	.mask = 0xfffffff0,
+	.features = PHY_BASIC_FEATURES | SUPPORTED_MII,
+	.probe = mv88e61xx_probe,
+	.config = mv88e61xx_phy_config,
+	.startup = mv88e61xx_phy_startup,
+	.shutdown = &genphy_shutdown,
+};
+
 int phy_mv88e61xx_init(void)
 {
 	phy_register(&mv88e61xx_driver);
 	phy_register(&mv88e609x_driver);
+	phy_register(&mv88e6071_driver);
 
 	return 0;
 }
-- 
2.17.1

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

* [U-Boot] [PATCH v4 5/5] net: phy: fix switch vendor name
  2019-10-26 23:14 [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071 Anatolij Gustschin
                   ` (3 preceding siblings ...)
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 4/5] net: phy: mv88e61xx: register phy_driver struct for 88E6071 Anatolij Gustschin
@ 2019-10-26 23:14 ` Anatolij Gustschin
  2019-11-22 21:26 ` [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071 Anatolij Gustschin
  5 siblings, 0 replies; 8+ messages in thread
From: Anatolij Gustschin @ 2019-10-26 23:14 UTC (permalink / raw)
  To: u-boot

Fix vendor name in MV88E61xx option description.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Reviewed-by: Chris Packham <judge.packham@gmail.com>
Tested-by: Chris Packham <judge.packham@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
---
 drivers/net/phy/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 30bd8e7653..ac044c8f36 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -46,7 +46,7 @@ config B53_PHY_PORTS
 endif # B53_SWITCH
 
 config MV88E61XX_SWITCH
-	bool "Marvel MV88E61xx Ethernet switch PHY support."
+	bool "Marvell MV88E61xx Ethernet switch PHY support."
 
 if MV88E61XX_SWITCH
 
-- 
2.17.1

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

* [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071
  2019-10-26 23:14 [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071 Anatolij Gustschin
                   ` (4 preceding siblings ...)
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 5/5] net: phy: fix switch vendor name Anatolij Gustschin
@ 2019-11-22 21:26 ` Anatolij Gustschin
  5 siblings, 0 replies; 8+ messages in thread
From: Anatolij Gustschin @ 2019-11-22 21:26 UTC (permalink / raw)
  To: u-boot

Hi Joe,

On Sun, 27 Oct 2019 01:14:36 +0200
Anatolij Gustschin agust at denx.de wrote:

> This series adds support for 88E6071 and compatible switches in the
> mv88e61xx driver.

Ping. Is there a chance to queue this for merging in v2020.01 ?


Thanks,
Anatolij

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

* [U-Boot] [PATCH v4 1/5] net: phy: mv88e61xx: rework to enable detection of 88E6071 devices
  2019-10-26 23:14 ` [U-Boot] [PATCH v4 1/5] net: phy: mv88e61xx: rework to enable detection of 88E6071 devices Anatolij Gustschin
@ 2019-11-22 21:48   ` Joe Hershberger
  0 siblings, 0 replies; 8+ messages in thread
From: Joe Hershberger @ 2019-11-22 21:48 UTC (permalink / raw)
  To: u-boot

On Sat, Oct 26, 2019 at 6:17 PM Anatolij Gustschin <agust@denx.de> wrote:
>
> Extend the driver to init switch register offsets from variables
> instead of compile time macros and enable detection of 88E6071 and
> compatible devices. Ethernet transfer (e.g. tftp) does not work yet,
> so enable the registration of the 'indirect mii' bus for easier PHY
> register access by 'mii' command.
>
> Signed-off-by: Anatolij Gustschin <agust@denx.de>

Acked-by: Joe Hershberger <joe.hershberger@ni.com>

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

end of thread, other threads:[~2019-11-22 21:48 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-26 23:14 [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071 Anatolij Gustschin
2019-10-26 23:14 ` [U-Boot] [PATCH v4 1/5] net: phy: mv88e61xx: rework to enable detection of 88E6071 devices Anatolij Gustschin
2019-11-22 21:48   ` Joe Hershberger
2019-10-26 23:14 ` [U-Boot] [PATCH v4 2/5] net: phy: mv88e61xx: add CPU port parameter init for 88E6071 Anatolij Gustschin
2019-10-26 23:14 ` [U-Boot] [PATCH v4 3/5] net: phy: mv88E61xx: fix ENERGY_DET init for mv88E6071 Anatolij Gustschin
2019-10-26 23:14 ` [U-Boot] [PATCH v4 4/5] net: phy: mv88e61xx: register phy_driver struct for 88E6071 Anatolij Gustschin
2019-10-26 23:14 ` [U-Boot] [PATCH v4 5/5] net: phy: fix switch vendor name Anatolij Gustschin
2019-11-22 21:26 ` [U-Boot] [PATCH v4 0/5] Extend mv88e61xx driver to support 88E6071 Anatolij Gustschin

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.