[01/11] net: phy: Add rockchip phy driver support
diff mbox

Message ID 1498192929-7519-2-git-send-email-david.wu@rock-chips.com
State New
Headers show

Commit Message

David Wu June 23, 2017, 4:41 a.m. UTC
Support internal ephy currently.

Signed-off-by: David Wu <david.wu@rock-chips.com>
---
 drivers/net/phy/Kconfig    |  4 ++
 drivers/net/phy/Makefile   |  1 +
 drivers/net/phy/rockchip.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+)
 create mode 100644 drivers/net/phy/rockchip.c

Comments

Andrew Lunn June 23, 2017, 1:55 p.m. UTC | #1
On Fri, Jun 23, 2017 at 12:41:59PM +0800, David Wu wrote:
> Support internal ephy currently.
> 
> Signed-off-by: David Wu <david.wu@rock-chips.com>
> ---
>  drivers/net/phy/Kconfig    |  4 ++
>  drivers/net/phy/Makefile   |  1 +
>  drivers/net/phy/rockchip.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 99 insertions(+)
>  create mode 100644 drivers/net/phy/rockchip.c
> 
> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> index c360dd6..86010d4 100644
> --- a/drivers/net/phy/Kconfig
> +++ b/drivers/net/phy/Kconfig
> @@ -350,6 +350,10 @@ config XILINX_GMII2RGMII
>           the Reduced Gigabit Media Independent Interface(RGMII) between
>           Ethernet physical media devices and the Gigabit Ethernet controller.
>  
> +config ROCKCHIP_MAC_PHY
> +	tristate "Drivers for ROCKCHIP MAC PHY"
> +	---help---
> +	  Currently supports the mac internal ephy.
>  endif # PHYLIB

Alphabetic order please for Kconfig and Makefile.

I will review the rest later today/tomorrow.

  Andrew
Florian Fainelli June 23, 2017, 4:18 p.m. UTC | #2
On 06/22/2017 09:41 PM, David Wu wrote:
> Support internal ephy currently.
> 
> Signed-off-by: David Wu <david.wu@rock-chips.com>
> ---
>  drivers/net/phy/Kconfig    |  4 ++
>  drivers/net/phy/Makefile   |  1 +
>  drivers/net/phy/rockchip.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 99 insertions(+)
>  create mode 100644 drivers/net/phy/rockchip.c
> 
> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> index c360dd6..86010d4 100644
> --- a/drivers/net/phy/Kconfig
> +++ b/drivers/net/phy/Kconfig
> @@ -350,6 +350,10 @@ config XILINX_GMII2RGMII
>           the Reduced Gigabit Media Independent Interface(RGMII) between
>           Ethernet physical media devices and the Gigabit Ethernet controller.
>  
> +config ROCKCHIP_MAC_PHY
> +	tristate "Drivers for ROCKCHIP MAC PHY"
> +	---help---
> +	  Currently supports the mac internal ephy.
>  endif # PHYLIB
>  
>  config MICREL_KS8995MA
> diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
> index e36db9a..6d96779 100644
> --- a/drivers/net/phy/Makefile
> +++ b/drivers/net/phy/Makefile
> @@ -69,3 +69,4 @@ obj-$(CONFIG_STE10XP)		+= ste10Xp.o
>  obj-$(CONFIG_TERANETICS_PHY)	+= teranetics.o
>  obj-$(CONFIG_VITESSE_PHY)	+= vitesse.o
>  obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o
> +obj-$(CONFIG_ROCKCHIP_MAC_PHY)	+= rockchip.o
> diff --git a/drivers/net/phy/rockchip.c b/drivers/net/phy/rockchip.c
> new file mode 100644
> index 0000000..69e96ec
> --- /dev/null
> +++ b/drivers/net/phy/rockchip.c
> @@ -0,0 +1,94 @@
> +/**
> + * Rockchip mac phy driver

MAC and PHY, capitalized.

> + *
> + * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
> + *
> + * David Wu<david.wu@rock-chips.com>
> + *
> + * 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.
> + *
> + */
> +
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mii.h>
> +#include <linux/ethtool.h>
> +#include <linux/phy.h>
> +#include <linux/netdevice.h>
> +
> +static int internal_config_init(struct phy_device *phydev)
> +{
> +	int val;
> +	u32 features;
> +
> +	/*enable auto mdix*/
> +	phy_write(phydev, 0x11, 0x0080);

That is probably the only meaningful change needed by this driver, and
even that is not quite correct because auto MDI-X can be changed from
user-space through ethtool, see
drivers/net/phy/marvell.c::marvell_config_aneg()

> +
> +	features = (SUPPORTED_TP | SUPPORTED_MII
> +			| SUPPORTED_AUI | SUPPORTED_FIBRE |
> +			SUPPORTED_BNC);

This is not necessary, using driver::features set to PHY_GBIT_FEATURES

> +
> +	/* Do we support autonegotiation? */
> +	val = phy_read(phydev, MII_BMSR);
> +	if (val < 0)
> +		return val;
> +
> +	if (val & BMSR_ANEGCAPABLE)
> +		features |= SUPPORTED_Autoneg;

If we have disabled auto-negotiation prior to probing this driver, and
somehow the PHY is not reset, then you are falsely not advertising
support for auto-negotiation just because it *currently is* disabled.

> +
> +	if (val & BMSR_100FULL)
> +		features |= SUPPORTED_100baseT_Full;
> +	if (val & BMSR_100HALF)
> +		features |= SUPPORTED_100baseT_Half;
> +	if (val & BMSR_10FULL)
> +		features |= SUPPORTED_10baseT_Full;
> +	if (val & BMSR_10HALF)
> +		features |= SUPPORTED_10baseT_Half;
> +
> +	if (val & BMSR_ESTATEN) {
> +		val = phy_read(phydev, MII_ESTATUS);
> +		if (val < 0)
> +			return val;
> +
> +		if (val & ESTATUS_1000_TFULL)
> +			features |= SUPPORTED_1000baseT_Full;
> +		if (val & ESTATUS_1000_THALF)
> +			features |= SUPPORTED_1000baseT_Half;
> +	}
> +
> +	phydev->supported = features;
> +	phydev->advertising = features;
> +
> +	return 0;
> +}
> +
> +static struct phy_driver rockchip_phy_driver[] = {
> +{
> +	.phy_id 	= 0x1234d400,
> +	.phy_id_mask	= 0xffffffff,

Last 4 digits are supposed to hold the revision, do you really need to
have such a strict mask here?

> +	.name		= "rockchip internal ephy",
> +	.features	= 0,

features shoul dbe set to what you support: PHY_GBIT_FEAUTERS

> +	.config_init	= internal_config_init,
> +	.config_aneg	= genphy_config_aneg,
> +	.read_status	= genphy_read_status,
> +	.suspend	= genphy_suspend,
> +	.resume 	= genphy_resume,
> +},
> +};
> +
> +module_phy_driver(rockchip_phy_driver);
> +
> +static struct mdio_device_id __maybe_unused rockchip_phy_tbl[] = {
> +	{ 0x1234d400, 0xffffffff },
> +	{ }
> +};
> +
> +MODULE_DEVICE_TABLE(mdio, rockchip_phy_tbl);
> +
> +MODULE_AUTHOR("David Wu<david.wu@rock-chips.com>");
> +MODULE_DESCRIPTION("Rockchip mac phy driver");
> +MODULE_LICENSE("GPL v2");
>
Andrew Lunn June 24, 2017, 2:10 a.m. UTC | #3
> +
> +static int internal_config_init(struct phy_device *phydev)
> +{

internal_ is a bit generic. The Marvell Ethernet switches have
internal phy, etc. rockchip_ would be a better prefix.

	 Andrew
Andrew Lunn June 24, 2017, 2:19 a.m. UTC | #4
On Fri, Jun 23, 2017 at 12:41:59PM +0800, David Wu wrote:
> Support internal ephy currently.
> 
> Signed-off-by: David Wu <david.wu@rock-chips.com>
> ---
>  drivers/net/phy/Kconfig    |  4 ++
>  drivers/net/phy/Makefile   |  1 +
>  drivers/net/phy/rockchip.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 99 insertions(+)
>  create mode 100644 drivers/net/phy/rockchip.c
> 
> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> index c360dd6..86010d4 100644
> --- a/drivers/net/phy/Kconfig
> +++ b/drivers/net/phy/Kconfig
> @@ -350,6 +350,10 @@ config XILINX_GMII2RGMII
>           the Reduced Gigabit Media Independent Interface(RGMII) between
>           Ethernet physical media devices and the Gigabit Ethernet controller.
>  
> +config ROCKCHIP_MAC_PHY

This is a bit of an odd name, having both MAC and PHY in it. Are there
any other RockChip PHYs? Any external PHYS? Are they register
incompatible with the internal PHY?  Is it even RockChip IP? Or has it
been licensed from somebody else?

I would more likely just call it ROCKCHIP_PHY.

  Andrew
Heiko Stuebner June 24, 2017, 8:38 a.m. UTC | #5
Am Samstag, 24. Juni 2017, 04:19:10 CEST schrieb Andrew Lunn:
> On Fri, Jun 23, 2017 at 12:41:59PM +0800, David Wu wrote:
> > Support internal ephy currently.
> > 
> > Signed-off-by: David Wu <david.wu@rock-chips.com>
> > ---
> >  drivers/net/phy/Kconfig    |  4 ++
> >  drivers/net/phy/Makefile   |  1 +
> >  drivers/net/phy/rockchip.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 99 insertions(+)
> >  create mode 100644 drivers/net/phy/rockchip.c
> > 
> > diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> > index c360dd6..86010d4 100644
> > --- a/drivers/net/phy/Kconfig
> > +++ b/drivers/net/phy/Kconfig
> > @@ -350,6 +350,10 @@ config XILINX_GMII2RGMII
> >           the Reduced Gigabit Media Independent Interface(RGMII) between
> >           Ethernet physical media devices and the Gigabit Ethernet controller.
> >  
> > +config ROCKCHIP_MAC_PHY
> 
> This is a bit of an odd name, having both MAC and PHY in it. Are there
> any other RockChip PHYs? Any external PHYS? Are they register
> incompatible with the internal PHY?  Is it even RockChip IP? Or has it
> been licensed from somebody else?
> 
> I would more likely just call it ROCKCHIP_PHY.

hmm, we do have quite a number of non-net phys in the phy subsystem
(DP, PCIe, ...) and given that the above would be CONFIG_ROCKCHIP_PHY
in a global sense, sounds like it could make things confusing.

So some addition sounds reasonable ... ROCKCHIP_ETH_PHY or so?


Heiko
Andrew Lunn June 24, 2017, 2:04 p.m. UTC | #6
> hmm, we do have quite a number of non-net phys in the phy subsystem
> (DP, PCIe, ...) and given that the above would be CONFIG_ROCKCHIP_PHY
> in a global sense, sounds like it could make things confusing.
> 
> So some addition sounds reasonable ... ROCKCHIP_ETH_PHY or so?

I follow you reasoning, but generic phy is the new kid on the
block. It is well established that Ethernet PHYs are called
<MANUFACTURER>_PHY.

If you do want to consider generic phy, the logical name would be
ROCKCHIP_PHY_PHY, since generic phy postfixes with _SATA, _USB, _PCIE,
etc. But that does leave an issues when we have an Ethernet PHY which
needs a generic PHY. In some sense, SERDES could be considered as
something supported by a generic PHY...

	Andrew
Heiko Stuebner June 24, 2017, 4:05 p.m. UTC | #7
Am Samstag, 24. Juni 2017, 16:04:06 CEST schrieb Andrew Lunn:
> > hmm, we do have quite a number of non-net phys in the phy subsystem
> > (DP, PCIe, ...) and given that the above would be CONFIG_ROCKCHIP_PHY
> > in a global sense, sounds like it could make things confusing.
> > 
> > So some addition sounds reasonable ... ROCKCHIP_ETH_PHY or so?
> 
> I follow you reasoning, but generic phy is the new kid on the
> block. It is well established that Ethernet PHYs are called
> <MANUFACTURER>_PHY.

Ok, then without further bikeshedding, let's just go with your
naming then (ROCKCHIP_PHY) :-) .


Heiko

> If you do want to consider generic phy, the logical name would be
> ROCKCHIP_PHY_PHY, since generic phy postfixes with _SATA, _USB, _PCIE,
> etc. But that does leave an issues when we have an Ethernet PHY which
> needs a generic PHY. In some sense, SERDES could be considered as
> something supported by a generic PHY...
> 
> 	Andrew
> 
>
David Wu June 27, 2017, 2:44 p.m. UTC | #8
Hi Andrew,

在 2017/6/24 10:19, Andrew Lunn 写道:
> On Fri, Jun 23, 2017 at 12:41:59PM +0800, David Wu wrote:
>> Support internal ephy currently.
>>
>> Signed-off-by: David Wu <david.wu@rock-chips.com>
>> ---
>>   drivers/net/phy/Kconfig    |  4 ++
>>   drivers/net/phy/Makefile   |  1 +
>>   drivers/net/phy/rockchip.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 99 insertions(+)
>>   create mode 100644 drivers/net/phy/rockchip.c
>>
>> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
>> index c360dd6..86010d4 100644
>> --- a/drivers/net/phy/Kconfig
>> +++ b/drivers/net/phy/Kconfig
>> @@ -350,6 +350,10 @@ config XILINX_GMII2RGMII
>>            the Reduced Gigabit Media Independent Interface(RGMII) between
>>            Ethernet physical media devices and the Gigabit Ethernet controller.
>>   
>> +config ROCKCHIP_MAC_PHY
> 
> This is a bit of an odd name, having both MAC and PHY in it. Are there
> any other RockChip PHYs? Any external PHYS? Are they register
> incompatible with the internal PHY?  Is it even RockChip IP? Or has it
> been licensed from somebody else?
> 

Maybe I just want to highlight it applies to the PHY with Mac 
connection, actually I was named Rockchip at the beginning, as Heiko 
said, PHY is a wide range, so add a modifier to restrict it.

Yes, we use other external phys, like realtek and etc...

If we have any other phy in our socs, it also could be expanded at 
rockchip_phy_tbl{} at rockchip.c

it has been licensed from somebody.

> I would more likely just call it ROCKCHIP_PHY.
> 
>    Andrew
> 
> 
>
Andrew Lunn June 27, 2017, 2:46 p.m. UTC | #9
> it has been licensed from somebody.

And does that somebody already have a driver for it? There is no point
adding a driver, if all you need to do is add the ID to another
driver.

	Andrew
David Wu June 27, 2017, 3:07 p.m. UTC | #10
Hi Andrew,

在 2017/6/27 22:46, Andrew Lunn 写道:
>> it has been licensed from somebody.
> 
> And does that somebody already have a driver for it? There is no point
> adding a driver, if all you need to do is add the ID to another
> driver.
> 

I didn't find it.
Maybe use the same, but the configuration is different.
But this may also be possible, upstream with a new driver.

> 	Andrew
> 
> 
>

Patch
diff mbox

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index c360dd6..86010d4 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -350,6 +350,10 @@  config XILINX_GMII2RGMII
          the Reduced Gigabit Media Independent Interface(RGMII) between
          Ethernet physical media devices and the Gigabit Ethernet controller.
 
+config ROCKCHIP_MAC_PHY
+	tristate "Drivers for ROCKCHIP MAC PHY"
+	---help---
+	  Currently supports the mac internal ephy.
 endif # PHYLIB
 
 config MICREL_KS8995MA
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index e36db9a..6d96779 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -69,3 +69,4 @@  obj-$(CONFIG_STE10XP)		+= ste10Xp.o
 obj-$(CONFIG_TERANETICS_PHY)	+= teranetics.o
 obj-$(CONFIG_VITESSE_PHY)	+= vitesse.o
 obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o
+obj-$(CONFIG_ROCKCHIP_MAC_PHY)	+= rockchip.o
diff --git a/drivers/net/phy/rockchip.c b/drivers/net/phy/rockchip.c
new file mode 100644
index 0000000..69e96ec
--- /dev/null
+++ b/drivers/net/phy/rockchip.c
@@ -0,0 +1,94 @@ 
+/**
+ * Rockchip mac phy driver
+ *
+ * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * David Wu<david.wu@rock-chips.com>
+ *
+ * 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.
+ *
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+
+static int internal_config_init(struct phy_device *phydev)
+{
+	int val;
+	u32 features;
+
+	/*enable auto mdix*/
+	phy_write(phydev, 0x11, 0x0080);
+
+	features = (SUPPORTED_TP | SUPPORTED_MII
+			| SUPPORTED_AUI | SUPPORTED_FIBRE |
+			SUPPORTED_BNC);
+
+	/* Do we support autonegotiation? */
+	val = phy_read(phydev, MII_BMSR);
+	if (val < 0)
+		return val;
+
+	if (val & BMSR_ANEGCAPABLE)
+		features |= SUPPORTED_Autoneg;
+
+	if (val & BMSR_100FULL)
+		features |= SUPPORTED_100baseT_Full;
+	if (val & BMSR_100HALF)
+		features |= SUPPORTED_100baseT_Half;
+	if (val & BMSR_10FULL)
+		features |= SUPPORTED_10baseT_Full;
+	if (val & BMSR_10HALF)
+		features |= SUPPORTED_10baseT_Half;
+
+	if (val & BMSR_ESTATEN) {
+		val = phy_read(phydev, MII_ESTATUS);
+		if (val < 0)
+			return val;
+
+		if (val & ESTATUS_1000_TFULL)
+			features |= SUPPORTED_1000baseT_Full;
+		if (val & ESTATUS_1000_THALF)
+			features |= SUPPORTED_1000baseT_Half;
+	}
+
+	phydev->supported = features;
+	phydev->advertising = features;
+
+	return 0;
+}
+
+static struct phy_driver rockchip_phy_driver[] = {
+{
+	.phy_id 	= 0x1234d400,
+	.phy_id_mask	= 0xffffffff,
+	.name		= "rockchip internal ephy",
+	.features	= 0,
+	.config_init	= internal_config_init,
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+	.suspend	= genphy_suspend,
+	.resume 	= genphy_resume,
+},
+};
+
+module_phy_driver(rockchip_phy_driver);
+
+static struct mdio_device_id __maybe_unused rockchip_phy_tbl[] = {
+	{ 0x1234d400, 0xffffffff },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(mdio, rockchip_phy_tbl);
+
+MODULE_AUTHOR("David Wu<david.wu@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip mac phy driver");
+MODULE_LICENSE("GPL v2");