Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Fix "MDIC write error" bug for 82574 and 82583. ...



details:   https://anonhg.NetBSD.org/src/rev/11ae5b0185a5
branches:  trunk
changeset: 787585:11ae5b0185a5
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Tue Jun 25 02:34:00 2013 +0000

description:
Fix "MDIC write error" bug for 82574 and 82583. For those chips, the semaphore
must be released after chip reset. Found and tested by Mark Davies.

diffstat:

 sys/dev/pci/if_wm.c |  68 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 52 insertions(+), 16 deletions(-)

diffs (117 lines):

diff -r 322ec92dfc17 -r 11ae5b0185a5 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Tue Jun 25 01:17:29 2013 +0000
+++ b/sys/dev/pci/if_wm.c       Tue Jun 25 02:34:00 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.258 2013/06/19 10:53:24 msaitoh Exp $      */
+/*     $NetBSD: if_wm.c,v 1.259 2013/06/25 02:34:00 msaitoh Exp $      */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.258 2013/06/19 10:53:24 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.259 2013/06/25 02:34:00 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -570,6 +570,8 @@
 static void    wm_put_swfw_semaphore(struct wm_softc *, uint16_t);
 static int     wm_get_swfwhw_semaphore(struct wm_softc *);
 static void    wm_put_swfwhw_semaphore(struct wm_softc *);
+static int     wm_get_hw_semaphore_82573(struct wm_softc *);
+static void    wm_put_hw_semaphore_82573(struct wm_softc *);
 
 static int     wm_read_eeprom_ich8(struct wm_softc *, int, int, uint16_t *);
 static int32_t wm_ich8_cycle_init(struct wm_softc *);
@@ -4018,7 +4020,6 @@
 {
        int phy_reset = 0;
        uint32_t reg, mask;
-       int i;
 
        /*
         * Allocate on-chip memory according to the MTU size.
@@ -4118,19 +4119,7 @@
        case WM_T_82573:
        case WM_T_82574:
        case WM_T_82583:
-               i = 0;
-               reg = CSR_READ(sc, WMREG_EXTCNFCTR)
-                   | EXTCNFCTR_MDIO_SW_OWNERSHIP;
-               do {
-                       CSR_WRITE(sc, WMREG_EXTCNFCTR,
-                           reg | EXTCNFCTR_MDIO_SW_OWNERSHIP);
-                       reg = CSR_READ(sc, WMREG_EXTCNFCTR);
-                       if ((reg & EXTCNFCTR_MDIO_SW_OWNERSHIP) != 0)
-                               break;
-                       reg |= EXTCNFCTR_MDIO_SW_OWNERSHIP;
-                       delay(2*1000);
-                       i++;
-               } while (i < WM_MDIO_OWNERSHIP_TIMEOUT);
+               wm_get_hw_semaphore_82573(sc);
                break;
        default:
                break;
@@ -4231,6 +4220,16 @@
                break;
        }
 
+       /* Must release the MDIO ownership after MAC reset */
+       switch (sc->sc_type) {
+       case WM_T_82574:
+       case WM_T_82583:
+               wm_put_hw_semaphore_82573(sc);
+               break;
+       default:
+               break;
+       }
+
        if (phy_reset != 0)
                wm_get_cfg_done(sc);
 
@@ -7524,6 +7523,43 @@
 }
 
 static int
+wm_get_hw_semaphore_82573(struct wm_softc *sc)
+{
+       int i = 0;
+       uint32_t reg;
+
+       reg = CSR_READ(sc, WMREG_EXTCNFCTR);
+       do {
+               CSR_WRITE(sc, WMREG_EXTCNFCTR,
+                   reg | EXTCNFCTR_MDIO_SW_OWNERSHIP);
+               reg = CSR_READ(sc, WMREG_EXTCNFCTR);
+               if ((reg & EXTCNFCTR_MDIO_SW_OWNERSHIP) != 0)
+                       break;
+               delay(2*1000);
+               i++;
+       } while (i < WM_MDIO_OWNERSHIP_TIMEOUT);
+
+       if (i == WM_MDIO_OWNERSHIP_TIMEOUT) {
+               wm_put_hw_semaphore_82573(sc);
+               log(LOG_ERR, "%s: Driver can't access the PHY\n",
+                   device_xname(sc->sc_dev));
+               return -1;
+       }
+
+       return 0;
+}
+
+static void
+wm_put_hw_semaphore_82573(struct wm_softc *sc)
+{
+       uint32_t reg;
+
+       reg = CSR_READ(sc, WMREG_EXTCNFCTR);
+       reg &= ~EXTCNFCTR_MDIO_SW_OWNERSHIP;
+       CSR_WRITE(sc, WMREG_EXTCNFCTR, reg);
+}
+
+static int
 wm_valid_nvm_bank_detect_ich8lan(struct wm_softc *sc, unsigned int *bank)
 {
        uint32_t eecd;



Home | Main Index | Thread Index | Old Index