From: Max Filippov <jcmvbkbc@gmail.com> Date: 2014-01-29 06:00:48
Hello David, Ben, Florian, Chris and everybody,
this series improves ethoc behavior in gigabit environment:
- first patch introduces two phylib setters for 'advertising' and 'supported'
fields of struct phy_device;
- second patch disables gigabit advertisement in the attached PHY making
possible to use gigabit link without any additional setup;
- third patch adds support to set up MII management bus frequency, adding
new fields to platform data and to OF bindings;
- fourth patch adds basic ethtool support to ethoc driver.
These changes allow to use KC-705 board with 50MHz xtensa core and OpenCores
10/100 Mbps MAC connected to gigabit network without any additional setup.
Changes v1->v2:
- new patch "phy: provide accessors for 'advertising' and 'supported' fields";
- disable both gigabit advertisement and support;
- drop MDIO bus frequency configurability, always configure for standard
2.5MHz;
- allow using common clock framework to provide ethoc clock;
- new patch: "net: ethoc: implement ethtool operations";
- drop device tree bindings documentation patch until common bindings format
for network drivers is decided.
Max Filippov (4):
phy: provide accessors for 'advertising' and 'supported' fields
net: ethoc: don't advertise gigabit speed on attached PHY
net: ethoc: set up MII management bus clock
net: ethoc: implement ethtool operations
drivers/net/ethernet/ethoc.c | 130 ++++++++++++++++++++++++++++++++++++++++++-
include/linux/phy.h | 12 ++++
include/net/ethoc.h | 1 +
3 files changed, 141 insertions(+), 2 deletions(-)
--
1.8.1.4
From: Max Filippov <jcmvbkbc@gmail.com> Date: 2014-01-29 06:00:54
OpenCores 10/100 Mbps MAC does not support speeds above 100 Mbps, but does
not disable advertisement when PHY supports them. This results in
non-functioning network when the MAC is connected to a gigabit PHY connected
to a gigabit switch.
The fix is to disable gigabit speed advertisement on attached PHY
unconditionally.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:
- disable both gigabit advertisement and support.
drivers/net/ethernet/ethoc.c | 8 ++++++++
1 file changed, 8 insertions(+)
From: Max Filippov <jcmvbkbc@gmail.com> Date: 2014-01-29 06:00:56
MII management bus clock is derived from the MAC clock by dividing it by
MIIMODER register CLKDIV field value. This value may need to be set up
in case it is undefined or its default value is too high (and
communication with PHY is too slow) or too low (and communication with
PHY is impossible). The value of CLKDIV is not specified directly, but
is derived from the MAC clock for the default MII management bus frequency
of 2.5MHz. The MAC clock may be specified in the platform data, or as
either 'clock-frequency' or 'clocks' device tree attribute.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:
- drop MDIO bus frequency configurability, always configure for standard
2.5MHz;
- allow using common clock framework to provide ethoc clock.
drivers/net/ethernet/ethoc.c | 37 +++++++++++++++++++++++++++++++++++--
include/net/ethoc.h | 1 +
2 files changed, 36 insertions(+), 2 deletions(-)
@@ -1038,8 +1042,7 @@ static int ethoc_probe(struct platform_device *pdev)}/* Allow the platform setup code to pass in a MAC address. */-if(dev_get_platdata(&pdev->dev)){-structethoc_platform_data*pdata=dev_get_platdata(&pdev->dev);+if(pdata){memcpy(netdev->dev_addr,pdata->hwaddr,IFHWADDRLEN);priv->phy_id=pdata->phy_id;}else{
@@ -1077,6 +1080,32 @@ static int ethoc_probe(struct platform_device *pdev)if(random_mac)netdev->addr_assign_type=NET_ADDR_RANDOM;+/* Allow the platform setup code to adjust MII management bus clock. */+if(pdata)+eth_clkfreq=pdata->eth_clkfreq;+else+of_property_read_u32(pdev->dev.of_node,+"clock-frequency",ð_clkfreq);+if(!eth_clkfreq){+structclk*clk=clk_get(&pdev->dev,NULL);++if(!IS_ERR(clk)){+priv->clk=clk;+clk_prepare_enable(clk);+eth_clkfreq=clk_get_rate(clk);+}+}+if(eth_clkfreq){+u32clkdiv=MIIMODER_CLKDIV(eth_clkfreq/2500000+1);++if(!clkdiv)+clkdiv=2;+dev_dbg(&pdev->dev,"setting MII clkdiv to %u\n",clkdiv);+ethoc_write(priv,MIIMODER,+(ethoc_read(priv,MIIMODER)&MIIMODER_NOPRE)|+clkdiv);+}+/* register MII bus */priv->mdio=mdiobus_alloc();if(!priv->mdio){
From: Max Filippov <jcmvbkbc@gmail.com> Date: 2014-01-29 06:01:41
The following methods are implemented:
- get/set settings;
- get registers length/registers;
- get link state (standard implementation);
- get/set ring parameters;
- get timestamping info (standard implementation).
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:
- new patch.
drivers/net/ethernet/ethoc.c | 85 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
@@ -1028,6 +1111,7 @@ static int ethoc_probe(struct platform_device *pdev)ret=-ENODEV;gotoerror;}+priv->num_bd=num_bd;/* num_tx must be a power of two */priv->num_tx=rounddown_pow_of_two(num_bd>>1);priv->num_rx=num_bd-priv->num_tx;
@@ -1148,6 +1232,7 @@ static int ethoc_probe(struct platform_device *pdev)netdev->netdev_ops=ðoc_netdev_ops;netdev->watchdog_timeo=ETHOC_TIMEOUT;netdev->features|=0;+netdev->ethtool_ops=ðoc_ethtool_ops;/* setup NAPI */netif_napi_add(netdev,&priv->napi,ethoc_poll,64);
From: Max Filippov <jcmvbkbc@gmail.com> Date: 2014-01-29 06:02:02
Many network drivers directly modify phy_device::advertising and
phy_device::supported. Provide accessors to these fields to better
isolate phylib from its users.
Suggested-by: Ben Hutchings <redacted>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:
- new patch
include/linux/phy.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
Hi Max,
Le 28/01/2014 22:00, Max Filippov a écrit :
quoted hunk
OpenCores 10/100 Mbps MAC does not support speeds above 100 Mbps, but does
not disable advertisement when PHY supports them. This results in
non-functioning network when the MAC is connected to a gigabit PHY connected
to a gigabit switch.
The fix is to disable gigabit speed advertisement on attached PHY
unconditionally.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:
- disable both gigabit advertisement and support.
drivers/net/ethernet/ethoc.c | 8 ++++++++
1 file changed, 8 insertions(+)
@@ -688,6 +688,14 @@ static int ethoc_mdio_probe(struct net_device *dev)}priv->phy=phy;+phy_update_advert(phy,+ADVERTISED_1000baseT_Full|+ADVERTISED_1000baseT_Half,0);+phy_start_aneg(phy);
This does not look necessary, you should not have to call
phy_start_aneg() because the PHY state machine is not yet started, at
best this calls does nothing.
The following methods are implemented:
- get/set settings;
- get registers length/registers;
- get link state (standard implementation);
- get/set ring parameters;
- get timestamping info (standard implementation).
Ideally you should have one patch per ethtool callback that you
implement just in case something happens to break, only the specific
patch can reverted/referenced.
quoted hunk
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:
- new patch.
drivers/net/ethernet/ethoc.c | 85 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
@@ -1028,6 +1111,7 @@ static int ethoc_probe(struct platform_device *pdev)ret=-ENODEV;gotoerror;}+priv->num_bd=num_bd;/* num_tx must be a power of two */priv->num_tx=rounddown_pow_of_two(num_bd>>1);priv->num_rx=num_bd-priv->num_tx;
@@ -1148,6 +1232,7 @@ static int ethoc_probe(struct platform_device *pdev)netdev->netdev_ops=ðoc_netdev_ops;netdev->watchdog_timeo=ETHOC_TIMEOUT;netdev->features|=0;+netdev->ethtool_ops=ðoc_ethtool_ops;/* setup NAPI */netif_napi_add(netdev,&priv->napi,ethoc_poll,64);
MII management bus clock is derived from the MAC clock by dividing it by
MIIMODER register CLKDIV field value. This value may need to be set up
in case it is undefined or its default value is too high (and
communication with PHY is too slow) or too low (and communication with
PHY is impossible). The value of CLKDIV is not specified directly, but
is derived from the MAC clock for the default MII management bus frequency
of 2.5MHz. The MAC clock may be specified in the platform data, or as
either 'clock-frequency' or 'clocks' device tree attribute.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:
- drop MDIO bus frequency configurability, always configure for standard
2.5MHz;
- allow using common clock framework to provide ethoc clock.
drivers/net/ethernet/ethoc.c | 37 +++++++++++++++++++++++++++++++++++--
include/net/ethoc.h | 1 +
2 files changed, 36 insertions(+), 2 deletions(-)
@@ -1038,8 +1042,7 @@ static int ethoc_probe(struct platform_device *pdev)}/* Allow the platform setup code to pass in a MAC address. */-if(dev_get_platdata(&pdev->dev)){-structethoc_platform_data*pdata=dev_get_platdata(&pdev->dev);+if(pdata){memcpy(netdev->dev_addr,pdata->hwaddr,IFHWADDRLEN);priv->phy_id=pdata->phy_id;}else{
@@ -1077,6 +1080,32 @@ static int ethoc_probe(struct platform_device *pdev)if(random_mac)netdev->addr_assign_type=NET_ADDR_RANDOM;+/* Allow the platform setup code to adjust MII management bus clock. */+if(pdata)+eth_clkfreq=pdata->eth_clkfreq;
Since this is a new member, why not make it a struct clk pointer
directly so you could simplify the code path?
This does look a bit convoluted, and it looks like the clk_get() or
getting the clock-frequency property should boil down to being the same
thing with of_clk_get() as it should resolve all clocks phandles and
fetch their frequencies appropriately.
quoted hunk
+
/* register MII bus */
priv->mdio = mdiobus_alloc();
if (!priv->mdio) {
From: Max Filippov <jcmvbkbc@gmail.com> Date: 2014-01-29 07:01:31
On Wed, Jan 29, 2014 at 10:47 AM, Florian Fainelli [off-list ref] wrote:
Hi Max,
Le 28/01/2014 22:00, Max Filippov a écrit :
quoted
OpenCores 10/100 Mbps MAC does not support speeds above 100 Mbps, but does
not disable advertisement when PHY supports them. This results in
non-functioning network when the MAC is connected to a gigabit PHY
connected
to a gigabit switch.
The fix is to disable gigabit speed advertisement on attached PHY
unconditionally.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:
- disable both gigabit advertisement and support.
drivers/net/ethernet/ethoc.c | 8 ++++++++
1 file changed, 8 insertions(+)
@@ -688,6 +688,14 @@ static int ethoc_mdio_probe(struct net_device *dev)}priv->phy=phy;+phy_update_advert(phy,+ADVERTISED_1000baseT_Full|+ADVERTISED_1000baseT_Half,0);+phy_start_aneg(phy);
This does not look necessary, you should not have to call phy_start_aneg()
because the PHY state machine is not yet started, at best this calls does
nothing.
This call actually makes the whole thing work, because otherwise once gigabit
support is cleared from the supported mask genphy_config_advert does not
update gigabit advertisement register, leaving it enabled.
Many network drivers directly modify phy_device::advertising and
phy_device::supported. Provide accessors to these fields to better
isolate phylib from its users.
Suggested-by: Ben Hutchings <redacted>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
After giving some more thought to this patch, I am not sure this
really adds anything, struct phy_device is already exposed to drivers,
and those drivers have been able to modify phydev->supported and
phydev->advertising to suit their needs.
From: Max Filippov <jcmvbkbc@gmail.com> Date: 2014-01-30 00:14:33
On Wed, Jan 29, 2014 at 11:01 AM, Florian Fainelli [off-list ref] wrote:
Le 28/01/2014 22:00, Max Filippov a écrit :
quoted
MII management bus clock is derived from the MAC clock by dividing it by
MIIMODER register CLKDIV field value. This value may need to be set up
in case it is undefined or its default value is too high (and
communication with PHY is too slow) or too low (and communication with
PHY is impossible). The value of CLKDIV is not specified directly, but
is derived from the MAC clock for the default MII management bus frequency
of 2.5MHz. The MAC clock may be specified in the platform data, or as
either 'clock-frequency' or 'clocks' device tree attribute.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:
- drop MDIO bus frequency configurability, always configure for standard
2.5MHz;
- allow using common clock framework to provide ethoc clock.
drivers/net/ethernet/ethoc.c | 37 +++++++++++++++++++++++++++++++++++--
include/net/ethoc.h | 1 +
2 files changed, 36 insertions(+), 2 deletions(-)
@@ -1038,8 +1042,7 @@ static int ethoc_probe(struct platform_device *pdev)}/* Allow the platform setup code to pass in a MAC address. */-if(dev_get_platdata(&pdev->dev)){-structethoc_platform_data*pdata=
@@ -1077,6 +1080,32 @@ static int ethoc_probe(struct platform_device
*pdev)
if (random_mac)
netdev->addr_assign_type = NET_ADDR_RANDOM;
+ /* Allow the platform setup code to adjust MII management bus
clock. */
+ if (pdata)
+ eth_clkfreq = pdata->eth_clkfreq;
Since this is a new member, why not make it a struct clk pointer directly so
you could simplify the code path?
Basically this is to provide flexibility for the user: it may be more
appropriate to
specify frequency if it's known and fixed, otherwise clk_get below
would find the
clock registered for this device/generic clock.
This does look a bit convoluted, and it looks like the clk_get() or getting
the clock-frequency property should boil down to being the same thing with
of_clk_get() as it should resolve all clocks phandles and fetch their
frequencies appropriately.
I can drop clock-frequency property checking to encourage usage of common
clock framework. I don't quite understand the rest of the objection, could you
please rephrase it? clk_get calls of_clk_get internally.
quoted
+
/* register MII bus */
priv->mdio = mdiobus_alloc();
if (!priv->mdio) {
From: Ben Hutchings <hidden> Date: 2014-01-30 01:59:47
On Wed, 2014-01-29 at 10:00 +0400, Max Filippov wrote:
The following methods are implemented:
- get/set settings;
- get registers length/registers;
- get link state (standard implementation);
- get/set ring parameters;
- get timestamping info (standard implementation).
From: Max Filippov <jcmvbkbc@gmail.com> Date: 2014-01-30 03:04:42
On Thu, Jan 30, 2014 at 5:59 AM, Ben Hutchings [off-list ref] wrote:
On Wed, 2014-01-29 at 10:00 +0400, Max Filippov wrote:
quoted
The following methods are implemented:
- get/set settings;
- get registers length/registers;
- get link state (standard implementation);
- get/set ring parameters;
- get timestamping info (standard implementation).
So the RX ring may only ever be shrunk?! Did you mean to compare with
priv->num_bd instead?
First all non-TX descriptors are made RX, and if that's more than user
requested I trim it.
[...]
OK, I get it. But it would be clearer if you used min().
Ben.
--
Ben Hutchings
It is a miracle that curiosity survives formal education. - Albert Einstein