@@ -658,14 +666,7 @@ static void eth_port_start(struct net_device *dev)structpxa168_eth_private*pep=netdev_priv(dev);inttx_curr_desc,rx_curr_desc;-/* Perform PHY reset, if there is a PHY. */-if(pep->phy!=NULL){-structethtool_cmdcmd;--pxa168_get_settings(pep->dev,&cmd);-phy_init_hw(pep->phy);-pxa168_set_settings(pep->dev,&cmd);-}+phy_start(pep->phy);/* Assignment of Tx CTRP of given queue */tx_curr_desc=pep->tx_curr_desc_q;
@@ -981,8 +984,11 @@ static int set_port_config_ext(struct pxa168_eth_private *pep)skb_size=PCXR_MFL_64K;/* Extended Port Configuration */-wrl(pep,-PORT_CONFIG_EXT,PCXR_2BSM|/* Two byte prefix aligns IP hdr */+wrl(pep,PORT_CONFIG_EXT,+PCXR_AN_SPEED_DIS|/* Disable HW AN */+PCXR_AN_DUPLEX_DIS|+PCXR_AN_FLOWCTL_DIS|+PCXR_2BSM|/* Two byte prefix aligns IP hdr */PCXR_DSCP_EN|/* Enable DSCP in IP */skb_size|PCXR_FLP|/* do not force link pass */PCXR_TX_HIGH_PRI);/* Transmit - high priority queue */
@@ -990,6 +996,63 @@ static int set_port_config_ext(struct pxa168_eth_private *pep)return0;}+staticvoidpxa168_eth_adjust_link(structnet_device*dev)+{+structpxa168_eth_private*pep=netdev_priv(dev);+structphy_device*phy=pep->phy;+u32cfg=rdl(pep,PORT_CONFIG);+u32cfgext=rdl(pep,PORT_CONFIG_EXT);++cfg&=~PCR_DUPLEX_FULL;+cfgext&=~(PCXR_SPEED_100|PCXR_FLOWCTL_DIS|PCXR_RMII_EN);++if(phy->interface==PHY_INTERFACE_MODE_RMII)+cfgext|=PCXR_RMII_EN;+if(phy->speed==SPEED_100)+cfgext|=PCXR_SPEED_100;+if(phy->duplex)+cfg|=PCR_DUPLEX_FULL;+if(!phy->pause)+cfgext|=PCXR_FLOWCTL_DIS;++wrl(pep,PORT_CONFIG,cfg);+wrl(pep,PORT_CONFIG_EXT,cfgext);+}++staticintpxa168_init_phy(structnet_device*dev)+{+structpxa168_eth_private*pep=netdev_priv(dev);+structethtool_cmdcmd;+interr;++if(pep->phy)+return0;++pep->phy=mdiobus_scan(pep->smi_bus,pep->phy_addr);+if(!pep->phy)+return-ENODEV;++err=phy_connect_direct(dev,pep->phy,pxa168_eth_adjust_link,+pep->phy_intf);+if(err)+returnerr;++err=pxa168_get_settings(dev,&cmd);+if(err)+returnerr;++cmd.phy_address=pep->phy_addr;+cmd.speed=pep->phy_speed;+cmd.duplex=pep->phy_duplex;+cmd.advertising=PHY_BASIC_FEATURES;+cmd.autoneg=AUTONEG_ENABLE;++if(cmd.speed!=0)+cmd.autoneg=AUTONEG_DISABLE;++returnpxa168_set_settings(dev,&cmd);+}+staticintpxa168_init_hw(structpxa168_eth_private*pep){interr=0;
@@ -890,43 +868,9 @@ static int pxa168_eth_collect_events(struct pxa168_eth_private *pep,}if(icr&ICR_RXBUF)ret=1;-if(icr&ICR_MII_CH){-pep->work_todo|=WORK_LINK;-ret=1;-}returnret;}-staticvoidhandle_link_event(structpxa168_eth_private*pep)-{-structnet_device*dev=pep->dev;-u32port_status;-intspeed;-intduplex;-intfc;--port_status=rdl(pep,PORT_STATUS);-if(!(port_status&LINK_UP)){-if(netif_carrier_ok(dev)){-netdev_info(dev,"link down\n");-netif_carrier_off(dev);-txq_reclaim(dev,1);-}-return;-}-if(port_status&PORT_SPEED_100)-speed=100;-else-speed=10;--duplex=(port_status&FULL_DUPLEX)?1:0;-fc=(port_status&FLOW_CONTROL_DISABLED)?0:1;-netdev_info(dev,"link up, %d Mb/s, %s duplex, flow control %sabled\n",-speed,duplex?"full":"half",fc?"en":"dis");-if(!netif_carrier_ok(dev))-netif_carrier_on(dev);-}-staticirqreturn_tpxa168_eth_int_handler(intirq,void*dev_id){structnet_device*dev=(structnet_device*)dev_id;
@@ -1301,10 +1245,6 @@ static int pxa168_rx_poll(struct napi_struct *napi, int budget)structnet_device*dev=pep->dev;intwork_done=0;-if(unlikely(pep->work_todo&WORK_LINK)){-pep->work_todo&=~(WORK_LINK);-handle_link_event(pep);-}/**Wecalltxq_reclaimeverytimesinceinNAPIinteruptsaredisabled*andduetothiswemisstheTX_DONEinterrupt,whichisnotupdatedin
@@ -1427,72 +1367,6 @@ static int pxa168_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr,return-EOPNOTSUPP;}-staticstructphy_device*phy_scan(structpxa168_eth_private*pep,intphy_addr)-{-structmii_bus*bus=pep->smi_bus;-structphy_device*phydev;-intstart;-intnum;-inti;--if(phy_addr==PXA168_ETH_PHY_ADDR_DEFAULT){-/* Scan entire range */-start=ethernet_phy_get(pep);-num=32;-}else{-/* Use phy addr specific to platform */-start=phy_addr&0x1f;-num=1;-}-phydev=NULL;-for(i=0;i<num;i++){-intaddr=(start+i)&0x1f;-if(bus->phy_map[addr]==NULL)-mdiobus_scan(bus,addr);--if(phydev==NULL){-phydev=bus->phy_map[addr];-if(phydev!=NULL)-ethernet_phy_set_addr(pep,addr);-}-}--returnphydev;-}--staticvoidphy_init(structpxa168_eth_private*pep)-{-structphy_device*phy=pep->phy;--phy_attach(pep->dev,dev_name(&phy->dev),pep->phy_intf);--phy->speed=pep->phy_speed;-phy->duplex=pep->phy_duplex;-phy->autoneg=AUTONEG_ENABLE;-phy->supported&=PHY_BASIC_FEATURES;-phy->advertising=phy->supported|ADVERTISED_Autoneg;--if(pep->phy_speed!=0){-phy->autoneg=AUTONEG_DISABLE;-phy->advertising=0;-}--phy_start_aneg(phy);-}--staticintethernet_phy_setup(structnet_device*dev)-{-structpxa168_eth_private*pep=netdev_priv(dev);--pep->phy=phy_scan(pep,pep->phy_addr&0x1f);-if(pep->phy!=NULL)-phy_init(pep);--update_hash_table_mac_address(pep,NULL,dev->dev_addr);--return0;-}-staticintpxa168_get_settings(structnet_device*dev,structethtool_cmd*cmd){structpxa168_eth_private*pep=netdev_priv(dev);
@@ -66,6 +66,42 @@clocks=<&chipCLKID_TWD>;};+eth1:ethernet@b90000{+compatible="marvell,pxa168-eth";+reg=<0xb900000x10000>;+clocks=<&chipCLKID_GETH1>;+interrupts=<GIC_SPI24IRQ_TYPE_LEVEL_HIGH>;+/* set by bootloader */+local-mac-address=[000000000000];+#address-cells=<1>;+#size-cells=<0>;+phy-handle=<ðphy1>;+status="disabled";++ethphy1:ethernet-phy@0{+phy-connection-type="mii";+reg=<0>;+};+};++eth0:ethernet@e50000{+compatible="marvell,pxa168-eth";+reg=<0xe500000x10000>;+clocks=<&chipCLKID_GETH0>;+interrupts=<GIC_SPI8IRQ_TYPE_LEVEL_HIGH>;+/* set by bootloader */+local-mac-address=[000000000000];+#address-cells=<1>;+#size-cells=<0>;+phy-handle=<ðphy0>;+status="disabled";++ethphy0:ethernet-phy@0{+phy-connection-type="mii";+reg=<0>;+};+};+apb@e80000{compatible="simple-bus";#address-cells=<1>;
@@ -79,11 +79,47 @@clocks=<&chipCLKID_TWD>;};+eth1:ethernet@b90000{+compatible="marvell,pxa168-eth";+reg=<0xb900000x10000>;+clocks=<&chipCLKID_GETH1>;+interrupts=<GIC_SPI24IRQ_TYPE_LEVEL_HIGH>;+/* set by bootloader */+local-mac-address=[000000000000];+#address-cells=<1>;+#size-cells=<0>;+phy-handle=<ðphy1>;+status="disabled";++ethphy1:ethernet-phy@0{+phy-connection-type="mii";+reg=<0>;+};+};+cpu-ctrl@dd0000{compatible="marvell,berlin-cpu-ctrl";reg=<0xdd00000x10000>;};+eth0:ethernet@e50000{+compatible="marvell,pxa168-eth";+reg=<0xe500000x10000>;+clocks=<&chipCLKID_GETH0>;+interrupts=<GIC_SPI8IRQ_TYPE_LEVEL_HIGH>;+/* set by bootloader */+local-mac-address=[000000000000];+#address-cells=<1>;+#size-cells=<0>;+phy-handle=<ðphy0>;+status="disabled";++ethphy0:ethernet-phy@0{+phy-connection-type="mii";+reg=<0>;+};+};+apb@e80000{compatible="simple-bus";#address-cells=<1>;
--
2.1.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
@@ -197,6 +197,9 @@ struct tx_desc {structpxa168_eth_private{intport_num;/* User Ethernet port number */intphy_addr;+intphy_speed;+intphy_duplex;+phy_interface_tphy_intf;intrx_resource_err;/* Rx ring resource error flag */
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Date: 2014-10-09 12:41:50
The PXA168 Ethernet IP support MII and RMII connection to its PHY.
Currently, pxa168 platform_data does not provide a way to pass that
and there is one user of pxa168 platform_data (mach-mmp/gplug).
Given the pinctrl settings of gplug it uses RMII, so add and pass
a corresponding phy_interface_t.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: "David S. Miller" <davem@davemloft.net>
Cc: "Antoine Ténart" <redacted>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Eric Miao <redacted>
Cc: Haojian Zhuang <haojian.zhuang@gmail.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
arch/arm/mach-mmp/gplugd.c | 2 ++
include/linux/pxa168_eth.h | 1 +
2 files changed, 3 insertions(+)
From: Thomas Petazzoni <hidden> Date: 2014-10-09 14:33:29
Dear Sebastian Hesselbarth,
On Thu, 9 Oct 2014 14:38:58 +0200, Sebastian Hesselbarth wrote:
This patch series deals with a removing a IP feature that can be found
on all currently supported Marvell Ethernet IP (pxa168_eth, mv643xx_eth,
mvneta). The MAC IP allows to automatically perform PHY auto-negotiation
without software interaction.
However, this feature (a) fundamentally clashes with the way libphy works
and (b) is unable to deal with quirky PHYs that require special treatment.
In this series, pxa168_eth driver is rewritten to completely disable that
feature and properly deal with libphy provided PHYs. The other two drivers
are suspect to future patch sets, also removing the code related with it.
Hum, in mvneta, we already disabled the automatic negotiation and use
libphy. What makes you think the current mvneta driver is wrong in this
respect?
Thanks,
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Date: 2014-10-09 14:42:01
On 10/09/2014 04:33 PM, Thomas Petazzoni wrote:
Dear Sebastian Hesselbarth,
On Thu, 9 Oct 2014 14:38:58 +0200, Sebastian Hesselbarth wrote:
quoted
This patch series deals with a removing a IP feature that can be found
on all currently supported Marvell Ethernet IP (pxa168_eth, mv643xx_eth,
mvneta). The MAC IP allows to automatically perform PHY auto-negotiation
without software interaction.
However, this feature (a) fundamentally clashes with the way libphy works
and (b) is unable to deal with quirky PHYs that require special treatment.
In this series, pxa168_eth driver is rewritten to completely disable that
feature and properly deal with libphy provided PHYs. The other two drivers
are suspect to future patch sets, also removing the code related with it.
Hum, in mvneta, we already disabled the automatic negotiation and use
libphy. What makes you think the current mvneta driver is wrong in this
respect?
I didn't check mvneta, but remember Ezequiel didn't clear all AN bits
in the barebox driver (which is based on Linux mvneta). Just mentioned
that I'll have a closer look at it.
But I agree, regarding libphy support mvneta is probably the best
already.
Sebastian
From: Thomas Petazzoni <hidden> Date: 2014-10-09 14:47:10
Dear Sebastian Hesselbarth,
On Thu, 09 Oct 2014 16:41:48 +0200, Sebastian Hesselbarth wrote:
quoted
Hum, in mvneta, we already disabled the automatic negotiation and use
libphy. What makes you think the current mvneta driver is wrong in this
respect?
I didn't check mvneta, but remember Ezequiel didn't clear all AN bits
in the barebox driver (which is based on Linux mvneta). Just mentioned
that I'll have a closer look at it.
Ah, ok.
But I agree, regarding libphy support mvneta is probably the best
already.
Well, I initially remember that the original driver coming from Marvell
was using the HW PHY stuff, and that I changed that because it would
not integrate well with the kernel libphy.
A drawback of this is that because the hardware has built-in PHY
polling which triggers a MAC interrupt when the PHY status changes, they
typically don't wire up the PHY interrupt. Therefore, since we're not
able to use the MAC interrupt for PHY event notifications, we rely on
software PHY polling, which means that link up / link down events take
a few seconds to be noticed by the kernel. Unfortunately, I don't think
the hardware allows to use the hardware PHY polling to get link changes
interrupt, but not let the hardware configure the PHY itself.
Best regards,
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Date: 2014-10-09 15:24:49
On 10/09/2014 04:47 PM, Thomas Petazzoni wrote:
Well, I initially remember that the original driver coming from Marvell
was using the HW PHY stuff, and that I changed that because it would
not integrate well with the kernel libphy.
A drawback of this is that because the hardware has built-in PHY
polling which triggers a MAC interrupt when the PHY status changes, they
typically don't wire up the PHY interrupt. Therefore, since we're not
able to use the MAC interrupt for PHY event notifications, we rely on
software PHY polling, which means that link up / link down events take
a few seconds to be noticed by the kernel. Unfortunately, I don't think
the hardware allows to use the hardware PHY polling to get link changes
interrupt, but not let the hardware configure the PHY itself.
Yeah, but that HW PHY stuff really only works properly with standard
compliant PHYs. In particular, the integrated Marvell PHY in Marvell
Berlin SoCs does not seem to reflect PHY status on BMCR properly /sigh/.
Anyway, I think we can live with PHY polling.
BTW, one thing I noticed here is that libphy calls adjust_link
over-and-over again although nothing has changed. I guess we can just
add some before/after comparison in the libphy state machine and only
call adjust_link when something has changed. I'll have to look closer
at the state machine first and maybe Florian can comment on this,
too.
Sebastian
On 10/09/2014 08:24 AM, Sebastian Hesselbarth wrote:
On 10/09/2014 04:47 PM, Thomas Petazzoni wrote:
quoted
Well, I initially remember that the original driver coming from Marvell
was using the HW PHY stuff, and that I changed that because it would
not integrate well with the kernel libphy.
A drawback of this is that because the hardware has built-in PHY
polling which triggers a MAC interrupt when the PHY status changes, they
typically don't wire up the PHY interrupt. Therefore, since we're not
able to use the MAC interrupt for PHY event notifications, we rely on
software PHY polling, which means that link up / link down events take
a few seconds to be noticed by the kernel. Unfortunately, I don't think
the hardware allows to use the hardware PHY polling to get link changes
interrupt, but not let the hardware configure the PHY itself.
Yeah, but that HW PHY stuff really only works properly with standard
compliant PHYs. In particular, the integrated Marvell PHY in Marvell
Berlin SoCs does not seem to reflect PHY status on BMCR properly /sigh/.
Anyway, I think we can live with PHY polling.
BTW, one thing I noticed here is that libphy calls adjust_link
over-and-over again although nothing has changed. I guess we can just
add some before/after comparison in the libphy state machine and only
call adjust_link when something has changed. I'll have to look closer
at the state machine first and maybe Florian can comment on this,
too.
There's basically nothing built in the generic libphy that would try to
limit the number of times the adjust_link() callback is invoked, some
changes went in the bcmgenet driver to avoid that, I have yet to see how
much of this logic is transferable to the libphy layer.
--
Florian
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Date: 2014-10-09 17:28:54
On 10/09/2014 06:57 PM, Florian Fainelli wrote:
On 10/09/2014 08:24 AM, Sebastian Hesselbarth wrote:
quoted
Yeah, but that HW PHY stuff really only works properly with standard
compliant PHYs. In particular, the integrated Marvell PHY in Marvell
Berlin SoCs does not seem to reflect PHY status on BMCR properly /sigh/.
Anyway, I think we can live with PHY polling.
BTW, one thing I noticed here is that libphy calls adjust_link
over-and-over again although nothing has changed. I guess we can just
add some before/after comparison in the libphy state machine and only
call adjust_link when something has changed. I'll have to look closer
at the state machine first and maybe Florian can comment on this,
too.
There's basically nothing built in the generic libphy that would try to
limit the number of times the adjust_link() callback is invoked, some
changes went in the bcmgenet driver to avoid that, I have yet to see how
much of this logic is transferable to the libphy layer.
Ok, thanks for the clarification. I guess for the final patch series,
I'll add a check for both registers modified in foo_adjust_link to bail
out if there is no change. That will save the two register writes per
second or so and also allow to phy_print_status() after the writels.
Sebastian
From: Antoine Tenart <hidden> Date: 2014-10-16 09:53:38
Hi Sebastian,
On Thu, Oct 09, 2014 at 02:38:58PM +0200, Sebastian Hesselbarth wrote:
This patch series deals with a removing a IP feature that can be found
on all currently supported Marvell Ethernet IP (pxa168_eth, mv643xx_eth,
mvneta). The MAC IP allows to automatically perform PHY auto-negotiation
without software interaction.
However, this feature (a) fundamentally clashes with the way libphy works
and (b) is unable to deal with quirky PHYs that require special treatment.
In this series, pxa168_eth driver is rewritten to completely disable that
feature and properly deal with libphy provided PHYs. The other two drivers
are suspect to future patch sets, also removing the code related with it.
Currently, the patches are based on next-20141009 and will be resent once
v3.18-rc1 drops. This is a Request-For-Test on both BG2Q and MMP/gplug as
I tested the series on a BG2Q, it worked well.
Antoine
these are the current users of pxa168_eth. A branch with this patches on
top of next-20141009 can be found at
git://git.infradead.org/users/hesselba/linux-berlin.git devel/bg2-bg2cd-eth-v1
It would be great to get a Tested-byfrom MMP guys on gplug - if they
have that board somewhere. Also, BG2Q (Antoine) needs a phy-connection-type
property. My guess is that, if it is using internal PHY, it is "mii", too.
--
Antoine Ténart, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Date: 2014-10-20 14:37:59
On 16.10.2014 11:53, Antoine Tenart wrote:
On Thu, Oct 09, 2014 at 02:38:58PM +0200, Sebastian Hesselbarth wrote:
quoted
This patch series deals with a removing a IP feature that can be found
on all currently supported Marvell Ethernet IP (pxa168_eth, mv643xx_eth,
mvneta). The MAC IP allows to automatically perform PHY auto-negotiation
without software interaction.
However, this feature (a) fundamentally clashes with the way libphy works
and (b) is unable to deal with quirky PHYs that require special treatment.
In this series, pxa168_eth driver is rewritten to completely disable that
feature and properly deal with libphy provided PHYs. The other two drivers
are suspect to future patch sets, also removing the code related with it.
Currently, the patches are based on next-20141009 and will be resent once
v3.18-rc1 drops. This is a Request-For-Test on both BG2Q and MMP/gplug as
I tested the series on a BG2Q, it worked well.
Antoine,
Thanks for testing! I assume you have added a phy-connection-type
property to BG2Q's ethernet node?
I doubt there will be any Tested-by from MMP guys anytime soon, so
I'll resend this with the minor remarks to be merged for 3.19.
Sebastian
From: Antoine Tenart <hidden> Date: 2014-10-20 15:10:45
Sebastian,
On Mon, Oct 20, 2014 at 04:37:51PM +0200, Sebastian Hesselbarth wrote:
On 16.10.2014 11:53, Antoine Tenart wrote:
quoted
On Thu, Oct 09, 2014 at 02:38:58PM +0200, Sebastian Hesselbarth wrote:
quoted
This patch series deals with a removing a IP feature that can be found
on all currently supported Marvell Ethernet IP (pxa168_eth, mv643xx_eth,
mvneta). The MAC IP allows to automatically perform PHY auto-negotiation
without software interaction.
However, this feature (a) fundamentally clashes with the way libphy works
and (b) is unable to deal with quirky PHYs that require special treatment.
In this series, pxa168_eth driver is rewritten to completely disable that
feature and properly deal with libphy provided PHYs. The other two drivers
are suspect to future patch sets, also removing the code related with it.
Currently, the patches are based on next-20141009 and will be resent once
v3.18-rc1 drops. This is a Request-For-Test on both BG2Q and MMP/gplug as
I tested the series on a BG2Q, it worked well.
Thanks for testing! I assume you have added a phy-connection-type
property to BG2Q's ethernet node?
Yes, I added the following property to the ethernet-phy node:
phy-connection-type = "mii";
Feel free to add this to your series, or I can also send a patch.
Antoine
--
Antoine Ténart, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com