Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci Use new nvm.{acquire, release}() for semaphore. A...



details:   https://anonhg.NetBSD.org/src/rev/3a6983f948d3
branches:  trunk
changeset: 825610:3a6983f948d3
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Tue Jul 25 06:00:17 2017 +0000

description:
Use new nvm.{acquire,release}() for semaphore. Almost the same except the
following:
 - 8257[12]: Don't directly access SPI but use EERD register.
 - 82575-I354: If the size of SPI ROM >= 32K words, use direct SPI access
   instead of EERD register access.
 - Add wm_nvm_eec_clock_raise() and wm_nvm_eec_clock_lower() and use them for
   Microwire/SPI bus control. Same as Linux and FreeBSD.
 - Redude timeout value for 80003 in wm_get_swfw_semaphore(). Same as
   Linux and FreeBSD.

diffstat:

 sys/dev/pci/if_wm.c    |  494 ++++++++++++++++++++++++++++++------------------
 sys/dev/pci/if_wmvar.h |   14 +-
 2 files changed, 317 insertions(+), 191 deletions(-)

diffs (truncated from 911 to 300 lines):

diff -r e157204558f4 -r 3a6983f948d3 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Tue Jul 25 05:01:25 2017 +0000
+++ b/sys/dev/pci/if_wm.c       Tue Jul 25 06:00:17 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.529 2017/07/20 10:00:25 msaitoh Exp $      */
+/*     $NetBSD: if_wm.c,v 1.530 2017/07/25 06:00:17 msaitoh Exp $      */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -83,7 +83,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.529 2017/07/20 10:00:25 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.530 2017/07/25 06:00:17 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -442,6 +442,12 @@
        int reset_delay_us;
 };
 
+struct wm_nvmop {
+       int (*acquire)(struct wm_softc *);
+       void (*release)(struct wm_softc *);
+       int (*read)(struct wm_softc *, int, int, uint16_t *);
+};
+
 /*
  * Software state per device.
  */
@@ -564,6 +570,7 @@
        kmutex_t *sc_ich_nvmmtx;        /* ICH/PCH specific NVM mutex */
 
        struct wm_phyop phy;
+       struct wm_nvmop nvm;
 };
 
 #define WM_CORE_LOCK(_sc)      if ((_sc)->sc_core_lock) mutex_enter((_sc)->sc_core_lock)
@@ -857,8 +864,6 @@
 static int     wm_nvm_read_word_invm(struct wm_softc *, uint16_t, uint16_t *);
 static int     wm_nvm_read_invm(struct wm_softc *, int, int, uint16_t *);
 /* Lock, detecting NVM type, validate checksum and read */
-static int     wm_nvm_acquire(struct wm_softc *);
-static void    wm_nvm_release(struct wm_softc *);
 static int     wm_nvm_is_onboard_eeprom(struct wm_softc *);
 static int     wm_nvm_get_flash_presence_i210(struct wm_softc *);
 static int     wm_nvm_validate_checksum(struct wm_softc *);
@@ -872,17 +877,23 @@
  */
 static int     wm_get_null(struct wm_softc *);
 static void    wm_put_null(struct wm_softc *);
+static int     wm_get_eecd(struct wm_softc *);
+static void    wm_put_eecd(struct wm_softc *);
 static int     wm_get_swsm_semaphore(struct wm_softc *); /* 8257[123] */
 static void    wm_put_swsm_semaphore(struct wm_softc *);
 static int     wm_get_swfw_semaphore(struct wm_softc *, uint16_t);
 static void    wm_put_swfw_semaphore(struct wm_softc *, uint16_t);
+static int     wm_get_nvm_80003(struct wm_softc *);
+static void    wm_put_nvm_80003(struct wm_softc *);
+static int     wm_get_nvm_82571(struct wm_softc *);
+static void    wm_put_nvm_82571(struct wm_softc *);
 static int     wm_get_phy_82575(struct wm_softc *);
 static void    wm_put_phy_82575(struct wm_softc *);
 static int     wm_get_swfwhw_semaphore(struct wm_softc *); /* For 574/583 */
 static void    wm_put_swfwhw_semaphore(struct wm_softc *);
 static int     wm_get_swflag_ich8lan(struct wm_softc *);       /* For PHY */
 static void    wm_put_swflag_ich8lan(struct wm_softc *);
-static int     wm_get_nvm_ich8lan(struct wm_softc *);          /* For NVM */
+static int     wm_get_nvm_ich8lan(struct wm_softc *);
 static void    wm_put_nvm_ich8lan(struct wm_softc *);
 static int     wm_get_hw_semaphore_82573(struct wm_softc *);
 static void    wm_put_hw_semaphore_82573(struct wm_softc *);
@@ -1713,8 +1724,8 @@
        sc->sc_type = wmp->wmp_type;
 
        /* Set default function pointers */
-       sc->phy.acquire = wm_get_null;
-       sc->phy.release = wm_put_null;
+       sc->phy.acquire = sc->nvm.acquire = wm_get_null;
+       sc->phy.release = sc->nvm.release = wm_put_null;
        sc->phy.reset_delay_us = (sc->sc_type >= WM_T_82571) ? 100 : 10000;
 
        if (sc->sc_type < WM_T_82543) {
@@ -2039,6 +2050,7 @@
        case WM_T_82543:
        case WM_T_82544:
                /* Microwire */
+               sc->nvm.read = wm_nvm_read_uwire;
                sc->sc_nvm_wordsize = 64;
                sc->sc_nvm_addrbits = 6;
                break;
@@ -2048,6 +2060,7 @@
        case WM_T_82546:
        case WM_T_82546_3:
                /* Microwire */
+               sc->nvm.read = wm_nvm_read_uwire;
                reg = CSR_READ(sc, WMREG_EECD);
                if (reg & EECD_EE_SIZE) {
                        sc->sc_nvm_wordsize = 256;
@@ -2057,19 +2070,22 @@
                        sc->sc_nvm_addrbits = 6;
                }
                sc->sc_flags |= WM_F_LOCK_EECD;
+               sc->nvm.acquire = wm_get_eecd;
+               sc->nvm.release = wm_put_eecd;
                break;
        case WM_T_82541:
        case WM_T_82541_2:
        case WM_T_82547:
        case WM_T_82547_2:
-               sc->sc_flags |= WM_F_LOCK_EECD;
                reg = CSR_READ(sc, WMREG_EECD);
                if (reg & EECD_EE_TYPE) {
                        /* SPI */
+                       sc->nvm.read = wm_nvm_read_spi;
                        sc->sc_flags |= WM_F_EEPROM_SPI;
                        wm_nvm_set_addrbits_size_eecd(sc);
                } else {
                        /* Microwire */
+                       sc->nvm.read = wm_nvm_read_uwire;
                        if ((reg & EECD_EE_ABITS) != 0) {
                                sc->sc_nvm_wordsize = 256;
                                sc->sc_nvm_addrbits = 8;
@@ -2078,29 +2094,37 @@
                                sc->sc_nvm_addrbits = 6;
                        }
                }
+               sc->sc_flags |= WM_F_LOCK_EECD;
+               sc->nvm.acquire = wm_get_eecd;
+               sc->nvm.release = wm_put_eecd;
                break;
        case WM_T_82571:
        case WM_T_82572:
                /* SPI */
+               sc->nvm.read = wm_nvm_read_eerd;
+               /* Not use WM_F_LOCK_EECD because we use EERD */
                sc->sc_flags |= WM_F_EEPROM_SPI;
                wm_nvm_set_addrbits_size_eecd(sc);
-               sc->sc_flags |= WM_F_LOCK_EECD | WM_F_LOCK_SWSM;
                sc->phy.acquire = wm_get_swsm_semaphore;
                sc->phy.release = wm_put_swsm_semaphore;
+               sc->nvm.acquire = wm_get_nvm_82571;
+               sc->nvm.release = wm_put_nvm_82571;
                break;
        case WM_T_82573:
        case WM_T_82574:
        case WM_T_82583:
+               sc->nvm.read = wm_nvm_read_eerd;
+               /* Not use WM_F_LOCK_EECD because we use EERD */
                if (sc->sc_type == WM_T_82573) {
-                       sc->sc_flags |= WM_F_LOCK_SWSM;
                        sc->phy.acquire = wm_get_swsm_semaphore;
                        sc->phy.release = wm_put_swsm_semaphore;
+                       sc->nvm.acquire = wm_get_nvm_82571;
+                       sc->nvm.release = wm_put_nvm_82571;
                } else {
-                       sc->sc_flags |= WM_F_LOCK_EXTCNF;
                        /* Both PHY and NVM use the same semaphore. */
-                       sc->phy.acquire
+                       sc->phy.acquire = sc->nvm.acquire
                            = wm_get_swfwhw_semaphore;
-                       sc->phy.release
+                       sc->phy.release = sc->nvm.release
                            = wm_put_swfwhw_semaphore;
                }
                if (wm_nvm_is_onboard_eeprom(sc) == 0) {
@@ -2111,7 +2135,6 @@
                        sc->sc_flags |= WM_F_EEPROM_SPI;
                        wm_nvm_set_addrbits_size_eecd(sc);
                }
-               sc->sc_flags |= WM_F_EEPROM_EERDEEWR;
                break;
        case WM_T_82575:
        case WM_T_82576:
@@ -2122,10 +2145,18 @@
                /* SPI */
                sc->sc_flags |= WM_F_EEPROM_SPI;
                wm_nvm_set_addrbits_size_eecd(sc);
-               sc->sc_flags |= WM_F_EEPROM_EERDEEWR | WM_F_LOCK_SWFW
-                   | WM_F_LOCK_SWSM;
+               if((sc->sc_type == WM_T_80003)
+                   || (sc->sc_nvm_wordsize < (1 << 15))) {
+                       sc->nvm.read = wm_nvm_read_eerd;
+                       /* Don't use WM_F_LOCK_EECD because we use EERD */
+               } else {
+                       sc->nvm.read = wm_nvm_read_spi;
+                       sc->sc_flags |= WM_F_LOCK_EECD;
+               }
                sc->phy.acquire = wm_get_phy_82575;
                sc->phy.release = wm_put_phy_82575;
+               sc->nvm.acquire = wm_get_nvm_80003;     
+               sc->nvm.release = wm_put_nvm_80003;     
                break;
        case WM_T_ICH8:
        case WM_T_ICH9:
@@ -2133,8 +2164,9 @@
        case WM_T_PCH:
        case WM_T_PCH2:
        case WM_T_PCH_LPT:
+               sc->nvm.read = wm_nvm_read_ich8;
                /* FLASH */
-               sc->sc_flags |= WM_F_EEPROM_FLASH | WM_F_LOCK_EXTCNF;
+               sc->sc_flags |= WM_F_EEPROM_FLASH;
                sc->sc_nvm_wordsize = 2048;
                memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag,WM_ICH8_FLASH);
                if (pci_mapreg_map(pa, WM_ICH8_FLASH, memtype, 0,
@@ -2154,10 +2186,13 @@
                sc->sc_flashreg_offset = 0;
                sc->phy.acquire = wm_get_swflag_ich8lan;
                sc->phy.release = wm_put_swflag_ich8lan;
+               sc->nvm.acquire = wm_get_nvm_ich8lan;
+               sc->nvm.release = wm_put_nvm_ich8lan;
                break;
        case WM_T_PCH_SPT:
+               sc->nvm.read = wm_nvm_read_spt;
                /* SPT has no GFPREG; flash registers mapped through BAR0 */
-               sc->sc_flags |= WM_F_EEPROM_FLASH | WM_F_LOCK_EXTCNF;
+               sc->sc_flags |= WM_F_EEPROM_FLASH;
                sc->sc_flasht = sc->sc_st;
                sc->sc_flashh = sc->sc_sh;
                sc->sc_ich8_flash_base = 0;
@@ -2171,20 +2206,25 @@
                sc->sc_flashreg_offset = WM_PCH_SPT_FLASHOFFSET;
                sc->phy.acquire = wm_get_swflag_ich8lan;
                sc->phy.release = wm_put_swflag_ich8lan;
+               sc->nvm.acquire = wm_get_nvm_ich8lan;
+               sc->nvm.release = wm_put_nvm_ich8lan;
                break;
        case WM_T_I210:
        case WM_T_I211:
                if (wm_nvm_get_flash_presence_i210(sc)) {
-                       wm_nvm_set_addrbits_size_eecd(sc);
+                       sc->nvm.read = wm_nvm_read_eerd;
+                       /* Don't use WM_F_LOCK_EECD because we use EERD */
                        sc->sc_flags |= WM_F_EEPROM_FLASH_HW;
-                       sc->sc_flags |= WM_F_EEPROM_EERDEEWR;
+                       wm_nvm_set_addrbits_size_eecd(sc);
                } else {
-                       sc->sc_nvm_wordsize = INVM_SIZE;
+                       sc->nvm.read = wm_nvm_read_invm;
                        sc->sc_flags |= WM_F_EEPROM_INVM;
-               }
-               sc->sc_flags |= WM_F_LOCK_SWFW | WM_F_LOCK_SWSM;
+                       sc->sc_nvm_wordsize = INVM_SIZE;
+               }
                sc->phy.acquire = wm_get_phy_82575;
                sc->phy.release = wm_put_phy_82575;
+               sc->nvm.acquire = wm_get_nvm_80003;
+               sc->nvm.release = wm_put_nvm_80003;
                break;
        default:
                break;
@@ -3674,7 +3714,7 @@
 
        if (wm_phy_resetisblocked(sc)) {
                /* XXX */
-               device_printf(sc->sc_dev, " PHY is blocked\n");
+               device_printf(sc->sc_dev, "PHY is blocked\n");
                return;
        }
 
@@ -11422,6 +11462,9 @@
        DPRINTF(WM_DEBUG_NVM, ("%s: %s called\n",
                device_xname(sc->sc_dev), __func__));
 
+       if (sc->nvm.acquire(sc) != 0)
+               return -1;
+
        for (i = 0; i < wordcnt; i++) {
                /* Clear SK and DI. */
                reg = CSR_READ(sc, WMREG_EECD) & ~(EECD_SK | EECD_DI);
@@ -11467,6 +11510,7 @@
                delay(2);
        }
 
+       sc->nvm.release(sc);
        return 0;
 }
 
@@ -11558,7 +11602,7 @@
        }
        if (usec >= SPI_MAX_RETRIES) {
                aprint_error_dev(sc->sc_dev,"EEPROM failed to become ready\n");
-               return 1;
+               return -1;
        }
        return 0;
 }
@@ -11574,18 +11618,22 @@
        uint32_t reg, val;
        int i;
        uint8_t opc;
+       int rv = 0;
 
        DPRINTF(WM_DEBUG_NVM, ("%s: %s called\n",
                device_xname(sc->sc_dev), __func__));
 
+       if (sc->nvm.acquire(sc) != 0)
+               return -1;



Home | Main Index | Thread Index | Old Index