Module Name: src
Committed By: snj
Date: Wed Mar 18 04:39:15 UTC 2015
Modified Files:
src/sys/dev/pci [netbsd-7]: if_wm.c if_wmreg.h
Log Message:
Pull up following revision(s) (requested by msaitoh in ticket #614):
sys/dev/pci/if_wm.c: revision 1.311-1.313
sys/dev/pci/if_wmreg.h: revision 1.66
Fix a bug that sc_mediatype is evaluated incorrectly. The real problem
might be occured only on fiber and serdes cases.
#####
- Initialize some hardware bits for 8257[1234], 82583, 80003, ICH* and PCH*.
Some of them are workaround code. From other *BSDs, Linux and documents.
- Add comment.
- Fix typo in comment.
#####
Fix a bug that the first access to NVM is failed on 8254[17] which use
SPI EEPROM. Observed on Dell PowerEdge [12]850. Thanks Tom Ivar Helbekkmo
for debugging.
To generate a diff of this commit:
cvs rdiff -u -r1.289.2.3 -r1.289.2.4 src/sys/dev/pci/if_wm.c
cvs rdiff -u -r1.60.2.1 -r1.60.2.2 src/sys/dev/pci/if_wmreg.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.289.2.3 src/sys/dev/pci/if_wm.c:1.289.2.4
--- src/sys/dev/pci/if_wm.c:1.289.2.3 Wed Feb 4 06:48:13 2015
+++ src/sys/dev/pci/if_wm.c Wed Mar 18 04:39:15 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.289.2.3 2015/02/04 06:48:13 snj Exp $ */
+/* $NetBSD: if_wm.c,v 1.289.2.4 2015/03/18 04:39:15 snj Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -81,7 +81,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.289.2.3 2015/02/04 06:48:13 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.289.2.4 2015/03/18 04:39:15 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -277,6 +277,10 @@ struct wm_softc {
int sc_rev; /* MAC revision */
wm_phy_type sc_phytype; /* PHY type */
uint32_t sc_mediatype; /* Media type (Copper, Fiber, SERDES)*/
+#define WM_MEDIATYPE_UNKNOWN 0x00
+#define WM_MEDIATYPE_FIBER 0x01
+#define WM_MEDIATYPE_COPPER 0x02
+#define WM_MEDIATYPE_SERDES 0x03 /* Internal SERDES */
int sc_funcid; /* unit number of the chip (0 to 3) */
int sc_flags; /* flags; see below */
int sc_if_flags; /* last if_flags */
@@ -557,6 +561,7 @@ static void wm_set_pcie_completion_timeo
static void wm_get_auto_rd_done(struct wm_softc *);
static void wm_lan_init_done(struct wm_softc *);
static void wm_get_cfg_done(struct wm_softc *);
+static void wm_initialize_hardware_bits(struct wm_softc *);
static void wm_reset(struct wm_softc *);
static int wm_add_rxbuf(struct wm_softc *, int);
static void wm_rxdrain(struct wm_softc *);
@@ -723,10 +728,10 @@ static const struct wm_product {
const char *wmp_name;
wm_chip_type wmp_type;
uint32_t wmp_flags;
-#define WMP_F_UNKNOWN 0x00
-#define WMP_F_FIBER 0x01
-#define WMP_F_COPPER 0x02
-#define WMP_F_SERDES 0x03 /* Internal SERDES */
+#define WMP_F_UNKNOWN WM_MEDIATYPE_UNKNOWN
+#define WMP_F_FIBER WM_MEDIATYPE_FIBER
+#define WMP_F_COPPER WM_MEDIATYPE_COPPER
+#define WMP_F_SERDES WM_MEDIATYPE_SERDES
#define WMP_MEDIATYPE(x) ((x) & 0x03)
} wm_products[] = {
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82542,
@@ -1739,6 +1744,7 @@ wm_attach(device_t parent, device_t self
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 */
@@ -1754,7 +1760,6 @@ wm_attach(device_t parent, device_t self
sc->sc_nvm_addrbits = 6;
}
}
- sc->sc_flags |= WM_F_LOCK_EECD;
break;
case WM_T_82571:
case WM_T_82572:
@@ -2106,10 +2111,10 @@ wm_attach(device_t parent, device_t self
wm_gmii_mediainit(sc, wmp->wmp_product);
} else if (sc->sc_type < WM_T_82543 ||
(CSR_READ(sc, WMREG_STATUS) & STATUS_TBIMODE) != 0) {
- if (sc->sc_mediatype & WMP_F_COPPER) {
+ if (sc->sc_mediatype == WM_MEDIATYPE_COPPER) {
aprint_error_dev(sc->sc_dev,
"WARNING: TBIMODE set on 1000BASE-T product!\n");
- sc->sc_mediatype = WMP_F_FIBER;
+ sc->sc_mediatype = WM_MEDIATYPE_FIBER;
}
wm_tbi_mediainit(sc);
} else {
@@ -2126,45 +2131,45 @@ wm_attach(device_t parent, device_t self
switch (link_mode) {
case CTRL_EXT_LINK_MODE_1000KX:
aprint_verbose_dev(sc->sc_dev, "1000KX\n");
- sc->sc_mediatype = WMP_F_SERDES;
+ sc->sc_mediatype = WM_MEDIATYPE_SERDES;
break;
case CTRL_EXT_LINK_MODE_SGMII:
if (wm_sgmii_uses_mdio(sc)) {
aprint_verbose_dev(sc->sc_dev,
"SGMII(MDIO)\n");
sc->sc_flags |= WM_F_SGMII;
- sc->sc_mediatype = WMP_F_COPPER;
+ sc->sc_mediatype = WM_MEDIATYPE_COPPER;
break;
}
aprint_verbose_dev(sc->sc_dev, "SGMII(I2C)\n");
/*FALLTHROUGH*/
case CTRL_EXT_LINK_MODE_PCIE_SERDES:
sc->sc_mediatype = wm_sfp_get_media_type(sc);
- if (sc->sc_mediatype == WMP_F_UNKNOWN) {
+ if (sc->sc_mediatype == WM_MEDIATYPE_UNKNOWN) {
if (link_mode
== CTRL_EXT_LINK_MODE_SGMII) {
sc->sc_mediatype
- = WMP_F_COPPER;
+ = WM_MEDIATYPE_COPPER;
sc->sc_flags |= WM_F_SGMII;
} else {
sc->sc_mediatype
- = WMP_F_SERDES;
+ = WM_MEDIATYPE_SERDES;
aprint_verbose_dev(sc->sc_dev,
"SERDES\n");
}
break;
}
- if (sc->sc_mediatype == WMP_F_SERDES)
+ if (sc->sc_mediatype == WM_MEDIATYPE_SERDES)
aprint_verbose_dev(sc->sc_dev,
"SERDES\n");
/* Change current link mode setting */
reg &= ~CTRL_EXT_LINK_MODE_MASK;
switch (sc->sc_mediatype) {
- case WMP_F_COPPER:
+ case WM_MEDIATYPE_COPPER:
reg |= CTRL_EXT_LINK_MODE_SGMII;
break;
- case WMP_F_SERDES:
+ case WM_MEDIATYPE_SERDES:
reg |= CTRL_EXT_LINK_MODE_PCIE_SERDES;
break;
default:
@@ -2175,7 +2180,7 @@ wm_attach(device_t parent, device_t self
case CTRL_EXT_LINK_MODE_GMII:
default:
aprint_verbose_dev(sc->sc_dev, "Copper\n");
- sc->sc_mediatype = WMP_F_COPPER;
+ sc->sc_mediatype = WM_MEDIATYPE_COPPER;
break;
}
@@ -2186,16 +2191,16 @@ wm_attach(device_t parent, device_t self
reg &= ~CTRL_EXT_I2C_ENA;
CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
- if (sc->sc_mediatype == WMP_F_COPPER)
+ if (sc->sc_mediatype == WM_MEDIATYPE_COPPER)
wm_gmii_mediainit(sc, wmp->wmp_product);
else
wm_tbi_mediainit(sc);
break;
default:
- if (sc->sc_mediatype & WMP_F_FIBER)
+ if (sc->sc_mediatype == WM_MEDIATYPE_FIBER)
aprint_error_dev(sc->sc_dev,
"WARNING: TBIMODE clear on 1000BASE-X product!\n");
- sc->sc_mediatype = WMP_F_COPPER;
+ sc->sc_mediatype = WM_MEDIATYPE_COPPER;
wm_gmii_mediainit(sc, wmp->wmp_product);
}
}
@@ -3209,6 +3214,200 @@ wm_get_cfg_done(struct wm_softc *sc)
}
}
+/* Init hardware bits */
+void
+wm_initialize_hardware_bits(struct wm_softc *sc)
+{
+ uint32_t tarc0, tarc1, reg;
+
+ /* 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)) {
+
+ /* Transmit Descriptor Control 0 */
+ reg = CSR_READ(sc, WMREG_TXDCTL(0));
+ reg |= TXDCTL_COUNT_DESC;
+ CSR_WRITE(sc, WMREG_TXDCTL(0), reg);
+
+ /* Transmit Descriptor Control 1 */
+ reg = CSR_READ(sc, WMREG_TXDCTL(1));
+ reg |= TXDCTL_COUNT_DESC;
+ CSR_WRITE(sc, WMREG_TXDCTL(1), reg);
+
+ /* TARC0 */
+ tarc0 = CSR_READ(sc, WMREG_TARC0);
+ switch (sc->sc_type) {
+ case WM_T_82571:
+ case WM_T_82572:
+ case WM_T_82573:
+ case WM_T_82574:
+ case WM_T_82583:
+ case WM_T_80003:
+ /* Clear bits 30..27 */
+ tarc0 &= ~__BITS(30, 27);
+ break;
+ default:
+ break;
+ }
+
+ switch (sc->sc_type) {
+ case WM_T_82571:
+ case WM_T_82572:
+ tarc0 |= __BITS(26, 23); /* TARC0 bits 23-26 */
+
+ tarc1 = CSR_READ(sc, WMREG_TARC1);
+ tarc1 &= ~__BITS(30, 29); /* Clear bits 30 and 29 */
+ tarc1 |= __BITS(26, 24); /* TARC1 bits 26-24 */
+ /* 8257[12] Errata No.7 */
+ tarc1 |= __BIT(22); /* TARC1 bits 22 */
+
+ /* TARC1 bit 28 */
+ if ((CSR_READ(sc, WMREG_TCTL) & TCTL_MULR) != 0)
+ tarc1 &= ~__BIT(28);
+ else
+ tarc1 |= __BIT(28);
+ CSR_WRITE(sc, WMREG_TARC1, tarc1);
+
+ /*
+ * 8257[12] Errata No.13
+ * Disable Dyamic Clock Gating.
+ */
+ reg = CSR_READ(sc, WMREG_CTRL_EXT);
+ reg &= ~CTRL_EXT_DMA_DYN_CLK;
+ CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
+ break;
+ case WM_T_82573:
+ case WM_T_82574:
+ case WM_T_82583:
+ if ((sc->sc_type == WM_T_82574)
+ || (sc->sc_type == WM_T_82583))
+ tarc0 |= __BIT(26); /* TARC0 bit 26 */
+
+ /* Extended Device Control */
+ reg = CSR_READ(sc, WMREG_CTRL_EXT);
+ reg &= ~__BIT(23); /* Clear bit 23 */
+ reg |= __BIT(22); /* Set bit 22 */
+ CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
+
+ /* Device Control */
+ sc->sc_ctrl &= ~__BIT(29); /* Clear bit 29 */
+ CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
+
+ /* PCIe Control Register */
+ if ((sc->sc_type == WM_T_82574)
+ || (sc->sc_type == WM_T_82583)) {
+ /*
+ * Document says this bit must be set for
+ * proper operation.
+ */
+ reg = CSR_READ(sc, WMREG_GCR);
+ reg |= __BIT(22);
+ CSR_WRITE(sc, WMREG_GCR, reg);
+
+ /*
+ * Apply workaround for hardware errata
+ * documented in errata docs Fixes issue where
+ * some error prone or unreliable PCIe
+ * completions are occurring, particularly
+ * with ASPM enabled. Without fix, issue can
+ * cause Tx timeouts.
+ */
+ reg = CSR_READ(sc, WMREG_GCR2);
+ reg |= __BIT(0);
+ CSR_WRITE(sc, WMREG_GCR2, reg);
+ }
+ break;
+ case WM_T_80003:
+ /* TARC0 */
+ if ((sc->sc_mediatype == WM_MEDIATYPE_FIBER)
+ || (sc->sc_mediatype == WM_MEDIATYPE_SERDES))
+ tarc0 &= ~__BIT(20); /* Clear bits 20 */
+
+ /* TARC1 bit 28 */
+ tarc1 = CSR_READ(sc, WMREG_TARC1);
+ if ((CSR_READ(sc, WMREG_TCTL) & TCTL_MULR) != 0)
+ tarc1 &= ~__BIT(28);
+ else
+ tarc1 |= __BIT(28);
+ CSR_WRITE(sc, WMREG_TARC1, tarc1);
+ break;
+ case WM_T_ICH8:
+ case WM_T_ICH9:
+ case WM_T_ICH10:
+ case WM_T_PCH:
+ case WM_T_PCH2:
+ case WM_T_PCH_LPT:
+ /* TARC 0 */
+ if (sc->sc_type == WM_T_ICH8) {
+ /* Set TARC0 bits 29 and 28 */
+ tarc0 |= __BITS(29, 28);
+ }
+ /* Set TARC0 bits 23,24,26,27 */
+ tarc0 |= __BITS(27, 26) | __BITS(24, 23);
+
+ /* CTRL_EXT */
+ reg = CSR_READ(sc, WMREG_CTRL_EXT);
+ reg |= __BIT(22); /* Set bit 22 */
+ /*
+ * Enable PHY low-power state when MAC is at D3
+ * w/o WoL
+ */
+ if (sc->sc_type >= WM_T_PCH)
+ reg |= CTRL_EXT_PHYPDEN;
+ CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
+
+ /* TARC1 */
+ tarc1 = CSR_READ(sc, WMREG_TARC1);
+ /* bit 28 */
+ if ((CSR_READ(sc, WMREG_TCTL) & TCTL_MULR) != 0)
+ tarc1 &= ~__BIT(28);
+ else
+ tarc1 |= __BIT(28);
+ tarc1 |= __BIT(24) | __BIT(26) | __BIT(30);
+ CSR_WRITE(sc, WMREG_TARC1, tarc1);
+
+ /* Device Status */
+ if (sc->sc_type == WM_T_ICH8) {
+ reg = CSR_READ(sc, WMREG_STATUS);
+ reg &= ~__BIT(31);
+ CSR_WRITE(sc, WMREG_STATUS, reg);
+
+ }
+
+ /*
+ * Work-around descriptor data corruption issue during
+ * NFS v2 UDP traffic, just disable the NFS filtering
+ * capability.
+ */
+ reg = CSR_READ(sc, WMREG_RFCTL);
+ reg |= WMREG_RFCTL_NFSWDIS | WMREG_RFCTL_NFSRDIS;
+ CSR_WRITE(sc, WMREG_RFCTL, reg);
+ break;
+ default:
+ break;
+ }
+ CSR_WRITE(sc, WMREG_TARC0, tarc0);
+
+ /*
+ * 8257[12] Errata No.52 and some others.
+ * Avoid RSS Hash Value bug.
+ */
+ switch (sc->sc_type) {
+ case WM_T_82571:
+ case WM_T_82572:
+ case WM_T_82573:
+ case WM_T_80003:
+ case WM_T_ICH8:
+ reg = CSR_READ(sc, WMREG_RFCTL);
+ reg |= WMREG_RFCTL_NEWIPV6EXDIS |WMREG_RFCTL_IPV6EXDIS;
+ CSR_WRITE(sc, WMREG_RFCTL, reg);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
/*
* wm_reset:
*
@@ -3263,6 +3462,7 @@ wm_reset(struct wm_softc *sc)
sc->sc_pba = PBA_20K;
break;
case WM_T_ICH8:
+ /* Workaround for a bit corruption issue in FIFO memory */
sc->sc_pba = PBA_8K;
CSR_WRITE(sc, WMREG_PBS, PBA_16K);
break;
@@ -3726,16 +3926,13 @@ wm_init_locked(struct ifnet *ifp)
break;
}
+ /* Init hardware bits */
+ wm_initialize_hardware_bits(sc);
+
/* Reset the PHY. */
if (sc->sc_flags & WM_F_HAS_MII)
wm_gmii_reset(sc);
- reg = CSR_READ(sc, WMREG_CTRL_EXT);
- /* Enable PHY low-power state when MAC is at D3 w/o WoL */
- if ((sc->sc_type == WM_T_PCH) || (sc->sc_type == WM_T_PCH2)
- || (sc->sc_type == WM_T_PCH_LPT))
- CSR_WRITE(sc, WMREG_CTRL_EXT, reg | CTRL_EXT_PHYPDEN);
-
/* Initialize the transmit descriptor ring. */
memset(sc->sc_txdescs, 0, WM_TXDESCSIZE(sc));
WM_CDTXSYNC(sc, 0, WM_NTXDESC(sc),
@@ -3763,12 +3960,12 @@ wm_init_locked(struct ifnet *ifp)
* Don't write TDT before TCTL.EN is set.
* See the document.
*/
- CSR_WRITE(sc, WMREG_TXDCTL, TXDCTL_QUEUE_ENABLE
+ CSR_WRITE(sc, WMREG_TXDCTL(0), TXDCTL_QUEUE_ENABLE
| TXDCTL_PTHRESH(0) | TXDCTL_HTHRESH(0)
| TXDCTL_WTHRESH(0));
else {
CSR_WRITE(sc, WMREG_TDT, 0);
- CSR_WRITE(sc, WMREG_TXDCTL, TXDCTL_PTHRESH(0) |
+ CSR_WRITE(sc, WMREG_TXDCTL(0), TXDCTL_PTHRESH(0) |
TXDCTL_HTHRESH(0) | TXDCTL_WTHRESH(0));
CSR_WRITE(sc, WMREG_RXDCTL, RXDCTL_PTHRESH(0) |
RXDCTL_HTHRESH(0) | RXDCTL_WTHRESH(1));
@@ -7232,7 +7429,7 @@ wm_check_for_link(struct wm_softc *sc)
uint32_t status;
uint32_t sig;
- if (sc->sc_mediatype & WMP_F_SERDES) {
+ if (sc->sc_mediatype == WM_MEDIATYPE_SERDES) {
sc->sc_tbi_linkup = 1;
return 0;
}
@@ -7331,7 +7528,7 @@ wm_tbi_mediainit(struct wm_softc *sc)
*/
sc->sc_ctrl |= CTRL_SWDPIO(0);
sc->sc_ctrl &= ~CTRL_SWDPIO(1);
- if (sc->sc_mediatype & WMP_F_SERDES)
+ if (sc->sc_mediatype == WM_MEDIATYPE_SERDES)
sc->sc_ctrl &= ~CTRL_LRST;
CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
@@ -7411,7 +7608,7 @@ wm_tbi_mediachange(struct ifnet *ifp)
uint32_t status;
int i;
- if (sc->sc_mediatype & WMP_F_SERDES)
+ if (sc->sc_mediatype == WM_MEDIATYPE_SERDES)
return 0;
if ((sc->sc_type == WM_T_82571) || (sc->sc_type == WM_T_82572)
@@ -7541,7 +7738,7 @@ wm_tbi_check_link(struct wm_softc *sc)
KASSERT(WM_TX_LOCKED(sc));
- if (sc->sc_mediatype & WMP_F_SERDES) {
+ if (sc->sc_mediatype == WM_MEDIATYPE_SERDES) {
sc->sc_tbi_linkup = 1;
return;
}
@@ -7630,7 +7827,7 @@ wm_sfp_get_media_type(struct wm_softc *s
uint32_t ctrl_ext;
uint8_t val = 0;
int timeout = 3;
- uint32_t mediatype = WMP_F_UNKNOWN;
+ uint32_t mediatype = WM_MEDIATYPE_UNKNOWN;
int rv = -1;
ctrl_ext = CSR_READ(sc, WMREG_CTRL_EXT);
@@ -7668,13 +7865,13 @@ wm_sfp_get_media_type(struct wm_softc *s
}
if ((val & (SFF_SFP_ETH_FLAGS_1000SX | SFF_SFP_ETH_FLAGS_1000LX)) != 0)
- mediatype = WMP_F_SERDES;
+ mediatype = WM_MEDIATYPE_SERDES;
else if ((val & SFF_SFP_ETH_FLAGS_1000T) != 0){
sc->sc_flags |= WM_F_SGMII;
- mediatype = WMP_F_COPPER;
+ mediatype = WM_MEDIATYPE_COPPER;
} else if ((val & SFF_SFP_ETH_FLAGS_100FX) != 0){
sc->sc_flags |= WM_F_SGMII;
- mediatype = WMP_F_SERDES;
+ mediatype = WM_MEDIATYPE_SERDES;
}
out:
@@ -9167,8 +9364,8 @@ wm_enable_wakeup(struct wm_softc *sc)
}
/* Keep the laser running on fiber adapters */
- if (((sc->sc_mediatype & WMP_F_FIBER) != 0)
- || (sc->sc_mediatype & WMP_F_SERDES) != 0) {
+ if ((sc->sc_mediatype == WM_MEDIATYPE_FIBER)
+ || (sc->sc_mediatype == WM_MEDIATYPE_SERDES)) {
reg = CSR_READ(sc, WMREG_CTRL_EXT);
reg |= CTRL_EXT_SWDPIN(3);
CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
@@ -9419,7 +9616,7 @@ wm_reset_init_script_82575(struct wm_sof
{
/*
* remark: this is untested code - we have no board without EEPROM
- * same setup as mentioned int the freeBSD driver for the i82575
+ * same setup as mentioned int the FreeBSD driver for the i82575
*/
/* SerDes configuration via SERDESCTRL */
Index: src/sys/dev/pci/if_wmreg.h
diff -u src/sys/dev/pci/if_wmreg.h:1.60.2.1 src/sys/dev/pci/if_wmreg.h:1.60.2.2
--- src/sys/dev/pci/if_wmreg.h:1.60.2.1 Fri Nov 7 21:34:56 2014
+++ src/sys/dev/pci/if_wmreg.h Wed Mar 18 04:39:15 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wmreg.h,v 1.60.2.1 2014/11/07 21:34:56 snj Exp $ */
+/* $NetBSD: if_wmreg.h,v 1.60.2.2 2015/03/18 04:39:15 snj Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -315,6 +315,7 @@ struct livengood_tcpip_ctxdesc {
#define CTRL_EXT_SPD_BYPS (1U << 15) /* speed select bypass */
#define CTRL_EXT_IPS1 (1U << 16) /* invert power state bit 1 */
#define CTRL_EXT_RO_DIS (1U << 17) /* relaxed ordering disabled */
+#define CTRL_EXT_DMA_DYN_CLK (1U << 19) /* DMA Dymamic Gating Enable */
#define CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define CTRL_EXT_LINK_MODE_GMII 0x00000000
#define CTRL_EXT_LINK_MODE_KMRN 0x00000000
@@ -756,11 +757,14 @@ struct livengood_tcpip_ctxdesc {
#define WMREG_TDFTS 0x3428 /* Transmit Data FIFO Tail Saved */
#define WMREG_TDFPC 0x3430 /* Transmit Data FIFO Packet Count */
-#define WMREG_TXDCTL 0x3828 /* Trandmit Descriptor Control */
+#define WMREG_TXDCTL(n) /* Trandmit Descriptor Control */ \
+ (((n) < 4) ? (0x3828 + ((n) * 0x100)) : (0xe028 + ((n) * 0x40)))
#define TXDCTL_PTHRESH(x) ((x) << 0) /* prefetch threshold */
#define TXDCTL_HTHRESH(x) ((x) << 8) /* host threshold */
#define TXDCTL_WTHRESH(x) ((x) << 16) /* write back threshold */
/* flags used starting with 82575 ... */
+#define TXDCTL_COUNT_DESC __BIT(22) /* Enable the counting of desc.
+ still to be processed. */
#define TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
#define TXDCTL_SWFLSH 0x04000000 /* Tx Desc. write-back flushing */
#define TXDCTL_PRIORITY 0x08000000
@@ -768,11 +772,12 @@ struct livengood_tcpip_ctxdesc {
#define WMREG_TADV 0x382c /* Transmit Absolute Interrupt Delay Timer */
#define WMREG_TSPMT 0x3830 /* TCP Segmentation Pad and Minimum
Threshold (Cordova) */
-#define WMREG_TARC0 0x3840 /* Tx arbitration count */
-
#define TSPMT_TSMT(x) (x) /* TCP seg min transfer */
#define TSPMT_TSPBP(x) ((x) << 16) /* TCP seg pkt buf padding */
+#define WMREG_TARC0 0x3840 /* Tx arbitration count (0) */
+#define WMREG_TARC1 0x3940 /* Tx arbitration count (1) */
+
#define WMREG_CRCERRS 0x4000 /* CRC Error Count */
#define WMREG_ALGNERRC 0x4004 /* Alignment Error Count */
#define WMREG_SYMERRC 0x4008 /* Symbol Error Count */
@@ -799,6 +804,13 @@ struct livengood_tcpip_ctxdesc {
#define WMREG_RLPML 0x5004 /* Rx Long Packet Max Length */
+#define WMREG_RFCTL 0x5008 /* Receive Filter Control */
+#define WMREG_RFCTL_NFSWDIS __BIT(6) /* NFS Write Disable */
+#define WMREG_RFCTL_NFSRDIS __BIT(7) /* NFS Read Disable */
+#define WMREG_RFCTL_ACKDIS __BIT(13) /* ACK Accelerate Disable */
+#define WMREG_RFCTL_IPV6EXDIS __BIT(16) /* IPv6 Extension Header Disable */
+#define WMREG_RFCTL_NEWIPV6EXDIS __BIT(17) /* New IPv6 Extension Header */
+
#define WMREG_WUC 0x5800 /* Wakeup Control */
#define WUC_APME 0x00000001 /* APM Enable */
#define WUC_PME_EN 0x00000002 /* PME Enable */
@@ -874,6 +886,8 @@ struct livengood_tcpip_ctxdesc {
#define SWFW_SOFT_SHIFT 0 /* software semaphores */
#define SWFW_FIRM_SHIFT 16 /* firmware semaphores */
+#define WMREG_GCR2 0x5b64 /* 3GPIO Control Register 2 */
+
#define WMREG_CRC_OFFSET 0x5f50
/*