Skip to content

Commit 4330ea7

Browse files
committed
Merge branch 'xilinx-gmiitorgmii-converter'
Kedareswara rao Appana says: ==================== net: phy: Add xilinx gmiitorgmii converter support 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. The conveter sits b/w the MAC and external phy like below MACB <==> GMII2RGMII <==> RGMII_PHY MDIO <========> GMII2RGMII MCAB <=======> <========> RGMII Using MAC MDIO bus we can access both the converter and the external PHY. We need to program the line speed of the converter during run time based On the external phy negotiated speed. This patch series does the below ---> Add mask for Control register 10Mbps speed. ---> Add support for xilinx gmiitorgmii converter. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents f08aff4 + f411a61 commit 4330ea7

File tree

5 files changed

+153
-0
lines changed

5 files changed

+153
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
XILINX GMIITORGMII Converter Driver Device Tree Bindings
2+
--------------------------------------------------------
3+
4+
The Gigabit Media Independent Interface (GMII) to Reduced Gigabit Media
5+
Independent Interface (RGMII) core provides the RGMII between RGMII-compliant
6+
Ethernet physical media devices (PHY) and the Gigabit Ethernet controller.
7+
This core can be used in all three modes of operation(10/100/1000 Mb/s).
8+
The Management Data Input/Output (MDIO) interface is used to configure the
9+
Speed of operation. This core can switch dynamically between the three
10+
Different speed modes by configuring the conveter register through mdio write.
11+
12+
This converter sits between the ethernet MAC and the external phy.
13+
MAC <==> GMII2RGMII <==> RGMII_PHY
14+
15+
For more details about mdio please refer phy.txt file in the same directory.
16+
17+
Required properties:
18+
- compatible : Should be "xlnx,gmii-to-rgmii-1.0"
19+
- reg : The ID number for the phy, usually a small integer
20+
- phy-handle : Should point to the external phy device.
21+
See ethernet.txt file in the same directory.
22+
23+
Example:
24+
mdio {
25+
#address-cells = <1>;
26+
#size-cells = <0>;
27+
phy: ethernet-phy@0 {
28+
......
29+
};
30+
gmiitorgmii: gmiitorgmii@8 {
31+
compatible = "xlnx,gmii-to-rgmii-1.0";
32+
reg = <8>;
33+
phy-handle = <&phy>;
34+
};
35+
};

drivers/net/phy/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,13 @@ config MICROSEMI_PHY
312312
---help---
313313
Currently supports the VSC8531 and VSC8541 PHYs
314314

315+
config 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+
315322
endif # PHYLIB
316323

317324
config MICREL_KS8995MA

drivers/net/phy/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,4 @@ obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o
5050
obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o
5151
obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o
5252
obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o
53+
obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o

drivers/net/phy/xilinx_gmii2rgmii.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/* Xilinx GMII2RGMII Converter driver
2+
*
3+
* Copyright (C) 2016 Xilinx, Inc.
4+
*
5+
* Author: Kedareswara rao Appana <[email protected]>
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+
30+
struct 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+
37+
static 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+
59+
int 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+
92+
static const struct of_device_id xgmiitorgmii_of_match[] = {
93+
{ .compatible = "xlnx,gmii-to-rgmii-1.0" },
94+
{},
95+
};
96+
MODULE_DEVICE_TABLE(of, xgmiitorgmii_of_match);
97+
98+
static 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+
106+
mdio_module_driver(xgmiitorgmii_driver);
107+
108+
MODULE_DESCRIPTION("Xilinx GMII2RGMII converter driver");
109+
MODULE_LICENSE("GPL");

include/uapi/linux/mii.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
4949
#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
5050
#define BMCR_RESET 0x8000 /* Reset to default state */
51+
#define BMCR_SPEED10 0x0000 /* Select 10Mbps */
5152

5253
/* Basic mode status register. */
5354
#define BMSR_ERCAP 0x0001 /* Ext-reg capability */

0 commit comments

Comments
 (0)