summaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorAppana Durga Kedareswara Rao <appana.durga.rao@xilinx.com>2016-08-10 01:50:08 -0400
committerDavid S. Miller <davem@davemloft.net>2016-08-12 19:57:20 -0400
commitf411a6160bd4278508b5892949ba1a7db6f73489 (patch)
tree9cb69754a161f74022a68a8e807a05c60ab467bc /drivers/net/phy
parent71e11aff34510e4133965d63ae6d91a0cf4aa876 (diff)
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 <appanad@xilinx.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/Kconfig7
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/xilinx_gmii2rgmii.c109
3 files changed, 117 insertions, 0 deletions
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
312 ---help--- 312 ---help---
313 Currently supports the VSC8531 and VSC8541 PHYs 313 Currently supports the VSC8531 and VSC8541 PHYs
314 314
315config XILINX_GMII2RGMII
316 tristate "Xilinx GMII2RGMII converter driver"
317 ---help---
318 This driver support xilinx GMII to RGMII IP core it provides
319 the Reduced Gigabit Media Independent Interface(RGMII) between
320 Ethernet physical media devices and the Gigabit Ethernet controller.
321
315endif # PHYLIB 322endif # PHYLIB
316 323
317config MICREL_KS8995MA 324config 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
50obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o 50obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o
51obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o 51obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o
52obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o 52obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o
53obj-$(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 @@
1/* Xilinx GMII2RGMII Converter driver
2 *
3 * Copyright (C) 2016 Xilinx, Inc.
4 *
5 * Author: Kedareswara rao Appana <appanad@xilinx.com>
6 *
7 * Description:
8 * This driver is developed for Xilinx GMII2RGMII Converter
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/mii.h>
23#include <linux/mdio.h>
24#include <linux/phy.h>
25#include <linux/of_mdio.h>
26
27#define XILINX_GMII2RGMII_REG 0x10
28#define XILINX_GMII2RGMII_SPEED_MASK (BMCR_SPEED1000 | BMCR_SPEED100)
29
30struct gmii2rgmii {
31 struct phy_device *phy_dev;
32 struct phy_driver *phy_drv;
33 struct phy_driver conv_phy_drv;
34 int addr;
35};
36
37static int xgmiitorgmii_read_status(struct phy_device *phydev)
38{
39 struct gmii2rgmii *priv = phydev->priv;
40 u16 val = 0;
41
42 priv->phy_drv->read_status(phydev);
43
44 val = mdiobus_read(phydev->mdio.bus, priv->addr, XILINX_GMII2RGMII_REG);
45 val &= XILINX_GMII2RGMII_SPEED_MASK;
46
47 if (phydev->speed == SPEED_1000)
48 val |= BMCR_SPEED1000;
49 else if (phydev->speed == SPEED_100)
50 val |= BMCR_SPEED100;
51 else
52 val |= BMCR_SPEED10;
53
54 mdiobus_write(phydev->mdio.bus, priv->addr, XILINX_GMII2RGMII_REG, val);
55
56 return 0;
57}
58
59int xgmiitorgmii_probe(struct mdio_device *mdiodev)
60{
61 struct device *dev = &mdiodev->dev;
62 struct device_node *np = dev->of_node, *phy_node;
63 struct gmii2rgmii *priv;
64
65 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
66 if (!priv)
67 return -ENOMEM;
68
69 phy_node = of_parse_phandle(np, "phy-handle", 0);
70 if (IS_ERR(phy_node)) {
71 dev_err(dev, "Couldn't parse phy-handle\n");
72 return -ENODEV;
73 }
74
75 priv->phy_dev = of_phy_find_device(phy_node);
76 if (!priv->phy_dev) {
77 dev_info(dev, "Couldn't find phydev\n");
78 return -EPROBE_DEFER;
79 }
80
81 priv->addr = mdiodev->addr;
82 priv->phy_drv = priv->phy_dev->drv;
83 memcpy(&priv->conv_phy_drv, priv->phy_dev->drv,
84 sizeof(struct phy_driver));
85 priv->conv_phy_drv.read_status = xgmiitorgmii_read_status;
86 priv->phy_dev->priv = priv;
87 priv->phy_dev->drv = &priv->conv_phy_drv;
88
89 return 0;
90}
91
92static const struct of_device_id xgmiitorgmii_of_match[] = {
93 { .compatible = "xlnx,gmii-to-rgmii-1.0" },
94 {},
95};
96MODULE_DEVICE_TABLE(of, xgmiitorgmii_of_match);
97
98static struct mdio_driver xgmiitorgmii_driver = {
99 .probe = xgmiitorgmii_probe,
100 .mdiodrv.driver = {
101 .name = "xgmiitorgmii",
102 .of_match_table = xgmiitorgmii_of_match,
103 },
104};
105
106mdio_module_driver(xgmiitorgmii_driver);
107
108MODULE_DESCRIPTION("Xilinx GMII2RGMII converter driver");
109MODULE_LICENSE("GPL");