aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSergei Shtylyov <sergei.shtylyov@cogentembedded.com>2013-03-31 05:50:07 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-31 19:42:33 -0400
commit1e1b812bbe1069fc8e2e372dca7d5f541c7a8ceb (patch)
tree70dd800eaa9af831acf96284c3bc7d13e562f581 /drivers/net
parent14bc435ea54cb888409efb54fc6b76c13ef530e9 (diff)
sh_eth: fix handling of no LINK signal
The code handling the absent LINK signal (or the absent PSR register -- which reflects the state of this signal) is quite naive and has probably never really worked. It's probably enough to say that this code is executed only on the LINK change interrupt (sic!) but even if we actually have the signal and choose to ignore it (it might be connected to PHY's link/activity LED output as on the Renesas BOCK-W board), sh_eth_adjust_link() on which this code relies to update 'mdp->link' gets executed later than the LINK change interrupt where it is checked, and so RX/TX never get enabled via ECMR register. So, ignore the LINK changed interrupt iff LINK signal is absent (or just chosen not to be used) or PSR register is absent, and enable/disable RX/TX directly in sh_eth_adjust_link() in this case. Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index bf5e3cf97c4d..1ca8b2b10adc 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1216,10 +1216,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
1216 if (felic_stat & ECSR_LCHNG) { 1216 if (felic_stat & ECSR_LCHNG) {
1217 /* Link Changed */ 1217 /* Link Changed */
1218 if (mdp->cd->no_psr || mdp->no_ether_link) { 1218 if (mdp->cd->no_psr || mdp->no_ether_link) {
1219 if (mdp->link == PHY_DOWN) 1219 goto ignore_link;
1220 link_stat = 0;
1221 else
1222 link_stat = PHY_ST_LINK;
1223 } else { 1220 } else {
1224 link_stat = (sh_eth_read(ndev, PSR)); 1221 link_stat = (sh_eth_read(ndev, PSR));
1225 if (mdp->ether_link_active_low) 1222 if (mdp->ether_link_active_low)
@@ -1242,6 +1239,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
1242 } 1239 }
1243 } 1240 }
1244 1241
1242ignore_link:
1245 if (intr_status & EESR_TWB) { 1243 if (intr_status & EESR_TWB) {
1246 /* Write buck end. unused write back interrupt */ 1244 /* Write buck end. unused write back interrupt */
1247 if (intr_status & EESR_TABT) /* Transmit Abort int */ 1245 if (intr_status & EESR_TABT) /* Transmit Abort int */
@@ -1392,12 +1390,16 @@ static void sh_eth_adjust_link(struct net_device *ndev)
1392 (sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR); 1390 (sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR);
1393 new_state = 1; 1391 new_state = 1;
1394 mdp->link = phydev->link; 1392 mdp->link = phydev->link;
1393 if (mdp->cd->no_psr || mdp->no_ether_link)
1394 sh_eth_rcv_snd_enable(ndev);
1395 } 1395 }
1396 } else if (mdp->link) { 1396 } else if (mdp->link) {
1397 new_state = 1; 1397 new_state = 1;
1398 mdp->link = PHY_DOWN; 1398 mdp->link = PHY_DOWN;
1399 mdp->speed = 0; 1399 mdp->speed = 0;
1400 mdp->duplex = -1; 1400 mdp->duplex = -1;
1401 if (mdp->cd->no_psr || mdp->no_ether_link)
1402 sh_eth_rcv_snd_disable(ndev);
1401 } 1403 }
1402 1404
1403 if (new_state && netif_msg_link(mdp)) 1405 if (new_state && netif_msg_link(mdp))