* [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules
@ 2020-10-29 22:25 Marek Behún
2020-10-29 22:25 ` [PATCH net-next v2 1/5] net: phy: mdio-i2c: support I2C MDIO protocol for RollBall " Marek Behún
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Marek Behún @ 2020-10-29 22:25 UTC (permalink / raw)
To: netdev; +Cc: davem, Marek Behún, Andrew Lunn, Russell King
Hello,
this is v2 of series adding support for RollBall/Hilink SFP modules.
Checked with:
checkpatch.pl --max-line-length=80
Changes from v1:
- wrapped to 80 columns as per Russell's request
- initialization of RollBall MDIO I2C protocol moved from sfp.c to
mdio-i2c.c as per Russell's request
- second patch removes the 802.3z check also from phylink_sfp_config
as suggested by Russell
- creation/destruction of mdiobus for SFP now occurs before probing
for PHY/after releasing PHY (as suggested by Russell)
- the last patch became a little simpler after the above was done
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Russell King <rmk+kernel@armlinux.org.uk>
Marek Behún (5):
net: phy: mdio-i2c: support I2C MDIO protocol for RollBall SFP modules
net: phylink: allow attaching phy for SFP modules on 802.3z mode
net: sfp: create/destroy I2C mdiobus before PHY probe/after PHY
release
net: phy: marvell10g: change MACTYPE if underlying MAC does not
support it
net: sfp: add support for multigig RollBall transceivers
drivers/net/mdio/mdio-i2c.c | 232 +++++++++++++++++++++++++++++++++-
drivers/net/phy/marvell10g.c | 31 +++++
drivers/net/phy/phylink.c | 5 +-
drivers/net/phy/sfp.c | 67 ++++++++--
include/linux/mdio/mdio-i2c.h | 8 +-
5 files changed, 322 insertions(+), 21 deletions(-)
base-commit: cd29296fdfca919590e4004a7e4905544f4c4a32
--
2.26.2
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net-next v2 1/5] net: phy: mdio-i2c: support I2C MDIO protocol for RollBall SFP modules
2020-10-29 22:25 [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules Marek Behún
@ 2020-10-29 22:25 ` Marek Behún
2020-10-30 15:20 ` Russell King - ARM Linux admin
2020-10-29 22:25 ` [PATCH net-next v2 2/5] net: phylink: allow attaching phy for SFP modules on 802.3z mode Marek Behún
` (4 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Marek Behún @ 2020-10-29 22:25 UTC (permalink / raw)
To: netdev; +Cc: davem, Marek Behún, Andrew Lunn, Russell King
Some multigig SFPs from RollBall and Hilink do not expose functional
MDIO access to the internal PHY of the SFP via I2C address 0x56
(although there seems to be read-only clause 22 access on this address).
Instead these SFPs PHY can be accessed via I2C via the SFP Enhanced
Digital Diagnostic Interface - I2C address 0x51. The SFP_PAGE has to be
selected to 3 and the password must be filled with 0xff bytes for this
PHY communication to work.
This extends the mdio-i2c driver to support this protocol by adding a
special parameter to mdio_i2c_alloc function via which this RollBall
protocol can be selected.
Signed-off-by: Marek Behún <kabel@kernel.org>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/mdio/mdio-i2c.c | 232 +++++++++++++++++++++++++++++++++-
drivers/net/phy/sfp.c | 2 +-
include/linux/mdio/mdio-i2c.h | 8 +-
3 files changed, 235 insertions(+), 7 deletions(-)
diff --git a/drivers/net/mdio/mdio-i2c.c b/drivers/net/mdio/mdio-i2c.c
index 09200a70b315..671c4c750c56 100644
--- a/drivers/net/mdio/mdio-i2c.c
+++ b/drivers/net/mdio/mdio-i2c.c
@@ -3,6 +3,7 @@
* MDIO I2C bridge
*
* Copyright (C) 2015-2016 Russell King
+ * Copyright (C) 2020 Marek Behun
*
* Network PHYs can appear on I2C buses when they are part of SFP module.
* This driver exposes these PHYs to the networking PHY code, allowing
@@ -12,6 +13,7 @@
#include <linux/i2c.h>
#include <linux/mdio/mdio-i2c.h>
#include <linux/phy.h>
+#include <linux/sfp.h>
/*
* I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is
@@ -28,7 +30,7 @@ static unsigned int i2c_mii_phy_addr(int phy_id)
return phy_id + 0x40;
}
-static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg)
+static int i2c_mii_read_default(struct mii_bus *bus, int phy_id, int reg)
{
struct i2c_adapter *i2c = bus->priv;
struct i2c_msg msgs[2];
@@ -62,7 +64,8 @@ static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg)
return data[0] << 8 | data[1];
}
-static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
+static int i2c_mii_write_default(struct mii_bus *bus, int phy_id, int reg,
+ u16 val)
{
struct i2c_adapter *i2c = bus->priv;
struct i2c_msg msg;
@@ -91,9 +94,210 @@ static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
return ret < 0 ? ret : 0;
}
-struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c)
+/* RollBall SFPs do not access internal PHY via I2C address 0x56, but
+ * instead via address 0x51, when SFP page is set to 0x03 and password to
+ * 0xffffffff:
+ *
+ * address size contents description
+ * ------- ---- -------- -----------
+ * 0x80 1 CMD 0x01/0x02/0x04 for write/read/done
+ * 0x81 1 DEV Clause 45 device
+ * 0x82 2 REG Clause 45 register
+ * 0x84 2 VAL Register value
+ */
+#define ROLLBALL_PHY_I2C_ADDR 0x51
+#define ROLLBALL_SFP_PASSWORD_ADDR 0x7b
+
+#define ROLLBALL_CMD_ADDR 0x80
+#define ROLLBALL_DATA_ADDR 0x81
+
+#define ROLLBALL_CMD_WRITE 0x01
+#define ROLLBALL_CMD_READ 0x02
+#define ROLLBALL_CMD_DONE 0x04
+
+static int i2c_rollball_mii_poll(struct mii_bus *bus, int bus_addr, u8 *buf,
+ size_t len)
+{
+ struct i2c_adapter *i2c = bus->priv;
+ struct i2c_msg msgs[2];
+ u8 buf0[2], *res;
+ int i, ret;
+
+ buf0[0] = ROLLBALL_CMD_ADDR;
+
+ msgs[0].addr = bus_addr;
+ msgs[0].flags = 0;
+ msgs[0].len = 1;
+ msgs[0].buf = &buf0[0];
+
+ res = buf ? buf : &buf0[1];
+
+ msgs[1].addr = bus_addr;
+ msgs[1].flags = I2C_M_RD;
+ msgs[1].len = buf ? len : 1;
+ msgs[1].buf = res;
+
+ /* By experiment it takes up to 70 ms to access a register for these
+ * SFPs. Sleep 20ms between iteratios and try 10 times.
+ */
+ i = 10;
+ do {
+ msleep(20);
+
+ ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs));
+ if (ret < 0)
+ return ret;
+ else if (ret != ARRAY_SIZE(msgs))
+ return -EIO;
+
+ if (*res == ROLLBALL_CMD_DONE)
+ return 0;
+ } while (i-- > 0);
+
+ dev_dbg(&bus->dev, "poll timed out\n");
+
+ return -ETIMEDOUT;
+}
+
+static int i2c_rollball_mii_cmd(struct mii_bus *bus, int bus_addr, u8 cmd,
+ u8 *data, size_t len)
+{
+ struct i2c_adapter *i2c = bus->priv;
+ struct i2c_msg msgs[2];
+ u8 cmdbuf[2];
+ int ret;
+
+ msgs[0].addr = bus_addr;
+ msgs[0].flags = 0;
+ msgs[0].len = len;
+ msgs[0].buf = data;
+
+ cmdbuf[0] = ROLLBALL_CMD_ADDR;
+ cmdbuf[1] = cmd;
+
+ msgs[1].addr = bus_addr;
+ msgs[1].flags = 0;
+ msgs[1].len = sizeof(cmdbuf);
+ msgs[1].buf = cmdbuf;
+
+ ret = i2c_transfer(i2c, msgs, 2);
+ if (ret < 0)
+ return ret;
+
+ return ret == ARRAY_SIZE(msgs) ? 0 : -EIO;
+}
+
+static int i2c_mii_read_rollball(struct mii_bus *bus, int phy_id, int reg)
+{
+ u8 buf[4], res[6];
+ int bus_addr, ret;
+ u16 val;
+
+ if (!(reg & MII_ADDR_C45))
+ return -EOPNOTSUPP;
+
+ bus_addr = i2c_mii_phy_addr(phy_id);
+ if (bus_addr != ROLLBALL_PHY_I2C_ADDR)
+ return 0xffff;
+
+ buf[0] = ROLLBALL_DATA_ADDR;
+ buf[1] = (reg >> 16) & 0x1f;
+ buf[2] = (reg >> 8) & 0xff;
+ buf[3] = reg & 0xff;
+
+ ret = i2c_rollball_mii_cmd(bus, bus_addr, ROLLBALL_CMD_READ, buf,
+ sizeof(buf));
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_rollball_mii_poll(bus, bus_addr, res, sizeof(res));
+ if (ret == -ETIMEDOUT)
+ return 0xffff;
+ else if (ret < 0)
+ return ret;
+
+ val = res[4] << 8 | res[5];
+
+ dev_dbg(&bus->dev, "read reg %02x:%04x = %04x\n", (reg >> 16) & 0x1f,
+ reg & 0xffff, val);
+
+ return val;
+}
+
+static int i2c_mii_write_rollball(struct mii_bus *bus, int phy_id, int reg,
+ u16 val)
+{
+ int bus_addr, ret;
+ u8 buf[6];
+
+ if (!(reg & MII_ADDR_C45))
+ return -EOPNOTSUPP;
+
+ bus_addr = i2c_mii_phy_addr(phy_id);
+ if (bus_addr != ROLLBALL_PHY_I2C_ADDR)
+ return 0;
+
+ buf[0] = ROLLBALL_DATA_ADDR;
+ buf[1] = (reg >> 16) & 0x1f;
+ buf[2] = (reg >> 8) & 0xff;
+ buf[3] = reg & 0xff;
+ buf[4] = val >> 8;
+ buf[5] = val & 0xff;
+
+ ret = i2c_rollball_mii_cmd(bus, bus_addr, ROLLBALL_CMD_WRITE, buf,
+ sizeof(buf));
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_rollball_mii_poll(bus, bus_addr, NULL, 0);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(&bus->dev, "write reg %02x:%04x = %04x\n", (reg >> 16) & 0x1f,
+ reg & 0xffff, val);
+
+ return 0;
+}
+
+static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
+{
+ u8 page_buf[2], pw_buf[5];
+ struct i2c_msg msgs[2];
+ int ret;
+
+ page_buf[0] = SFP_PAGE;
+ page_buf[1] = 3;
+
+ msgs[0].addr = ROLLBALL_PHY_I2C_ADDR;
+ msgs[0].flags = 0;
+ msgs[0].len = sizeof(page_buf);
+ msgs[0].buf = page_buf;
+
+ pw_buf[0] = ROLLBALL_SFP_PASSWORD_ADDR;
+ pw_buf[1] = 0xff;
+ pw_buf[2] = 0xff;
+ pw_buf[3] = 0xff;
+ pw_buf[4] = 0xff;
+
+ msgs[1].addr = ROLLBALL_PHY_I2C_ADDR;
+ msgs[1].flags = 0;
+ msgs[1].len = sizeof(pw_buf);
+ msgs[1].buf = pw_buf;
+
+ ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs));
+ if (ret < 0)
+ return ret;
+ else if (ret != ARRAY_SIZE(msgs))
+ return -EIO;
+
+ return 0;
+}
+
+struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
+ enum mdio_i2c_proto protocol)
{
struct mii_bus *mii;
+ int ret;
if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
return ERR_PTR(-EINVAL);
@@ -104,10 +308,28 @@ struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c)
snprintf(mii->id, MII_BUS_ID_SIZE, "i2c:%s", dev_name(parent));
mii->parent = parent;
- mii->read = i2c_mii_read;
- mii->write = i2c_mii_write;
mii->priv = i2c;
+ switch (protocol) {
+ case MDIO_I2C_ROLLBALL:
+ ret = i2c_mii_init_rollball(i2c);
+ if (ret < 0) {
+ dev_err(parent,
+ "Cannot initialize RollBall MDIO I2C protocol: %d\n",
+ ret);
+ mdiobus_free(mii);
+ return ERR_PTR(ret);
+ }
+
+ mii->read = i2c_mii_read_rollball;
+ mii->write = i2c_mii_write_rollball;
+ break;
+ default:
+ mii->read = i2c_mii_read_default;
+ mii->write = i2c_mii_write_default;
+ break;
+ }
+
return mii;
}
EXPORT_SYMBOL_GPL(mdio_i2c_alloc);
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 1d18c10e8f82..b1f9fc3a5584 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -409,7 +409,7 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
sfp->read = sfp_i2c_read;
sfp->write = sfp_i2c_write;
- i2c_mii = mdio_i2c_alloc(sfp->dev, i2c);
+ i2c_mii = mdio_i2c_alloc(sfp->dev, i2c, MDIO_I2C_DEFAULT);
if (IS_ERR(i2c_mii))
return PTR_ERR(i2c_mii);
diff --git a/include/linux/mdio/mdio-i2c.h b/include/linux/mdio/mdio-i2c.h
index b1d27f7cd23f..53eedb0dc1d3 100644
--- a/include/linux/mdio/mdio-i2c.h
+++ b/include/linux/mdio/mdio-i2c.h
@@ -11,6 +11,12 @@ struct device;
struct i2c_adapter;
struct mii_bus;
-struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c);
+enum mdio_i2c_proto {
+ MDIO_I2C_DEFAULT,
+ MDIO_I2C_ROLLBALL,
+};
+
+struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
+ enum mdio_i2c_proto protocol);
#endif
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v2 2/5] net: phylink: allow attaching phy for SFP modules on 802.3z mode
2020-10-29 22:25 [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules Marek Behún
2020-10-29 22:25 ` [PATCH net-next v2 1/5] net: phy: mdio-i2c: support I2C MDIO protocol for RollBall " Marek Behún
@ 2020-10-29 22:25 ` Marek Behún
2020-10-30 16:29 ` Russell King - ARM Linux admin
2020-10-29 22:25 ` [PATCH net-next v2 3/5] net: sfp: create/destroy I2C mdiobus before PHY probe/after PHY release Marek Behún
` (3 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Marek Behún @ 2020-10-29 22:25 UTC (permalink / raw)
To: netdev; +Cc: davem, Marek Behún, Andrew Lunn, Russell King
Some SFPs may contain an internal PHY which may in some cases want to
connect with the host interface in 1000base-x/2500base-x mode.
Do not fail if such PHY is being attached in one of these PHY interface
modes.
Signed-off-by: Marek Behún <kabel@kernel.org>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 5d8c015bc9f2..705c49c37348 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1018,7 +1018,7 @@ static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy,
{
if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED ||
(pl->cfg_link_an_mode == MLO_AN_INBAND &&
- phy_interface_mode_is_8023z(interface))))
+ phy_interface_mode_is_8023z(interface) && !pl->sfp_bus)))
return -EINVAL;
if (pl->phydev)
@@ -2069,9 +2069,6 @@ static int phylink_sfp_config(struct phylink *pl, u8 mode,
phylink_an_mode_str(mode), phy_modes(config.interface),
__ETHTOOL_LINK_MODE_MASK_NBITS, support);
- if (phy_interface_mode_is_8023z(iface) && pl->phydev)
- return -EINVAL;
-
changed = !linkmode_equal(pl->supported, support);
if (changed) {
linkmode_copy(pl->supported, support);
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v2 3/5] net: sfp: create/destroy I2C mdiobus before PHY probe/after PHY release
2020-10-29 22:25 [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules Marek Behún
2020-10-29 22:25 ` [PATCH net-next v2 1/5] net: phy: mdio-i2c: support I2C MDIO protocol for RollBall " Marek Behún
2020-10-29 22:25 ` [PATCH net-next v2 2/5] net: phylink: allow attaching phy for SFP modules on 802.3z mode Marek Behún
@ 2020-10-29 22:25 ` Marek Behún
2020-10-30 16:31 ` Russell King - ARM Linux admin
2020-10-29 22:25 ` [PATCH net-next v2 4/5] net: phy: marvell10g: change MACTYPE if underlying MAC does not support it Marek Behún
` (2 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Marek Behún @ 2020-10-29 22:25 UTC (permalink / raw)
To: netdev; +Cc: davem, Marek Behún, Andrew Lunn, Russell King
Instead of configuring the I2C mdiobus when SFP driver is probed,
create/destroy the mdiobus before the PHY is probed for/after it is
released.
This way we can tell the mdio-i2c code which protocol to use for each
SFP transceiver.
Signed-off-by: Marek Behún <kabel@kernel.org>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/sfp.c | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index b1f9fc3a5584..3c3da19039d5 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -217,6 +217,7 @@ struct sfp {
struct i2c_adapter *i2c;
struct mii_bus *i2c_mii;
struct sfp_bus *sfp_bus;
+ enum mdio_i2c_proto mdio_protocol;
struct phy_device *mod_phy;
const struct sff_data *type;
u32 max_power_mW;
@@ -399,9 +400,6 @@ static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
{
- struct mii_bus *i2c_mii;
- int ret;
-
if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
return -EINVAL;
@@ -409,7 +407,15 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
sfp->read = sfp_i2c_read;
sfp->write = sfp_i2c_write;
- i2c_mii = mdio_i2c_alloc(sfp->dev, i2c, MDIO_I2C_DEFAULT);
+ return 0;
+}
+
+static int sfp_i2c_mdiobus_create(struct sfp *sfp)
+{
+ struct mii_bus *i2c_mii;
+ int ret;
+
+ i2c_mii = mdio_i2c_alloc(sfp->dev, sfp->i2c, sfp->mdio_protocol);
if (IS_ERR(i2c_mii))
return PTR_ERR(i2c_mii);
@@ -427,6 +433,12 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
return 0;
}
+static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
+{
+ mdiobus_unregister(sfp->i2c_mii);
+ sfp->i2c_mii = NULL;
+}
+
/* Interface */
static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
{
@@ -1768,6 +1780,8 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
else
sfp->module_t_start_up = T_START_UP;
+ sfp->mdio_protocol = MDIO_I2C_DEFAULT;
+
return 0;
}
@@ -1936,8 +1950,10 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
sfp_sm_link_down(sfp);
if (sfp->sm_state > SFP_S_INIT)
sfp_module_stop(sfp->sfp_bus);
- if (sfp->mod_phy)
+ if (sfp->mod_phy) {
sfp_sm_phy_detach(sfp);
+ sfp_i2c_mdiobus_destroy(sfp);
+ }
sfp_module_tx_disable(sfp);
sfp_soft_stop_poll(sfp);
sfp_sm_next(sfp, SFP_S_DOWN, 0);
@@ -2000,6 +2016,12 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
sfp->sm_fault_retries == N_FAULT_INIT);
} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
init_done:
+ /* Create mdiobus and start trying for PHY */
+ ret = sfp_i2c_mdiobus_create(sfp);
+ if (ret < 0) {
+ sfp_sm_next(sfp, SFP_S_FAIL, 0);
+ break;
+ }
sfp->sm_phy_retries = R_PHY_RETRY;
goto phy_probe;
}
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v2 4/5] net: phy: marvell10g: change MACTYPE if underlying MAC does not support it
2020-10-29 22:25 [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules Marek Behún
` (2 preceding siblings ...)
2020-10-29 22:25 ` [PATCH net-next v2 3/5] net: sfp: create/destroy I2C mdiobus before PHY probe/after PHY release Marek Behún
@ 2020-10-29 22:25 ` Marek Behún
2020-10-29 22:25 ` [PATCH net-next v2 5/5] net: sfp: add support for multigig RollBall transceivers Marek Behún
2020-10-30 15:01 ` [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules Russell King - ARM Linux admin
5 siblings, 0 replies; 12+ messages in thread
From: Marek Behún @ 2020-10-29 22:25 UTC (permalink / raw)
To: netdev; +Cc: davem, Marek Behún, Andrew Lunn, Russell King
RollBall SFPs contain a Marvell 88X3310 PHY, but by default the MACTYPE
is set to 10GBASE-R with Rate Matching.
Some devices (for example those based on Armada 38x) only support up to
2500base-x SerDes modes.
Change the PHY's MACTYPE to 4 (which means changing between 10gbase-r,
5gbase-r, 2500base-x ans SGMII depending on copper speed) if this is the
case (which is infered from phydev->interface).
Signed-off-by: Marek Behún <kabel@kernel.org>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/marvell10g.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index 1901ba277413..9e8e9aa66972 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -453,6 +453,33 @@ static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev)
MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV;
}
+static int mv3310_select_mactype(struct phy_device *phydev)
+{
+ int mac_type, ret;
+
+ /* On some devices the MAC does not support 10G mode, but may support
+ * lower modes, such as SGMII or 2500base-x.
+ * By changing MACTYPE of the PHY to 4 in this case, we ensure that
+ * the MAC will link with the PHY at least for these lower speeds.
+ */
+ switch (phydev->interface) {
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ mac_type = 4;
+ break;
+ default:
+ return 0;
+ }
+
+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
+ MV_V2_PORT_MAC_TYPE_MASK, mac_type);
+ if (ret <= 0)
+ return ret;
+
+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
+ MV_V2_PORT_CTRL_SWRST, MV_V2_PORT_CTRL_SWRST);
+}
+
static int mv3310_config_init(struct phy_device *phydev)
{
struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
@@ -474,6 +501,10 @@ static int mv3310_config_init(struct phy_device *phydev)
if (err)
return err;
+ err = mv3310_select_mactype(phydev);
+ if (err)
+ return err;
+
val = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL);
if (val < 0)
return val;
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v2 5/5] net: sfp: add support for multigig RollBall transceivers
2020-10-29 22:25 [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules Marek Behún
` (3 preceding siblings ...)
2020-10-29 22:25 ` [PATCH net-next v2 4/5] net: phy: marvell10g: change MACTYPE if underlying MAC does not support it Marek Behún
@ 2020-10-29 22:25 ` Marek Behún
2020-10-30 16:33 ` Russell King - ARM Linux admin
2020-10-30 15:01 ` [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules Russell King - ARM Linux admin
5 siblings, 1 reply; 12+ messages in thread
From: Marek Behún @ 2020-10-29 22:25 UTC (permalink / raw)
To: netdev; +Cc: davem, Marek Behún, Andrew Lunn, Russell King
This adds support for multigig copper SFP modules from RollBall/Hilink.
These modules have a specific way to access clause 45 registers of the
internal PHY.
We also need to wait at least 25 seconds after deasserting TX disable
before accessing the PHY. The code waits for 30 seconds just to be sure.
Signed-off-by: Marek Behún <kabel@kernel.org>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/sfp.c | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 3c3da19039d5..a0a2af817c0f 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -165,6 +165,7 @@ static const enum gpiod_flags gpio_flags[] = {
* on board (for a copper SFP) time to initialise.
*/
#define T_WAIT msecs_to_jiffies(50)
+#define T_WAIT_ROLLBALL msecs_to_jiffies(30000)
#define T_START_UP msecs_to_jiffies(300)
#define T_START_UP_BAD_GPON msecs_to_jiffies(60000)
@@ -204,8 +205,11 @@ static const enum gpiod_flags gpio_flags[] = {
/* SFP modules appear to always have their PHY configured for bus address
* 0x56 (which with mdio-i2c, translates to a PHY address of 22).
+ * RollBall SFPs access phy via SFP Enhanced Digital Diagnostic Interface
+ * via address 0x51 (mdio-i2c will use RollBall protocol on this address).
*/
-#define SFP_PHY_ADDR 22
+#define SFP_PHY_ADDR 22
+#define SFP_PHY_ADDR_ROLLBALL 17
struct sff_data {
unsigned int gpios;
@@ -218,6 +222,7 @@ struct sfp {
struct mii_bus *i2c_mii;
struct sfp_bus *sfp_bus;
enum mdio_i2c_proto mdio_protocol;
+ int phy_addr;
struct phy_device *mod_phy;
const struct sff_data *type;
u32 max_power_mW;
@@ -249,6 +254,7 @@ struct sfp {
struct sfp_eeprom_id id;
unsigned int module_power_mW;
unsigned int module_t_start_up;
+ unsigned int module_t_wait;
#if IS_ENABLED(CONFIG_HWMON)
struct sfp_diag diag;
@@ -1443,7 +1449,7 @@ static int sfp_sm_probe_phy(struct sfp *sfp, bool is_c45)
struct phy_device *phy;
int err;
- phy = get_phy_device(sfp->i2c_mii, SFP_PHY_ADDR, is_c45);
+ phy = get_phy_device(sfp->i2c_mii, sfp->phy_addr, is_c45);
if (phy == ERR_PTR(-ENODEV))
return PTR_ERR(phy);
if (IS_ERR(phy)) {
@@ -1781,6 +1787,22 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
sfp->module_t_start_up = T_START_UP;
sfp->mdio_protocol = MDIO_I2C_DEFAULT;
+ sfp->phy_addr = SFP_PHY_ADDR;
+ sfp->module_t_wait = T_WAIT;
+
+ if (((!memcmp(id.base.vendor_name, "OEM ", 16) ||
+ !memcmp(id.base.vendor_name, "Turris ", 16)) &&
+ (!memcmp(id.base.vendor_pn, "SFP-10G-T ", 16) ||
+ !memcmp(id.base.vendor_pn, "RTSFP-10", 8)))) {
+ sfp->mdio_protocol = MDIO_I2C_ROLLBALL;
+ sfp->phy_addr = SFP_PHY_ADDR_ROLLBALL;
+ sfp->module_t_wait = T_WAIT_ROLLBALL;
+
+ /* RollBall SFPs may have wrong (zero) extended compliacne code
+ * burned in EEPROM. For PHY probing we need the correct one.
+ */
+ id.base.extended_cc = SFF8024_ECC_10GBASE_T_SFI;
+ }
return 0;
}
@@ -1977,9 +1999,10 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
/* We need to check the TX_FAULT state, which is not defined
* while TX_DISABLE is asserted. The earliest we want to do
- * anything (such as probe for a PHY) is 50ms.
+ * anything (such as probe for a PHY) is 50ms (or more on
+ * specific modules).
*/
- sfp_sm_next(sfp, SFP_S_WAIT, T_WAIT);
+ sfp_sm_next(sfp, SFP_S_WAIT, sfp->module_t_wait);
break;
case SFP_S_WAIT:
@@ -1993,8 +2016,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
* deasserting.
*/
timeout = sfp->module_t_start_up;
- if (timeout > T_WAIT)
- timeout -= T_WAIT;
+ if (timeout > sfp->module_t_wait)
+ timeout -= sfp->module_t_wait;
else
timeout = 1;
--
2.26.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules
2020-10-29 22:25 [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules Marek Behún
` (4 preceding siblings ...)
2020-10-29 22:25 ` [PATCH net-next v2 5/5] net: sfp: add support for multigig RollBall transceivers Marek Behún
@ 2020-10-30 15:01 ` Russell King - ARM Linux admin
2020-10-30 15:29 ` Vladimir Oltean
5 siblings, 1 reply; 12+ messages in thread
From: Russell King - ARM Linux admin @ 2020-10-30 15:01 UTC (permalink / raw)
To: Marek Behún; +Cc: netdev, davem, Andrew Lunn
A general point: please have me in the To: line rather than the Cc:
line so that I can find emails better; I've just spent quite a while
trying to find this series you posted last night amongst all the
other emails that I'm Cc'd on.
(The difference between To: and Cc: is that you expect those in the To:
header to be the primary recipients who you expect action from, and
those in the Cc: to be secondary recipients for information.)
https://blog.thedigitalgroup.com/to-vs-cc-vs-bcc-how-to-use-them-correctly
https://www.writebetteremails.com/to-cc.htm
https://thinkproductive.co.uk/email-using-cc-bcc-to/
... etc ...
Thanks.
On Thu, Oct 29, 2020 at 11:25:04PM +0100, Marek Behún wrote:
> Hello,
>
> this is v2 of series adding support for RollBall/Hilink SFP modules.
>
> Checked with:
> checkpatch.pl --max-line-length=80
>
> Changes from v1:
> - wrapped to 80 columns as per Russell's request
> - initialization of RollBall MDIO I2C protocol moved from sfp.c to
> mdio-i2c.c as per Russell's request
> - second patch removes the 802.3z check also from phylink_sfp_config
> as suggested by Russell
> - creation/destruction of mdiobus for SFP now occurs before probing
> for PHY/after releasing PHY (as suggested by Russell)
> - the last patch became a little simpler after the above was done
>
> Cc: Andrew Lunn <andrew@lunn.ch>
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>
> Marek Behún (5):
> net: phy: mdio-i2c: support I2C MDIO protocol for RollBall SFP modules
> net: phylink: allow attaching phy for SFP modules on 802.3z mode
> net: sfp: create/destroy I2C mdiobus before PHY probe/after PHY
> release
> net: phy: marvell10g: change MACTYPE if underlying MAC does not
> support it
> net: sfp: add support for multigig RollBall transceivers
>
> drivers/net/mdio/mdio-i2c.c | 232 +++++++++++++++++++++++++++++++++-
> drivers/net/phy/marvell10g.c | 31 +++++
> drivers/net/phy/phylink.c | 5 +-
> drivers/net/phy/sfp.c | 67 ++++++++--
> include/linux/mdio/mdio-i2c.h | 8 +-
> 5 files changed, 322 insertions(+), 21 deletions(-)
>
>
> base-commit: cd29296fdfca919590e4004a7e4905544f4c4a32
> --
> 2.26.2
>
>
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 1/5] net: phy: mdio-i2c: support I2C MDIO protocol for RollBall SFP modules
2020-10-29 22:25 ` [PATCH net-next v2 1/5] net: phy: mdio-i2c: support I2C MDIO protocol for RollBall " Marek Behún
@ 2020-10-30 15:20 ` Russell King - ARM Linux admin
0 siblings, 0 replies; 12+ messages in thread
From: Russell King - ARM Linux admin @ 2020-10-30 15:20 UTC (permalink / raw)
To: Marek Behún; +Cc: netdev, davem, Andrew Lunn
On Thu, Oct 29, 2020 at 11:25:05PM +0100, Marek Behún wrote:
> @@ -91,9 +94,210 @@ static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
> return ret < 0 ? ret : 0;
> }
>
> -struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c)
> +/* RollBall SFPs do not access internal PHY via I2C address 0x56, but
> + * instead via address 0x51, when SFP page is set to 0x03 and password to
> + * 0xffffffff:
> + *
> + * address size contents description
> + * ------- ---- -------- -----------
> + * 0x80 1 CMD 0x01/0x02/0x04 for write/read/done
> + * 0x81 1 DEV Clause 45 device
> + * 0x82 2 REG Clause 45 register
> + * 0x84 2 VAL Register value
> + */
...
> +static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
> +{
> + u8 page_buf[2], pw_buf[5];
> + struct i2c_msg msgs[2];
> + int ret;
> +
> + page_buf[0] = SFP_PAGE;
> + page_buf[1] = 3;
> +
> + msgs[0].addr = ROLLBALL_PHY_I2C_ADDR;
> + msgs[0].flags = 0;
> + msgs[0].len = sizeof(page_buf);
> + msgs[0].buf = page_buf;
> +
> + pw_buf[0] = ROLLBALL_SFP_PASSWORD_ADDR;
> + pw_buf[1] = 0xff;
> + pw_buf[2] = 0xff;
> + pw_buf[3] = 0xff;
> + pw_buf[4] = 0xff;
> +
> + msgs[1].addr = ROLLBALL_PHY_I2C_ADDR;
> + msgs[1].flags = 0;
> + msgs[1].len = sizeof(pw_buf);
> + msgs[1].buf = pw_buf;
> +
> + ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs));
> + if (ret < 0)
> + return ret;
> + else if (ret != ARRAY_SIZE(msgs))
> + return -EIO;
> +
> + return 0;
> +}
One of the points I raised in the previous review was: "Also, shouldn't
we ensure that we are on page 1 before attempting any access?" I
actually meant page 3 which I corrected when commenting on patch 5:
"I think this needs to be done in the MDIO driver - if we have userspace
or otherwise expand what we're doing, relying on page 3 remaining
selected will be very fragile."
I feel that point still stands; if the SFP page is changed after
i2c_mii_init_rollball() and before a subsequent access, the subsequent
access is not going to hit the correct page, and we will lose access
to the PHY. Worse, we will end up writing to that other page.
That said, I don't see anything in SFF8472 that would result in a
clash, so I think I would like to see the comment at the beginning
make explicit the expectation that SFP_PAGE will remain set to 3
throughout the lifetime of the module plugged into the system.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules
2020-10-30 15:01 ` [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules Russell King - ARM Linux admin
@ 2020-10-30 15:29 ` Vladimir Oltean
0 siblings, 0 replies; 12+ messages in thread
From: Vladimir Oltean @ 2020-10-30 15:29 UTC (permalink / raw)
To: Russell King - ARM Linux admin
Cc: Marek Behún, netdev, davem, Andrew Lunn
On Fri, Oct 30, 2020 at 03:01:38PM +0000, Russell King - ARM Linux admin wrote:
> https://blog.thedigitalgroup.com/to-vs-cc-vs-bcc-how-to-use-them-correctly
I have to disagree about some of the information provided in this link:
------------------------------[cut here]------------------------------
Using the BCC Field:
BCC is for Blind Carbon Copy. It sends copies of the email to multiple
recipients, the only difference being that none of the recipients are
made aware of who else has received the email.
The BCC field is used when you want to send an email to multiple
recipients but do not want any of them to know about the other people
you have sent them to. There can be many scenarios where the BCC field
might be used, and the purpose might be a desire to keep the names of
the recipients a secret to one another and also protect the privacy of
recipients.
The most common application is for sending an email to a long list of
people who do not know each other, such as mailing lists. This protects
the privacy of the recipients as they are not able to view each other’s
email addresses.
------------------------------[cut here]------------------------------
It's plain stupid to put a mailing list in Bcc. I have filters that move
inbound emails from Inbox to separate folders based on the mailing list
from To: or CC:, except for emails where my address is also in To: or Cc:.
But when the mailing list is in Bcc, that email evades the filter and
arrives directly in my inbox, regardless of whether I'm even an intended
recipient or not.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 2/5] net: phylink: allow attaching phy for SFP modules on 802.3z mode
2020-10-29 22:25 ` [PATCH net-next v2 2/5] net: phylink: allow attaching phy for SFP modules on 802.3z mode Marek Behún
@ 2020-10-30 16:29 ` Russell King - ARM Linux admin
0 siblings, 0 replies; 12+ messages in thread
From: Russell King - ARM Linux admin @ 2020-10-30 16:29 UTC (permalink / raw)
To: Marek Behún; +Cc: netdev, davem, Andrew Lunn
On Thu, Oct 29, 2020 at 11:25:06PM +0100, Marek Behún wrote:
> Some SFPs may contain an internal PHY which may in some cases want to
> connect with the host interface in 1000base-x/2500base-x mode.
> Do not fail if such PHY is being attached in one of these PHY interface
> modes.
>
> Signed-off-by: Marek Behún <kabel@kernel.org>
> Cc: Andrew Lunn <andrew@lunn.ch>
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Russell King <rmk+kernel@armlinux.org.uk>
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 3/5] net: sfp: create/destroy I2C mdiobus before PHY probe/after PHY release
2020-10-29 22:25 ` [PATCH net-next v2 3/5] net: sfp: create/destroy I2C mdiobus before PHY probe/after PHY release Marek Behún
@ 2020-10-30 16:31 ` Russell King - ARM Linux admin
0 siblings, 0 replies; 12+ messages in thread
From: Russell King - ARM Linux admin @ 2020-10-30 16:31 UTC (permalink / raw)
To: Marek Behún; +Cc: netdev, davem, Andrew Lunn
On Thu, Oct 29, 2020 at 11:25:07PM +0100, Marek Behún wrote:
> @@ -1936,8 +1950,10 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
> sfp_sm_link_down(sfp);
> if (sfp->sm_state > SFP_S_INIT)
> sfp_module_stop(sfp->sfp_bus);
> - if (sfp->mod_phy)
> + if (sfp->mod_phy) {
> sfp_sm_phy_detach(sfp);
> + sfp_i2c_mdiobus_destroy(sfp);
> + }
if (sfp->mod_phy)
sfp_sm_phy_detach(sfp);
if (sfp->i2c_mii)
sfp_i2c_mdiobus_destroy(sfp);
would be better IMHO, in case we end up with the MDIO bus registered
but don't discover a PHY. (which is entirely possible with Mikrotik
SFPs where the PHY is not accessible.)
Other than that, I don't see any obvious issues.
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 5/5] net: sfp: add support for multigig RollBall transceivers
2020-10-29 22:25 ` [PATCH net-next v2 5/5] net: sfp: add support for multigig RollBall transceivers Marek Behún
@ 2020-10-30 16:33 ` Russell King - ARM Linux admin
0 siblings, 0 replies; 12+ messages in thread
From: Russell King - ARM Linux admin @ 2020-10-30 16:33 UTC (permalink / raw)
To: Marek Behún; +Cc: netdev, davem, Andrew Lunn
On Thu, Oct 29, 2020 at 11:25:09PM +0100, Marek Behún wrote:
> This adds support for multigig copper SFP modules from RollBall/Hilink.
> These modules have a specific way to access clause 45 registers of the
> internal PHY.
>
> We also need to wait at least 25 seconds after deasserting TX disable
> before accessing the PHY. The code waits for 30 seconds just to be sure.
>
> Signed-off-by: Marek Behún <kabel@kernel.org>
> Cc: Andrew Lunn <andrew@lunn.ch>
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Russell King <rmk+kernel@armlinux.org.uk>
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2020-10-30 16:33 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-10-29 22:25 [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules Marek Behún
2020-10-29 22:25 ` [PATCH net-next v2 1/5] net: phy: mdio-i2c: support I2C MDIO protocol for RollBall " Marek Behún
2020-10-30 15:20 ` Russell King - ARM Linux admin
2020-10-29 22:25 ` [PATCH net-next v2 2/5] net: phylink: allow attaching phy for SFP modules on 802.3z mode Marek Behún
2020-10-30 16:29 ` Russell King - ARM Linux admin
2020-10-29 22:25 ` [PATCH net-next v2 3/5] net: sfp: create/destroy I2C mdiobus before PHY probe/after PHY release Marek Behún
2020-10-30 16:31 ` Russell King - ARM Linux admin
2020-10-29 22:25 ` [PATCH net-next v2 4/5] net: phy: marvell10g: change MACTYPE if underlying MAC does not support it Marek Behún
2020-10-29 22:25 ` [PATCH net-next v2 5/5] net: sfp: add support for multigig RollBall transceivers Marek Behún
2020-10-30 16:33 ` Russell King - ARM Linux admin
2020-10-30 15:01 ` [PATCH net-next v2 0/5] Support for RollBall 10G copper SFP modules Russell King - ARM Linux admin
2020-10-30 15:29 ` Vladimir Oltean
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).