This patch series does the following
---> Add support for gmii2rgmii converter.
---> Add support for gmii2rgmii converter in the macb driver.
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.
Kedareswara rao Appana (4):
Documentation: DT: net: Add Xilinx gmiitorgmii converter device tree
binding documentation
net: ethernet: xilinx: Add gmii2rgmii converter support
Documentation: DT: net: Update binding doc for gmiitorgmii conveter
net: macb: Add gmii2rgmii phy converter support
Documentation/devicetree/bindings/net/macb.txt | 4 ++
.../devicetree/bindings/net/xilinx_gmii2rgmii.txt | 31 +++++++++
drivers/net/ethernet/cadence/macb.c | 21 ++++++
drivers/net/ethernet/cadence/macb.h | 1 +
drivers/net/ethernet/xilinx/Kconfig | 8 +++
drivers/net/ethernet/xilinx/Makefile | 1 +
drivers/net/ethernet/xilinx/xilinx_gmii2rgmii.c | 79 ++++++++++++++++++++++
include/linux/xilinx_gmii2rgmii.h | 24 +++++++
8 files changed, 169 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/xilinx_gmii2rgmii.txt
create mode 100644 drivers/net/ethernet/xilinx/xilinx_gmii2rgmii.c
create mode 100644 include/linux/xilinx_gmii2rgmii.h
--
2.1.2
@@ -0,0 +1,31 @@+* XILINX GMIITORGMII Converter Driver++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 MDIO is a bus to which the PHY devices are connected. For each+device that exists on this bus, a child node should be created. See+the definition of the PHY node in booting-without-of.txt for an example+of how to define a PHY.++Required properties:+ - compatible : Should be "xlnx,gmiitorgmii"+ - reg : The ID number for the phy, usually a small integer++Example:+ mdio {+ #address-cells = <1>;+ #size-cells = <0>;+ ethernet-phy at 0 {+ ......+ };+ gmii_to_rgmii: gmii_to_rgmii at 8 {+ compatible = "xlnx,gmiitorgmii";+ reg = <8>;+ };+ };
This patch adds support for gmii2rgmii 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.
Signed-off-by: Kedareswara rao Appana <redacted>
---
Changes for v2:
--> Passed struct xphy pointer directly to the fix_mac_speed
API as suggested by the Florian.
--> Added checks for the phy-node fail case as suggested
by the Florian.
drivers/net/ethernet/xilinx/Kconfig | 8 +++
drivers/net/ethernet/xilinx/Makefile | 1 +
drivers/net/ethernet/xilinx/xilinx_gmii2rgmii.c | 79 +++++++++++++++++++++++++
include/linux/xilinx_gmii2rgmii.h | 24 ++++++++
4 files changed, 112 insertions(+)
create mode 100644 drivers/net/ethernet/xilinx/xilinx_gmii2rgmii.c
create mode 100644 include/linux/xilinx_gmii2rgmii.h
This patch adds support for gmii2rgmii phy converter in the macb driver.
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.
Signed-off-by: Kedareswara rao Appana <redacted>
---
Changes for v2:
---> Moved header file define xilinx_gmii2rgmii.h to macb.c file
as suggested by the Nicolas.
---> Updated the commit meassage as suggested by the Nicolas.
---> Fixed minor coding comments as suggested by the Nicolas.
drivers/net/ethernet/cadence/macb.c | 21 +++++++++++++++++++++
drivers/net/ethernet/cadence/macb.h | 1 +
2 files changed, 22 insertions(+)
@@ -257,6 +258,14 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,return0;}+staticinlinevoidmacb_hw_fix_mac_speed(structmacb*bp,+structphy_device*phydev)+{+if(bp->converter_phy.fix_mac_speed)+bp->converter_phy.fix_mac_speed(&bp->converter_phy,+phydev->speed);+}+/***macb_set_tx_clk()-Setaclocktoanewfrequency*@clkPointertotheclocktochange
@@ -23,6 +23,10 @@ Required properties: Optional elements: 'tx_clk' - clocks: Phandles to input clocks.+Optional properties:+- gmii2rgmii-phy-handle: phy-handle for gmiitorgmii converter.+ See xilinx_gmii2rgmii.txt file in the same directory.+ Optional properties for PHY child node: - reset-gpios : Should specify the gpio for phy reset - magic-packet : If present, indicates that the hardware supports waking
From: Nicolas Ferre <hidden> Date: 2016-07-04 09:54:24
Le 04/07/2016 11:04, Kedareswara rao Appana a ?crit :
quoted hunk
This patch adds support for gmii2rgmii 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.
Signed-off-by: Kedareswara rao Appana <redacted>
---
Changes for v2:
--> Passed struct xphy pointer directly to the fix_mac_speed
API as suggested by the Florian.
--> Added checks for the phy-node fail case as suggested
by the Florian.
drivers/net/ethernet/xilinx/Kconfig | 8 +++
drivers/net/ethernet/xilinx/Makefile | 1 +
drivers/net/ethernet/xilinx/xilinx_gmii2rgmii.c | 79 +++++++++++++++++++++++++
include/linux/xilinx_gmii2rgmii.h | 24 ++++++++
4 files changed, 112 insertions(+)
create mode 100644 drivers/net/ethernet/xilinx/xilinx_gmii2rgmii.c
create mode 100644 include/linux/xilinx_gmii2rgmii.h
I see a compilation issue here:
You should provide a way to have this function even if the
NET_VENDOR_XILINX config option is not selected (test to compile with
the sama5_defconfig and you'll see).
What about making this function void in case of !XILINX?
(so, NACK for the series as it is).
Bye,
--
Nicolas Ferre
I see a compilation issue here:
You should provide a way to have this function even if the NET_VENDOR_XILINX
config option is not selected (test to compile with the sama5_defconfig and
you'll see).
Ok will fix in the next version...
What about making this function void in case of !XILINX?
This is one way to get rid of compilation error. Changes will be look like below
#ifdef CONFIG_NET_VENDOR_XILINX
extern int gmii2rgmii_phyprobe(struct gmii2rgmii *xphy);
#else
extern void gmii2rgmii_phyprobe(struct gmii2rgmii *xphy);
void gmii2rgmii_phyprobe(struct gmii2rgmii *xphy)
{
}
#endif
For me the changes are looking odd...
Other possible ways
1) Put a config check around phyprobe api in the macb driver.
#ifdef CONFIG_XILINX_GMII2RGMII
gmii2rgmii_phyprobe(&bp->converter_phy);
#endif
2) Select NET_VENDOR_XILINX in the macb Kconfig
@ -22,6 +22,7 @@ config MACB
tristate "Cadence MACB/GEM support"
depends on HAS_DMA
select PHYLIB
+ select NET_VENDOR_XILINX
Please let me know which one you prefer will fix that and will post v3...
Regards,
Kedar.
I see a compilation issue here:
You should provide a way to have this function even if the NET_VENDOR_XILINX
config option is not selected (test to compile with the sama5_defconfig and
you'll see).
Ok will fix in the next version...
quoted
What about making this function void in case of !XILINX?
This is one way to get rid of compilation error. Changes will be look like below
#ifdef CONFIG_NET_VENDOR_XILINX
You may need to have:
#if defined(CONFIG_NET_VENDOR_XILINX) && defined(CONFIG_XILINX_GMII2RGMII)
On one single line, like:
static inline void gmii2rgmii_phyprobe(struct gmii2rgmii *xphy) { }
#endif
For me the changes are looking odd...
For me, it's okay...
Other possible ways
1) Put a config check around phyprobe api in the macb driver.
#ifdef CONFIG_XILINX_GMII2RGMII
gmii2rgmii_phyprobe(&bp->converter_phy);
#endif
Nope!
2) Select NET_VENDOR_XILINX in the macb Kconfig
@ -22,6 +22,7 @@ config MACB
tristate "Cadence MACB/GEM support"
depends on HAS_DMA
select PHYLIB
+ select NET_VENDOR_XILINX
Please let me know which one you prefer will fix that and will post v3...
First one with my changes is the best. But maybe wait for more feedback...
Bye,
--
Nicolas Ferre
On one single line, like:
static inline void gmii2rgmii_phyprobe(struct gmii2rgmii *xphy) { }
quoted
#endif
For me the changes are looking odd...
For me, it's okay...
Ok will fix as you suggested...
quoted
Other possible ways
1) Put a config check around phyprobe api in the macb driver.
#ifdef CONFIG_XILINX_GMII2RGMII
gmii2rgmii_phyprobe(&bp->converter_phy);
#endif
Nope!
quoted
2) Select NET_VENDOR_XILINX in the macb Kconfig @ -22,6 +22,7 @@
config MACB
tristate "Cadence MACB/GEM support"
depends on HAS_DMA
select PHYLIB
+ select NET_VENDOR_XILINX
quoted
Please let me know which one you prefer will fix that and will post v3...
First one with my changes is the best. But maybe wait for more feedback...
Ok sure will wait and will post next version with your suggestion in case of no comments...
Regards,
Kedar.
@@ -0,0 +1,31 @@+* XILINX GMIITORGMII Converter Driver++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 MDIO is a bus to which the PHY devices are connected. For each+device that exists on this bus, a child node should be created. See+the definition of the PHY node in booting-without-of.txt for an example+of how to define a PHY.++Required properties:+ - compatible : Should be "xlnx,gmiitorgmii"+ - reg : The ID number for the phy, usually a small integer++Example:+ mdio {+ #address-cells = <1>;+ #size-cells = <0>;+ ethernet-phy at 0 {+ ......+ };+ gmii_to_rgmii: gmii_to_rgmii at 8 {+ compatible = "xlnx,gmiitorgmii";+ reg = <8>;+ };+ };
Hi Kedareswara
So looking at the device tree, you have the gmiitorgmii as an mdio
device. It will get probed as an mdio device, and from that you know
the address on the bus. However, your driver does not actually do
this. xilinx_gmii2rgmii.c is just a library of two functions, and does
not use any of this device tree information. You device tree binding
is completely bogus.
What i think is a much more logical structure, and fits the hardware,
which is what DT is all about, is to make your driver an mdio driver.
Also, have a phy-handle pointing to the PHY in the gmii_to_rgmii node.
You then no longer need the exported gmii2rgmii_phyprobe() function.
Next, you want gmiitorgmii driver to register a phy. The MAC driver
can then look this up using phy-handle:
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy: ethernet-phy at 0 {
reg = <0>;
};
gmii_to_rgmii: gmii-to-rgmii at 8 {
compatible = "xlnx,gmiitorgmii";
reg = <8>;
phy-handle = <&phy>;
};
};
macb0: ethernet at fffc4000 {
compatible = "cdns,at32ap7000-macb";
reg = <0xfffc4000 0x4000>;
interrupts = <21>;
phy-mode = "rmii";
phy-handle = <&gmii_to_rgmii>
local-mac-address = [3a 0e 03 04 05 06];
clock-names = "pclk", "hclk", "tx_clk";
clocks = <&clkc 30>, <&clkc 30>, <&clkc 13>;
ethernet-phy at 1 {
reg = <0x1>;
reset-gpios = <&pioE 6 1>;
};
};
This description is the same as the figure in the data sheet. You have
the gmii_to_rgmii which passes through to the real PHY.
The phy device that gmiitorgmii registers needs to pass through all
its operations to the real PHY. The exception is read_status()
function. You want to wrap this, so that after it completes and you
know the speed the PHY is using, you set the same speed in your
gmiitorgmii device.
Everything then becomes transparent. There is no need to change the
MAC driver, and you have a generic solution which will work with any
MAC and PHY.
Andrew
@@ -0,0 +1,31 @@+* XILINX GMIITORGMII Converter Driver++The Gigabit Media Independent Interface (GMII) to Reduced Gigabit
Media
quoted
+Independent Interface (RGMII) core provides the RGMII between RGMII-
compliant
quoted
+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
quoted
+Speed of operation. This core can switch dynamically between the three
+Different speed modes by configuring the conveter register through mdio
write.
quoted
+
+The MDIO is a bus to which the PHY devices are connected. For each
+device that exists on this bus, a child node should be created. See
+the definition of the PHY node in booting-without-of.txt for an example
+of how to define a PHY.
+
+Required properties:
+ - compatible : Should be "xlnx,gmiitorgmii"
+ - reg : The ID number for the phy, usually a small integer
+
+Example:
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ethernet-phy at 0 {
+ ......
+ };
+ gmii_to_rgmii: gmii_to_rgmii at 8 {
+ compatible = "xlnx,gmiitorgmii";
+ reg = <8>;
+ };
+ };
Hi Kedareswara
So looking at the device tree, you have the gmiitorgmii as an mdio
device. It will get probed as an mdio device, and from that you know
the address on the bus. However, your driver does not actually do
this. xilinx_gmii2rgmii.c is just a library of two functions, and does
not use any of this device tree information. You device tree binding
is completely bogus.
What i think is a much more logical structure, and fits the hardware,
which is what DT is all about, is to make your driver an mdio driver.
Also, have a phy-handle pointing to the PHY in the gmii_to_rgmii node.
You then no longer need the exported gmii2rgmii_phyprobe() function.
Next, you want gmiitorgmii driver to register a phy. The MAC driver
can then look this up using phy-handle:
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy: ethernet-phy at 0 {
reg = <0>;
};
gmii_to_rgmii: gmii-to-rgmii at 8 {
compatible = "xlnx,gmiitorgmii";
reg = <8>;
phy-handle = <&phy>;
};
};
Thanks for your inputs initially we too thought the similar implementation
But the GMII2RGMII converter contains only one register and it is
not compatible to the standard ethernet MII interface. Also it doesn't have
a standard VID and PID registers So, during the mdio bus scan, this device will
not appear. When macb driver calls the gmii2rgmii phy-handle through
phy_connect_direct/of_phy_connect, these calls fail for the above reason.
So, we come up with the current implementation.
Please suggest if you have any other solutions in mind or if our understanding
is wrong for the current approach that you suggested.
Regards,
Punnaiah
macb0: ethernet at fffc4000 {
compatible = "cdns,at32ap7000-macb";
reg = <0xfffc4000 0x4000>;
interrupts = <21>;
phy-mode = "rmii";
phy-handle = <&gmii_to_rgmii>
local-mac-address = [3a 0e 03 04 05 06];
clock-names = "pclk", "hclk", "tx_clk";
clocks = <&clkc 30>, <&clkc 30>, <&clkc 13>;
ethernet-phy at 1 {
reg = <0x1>;
reset-gpios = <&pioE 6 1>;
};
};
This description is the same as the figure in the data sheet. You have
the gmii_to_rgmii which passes through to the real PHY.
The phy device that gmiitorgmii registers needs to pass through all
its operations to the real PHY. The exception is read_status()
function. You want to wrap this, so that after it completes and you
know the speed the PHY is using, you set the same speed in your
gmiitorgmii device.
Everything then becomes transparent. There is no need to change the
MAC driver, and you have a generic solution which will work with any
MAC and PHY.
Andrew
From: Andrew Lunn <andrew@lunn.ch> Date: 2016-07-06 14:21:37
quoted
Hi Kedareswara
So looking at the device tree, you have the gmiitorgmii as an mdio
device. It will get probed as an mdio device, and from that you know
the address on the bus. However, your driver does not actually do
this. xilinx_gmii2rgmii.c is just a library of two functions, and does
not use any of this device tree information. You device tree binding
is completely bogus.
What i think is a much more logical structure, and fits the hardware,
which is what DT is all about, is to make your driver an mdio driver.
Also, have a phy-handle pointing to the PHY in the gmii_to_rgmii node.
You then no longer need the exported gmii2rgmii_phyprobe() function.
Next, you want gmiitorgmii driver to register a phy. The MAC driver
can then look this up using phy-handle:
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy: ethernet-phy at 0 {
reg = <0>;
};
gmii_to_rgmii: gmii-to-rgmii at 8 {
compatible = "xlnx,gmiitorgmii";
reg = <8>;
phy-handle = <&phy>;
};
};
Thanks for your inputs initially we too thought the similar implementation
But the GMII2RGMII converter contains only one register and it is
not compatible to the standard ethernet MII interface. Also it doesn't have
a standard VID and PID registers So, during the mdio bus scan, this device will
not appear.
Hi Punnaiah
Use missed some subtlety in my description. I did not call the
GMII2RGMII a PHY device, i called it an MDIO device. These are
different things. Go look at the MDIO subsystem to figure out the
difference.
Andrew
-----Original Message-----
From: Andrew Lunn [mailto:andrew at lunn.ch]
Sent: Wednesday, July 06, 2016 7:51 PM
To: Punnaiah Choudary Kalluri <redacted>
Cc: Appana Durga Kedareswara Rao <redacted>;
robh+dt at kernel.org; mark.rutland at arm.com; Michal Simek
[off-list ref]; Soren Brinkmann [off-list ref];
nicolas.ferre at atmel.com; f.fainelli at gmail.com; Anirudha Sarangi
[off-list ref]; Harini Katakam [off-list ref];
netdev at vger.kernel.org; devicetree at vger.kernel.org; linux-arm-
kernel at lists.infradead.org; linux-kernel at vger.kernel.org
Subject: Re: [RFC PATCH v2 1/4] Documentation: DT: net: Add Xilinx
gmiitorgmii converter device tree binding documentation
quoted
quoted
Hi Kedareswara
So looking at the device tree, you have the gmiitorgmii as an mdio
device. It will get probed as an mdio device, and from that you know
the address on the bus. However, your driver does not actually do
this. xilinx_gmii2rgmii.c is just a library of two functions, and does
not use any of this device tree information. You device tree binding
is completely bogus.
What i think is a much more logical structure, and fits the hardware,
which is what DT is all about, is to make your driver an mdio driver.
Also, have a phy-handle pointing to the PHY in the gmii_to_rgmii node.
You then no longer need the exported gmii2rgmii_phyprobe() function.
Next, you want gmiitorgmii driver to register a phy. The MAC driver
can then look this up using phy-handle:
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy: ethernet-phy at 0 {
reg = <0>;
};
gmii_to_rgmii: gmii-to-rgmii at 8 {
compatible = "xlnx,gmiitorgmii";
reg = <8>;
phy-handle = <&phy>;
};
};
Thanks for your inputs initially we too thought the similar implementation
But the GMII2RGMII converter contains only one register and it is
not compatible to the standard ethernet MII interface. Also it doesn't have
a standard VID and PID registers So, during the mdio bus scan, this device
will
quoted
not appear.
Hi Punnaiah
Use missed some subtlety in my description. I did not call the
GMII2RGMII a PHY device, i called it an MDIO device. These are
different things. Go look at the MDIO subsystem to figure out the
difference.
Hi Kedareswara
So looking at the device tree, you have the gmiitorgmii as an mdio
device. It will get probed as an mdio device, and from that you
know the address on the bus. However, your driver does not
actually do this. xilinx_gmii2rgmii.c is just a library of two
functions, and does not use any of this device tree information.
You device tree binding is completely bogus.
What i think is a much more logical structure, and fits the
hardware, which is what DT is all about, is to make your driver an mdio
driver.
quoted
quoted
quoted
Also, have a phy-handle pointing to the PHY in the gmii_to_rgmii node.
You then no longer need the exported gmii2rgmii_phyprobe() function.
Next, you want gmiitorgmii driver to register a phy. The MAC
driver can then look this up using phy-handle:
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy: ethernet-phy at 0 {
reg = <0>;
};
gmii_to_rgmii: gmii-to-rgmii at 8 {
compatible = "xlnx,gmiitorgmii";
reg = <8>;
phy-handle = <&phy>;
};
};
Thanks for your inputs initially we too thought the similar
implementation But the GMII2RGMII converter contains only one
register and it is not compatible to the standard ethernet MII
interface. Also it doesn't have a standard VID and PID registers So,
during the mdio bus scan, this device
will
quoted
not appear.
I tried to implement the driver as you suggested but there are few limitations in this
Implementation please correct me if my understanding is wrong...
The device-tree will look like below...
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy: ethernet-phy at 0 {
reg = <0>;
};
gmii_to_rgmii: gmii-to-rgmii at 8 {
compatible = "xlnx,gmiitorgmii";
reg = <8>;
phy-handle = <&phy>;
};
};
The MAC driver does the below.
---> It creates a MDIO device for the gmii_to_rgmii node.
---> It creates a PHY device for the External PHY node.
The GMII2RGMII driver does the below.
1) It registers the gmii_to_rgmii node as a MDIO driver.
It contains the external phy as a phy-handle
2) Register a PHY Driver.
---> Register it as a phy driver (phy_register_driver):
For this implementation the converter won't have any VID or DID(PHY register 2 and 3)
---> Register phy using of_phy_connect call:
For this implementation needed a netdev pointer to pass it to the of_phy_connect call.
(Need to allocate a network device during probe and need to register it as netdev)
For the 2nd one implement I am facing above limitations...
Please correct me if my understanding is wrong...
Regards,
Kedar.
From: Andrew Lunn <andrew@lunn.ch> Date: 2016-07-27 08:05:52
Hi Appana
Here is roughly what i was thinking:
struct priv {
phy_device *master;
phy_device *slave;
struct phy_driver *slave_drv;
};
phy_status_clone(phy_device *master, phy_device *slave)
{
master->speed = slave->speed;
master->duplex = slave->duplex;
master->pause = slave->pause;
}
read_status(struct phy_device *phydev)
{
struct priv *priv = phydev->priv;
/* Get the status from the slave, and duplicate in into the
* master */
slave_drv->read_status(priv->slave);
phy_status_clone(priv->master, priv->slave);
/* Update the gmiitorgmii with the current link parameters */
update_link(master);
}
config_init(struct phy_device *phydev)
{
struct priv *priv = phydev->priv;
/* Configure the slave, and duplicate in into the master */
slave_drv->config_init(priv->slave);
phy_status_clone(priv->master, priv->slave);
}
struct phy_driver master_drv = {
.read_status = read_status,
.config_init = config_init,
.soft_reset = ...
.suspend = ...
};
probe(mdio_device *mdio)
{
struct priv *priv = devm_alloc();
/* Use the phy-handle property to find the slave phy */
node_phy = of_parse_phandle(mdio->of_node, "phy", 0);
priv->slave = of_phy_find_device(node_phy);
/* Create the master phy on the control address. Use the phy
ID from the slave. */
priv->master = phy_device_create(mdio->bus, mdio->addr,
phy->slave->phy_id,
phy->slave->is_c45,
phy->slave->c45_ids);
slave_dev_drv = phydev->mdio.dev.driver;
priv->slave_drv = to_phy_driver(slave_dev_drv);
priv->master->mdio.dev.driver = master_drv;
}
It would however be nice to only have one phydev structure, so you are
not copying status and settings backwards and forwards from one to the
other all the time, and need a wrapper for every function in
phy_driver. Studying the structures a bit, that might be possible. You
would then only need to wrap the read_status(), so that when the link
speed/duplex changes, you can configure the converter as appropriate.
Andrew
Hi Appana
Here is roughly what i was thinking:
struct priv {
phy_device *master;
phy_device *slave;
struct phy_driver *slave_drv;
};
phy_status_clone(phy_device *master, phy_device *slave)
{
master->speed = slave->speed;
master->duplex = slave->duplex;
master->pause = slave->pause;
}
read_status(struct phy_device *phydev)
{
struct priv *priv = phydev->priv;
/* Get the status from the slave, and duplicate in into the
* master */
slave_drv->read_status(priv->slave);
phy_status_clone(priv->master, priv->slave);
/* Update the gmiitorgmii with the current link parameters */
update_link(master);
}
config_init(struct phy_device *phydev)
{
struct priv *priv = phydev->priv;
/* Configure the slave, and duplicate in into the master */
slave_drv->config_init(priv->slave);
phy_status_clone(priv->master, priv->slave);
}
struct phy_driver master_drv = {
.read_status = read_status,
.config_init = config_init,
.soft_reset = ...
.suspend = ...
};
probe(mdio_device *mdio)
{
struct priv *priv = devm_alloc();
/* Use the phy-handle property to find the slave phy */
node_phy = of_parse_phandle(mdio->of_node, "phy", 0);
priv->slave = of_phy_find_device(node_phy);
/* Create the master phy on the control address. Use the phy
ID from the slave. */
priv->master = phy_device_create(mdio->bus, mdio->addr,
phy->slave->phy_id,
phy->slave->is_c45,
phy->slave->c45_ids);
slave_dev_drv = phydev->mdio.dev.driver;
priv->slave_drv = to_phy_driver(slave_dev_drv);
priv->master->mdio.dev.driver = master_drv;
The key here is really that except for the phy_driver::read_status
callback, we want to defer every operation to the slave (full MDIO
register range compatible) PHY.
}
It would however be nice to only have one phydev structure, so you are
not copying status and settings backwards and forwards from one to the
other all the time, and need a wrapper for every function in
phy_driver. Studying the structures a bit, that might be possible. You
would then only need to wrap the read_status(), so that when the link
speed/duplex changes, you can configure the converter as appropriate.
Hi Appana
Here is roughly what i was thinking:
struct priv {
phy_device *master;
phy_device *slave;
struct phy_driver *slave_drv;
};
phy_status_clone(phy_device *master, phy_device *slave) {
master->speed = slave->speed;
master->duplex = slave->duplex;
master->pause = slave->pause;
}
read_status(struct phy_device *phydev) {
struct priv *priv = phydev->priv;
/* Get the status from the slave, and duplicate in into the
* master */
slave_drv->read_status(priv->slave);
phy_status_clone(priv->master, priv->slave);
/* Update the gmiitorgmii with the current link parameters */
update_link(master);
}
config_init(struct phy_device *phydev) {
struct priv *priv = phydev->priv;
/* Configure the slave, and duplicate in into the master */
slave_drv->config_init(priv->slave);
phy_status_clone(priv->master, priv->slave); }
struct phy_driver master_drv = {
.read_status = read_status,
.config_init = config_init,
.soft_reset = ...
.suspend = ...
};
probe(mdio_device *mdio)
{
struct priv *priv = devm_alloc();
/* Use the phy-handle property to find the slave phy */
node_phy = of_parse_phandle(mdio->of_node, "phy", 0);
priv->slave = of_phy_find_device(node_phy);
/* Create the master phy on the control address. Use the phy
ID from the slave. */
priv->master = phy_device_create(mdio->bus, mdio->addr,
phy->slave->phy_id,
phy->slave->is_c45,
phy->slave->c45_ids);
slave_dev_drv = phydev->mdio.dev.driver;
priv->slave_drv = to_phy_driver(slave_dev_drv);
priv->master->mdio.dev.driver = master_drv;
The key here is really that except for the phy_driver::read_status callback, we
want to defer every operation to the slave (full MDIO register range compatible)
PHY.
Will fix it in the next version...
quoted
}
It would however be nice to only have one phydev structure, so you are
not copying status and settings backwards and forwards from one to the
other all the time, and need a wrapper for every function in
phy_driver. Studying the structures a bit, that might be possible. You
would then only need to wrap the read_status(), so that when the link
speed/duplex changes, you can configure the converter as appropriate.
Agreed.
Will implement as suggested by Andrew...
Regards,
Kedar.