From: Antoine Tenart <hidden> Date: 2017-06-07 08:38:01
Hello,
This series aims to add the xSMI support (also called xMDIO) to the
mvmdio driver. The xSMI interface complies with the IEEE 802.3 clause 45
and is used by 10GbE devices. On 7k and 8k (as of now), such an
interface is found and is used by Ethernet controllers.
Patches 1-3 are cosmetic cleanups.
Patches 4-6 are prerequisites to the xSMI support.
Patches 7-9 add the xSMI support to the mvmdio driver, and a node is
added both in the cp110 slave and master device trees.
This was tested on an Armada 8040 mcbin, as well as on both the
Armada 7040 DB and the Armada 8040 DB to ensure the SMI interface
was still working.
Thanks,
Antoine
Antoine Tenart (9):
net: mvmdio: reorder headers alphabetically
net: mvmdio: use tabs for defines
net: mvmdio: use GENMASK for masks
net: mvmdio: move the read valid check into its own function
net: mvmdio: introduce an ops structure
net: mvmdio: put the poll intervals in the private structure
net: mvmdio: add xmdio support
dt-bindings: orion-mdio: document the new xmdio compatible
arm64: marvell: dts: add xmdio nodes for 7k/8k
.../devicetree/bindings/net/marvell-orion-mdio.txt | 8 +-
.../boot/dts/marvell/armada-cp110-master.dtsi | 7 +
.../arm64/boot/dts/marvell/armada-cp110-slave.dtsi | 7 +
drivers/net/ethernet/marvell/Kconfig | 6 +-
drivers/net/ethernet/marvell/mvmdio.c | 200 +++++++++++++++++----
5 files changed, 184 insertions(+), 44 deletions(-)
--
2.9.4
From: Antoine Tenart <hidden> Date: 2017-06-07 08:38:04
Cosmetic patch to use the GENMASK helper for masks.
Signed-off-by: Antoine Tenart <redacted>
---
drivers/net/ethernet/marvell/mvmdio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Antoine Tenart <hidden> Date: 2017-06-07 08:38:05
Move the read valid check in its own function. This is needed as a
requirement to factorize the driver to add the xMDIO support in the
future.
Signed-off-by: Antoine Tenart <redacted>
---
drivers/net/ethernet/marvell/mvmdio.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
@@ -69,6 +69,11 @@ static int orion_mdio_smi_is_done(struct orion_mdio_dev *dev)return!(readl(dev->regs)&MVMDIO_SMI_BUSY);}+staticintorion_mdio_smi_is_read_valid(structorion_mdio_dev*dev)+{+return!(readl(dev->regs)&MVMDIO_SMI_READ_VALID);+}+/* Wait for the SMI unit to be ready for another operation*/staticintorion_mdio_wait_ready(structmii_bus*bus)
@@ -113,7 +118,6 @@ static int orion_mdio_read(struct mii_bus *bus, int mii_id,intregnum){structorion_mdio_dev*dev=bus->priv;-u32val;intret;mutex_lock(&dev->lock);
@@ -131,14 +135,13 @@ static int orion_mdio_read(struct mii_bus *bus, int mii_id,if(ret<0)gotoout;-val=readl(dev->regs);-if(!(val&MVMDIO_SMI_READ_VALID)){+if(orion_mdio_smi_is_read_valid(dev)){dev_err(bus->parent,"SMI bus read not valid\n");ret=-ENODEV;gotoout;}-ret=val&GENMASK(15,0);+ret=readl(dev->regs)&GENMASK(15,0);out:mutex_unlock(&dev->lock);returnret;
From: Antoine Tenart <hidden> Date: 2017-06-07 08:38:06
Introduce an ops structure to add an indirection on functions accessing
the registers. This is needed to add the xMDIO support later.
Signed-off-by: Antoine Tenart <redacted>
---
drivers/net/ethernet/marvell/mvmdio.c | 65 +++++++++++++++++++++++++++--------
1 file changed, 51 insertions(+), 14 deletions(-)
@@ -74,6 +83,30 @@ static int orion_mdio_smi_is_read_valid(struct orion_mdio_dev *dev)return!(readl(dev->regs)&MVMDIO_SMI_READ_VALID);}+staticvoidorion_mdio_start_read_op(structorion_mdio_dev*dev,intmii_id,+intregnum)+{+writel(((mii_id<<MVMDIO_SMI_PHY_ADDR_SHIFT)|+(regnum<<MVMDIO_SMI_PHY_REG_SHIFT)|+MVMDIO_SMI_READ_OPERATION),+dev->regs);+}++staticu16orion_mdio_read_op(structorion_mdio_dev*dev)+{+returnreadl(dev->regs)&GENMASK(15,0);+}++staticvoidorion_mdio_write_op(structorion_mdio_dev*dev,intmii_id,+intregnum,u16value)+{+writel(((mii_id<<MVMDIO_SMI_PHY_ADDR_SHIFT)|+(regnum<<MVMDIO_SMI_PHY_REG_SHIFT)|+MVMDIO_SMI_WRITE_OPERATION|+(value<<MVMDIO_SMI_DATA_SHIFT)),+dev->regs);+}+/* Wait for the SMI unit to be ready for another operation*/staticintorion_mdio_wait_ready(structmii_bus*bus)
@@ -84,7 +117,7 @@ static int orion_mdio_wait_ready(struct mii_bus *bus)inttimedout=0;while(1){-if(orion_mdio_smi_is_done(dev))+if(dev->ops->is_done(dev))return0;elseif(timedout)break;
@@ -103,8 +136,7 @@ static int orion_mdio_wait_ready(struct mii_bus *bus)if(timeout<2)timeout=2;wait_event_timeout(dev->smi_busy_wait,-orion_mdio_smi_is_done(dev),-timeout);+dev->ops->is_done(dev),timeout);++timedout;}
@@ -126,22 +158,19 @@ static int orion_mdio_read(struct mii_bus *bus, int mii_id,if(ret<0)gotoout;-writel(((mii_id<<MVMDIO_SMI_PHY_ADDR_SHIFT)|-(regnum<<MVMDIO_SMI_PHY_REG_SHIFT)|-MVMDIO_SMI_READ_OPERATION),-dev->regs);+dev->ops->start_read(dev,mii_id,regnum);ret=orion_mdio_wait_ready(bus);if(ret<0)gotoout;-if(orion_mdio_smi_is_read_valid(dev)){+if(dev->ops->is_read_valid(dev)){dev_err(bus->parent,"SMI bus read not valid\n");ret=-ENODEV;gotoout;}-ret=readl(dev->regs)&GENMASK(15,0);+ret=dev->ops->read(dev);out:mutex_unlock(&dev->lock);returnret;
@@ -159,11 +188,7 @@ static int orion_mdio_write(struct mii_bus *bus, int mii_id,if(ret<0)gotoout;-writel(((mii_id<<MVMDIO_SMI_PHY_ADDR_SHIFT)|-(regnum<<MVMDIO_SMI_PHY_REG_SHIFT)|-MVMDIO_SMI_WRITE_OPERATION|-(value<<MVMDIO_SMI_DATA_SHIFT)),-dev->regs);+dev->ops->write(dev,mii_id,regnum,value);out:mutex_unlock(&dev->lock);
@@ -190,6 +215,7 @@ static int orion_mdio_probe(struct platform_device *pdev)structresource*r;structmii_bus*bus;structorion_mdio_dev*dev;+structorion_mdio_ops*ops;inti,ret;r=platform_get_resource(pdev,IORESOURCE_MEM,0);
@@ -249,6 +275,17 @@ static int orion_mdio_probe(struct platform_device *pdev)mutex_init(&dev->lock);+ops=devm_kzalloc(&pdev->dev,sizeof(*ops),GFP_KERNEL);+if(!ops)+return-ENOMEM;++ops->is_done=orion_mdio_smi_is_done;+ops->is_read_valid=orion_mdio_smi_is_read_valid;+ops->start_read=orion_mdio_start_read_op;+ops->read=orion_mdio_read_op;+ops->write=orion_mdio_write_op;+dev->ops=ops;+if(pdev->dev.of_node)ret=of_mdiobus_register(bus,pdev->dev.of_node);else
From: Antoine Tenart <hidden> Date: 2017-06-07 08:38:07
Put the two poll intervals (min and max) in the driver's private
structure. This is needed to add the xmdio support later.
Signed-off-by: Antoine Tenart <redacted>
---
drivers/net/ethernet/marvell/mvmdio.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
From: Antoine Tenart <hidden> Date: 2017-06-07 08:38:08
This patch adds the xMDIO interface support in the mvmdio driver. This
interface is used in Ethernet controllers on Marvell 370, 7k and 8k (as
of now). The xSMI interface supported by this driver complies with the
IEEE 802.3 clause 45 (while the SMI interface complies with the clause
22). The xSMI interface is used by 10GbE devices.
Signed-off-by: Antoine Tenart <redacted>
---
drivers/net/ethernet/marvell/Kconfig | 6 +-
drivers/net/ethernet/marvell/mvmdio.c | 121 ++++++++++++++++++++++++++++------
2 files changed, 104 insertions(+), 23 deletions(-)
@@ -110,6 +123,47 @@ static void orion_mdio_write_op(struct orion_mdio_dev *dev, int mii_id,dev->regs);}+/* xsmi */+staticintxsmi_is_done(structorion_mdio_dev*dev)+{+return!(readl(dev->regs+MVMDIO_XSMI_MGNT_REG)&MVMDIO_XSMI_BUSY);+}++staticintxsmi_is_read_valid(structorion_mdio_dev*dev)+{+return!(readl(dev->regs+MVMDIO_XSMI_MGNT_REG)&+MVMDIO_XSMI_READ_VALID);+}++staticvoidxsmi_start_read_op(structorion_mdio_dev*dev,intmii_id,+intregnum)+{+u16dev_addr=regnum>>16;++writel(regnum&GENMASK(15,0),dev->regs+MVMDIO_XSMI_ADDR_REG);+writel((mii_id<<MVMDIO_XSMI_PHYADDR_SHIFT)|+(dev_addr<<MVMDIO_XSMI_DEVADDR_SHIFT)|+MVMDIO_XSMI_READ_OPERATION,+dev->regs+MVMDIO_XSMI_MGNT_REG);+}++staticu16xsmi_read_op(structorion_mdio_dev*dev)+{+returnreadl(dev->regs+MVMDIO_XSMI_MGNT_REG)&GENMASK(15,0);+}++staticvoidxsmi_write_op(structorion_mdio_dev*dev,intmii_id,+intregnum,u16value)+{+u16dev_addr=regnum>>16;++writel(regnum&GENMASK(15,0),dev->regs+MVMDIO_XSMI_ADDR_REG);+writel((mii_id<<MVMDIO_XSMI_PHYADDR_SHIFT)|+(dev_addr<<MVMDIO_XSMI_DEVADDR_SHIFT)|+MVMDIO_XSMI_WRITE_OPERATION|value,+dev->regs+MVMDIO_XSMI_MGNT_REG);+}+/* Wait for the SMI unit to be ready for another operation*/staticintorion_mdio_wait_ready(structmii_bus*bus)
From: Antoine Tenart <hidden> Date: 2017-06-07 08:38:09
A new compatible for Marvell xMDIO interfaces was added into the Marvell
MDIO driver. Document this new compatible.
Signed-off-by: Antoine Tenart <redacted>
---
Documentation/devicetree/bindings/net/marvell-orion-mdio.txt | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
@@ -1,12 +1,12 @@ * Marvell MDIO Ethernet Controller interface The Ethernet controllers of the Marvel Kirkwood, Dove, Orion5x,-MV78xx0, Armada 370 and Armada XP have an identical unit that provides-an interface with the MDIO bus. This driver handles this MDIO-interface.+MV78xx0, Armada 370, Armada XP, Armada 7k and Armada 8k have an+identical unit that provides an interface with the MDIO bus or to+the xMDIO bus. This driver handles these interfaces. Required properties:-- compatible: "marvell,orion-mdio"+- compatible: "marvell,orion-mdio" or "marvell,xmdio" - reg: address and length of the MDIO registers. When an interrupt is not present, the length is the size of the SMI register (4 bytes) otherwise it must be 0x84 bytes to cover the interrupt control
From: Antoine Tenart <hidden> Date: 2017-06-07 08:38:10
Add the description of the xMDIO bus for the Marvell Armada 7k and
Marvell Armada 8k; for both CP110 slave and master. This bus is found
on Marvell Ethernet controllers and provides an interface with the
xMDIO bus.
Signed-off-by: Antoine Tenart <redacted>
---
arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi | 7 +++++++
arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi | 7 +++++++
2 files changed, 14 insertions(+)
From: Sergei Shtylyov <hidden> Date: 2017-06-07 10:00:21
Hello!
On 6/7/2017 11:38 AM, Antoine Tenart wrote:
quoted hunk
Move the read valid check in its own function. This is needed as a
requirement to factorize the driver to add the xMDIO support in the
future.
Signed-off-by: Antoine Tenart <redacted>
---
drivers/net/ethernet/marvell/mvmdio.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
@@ -69,6 +69,11 @@ static int orion_mdio_smi_is_done(struct orion_mdio_dev *dev)return!(readl(dev->regs)&MVMDIO_SMI_BUSY);}+staticintorion_mdio_smi_is_read_valid(structorion_mdio_dev*dev)+{+return!(readl(dev->regs)&MVMDIO_SMI_READ_VALID);+}+/* Wait for the SMI unit to be ready for another operation*/staticintorion_mdio_wait_ready(structmii_bus*bus)
@@ -113,7 +118,6 @@ static int orion_mdio_read(struct mii_bus *bus, int mii_id,intregnum){structorion_mdio_dev*dev=bus->priv;-u32val;intret;mutex_lock(&dev->lock);
@@ -131,14 +135,13 @@ static int orion_mdio_read(struct mii_bus *bus, int mii_id,if(ret<0)gotoout;-val=readl(dev->regs);-if(!(val&MVMDIO_SMI_READ_VALID)){+if(orion_mdio_smi_is_read_valid(dev)){dev_err(bus->parent,"SMI bus read not valid\n");
I think you reversed the valuid/invalid sense in the new function's name.
On Wed, Jun 07, 2017 at 10:38:08AM +0200, Antoine Tenart wrote:
This patch adds the xMDIO interface support in the mvmdio driver. This
interface is used in Ethernet controllers on Marvell 370, 7k and 8k (as
of now). The xSMI interface supported by this driver complies with the
IEEE 802.3 clause 45 (while the SMI interface complies with the clause
22). The xSMI interface is used by 10GbE devices.
Signed-off-by: Antoine Tenart <redacted>
Hi Antoine
I've only take a quick look, but i don't see anywhere you look at the
register address and see if it has MII_ADDR_C45 to determine if a C45
transaction should be done, or a C22. The MDIO bus can have a mix of
C45 and C22 devices on it, and you need to use the correct transaction
type depending on the target device/address.
Andrew
From: Antoine Tenart <hidden> Date: 2017-06-07 14:42:32
Hi Andrew,
On Wed, Jun 07, 2017 at 02:12:05PM +0200, Andrew Lunn wrote:
On Wed, Jun 07, 2017 at 10:38:08AM +0200, Antoine Tenart wrote:
quoted
This patch adds the xMDIO interface support in the mvmdio driver. This
interface is used in Ethernet controllers on Marvell 370, 7k and 8k (as
of now). The xSMI interface supported by this driver complies with the
IEEE 802.3 clause 45 (while the SMI interface complies with the clause
22). The xSMI interface is used by 10GbE devices.
I've only take a quick look, but i don't see anywhere you look at the
register address and see if it has MII_ADDR_C45 to determine if a C45
transaction should be done, or a C22. The MDIO bus can have a mix of
C45 and C22 devices on it, and you need to use the correct transaction
type depending on the target device/address.
From: Antoine Tenart <hidden> Date: 2017-06-07 14:43:08
Hello,
On Wed, Jun 07, 2017 at 01:00:21PM +0300, Sergei Shtylyov wrote:
On 6/7/2017 11:38 AM, Antoine Tenart wrote:
quoted
- val = readl(dev->regs);
- if (!(val & MVMDIO_SMI_READ_VALID)) {
+ if (orion_mdio_smi_is_read_valid(dev)) {
dev_err(bus->parent, "SMI bus read not valid\n");
I think you reversed the valuid/invalid sense in the new function's name.
This patch adds the xMDIO interface support in the mvmdio driver. This
interface is used in Ethernet controllers on Marvell 370, 7k and 8k (as
of now). The xSMI interface supported by this driver complies with the
IEEE 802.3 clause 45 (while the SMI interface complies with the clause
22). The xSMI interface is used by 10GbE devices.
Signed-off-by: Antoine Tenart <redacted>
---
Instead of doing this, you could have the ops structure declared e.g: a
static global variables in the driver and reference them from the
of_device_id .data field, something like:
static struct orion_mdio_ops mdio_ops = {
...
};
static struct orion_mdio_data mdio_data = {
.ops = &mdio_ops,
.poll_intervall_min = ...,
.poll_interfave_max = ...,
};
static struct orion_mdio_ops xmdio_ops = {
...
};
static strcut orion_mdio_data xmdio_ data = {
};
and then reference those using of_id->data in the probe function
quoted hunk
+
+ dev->ops = ops;
+ return 0;
+}
+
static int orion_mdio_probe(struct platform_device *pdev)
{
struct resource *r;
struct mii_bus *bus;
struct orion_mdio_dev *dev;
- struct orion_mdio_ops *ops;
int i, ret;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -278,18 +367,9 @@ static int orion_mdio_probe(struct platform_device *pdev) mutex_init(&dev->lock);- ops = devm_kzalloc(&pdev->dev, sizeof(*ops), GFP_KERNEL);- if (!ops)- return -ENOMEM;-- dev->poll_interval_min = MVMDIO_SMI_POLL_INTERVAL_MIN;- dev->poll_interval_max = MVMDIO_SMI_POLL_INTERVAL_MAX;- ops->is_done = orion_mdio_smi_is_done;- ops->is_read_valid = orion_mdio_smi_is_read_valid;- ops->start_read = orion_mdio_start_read_op;- ops->read = orion_mdio_read_op;- ops->write = orion_mdio_write_op;- dev->ops = ops;+ ret = orion_mdio_populate_ops(pdev, dev);+ if (ret)+ return ret; if (pdev->dev.of_node) ret = of_mdiobus_register(bus, pdev->dev.of_node);
From: linux@armlinux.org.uk (Russell King - ARM Linux) Date: 2017-06-07 15:56:36
On Wed, Jun 07, 2017 at 08:48:06AM -0700, Florian Fainelli wrote:
On 06/07/2017 01:38 AM, Antoine Tenart wrote:
quoted
This patch adds the xMDIO interface support in the mvmdio driver. This
interface is used in Ethernet controllers on Marvell 370, 7k and 8k (as
of now). The xSMI interface supported by this driver complies with the
IEEE 802.3 clause 45 (while the SMI interface complies with the clause
22). The xSMI interface is used by 10GbE devices.
Signed-off-by: Antoine Tenart <redacted>
---
Instead of doing this, you could have the ops structure declared e.g: a
static global variables in the driver and reference them from the
of_device_id .data field, something like:
static struct orion_mdio_ops mdio_ops = {
...
};
In this case, don't forget the "const" for static structures containing
only function pointers (so that the function pointers can't be exploited.)
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
Instead of doing this, you could have the ops structure declared e.g: a
static global variables in the driver and reference them from the
of_device_id .data field, something like:
Good idea, I'll update the series using static global variables for ops
and poll intervals and reference them in the .data field.
Thanks!
Antoine
--
Antoine T?nart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170607/b292725a/attachment-0001.sig>
Put the two poll intervals (min and max) in the driver's private
structure. This is needed to add the xmdio support later.
Signed-off-by: Antoine Tenart <redacted>
Introduce an ops structure to add an indirection on functions accessing
the registers. This is needed to add the xMDIO support later.
Signed-off-by: Antoine Tenart <redacted>
---
drivers/net/ethernet/marvell/mvmdio.c | 65 +++++++++++++++++++++++++++--------
1 file changed, 51 insertions(+), 14 deletions(-)
@@ -74,6 +83,30 @@ static int orion_mdio_smi_is_read_valid(struct orion_mdio_dev *dev)return!(readl(dev->regs)&MVMDIO_SMI_READ_VALID);}+staticvoidorion_mdio_start_read_op(structorion_mdio_dev*dev,intmii_id,+intregnum)+{+writel(((mii_id<<MVMDIO_SMI_PHY_ADDR_SHIFT)|+(regnum<<MVMDIO_SMI_PHY_REG_SHIFT)|+MVMDIO_SMI_READ_OPERATION),+dev->regs);+}++staticu16orion_mdio_read_op(structorion_mdio_dev*dev)+{+returnreadl(dev->regs)&GENMASK(15,0);+}++staticvoidorion_mdio_write_op(structorion_mdio_dev*dev,intmii_id,+intregnum,u16value)+{+writel(((mii_id<<MVMDIO_SMI_PHY_ADDR_SHIFT)|+(regnum<<MVMDIO_SMI_PHY_REG_SHIFT)|+MVMDIO_SMI_WRITE_OPERATION|+(value<<MVMDIO_SMI_DATA_SHIFT)),+dev->regs);+}+/* Wait for the SMI unit to be ready for another operation*/staticintorion_mdio_wait_ready(structmii_bus*bus)
@@ -84,7 +117,7 @@ static int orion_mdio_wait_ready(struct mii_bus *bus)inttimedout=0;while(1){-if(orion_mdio_smi_is_done(dev))+if(dev->ops->is_done(dev))
Nit: you could actually keep this function (and all of them that have a
corresponding dev->ops function pointer) and just make it a static
inline that calls into dev->ops->is_done()
That would limit the delta to review, and it would still be within the
namespace of the driver (orion_mdio_*).
Your call.
Russell pointed out on IRC the mdio/xmdio interfaces aren't wired to
anything on the mcbin. We could either disable these interfaces by
default, or add explicit disables in the mcbin device tree.
What's your thoughts on this?
Thanks!
Antoine
--
Antoine T?nart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170608/d6e8a142/attachment-0001.sig>