Module Name: src
Committed By: msaitoh
Date: Fri May 6 08:56:20 UTC 2016
Modified Files:
src/sys/dev/pci: if_wm.c if_wmreg.h if_wmvar.h
Log Message:
Basic support for I219. It doesn't work on I219, so it's disabled.
To generate a diff of this commit:
cvs rdiff -u -r1.391 -r1.392 src/sys/dev/pci/if_wm.c
cvs rdiff -u -r1.88 -r1.89 src/sys/dev/pci/if_wmreg.h
cvs rdiff -u -r1.30 -r1.31 src/sys/dev/pci/if_wmvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/if_wm.c
diff -u src/sys/dev/pci/if_wm.c:1.391 src/sys/dev/pci/if_wm.c:1.392
--- src/sys/dev/pci/if_wm.c:1.391 Tue Feb 9 08:32:11 2016
+++ src/sys/dev/pci/if_wm.c Fri May 6 08:56:20 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.391 2016/02/09 08:32:11 ozaki-r Exp $ */
+/* $NetBSD: if_wm.c,v 1.392 2016/05/06 08:56:20 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.391 2016/02/09 08:32:11 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.392 2016/05/06 08:56:20 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -146,8 +146,9 @@ __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.
#define WM_DEBUG_GMII 0x08
#define WM_DEBUG_MANAGE 0x10
#define WM_DEBUG_NVM 0x20
+#define WM_DEBUG_INIT 0x40
int wm_debug = WM_DEBUG_TX | WM_DEBUG_RX | WM_DEBUG_LINK | WM_DEBUG_GMII
- | WM_DEBUG_MANAGE | WM_DEBUG_NVM;
+ | WM_DEBUG_MANAGE | WM_DEBUG_NVM | WM_DEBUG_INIT;
#define DPRINTF(x, y) if (wm_debug & (x)) printf y
#else
@@ -334,6 +335,10 @@ struct wm_softc {
bus_space_tag_t sc_flasht; /* flash registers space tag */
bus_space_handle_t sc_flashh; /* flash registers space handle */
bus_size_t sc_flashs; /* flash registers space size */
+ off_t sc_flashreg_offset; /*
+ * offset to flash registers from
+ * start of BAR
+ */
bus_dma_tag_t sc_dmat; /* bus DMA tag */
struct ethercom sc_ethercom; /* ethernet common data */
@@ -490,15 +495,19 @@ do { \
#define CSR_WRITE_FLUSH(sc) \
(void) CSR_READ((sc), WMREG_STATUS)
-#define ICH8_FLASH_READ32(sc, reg) \
- bus_space_read_4((sc)->sc_flasht, (sc)->sc_flashh, (reg))
-#define ICH8_FLASH_WRITE32(sc, reg, data) \
- bus_space_write_4((sc)->sc_flasht, (sc)->sc_flashh, (reg), (data))
-
-#define ICH8_FLASH_READ16(sc, reg) \
- bus_space_read_2((sc)->sc_flasht, (sc)->sc_flashh, (reg))
-#define ICH8_FLASH_WRITE16(sc, reg, data) \
- bus_space_write_2((sc)->sc_flasht, (sc)->sc_flashh, (reg), (data))
+#define ICH8_FLASH_READ32(sc, reg) \
+ bus_space_read_4((sc)->sc_flasht, (sc)->sc_flashh, \
+ (reg) + sc->sc_flashreg_offset)
+#define ICH8_FLASH_WRITE32(sc, reg, data) \
+ bus_space_write_4((sc)->sc_flasht, (sc)->sc_flashh, \
+ (reg) + sc->sc_flashreg_offset, (data))
+
+#define ICH8_FLASH_READ16(sc, reg) \
+ bus_space_read_2((sc)->sc_flasht, (sc)->sc_flashh, \
+ (reg) + sc->sc_flashreg_offset)
+#define ICH8_FLASH_WRITE16(sc, reg, data) \
+ bus_space_write_2((sc)->sc_flasht, (sc)->sc_flashh, \
+ (reg) + sc->sc_flashreg_offset, (data))
#define WM_CDTXADDR(txq, x) ((txq)->txq_desc_dma + WM_CDTXOFF((x)))
#define WM_CDRXADDR(rxq, x) ((rxq)->rxq_desc_dma + WM_CDRXOFF((x)))
@@ -688,10 +697,12 @@ static int wm_nvm_valid_bank_detect_ich8
static int32_t wm_ich8_cycle_init(struct wm_softc *);
static int32_t wm_ich8_flash_cycle(struct wm_softc *, uint32_t);
static int32_t wm_read_ich8_data(struct wm_softc *, uint32_t, uint32_t,
- uint16_t *);
+ uint32_t *);
static int32_t wm_read_ich8_byte(struct wm_softc *, uint32_t, uint8_t *);
static int32_t wm_read_ich8_word(struct wm_softc *, uint32_t, uint16_t *);
+static int32_t wm_read_ich8_dword(struct wm_softc *, uint32_t, uint32_t *);
static int wm_nvm_read_ich8(struct wm_softc *, int, int, uint16_t *);
+static int wm_nvm_read_spt(struct wm_softc *, int, int, uint16_t *);
/* iNVM */
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 *);
@@ -732,7 +743,7 @@ static int wm_enable_mng_pass_thru(struc
static bool wm_phy_resetisblocked(struct wm_softc *);
static void wm_get_hw_control(struct wm_softc *);
static void wm_release_hw_control(struct wm_softc *);
-static void wm_gate_hw_phy_config_ich8lan(struct wm_softc *, int);
+static void wm_gate_hw_phy_config_ich8lan(struct wm_softc *, bool);
static void wm_smbustopci(struct wm_softc *);
static void wm_init_manageability(struct wm_softc *);
static void wm_release_manageability(struct wm_softc *);
@@ -1282,6 +1293,20 @@ static const struct wm_product {
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I218_LM3,
"I218 LM Ethernet Connection",
WM_T_PCH_LPT, WMP_F_COPPER },
+#if 0
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V,
+ "I219 V Ethernet Connection",
+ WM_T_PCH_SPT, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V2,
+ "I219 V Ethernet Connection",
+ WM_T_PCH_SPT, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM,
+ "I219 LM Ethernet Connection",
+ WM_T_PCH_SPT, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM2,
+ "I219 LM Ethernet Connection",
+ WM_T_PCH_SPT, WMP_F_COPPER },
+#endif
{ 0, 0,
NULL,
0, 0 },
@@ -1710,7 +1735,8 @@ alloc_retry:
&& (sc->sc_type != WM_T_ICH10)
&& (sc->sc_type != WM_T_PCH)
&& (sc->sc_type != WM_T_PCH2)
- && (sc->sc_type != WM_T_PCH_LPT)) {
+ && (sc->sc_type != WM_T_PCH_LPT)
+ && (sc->sc_type != WM_T_PCH_SPT)) {
/* ICH* and PCH* have no PCIe capability registers */
if (pci_get_capability(pa->pa_pc, pa->pa_tag,
PCI_CAP_PCIEXPRESS, &sc->sc_pcixe_capoff,
@@ -1799,7 +1825,7 @@ alloc_retry:
/* get PHY control from SMBus to PCIe */
if ((sc->sc_type == WM_T_PCH) || (sc->sc_type == WM_T_PCH2)
- || (sc->sc_type == WM_T_PCH_LPT))
+ || (sc->sc_type == WM_T_PCH_LPT) || (sc->sc_type == WM_T_PCH_SPT))
wm_smbustopci(sc);
/* Reset the chip to a known state. */
@@ -1910,6 +1936,22 @@ alloc_retry:
sc->sc_ich8_flash_bank_size -= (reg & ICH_GFPREG_BASE_MASK);
sc->sc_ich8_flash_bank_size *= ICH_FLASH_SECTOR_SIZE;
sc->sc_ich8_flash_bank_size /= 2 * sizeof(uint16_t);
+ sc->sc_flashreg_offset = 0;
+ break;
+ case WM_T_PCH_SPT:
+ /* SPT has no GFPREG; flash registers mapped through BAR0 */
+ sc->sc_flags |= WM_F_EEPROM_FLASH | WM_F_LOCK_EXTCNF;
+ sc->sc_flasht = sc->sc_st;
+ sc->sc_flashh = sc->sc_sh;
+ sc->sc_ich8_flash_base = 0;
+ sc->sc_nvm_wordsize =
+ (((CSR_READ(sc, WMREG_STRAP) >> 1) & 0x1F) + 1)
+ * NVM_SIZE_MULTIPLIER;
+ /* It is size in bytes, we want words */
+ sc->sc_nvm_wordsize /= 2;
+ /* assume 2 banks */
+ sc->sc_ich8_flash_bank_size = sc->sc_nvm_wordsize / 2;
+ sc->sc_flashreg_offset = WM_PCH_SPT_FLASHOFFSET;
break;
case WM_T_I210:
case WM_T_I211:
@@ -2030,6 +2072,7 @@ alloc_retry:
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
/* Non-AMT based hardware can now take control from firmware */
if ((sc->sc_flags & WM_F_HAS_AMT) == 0)
wm_get_hw_control(sc);
@@ -2121,6 +2164,7 @@ alloc_retry:
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
/* XXX The funcid should be checked on some devices */
apme_mask = WUC_APME;
eeprom_data = CSR_READ(sc, WMREG_WUC);
@@ -2237,7 +2281,7 @@ alloc_retry:
if (sc->sc_type == WM_T_ICH8 || sc->sc_type == WM_T_ICH9
|| sc->sc_type == WM_T_ICH10 || sc->sc_type == WM_T_PCH
|| sc->sc_type == WM_T_PCH2 || sc->sc_type == WM_T_PCH_LPT
- || sc->sc_type == WM_T_82573
+ || sc->sc_type == WM_T_PCH_SPT || sc->sc_type == WM_T_82573
|| sc->sc_type == WM_T_82574 || sc->sc_type == WM_T_82583) {
/* STATUS_TBIMODE reserved/reused, can't rely on it */
wm_gmii_mediainit(sc, wmp->wmp_product);
@@ -2376,6 +2420,7 @@ alloc_retry:
case WM_T_ICH10:
case WM_T_PCH2: /* PCH2 supports 9K frame size */
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
/* XXX limited to 9234 */
sc->sc_ethercom.ec_capabilities |= ETHERCAP_JUMBO_MTU;
break;
@@ -2783,6 +2828,8 @@ wm_ioctl(struct ifnet *ifp, u_long cmd,
struct sockaddr_dl *sdl;
int s, error;
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
#ifndef WM_MPSAFE
s = splnet();
#endif
@@ -3000,7 +3047,8 @@ wm_mchash(struct wm_softc *sc, const uin
if ((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9)
|| (sc->sc_type == WM_T_ICH10) || (sc->sc_type == WM_T_PCH)
- || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT)) {
+ || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT)
+ || (sc->sc_type == WM_T_PCH_SPT)) {
hash = (enaddr[4] >> ich8_lo_shift[sc->sc_mchash_type]) |
(((uint16_t) enaddr[5]) << ich8_hi_shift[sc->sc_mchash_type]);
return (hash & 0x3ff);
@@ -3027,6 +3075,8 @@ wm_set_filter(struct wm_softc *sc)
uint32_t hash, reg, bit;
int i, size, ralmax;
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
if (sc->sc_type >= WM_T_82544)
mta_reg = WMREG_CORDOVA_MTA;
else
@@ -3052,7 +3102,7 @@ wm_set_filter(struct wm_softc *sc)
size = WM_RAL_TABSIZE_ICH8;
else if (sc->sc_type == WM_T_PCH2)
size = WM_RAL_TABSIZE_PCH2;
- else if (sc->sc_type == WM_T_PCH_LPT)
+ else if ((sc->sc_type == WM_T_PCH_LPT) ||(sc->sc_type == WM_T_PCH_SPT))
size = WM_RAL_TABSIZE_PCH_LPT;
else if (sc->sc_type == WM_T_82575)
size = WM_RAL_TABSIZE_82575;
@@ -3064,7 +3114,7 @@ wm_set_filter(struct wm_softc *sc)
size = WM_RAL_TABSIZE;
wm_set_ral(sc, CLLADDR(ifp->if_sadl), 0);
- if (sc->sc_type == WM_T_PCH_LPT) {
+ if ((sc->sc_type == WM_T_PCH_LPT) || (sc->sc_type == WM_T_PCH_SPT)) {
i = __SHIFTOUT(CSR_READ(sc, WMREG_FWSM), FWSM_WLOCK_MAC);
switch (i) {
case 0:
@@ -3088,7 +3138,8 @@ wm_set_filter(struct wm_softc *sc)
if ((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9)
|| (sc->sc_type == WM_T_ICH10) || (sc->sc_type == WM_T_PCH)
- || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT))
+ || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT)
+ || (sc->sc_type == WM_T_PCH_SPT))
size = WM_ICH8_MC_TABSIZE;
else
size = WM_MC_TABSIZE;
@@ -3116,7 +3167,8 @@ wm_set_filter(struct wm_softc *sc)
if ((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9)
|| (sc->sc_type == WM_T_ICH10) || (sc->sc_type == WM_T_PCH)
|| (sc->sc_type == WM_T_PCH2)
- || (sc->sc_type == WM_T_PCH_LPT))
+ || (sc->sc_type == WM_T_PCH_LPT)
+ || (sc->sc_type == WM_T_PCH_SPT))
reg &= 0x1f;
else
reg &= 0x7f;
@@ -3156,6 +3208,9 @@ wm_set_filter(struct wm_softc *sc)
static void
wm_set_vlan(struct wm_softc *sc)
{
+
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
/* Deal with VLAN enables. */
if (VLAN_ATTACHED(&sc->sc_ethercom))
sc->sc_ctrl |= CTRL_VME;
@@ -3245,6 +3300,7 @@ wm_lan_init_done(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
for (i = 0; i < WM_ICH8_LAN_INIT_TIMEOUT; i++) {
reg = CSR_READ(sc, WMREG_STATUS);
if ((reg & STATUS_LAN_INIT_DONE) != 0)
@@ -3327,6 +3383,7 @@ wm_get_cfg_done(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
delay(10*1000);
if (sc->sc_type >= WM_T_ICH10)
wm_lan_init_done(sc);
@@ -3350,6 +3407,8 @@ wm_initialize_hardware_bits(struct wm_so
{
uint32_t tarc0, tarc1, reg;
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
/* For 82571 variant, 80003 and ICHs */
if (((sc->sc_type >= WM_T_82571) && (sc->sc_type <= WM_T_82583))
|| (sc->sc_type >= WM_T_80003)) {
@@ -3572,6 +3631,8 @@ wm_reset(struct wm_softc *sc)
int i, error = 0;
uint32_t reg, mask;
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
/*
* Allocate on-chip memory according to the MTU size.
* The Packet Buffer Allocation register must be written
@@ -3630,6 +3691,7 @@ wm_reset(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
sc->sc_pba = PBA_26K;
break;
default:
@@ -3751,6 +3813,7 @@ wm_reset(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
reg = CSR_READ(sc, WMREG_CTRL) | CTRL_RST;
if (wm_phy_resetisblocked(sc) == false) {
/*
@@ -3760,7 +3823,7 @@ wm_reset(struct wm_softc *sc)
if ((sc->sc_type == WM_T_PCH2)
&& ((CSR_READ(sc, WMREG_FWSM) & FWSM_FW_VALID)
== 0))
- wm_gate_hw_phy_config_ich8lan(sc, 1);
+ wm_gate_hw_phy_config_ich8lan(sc, true);
reg |= CTRL_PHY_RESET;
phy_reset = 1;
@@ -3880,6 +3943,7 @@ wm_reset(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
break;
default:
panic("%s: unknown type\n", __func__);
@@ -4448,6 +4512,8 @@ wm_init_locked(struct ifnet *ifp)
int i, j, trynum, error = 0;
uint32_t reg;
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
KASSERT(WM_CORE_LOCKED(sc));
/*
* *_HDR_ALIGNED_P is constant 1 if __NO_STRICT_ALIGMENT is set.
@@ -4492,6 +4558,7 @@ wm_init_locked(struct ifnet *ifp)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
/* AMT based hardware can now take control from firmware */
if ((sc->sc_flags & WM_F_HAS_AMT) != 0)
wm_get_hw_control(sc);
@@ -4556,7 +4623,8 @@ wm_init_locked(struct ifnet *ifp)
*/
if ((sc->sc_type != WM_T_ICH8) && (sc->sc_type != WM_T_ICH9)
&& (sc->sc_type != WM_T_ICH10) && (sc->sc_type != WM_T_PCH)
- && (sc->sc_type != WM_T_PCH2) && (sc->sc_type != WM_T_PCH_LPT)) {
+ && (sc->sc_type != WM_T_PCH2) && (sc->sc_type != WM_T_PCH_LPT)
+ && (sc->sc_type != WM_T_PCH_SPT)) {
CSR_WRITE(sc, WMREG_FCAL, FCAL_CONST);
CSR_WRITE(sc, WMREG_FCAH, FCAH_CONST);
CSR_WRITE(sc, WMREG_FCT, ETHERTYPE_FLOWCONTROL);
@@ -4590,6 +4658,7 @@ wm_init_locked(struct ifnet *ifp)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
/*
* Set the mac to wait the maximum time between each
* iteration and increase the max iterations when
@@ -4829,7 +4898,8 @@ wm_init_locked(struct ifnet *ifp)
if ((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9)
|| (sc->sc_type == WM_T_ICH10) || (sc->sc_type == WM_T_PCH)
- || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT)) {
+ || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT)
+ || (sc->sc_type == WM_T_PCH_SPT)) {
reg = CSR_READ(sc, WMREG_KABGTXD);
reg |= KABGTXD_BGSQLBIAS;
CSR_WRITE(sc, WMREG_KABGTXD, reg);
@@ -4959,6 +5029,7 @@ wm_init_locked(struct ifnet *ifp)
CSR_WRITE(sc, WMREG_PBA_ECC, reg);
break;
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
reg = CSR_READ(sc, WMREG_PBECCSTS);
reg |= PBECCSTS_UNCORR_ECC_ENABLE;
CSR_WRITE(sc, WMREG_PBECCSTS, reg);
@@ -5024,6 +5095,8 @@ wm_stop_locked(struct ifnet *ifp, int di
struct wm_txsoft *txs;
int i, qidx;
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
KASSERT(WM_CORE_LOCKED(sc));
sc->sc_stopping = true;
@@ -5800,6 +5873,8 @@ wm_init_txrx_queues(struct wm_softc *sc)
{
int i, error;
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
for (i = 0; i < sc->sc_ntxqueues; i++) {
struct wm_txqueue *txq = &sc->sc_txq[i];
WM_TX_LOCK(txq);
@@ -7623,6 +7698,8 @@ wm_gmii_reset(struct wm_softc *sc)
uint32_t reg;
int rv;
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
/* get phy semaphore */
switch (sc->sc_type) {
case WM_T_82571:
@@ -7649,6 +7726,7 @@ wm_gmii_reset(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
rv = wm_get_swfwhw_semaphore(sc);
break;
default:
@@ -7740,6 +7818,7 @@ wm_gmii_reset(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
/* generic reset */
CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_PHY_RESET);
CSR_WRITE_FLUSH(sc);
@@ -7780,10 +7859,11 @@ wm_gmii_reset(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
wm_put_swfwhw_semaphore(sc);
break;
default:
- /* nothing to do*/
+ /* nothing to do */
rv = 0;
break;
}
@@ -7831,6 +7911,7 @@ wm_gmii_reset(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
/* Allow time for h/w to get to a quiescent state afer reset */
delay(10*1000);
@@ -8015,7 +8096,7 @@ wm_gmii_mediainit(struct wm_softc *sc, p
}
break;
}
- if ((sc->sc_type >= WM_T_PCH) && (sc->sc_type <= WM_T_PCH_LPT)) {
+ if ((sc->sc_type >= WM_T_PCH) && (sc->sc_type <= WM_T_PCH_SPT)) {
/* All PCH* use _hv_ */
mii->mii_readreg = wm_gmii_hv_readreg;
mii->mii_writereg = wm_gmii_hv_writereg;
@@ -9998,6 +10079,21 @@ wm_nvm_valid_bank_detect_ich8lan(struct
uint8_t sig_byte = 0;
switch (sc->sc_type) {
+ case WM_T_PCH_SPT:
+ /*
+ * In SPT, read from the CTRL_EXT reg instead of accessing the
+ * sector valid bits from the NVM.
+ */
+ *bank = CSR_READ(sc, WMREG_CTRL_EXT) & CTRL_EXT_NVMVS;
+ if ((*bank == 0) || (*bank == 1)) {
+ aprint_error_dev(sc->sc_dev,
+ "%s: no valid NVM bank present\n",
+ __func__);
+ return -1;
+ } else {
+ *bank = *bank - 2;
+ return 0;
+ }
case WM_T_ICH8:
case WM_T_ICH9:
eecd = CSR_READ(sc, WMREG_EECD);
@@ -10136,16 +10232,16 @@ wm_ich8_flash_cycle(struct wm_softc *sc,
}
/******************************************************************************
- * Reads a byte or word from the NVM using the ICH8 flash access registers.
+ * Reads a byte or (d)word from the NVM using the ICH8 flash access registers.
*
* sc - The pointer to the hw structure
* index - The index of the byte or word to read.
- * size - Size of data to read, 1=byte 2=word
+ * size - Size of data to read, 1=byte 2=word, 4=dword
* data - Pointer to the word to store the value read.
*****************************************************************************/
static int32_t
wm_read_ich8_data(struct wm_softc *sc, uint32_t index,
- uint32_t size, uint16_t *data)
+ uint32_t size, uint32_t *data)
{
uint16_t hsfsts;
uint16_t hsflctl;
@@ -10154,7 +10250,7 @@ wm_read_ich8_data(struct wm_softc *sc, u
int32_t error = 1;
int32_t count = 0;
- if (size < 1 || size > 2 || data == 0x0 ||
+ if (size < 1 || size > 4 || data == 0x0 ||
index > ICH_FLASH_LINEAR_ADDR_MASK)
return error;
@@ -10173,7 +10269,15 @@ wm_read_ich8_data(struct wm_softc *sc, u
hsflctl |= ((size - 1) << HSFCTL_BCOUNT_SHIFT)
& HSFCTL_BCOUNT_MASK;
hsflctl |= ICH_CYCLE_READ << HSFCTL_CYCLE_SHIFT;
- ICH8_FLASH_WRITE16(sc, ICH_FLASH_HSFCTL, hsflctl);
+ if (sc->sc_type == WM_T_PCH_SPT) {
+ /*
+ * In SPT, This register is in Lan memory space, not
+ * flash. Therefore, only 32 bit access is supported.
+ */
+ ICH8_FLASH_WRITE32(sc, ICH_FLASH_HSFCTL,
+ (uint32_t)hsflctl);
+ } else
+ ICH8_FLASH_WRITE16(sc, ICH_FLASH_HSFCTL, hsflctl);
/*
* Write the last 24 bits of index into Flash Linear address
@@ -10197,6 +10301,8 @@ wm_read_ich8_data(struct wm_softc *sc, u
*data = (uint8_t)(flash_data & 0x000000FF);
else if (size == 2)
*data = (uint16_t)(flash_data & 0x0000FFFF);
+ else if (size == 4)
+ *data = (uint32_t)flash_data;
break;
} else {
/*
@@ -10228,7 +10334,7 @@ static int32_t
wm_read_ich8_byte(struct wm_softc *sc, uint32_t index, uint8_t* data)
{
int32_t status;
- uint16_t word = 0;
+ uint32_t word = 0;
status = wm_read_ich8_data(sc, index, 1, &word);
if (status == 0)
@@ -10250,8 +10356,30 @@ static int32_t
wm_read_ich8_word(struct wm_softc *sc, uint32_t index, uint16_t *data)
{
int32_t status;
+ uint32_t word = 0;
+
+ status = wm_read_ich8_data(sc, index, 2, &word);
+ if (status == 0)
+ *data = (uint16_t)word;
+ else
+ *data = 0;
+
+ return status;
+}
+
+/******************************************************************************
+ * Reads a dword from the NVM using the ICH8 flash access registers.
+ *
+ * sc - pointer to wm_hw structure
+ * index - The starting byte index of the word to read.
+ * data - Pointer to a word to store the value read.
+ *****************************************************************************/
+static int32_t
+wm_read_ich8_dword(struct wm_softc *sc, uint32_t index, uint32_t *data)
+{
+ int32_t status;
- status = wm_read_ich8_data(sc, index, 2, data);
+ status = wm_read_ich8_data(sc, index, 4, data);
return status;
}
@@ -10316,6 +10444,72 @@ wm_nvm_read_ich8(struct wm_softc *sc, in
return error;
}
+/******************************************************************************
+ * Reads a 16 bit word or words from the EEPROM using the SPT's flash access
+ * register.
+ *
+ * sc - Struct containing variables accessed by shared code
+ * offset - offset of word in the EEPROM to read
+ * data - word read from the EEPROM
+ * words - number of words to read
+ *****************************************************************************/
+static int
+wm_nvm_read_spt(struct wm_softc *sc, int offset, int words, uint16_t *data)
+{
+ int32_t error = 0;
+ uint32_t flash_bank = 0;
+ uint32_t act_offset = 0;
+ uint32_t bank_offset = 0;
+ uint32_t dword = 0;
+ uint16_t i = 0;
+
+ /*
+ * We need to know which is the valid flash bank. In the event
+ * that we didn't allocate eeprom_shadow_ram, we may not be
+ * managing flash_bank. So it cannot be trusted and needs
+ * to be updated with each read.
+ */
+ error = wm_nvm_valid_bank_detect_ich8lan(sc, &flash_bank);
+ if (error) {
+ DPRINTF(WM_DEBUG_NVM, ("%s: failed to detect NVM bank\n",
+ device_xname(sc->sc_dev)));
+ flash_bank = 0;
+ }
+
+ /*
+ * Adjust offset appropriately if we're on bank 1 - adjust for word
+ * size
+ */
+ bank_offset = flash_bank * (sc->sc_ich8_flash_bank_size * 2);
+
+ error = wm_get_swfwhw_semaphore(sc);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
+ __func__);
+ return error;
+ }
+
+ for (i = 0; i < words; i++) {
+ /* The NVM part needs a byte offset, hence * 2 */
+ act_offset = bank_offset + ((offset + i) * 2);
+ /* but we must read dword aligned, so mask ... */
+ error = wm_read_ich8_dword(sc, act_offset & ~0x3, &dword);
+ if (error) {
+ aprint_error_dev(sc->sc_dev,
+ "%s: failed to read NVM\n", __func__);
+ break;
+ }
+ /* ... and pick out low or high word */
+ if ((act_offset & 0x2) == 0)
+ data[i] = (uint16_t)(dword & 0xFFFF);
+ else
+ data[i] = (uint16_t)((dword >> 16) & 0xFFFF);
+ }
+
+ wm_put_swfwhw_semaphore(sc);
+ return error;
+}
+
/* iNVM */
static int
@@ -10570,6 +10764,7 @@ wm_nvm_validate_checksum(struct wm_softc
if ((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9)
|| (sc->sc_type == WM_T_ICH10) || (sc->sc_type == WM_T_PCH)
|| (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT)) {
+ /* XXX PCH_SPT? */
wm_nvm_read(sc, csum_wordaddr, 1, &eeprom_data);
if ((eeprom_data & valid_checksum) == 0) {
DPRINTF(WM_DEBUG_NVM,
@@ -10756,6 +10951,8 @@ wm_nvm_read(struct wm_softc *sc, int wor
|| (sc->sc_type == WM_T_ICH10) || (sc->sc_type == WM_T_PCH)
|| (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT))
rv = wm_nvm_read_ich8(sc, word, wordcnt, data);
+ else if (sc->sc_type == WM_T_PCH_SPT)
+ rv = wm_nvm_read_spt(sc, word, wordcnt, data);
else if (sc->sc_flags & WM_F_EEPROM_INVM)
rv = wm_nvm_read_invm(sc, word, wordcnt, data);
else if (sc->sc_flags & WM_F_EEPROM_EERDEEWR)
@@ -10971,6 +11168,7 @@ wm_check_mng_mode(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
rv = wm_check_mng_mode_ich8lan(sc);
break;
case WM_T_82574:
@@ -11086,6 +11284,7 @@ wm_phy_resetisblocked(struct wm_softc *s
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
do {
reg = CSR_READ(sc, WMREG_FWSM);
if ((reg & FWSM_RSPCIPHY) == 0) {
@@ -11138,6 +11337,7 @@ wm_get_hw_control(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
reg = CSR_READ(sc, WMREG_CTRL_EXT);
CSR_WRITE(sc, WMREG_CTRL_EXT, reg | CTRL_EXT_DRV_LOAD);
break;
@@ -11165,13 +11365,13 @@ wm_release_hw_control(struct wm_softc *s
}
static void
-wm_gate_hw_phy_config_ich8lan(struct wm_softc *sc, int on)
+wm_gate_hw_phy_config_ich8lan(struct wm_softc *sc, bool gate)
{
uint32_t reg;
reg = CSR_READ(sc, WMREG_EXTCNFCTR);
- if (on != 0)
+ if (gate)
reg |= EXTCNFCTR_GATE_PHY_CFG;
else
reg &= ~EXTCNFCTR_GATE_PHY_CFG;
@@ -11210,6 +11410,8 @@ static void
wm_init_manageability(struct wm_softc *sc)
{
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
if (sc->sc_flags & WM_F_HAS_MANAGE) {
uint32_t manc2h = CSR_READ(sc, WMREG_MANC2H);
uint32_t manc = CSR_READ(sc, WMREG_MANC);
@@ -11274,6 +11476,7 @@ wm_get_wakeup(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT: /* XXX only Q170 chipset? */
sc->sc_flags |= WM_F_HAS_AMT;
sc->sc_flags |= WM_F_ASF_FIRMWARE_PRES;
break;
@@ -11387,6 +11590,7 @@ wm_enable_wakeup(struct wm_softc *sc)
case WM_T_PCH:
case WM_T_PCH2:
case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
/* Disable gig during WOL */
reg = CSR_READ(sc, WMREG_PHY_CTRL);
reg |= PHY_CTRL_D0A_LPLU | PHY_CTRL_GBE_DIS;
Index: src/sys/dev/pci/if_wmreg.h
diff -u src/sys/dev/pci/if_wmreg.h:1.88 src/sys/dev/pci/if_wmreg.h:1.89
--- src/sys/dev/pci/if_wmreg.h:1.88 Fri Dec 25 04:50:16 2015
+++ src/sys/dev/pci/if_wmreg.h Fri May 6 08:56:20 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wmreg.h,v 1.88 2015/12/25 04:50:16 msaitoh Exp $ */
+/* $NetBSD: if_wmreg.h,v 1.89 2016/05/06 08:56:20 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -202,6 +202,10 @@ struct livengood_tcpip_ctxdesc {
/* registers for FLASH access on ICH8 */
#define WM_ICH8_FLASH 0x0014
+/* XXX Only for PCH_SPT? */
+#define WM_PCI_DESCRING_STATUS 0xe4
+#define DESCRING_STATUS_FLUSH_REQ __BIT(8)
+
/*
* Wiseman Control/Status Registers.
*/
@@ -270,6 +274,12 @@ struct livengood_tcpip_ctxdesc {
#define STATUS_GIO_M_ENA (1U << 19) /* GIO master enable */
#define STATUS_DEV_RST_SET (1U << 20) /* Device Reset Set */
+/* Strapping Option Register (PCH_SPT and newer) */
+#define WMREG_STRAP 0x000c
+#define STRAP_NVMSIZE __BITS(1, 6)
+#define STRAP_FREQ __BITS(12, 13)
+#define STRAP_SMBUSADDR __BITS(17, 23)
+
#define WMREG_EECD 0x0010 /* EEPROM Control Register */
#define EECD_SK (1U << 0) /* clock */
#define EECD_CS (1U << 1) /* chip select */
@@ -301,6 +311,7 @@ struct livengood_tcpip_ctxdesc {
#define WMREG_CTRL_EXT 0x0018 /* Extended Device Control Register */
#define CTRL_EXT_NSICR __BIT(0) /* Non Interrupt clear on read */
#define CTRL_EXT_GPI_EN(x) (1U << (x)) /* gpin interrupt enable */
+#define CTRL_EXT_NVMVS __BITS(0, 1) /* NVM valid sector */
#define CTRL_EXT_SWDPINS_SHIFT 4
#define CTRL_EXT_SWDPINS_MASK 0x0d
/* The bit order of the SW Definable pin is not 6543 but 3654! */
@@ -310,6 +321,7 @@ struct livengood_tcpip_ctxdesc {
#define CTRL_EXT_SWDPIO_MASK 0x0d
#define CTRL_EXT_SWDPIO(x) (1U << (CTRL_EXT_SWDPIO_SHIFT \
+ ((x) == 3 ? 3 : ((x) - 4))))
+#define CTRL_EXT_FORCE_SMBUS __BIT(11) /* Force SMBus mode */
#define CTRL_EXT_ASDCHK (1U << 12) /* ASD check */
#define CTRL_EXT_EE_RST (1U << 13) /* EEPROM reset */
#define CTRL_EXT_IPS (1U << 14) /* invert power state bit 0 */
@@ -497,6 +509,7 @@ struct livengood_tcpip_ctxdesc {
#define RCTL_RDMTS_MASK RCTL_RDMTS(3)
#define RCTL_MO(x) ((x) << 12) /* multicast offset */
#define RCTL_BAM (1U << 15) /* broadcast accept mode */
+#define RCTL_RDMTS_HEX __BIT(16)
#define RCTL_2k (0 << 16) /* 2k Rx buffers */
#define RCTL_1k (1 << 16) /* 1k Rx buffers */
#define RCTL_512 (2 << 16) /* 512 byte Rx buffers */
@@ -715,6 +728,8 @@ struct livengood_tcpip_ctxdesc {
#define PHY_CTRL_NOND0A_GBE_DIS (1 << 3)
#define PHY_CTRL_GBE_DIS (1 << 6)
+#define WMREG_IOSFPC 0x0f28 /* Tx corrupted data */
+
#define WMREG_PBA 0x1000 /* Packet Buffer Allocation */
#define PBA_BYTE_SHIFT 10 /* KB -> bytes */
#define PBA_ADDR_SHIFT 7 /* KB -> quadwords */
@@ -1021,6 +1036,9 @@ struct livengood_tcpip_ctxdesc {
#define SWFW_FIRM_SHIFT 16 /* firmware semaphores */
#define WMREG_GCR2 0x5b64 /* 3GPIO Control Register 2 */
+#define WMREG_FEXTNVM9 0x5bb4 /* Future Extended NVM 9 */
+#define WMREG_FEXTNVM11 0x5bbc /* Future Extended NVM 11 */
+#define FEXTNVM11_DIS_MULRFIX __BIT(13) /* Disable MULR fix */
#define WMREG_CRC_OFFSET 0x5f50
@@ -1244,6 +1262,9 @@ struct livengood_tcpip_ctxdesc {
#define ICH_NVM_VALID_SIG_MASK 0xc0
#define ICH_NVM_SIG_VALUE 0x80
+#define NVM_SIZE_MULTIPLIER 4096 /* multiplier for NVMS field */
+#define WM_PCH_SPT_FLASHOFFSET 0xe000 /* offset of NVM access regs(PCH_SPT)*/
+
/* for PCI express Capability registers */
#define WM_PCIE_DCSR2_16MS 0x00000005
Index: src/sys/dev/pci/if_wmvar.h
diff -u src/sys/dev/pci/if_wmvar.h:1.30 src/sys/dev/pci/if_wmvar.h:1.31
--- src/sys/dev/pci/if_wmvar.h:1.30 Fri Dec 25 04:50:16 2015
+++ src/sys/dev/pci/if_wmvar.h Fri May 6 08:56:20 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wmvar.h,v 1.30 2015/12/25 04:50:16 msaitoh Exp $ */
+/* $NetBSD: if_wmvar.h,v 1.31 2016/05/06 08:56:20 msaitoh Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -149,6 +149,7 @@ typedef enum {
WM_T_PCH, /* PCH (Platform Controller Hub) LAN */
WM_T_PCH2, /* PCH2 LAN */
WM_T_PCH_LPT, /* PCH "Lynx Point" LAN (I217, I218) */
+ WM_T_PCH_SPT, /* PCH "Sunrise Point" LAN (I219) */
} wm_chip_type;
typedef enum {