From 300d8b93d73533411a98362350fe7d1795f1a044 Mon Sep 17 00:00:00 2001 From: Appana Durga Kedareswara Rao Date: Wed, 10 Aug 2016 11:20:06 +0530 Subject: [PATCH 1/3] net: Add mask for Control register 10Mbps speed This patch adds mask for the Control register 10Mbps speed. Reviewed-by: Florian Fainelli Signed-off-by: Kedareswara rao Appana Signed-off-by: David S. Miller --- include/uapi/linux/mii.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/mii.h b/include/uapi/linux/mii.h index 237fac4bc17b..15d8510cdae0 100644 --- a/include/uapi/linux/mii.h +++ b/include/uapi/linux/mii.h @@ -48,6 +48,7 @@ #define BMCR_SPEED100 0x2000 /* Select 100Mbps */ #define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ #define BMCR_RESET 0x8000 /* Reset to default state */ +#define BMCR_SPEED10 0x0000 /* Select 10Mbps */ /* Basic mode status register. */ #define BMSR_ERCAP 0x0001 /* Ext-reg capability */ From 71e11aff34510e4133965d63ae6d91a0cf4aa876 Mon Sep 17 00:00:00 2001 From: Appana Durga Kedareswara Rao Date: Wed, 10 Aug 2016 11:20:07 +0530 Subject: [PATCH 2/3] Documentation: DT: net: Add Xilinx gmiitorgmii converter device tree binding documentation Device-tree binding documentation for xilinx gmiitorgmii converter. Signed-off-by: Kedareswara rao Appana Acked-by: Rob Herring Signed-off-by: David S. Miller --- .../bindings/net/xilinx_gmii2rgmii.txt | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/xilinx_gmii2rgmii.txt diff --git a/Documentation/devicetree/bindings/net/xilinx_gmii2rgmii.txt b/Documentation/devicetree/bindings/net/xilinx_gmii2rgmii.txt new file mode 100644 index 000000000000..038dda48b8e6 --- /dev/null +++ b/Documentation/devicetree/bindings/net/xilinx_gmii2rgmii.txt @@ -0,0 +1,35 @@ +XILINX GMIITORGMII Converter Driver Device Tree Bindings +-------------------------------------------------------- + +The Gigabit Media Independent Interface (GMII) to Reduced Gigabit Media +Independent Interface (RGMII) core provides the RGMII between RGMII-compliant +Ethernet physical media devices (PHY) and the Gigabit Ethernet controller. +This core can be used in all three modes of operation(10/100/1000 Mb/s). +The Management Data Input/Output (MDIO) interface is used to configure the +Speed of operation. This core can switch dynamically between the three +Different speed modes by configuring the conveter register through mdio write. + +This converter sits between the ethernet MAC and the external phy. +MAC <==> GMII2RGMII <==> RGMII_PHY + +For more details about mdio please refer phy.txt file in the same directory. + +Required properties: +- compatible : Should be "xlnx,gmii-to-rgmii-1.0" +- reg : The ID number for the phy, usually a small integer +- phy-handle : Should point to the external phy device. + See ethernet.txt file in the same directory. + +Example: + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy: ethernet-phy@0 { + ...... + }; + gmiitorgmii: gmiitorgmii@8 { + compatible = "xlnx,gmii-to-rgmii-1.0"; + reg = <8>; + phy-handle = <&phy>; + }; + }; From f411a6160bd4278508b5892949ba1a7db6f73489 Mon Sep 17 00:00:00 2001 From: Appana Durga Kedareswara Rao Date: Wed, 10 Aug 2016 11:20:08 +0530 Subject: [PATCH 3/3] net: phy: Add gmiitorgmii converter support This patch adds support for gmiitorgmii converter. The GMII to RGMII IP core provides the Reduced Gigabit Media Independent Interface (RGMII) between Ethernet physical media Devices and the Gigabit Ethernet controller. This core can Switch dynamically between the three different speed modes of Operation by configuring the converter register through mdio write. MDIO interface is used to set operating speed of Ethernet MAC. This converter sits between the MAC and the external phy MAC <==> GMII2RGMII <==> RGMII_PHY Signed-off-by: Kedareswara rao Appana Signed-off-by: David S. Miller --- drivers/net/phy/Kconfig | 7 ++ drivers/net/phy/Makefile | 1 + drivers/net/phy/xilinx_gmii2rgmii.c | 109 ++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 drivers/net/phy/xilinx_gmii2rgmii.c diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 1b534eaaca3d..d66133bf3eb5 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -312,6 +312,13 @@ config MICROSEMI_PHY ---help--- Currently supports the VSC8531 and VSC8541 PHYs +config XILINX_GMII2RGMII + tristate "Xilinx GMII2RGMII converter driver" + ---help--- + This driver support xilinx GMII to RGMII IP core it provides + the Reduced Gigabit Media Independent Interface(RGMII) between + Ethernet physical media devices and the Gigabit Ethernet controller. + endif # PHYLIB config MICREL_KS8995MA diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index a713bd4da70a..73d65ce04454 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -50,3 +50,4 @@ obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o +obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o diff --git a/drivers/net/phy/xilinx_gmii2rgmii.c b/drivers/net/phy/xilinx_gmii2rgmii.c new file mode 100644 index 000000000000..8e980ad476a4 --- /dev/null +++ b/drivers/net/phy/xilinx_gmii2rgmii.c @@ -0,0 +1,109 @@ +/* Xilinx GMII2RGMII Converter driver + * + * Copyright (C) 2016 Xilinx, Inc. + * + * Author: Kedareswara rao Appana + * + * Description: + * This driver is developed for Xilinx GMII2RGMII Converter + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include + +#define XILINX_GMII2RGMII_REG 0x10 +#define XILINX_GMII2RGMII_SPEED_MASK (BMCR_SPEED1000 | BMCR_SPEED100) + +struct gmii2rgmii { + struct phy_device *phy_dev; + struct phy_driver *phy_drv; + struct phy_driver conv_phy_drv; + int addr; +}; + +static int xgmiitorgmii_read_status(struct phy_device *phydev) +{ + struct gmii2rgmii *priv = phydev->priv; + u16 val = 0; + + priv->phy_drv->read_status(phydev); + + val = mdiobus_read(phydev->mdio.bus, priv->addr, XILINX_GMII2RGMII_REG); + val &= XILINX_GMII2RGMII_SPEED_MASK; + + if (phydev->speed == SPEED_1000) + val |= BMCR_SPEED1000; + else if (phydev->speed == SPEED_100) + val |= BMCR_SPEED100; + else + val |= BMCR_SPEED10; + + mdiobus_write(phydev->mdio.bus, priv->addr, XILINX_GMII2RGMII_REG, val); + + return 0; +} + +int xgmiitorgmii_probe(struct mdio_device *mdiodev) +{ + struct device *dev = &mdiodev->dev; + struct device_node *np = dev->of_node, *phy_node; + struct gmii2rgmii *priv; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + phy_node = of_parse_phandle(np, "phy-handle", 0); + if (IS_ERR(phy_node)) { + dev_err(dev, "Couldn't parse phy-handle\n"); + return -ENODEV; + } + + priv->phy_dev = of_phy_find_device(phy_node); + if (!priv->phy_dev) { + dev_info(dev, "Couldn't find phydev\n"); + return -EPROBE_DEFER; + } + + priv->addr = mdiodev->addr; + priv->phy_drv = priv->phy_dev->drv; + memcpy(&priv->conv_phy_drv, priv->phy_dev->drv, + sizeof(struct phy_driver)); + priv->conv_phy_drv.read_status = xgmiitorgmii_read_status; + priv->phy_dev->priv = priv; + priv->phy_dev->drv = &priv->conv_phy_drv; + + return 0; +} + +static const struct of_device_id xgmiitorgmii_of_match[] = { + { .compatible = "xlnx,gmii-to-rgmii-1.0" }, + {}, +}; +MODULE_DEVICE_TABLE(of, xgmiitorgmii_of_match); + +static struct mdio_driver xgmiitorgmii_driver = { + .probe = xgmiitorgmii_probe, + .mdiodrv.driver = { + .name = "xgmiitorgmii", + .of_match_table = xgmiitorgmii_of_match, + }, +}; + +mdio_module_driver(xgmiitorgmii_driver); + +MODULE_DESCRIPTION("Xilinx GMII2RGMII converter driver"); +MODULE_LICENSE("GPL");