Commit f8febec6 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

LPDC link stability fix - EP MDIO read race condition

Since driver reads periodically MDIO registers (timer function to check
link state) and HAL reads periodically LPDC MDIO registers (through
ioctl call) it happened once in a while that ioctl read operation would be
interleaved with timer function. As a result HAL would get the value
read from a different MDIO register than the one requested. This had
caused occasional link restarts on LPDC ports.
parent 5f2b50fc
......@@ -54,6 +54,7 @@ int wrn_phy_read(struct net_device *dev, int phy_id, int location)
{
struct wrn_ep *ep = netdev_priv(dev);
u32 val;
int ctrl_adr, retries;
if (WR_IS_NODE) {
/*
......@@ -65,10 +66,31 @@ int wrn_phy_read(struct net_device *dev, int phy_id, int location)
return -1;
}
wrn_ep_write(ep, MDIO_CR, EP_MDIO_CR_ADDR_W(location));
/* First check if there is previous MDIO operation still ongoing */
while( (wrn_ep_read(ep, MDIO_ASR) & EP_MDIO_ASR_READY) == 0)
;
val = wrn_ep_read(ep, MDIO_ASR);
;
retries = 100;
while(retries > 0) {
wrn_ep_write(ep, MDIO_CR, EP_MDIO_CR_ADDR_W(location));
while( (wrn_ep_read(ep, MDIO_ASR) & EP_MDIO_ASR_READY) == 0)
;
val = wrn_ep_read(ep, MDIO_ASR);
/* control read from MDIO_CR to be sure we read value from requested
* register */
ctrl_adr = EP_MDIO_CR_ADDR_R(wrn_ep_read(ep, MDIO_CR));
if (ctrl_adr == location)
break;
else {
/* there was a conflict, retry the read */
retries--;
}
}
/* If we got here with retries == 0, this means the read failed... */
if (retries == 0) {
printk("%s readout error on port wri%d\n", __func__, ep->ep_number + 1);
}
/* mask from wbgen macros */
return EP_MDIO_ASR_RDATA_R(val);
}
......@@ -88,6 +110,10 @@ void wrn_phy_write(struct net_device *dev, int phy_id, int location,
return;
}
/* First check if there is previous MDIO operation still ongoing */
while( (wrn_ep_read(ep, MDIO_ASR) & EP_MDIO_ASR_READY) == 0)
;
wrn_ep_write(ep, MDIO_CR,
EP_MDIO_CR_ADDR_W(location)
| EP_MDIO_CR_DATA_W(value)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment