Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Make wm_reset() and wm_gmii_reset() close to e10...
details: https://anonhg.NetBSD.org/src/rev/8035a73a6ee6
branches: trunk
changeset: 750584:8035a73a6ee6
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Thu Jan 07 17:45:58 2010 +0000
description:
Make wm_reset() and wm_gmii_reset() close to e1000 driver.
At least, this change make wm_attach() stable on ICH9.
diffstat:
sys/dev/pci/if_wm.c | 375 ++++++++++++++++++++++++++++++++++++++++++------
sys/dev/pci/if_wmreg.h | 13 +-
sys/dev/pci/if_wmvar.h | 6 +-
3 files changed, 342 insertions(+), 52 deletions(-)
diffs (truncated from 611 to 300 lines):
diff -r 95b606975d15 -r 8035a73a6ee6 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Thu Jan 07 17:34:38 2010 +0000
+++ b/sys/dev/pci/if_wm.c Thu Jan 07 17:45:58 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.188 2010/01/07 17:34:38 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.189 2010/01/07 17:45:58 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.188 2010/01/07 17:34:38 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.189 2010/01/07 17:45:58 msaitoh Exp $");
#include "bpfilter.h"
#include "rnd.h"
@@ -535,6 +535,8 @@
static void wm_attach(device_t, device_t, void *);
static int wm_is_onboard_nvm_eeprom(struct wm_softc *);
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 int wm_get_swsm_semaphore(struct wm_softc *);
static void wm_put_swsm_semaphore(struct wm_softc *);
static int wm_poll_eerd_eewr_done(struct wm_softc *, int);
@@ -555,6 +557,7 @@
static int wm_check_mng_mode_ich8lan(struct wm_softc *);
static int wm_check_mng_mode_82574(struct wm_softc *);
static int wm_check_mng_mode_generic(struct wm_softc *);
+static int wm_check_reset_block(struct wm_softc *);
static void wm_get_hw_control(struct wm_softc *);
static int wm_check_for_link(struct wm_softc *);
@@ -994,6 +997,7 @@
break;
default:
memh_valid = 0;
+ break;
}
if (memh_valid) {
@@ -1171,6 +1175,7 @@
"unknown PCIXSPD %d; assuming 66MHz\n",
reg & STATUS_PCIXSPD_MASK);
sc->sc_bus_speed = 66;
+ break;
}
} else
sc->sc_bus_speed = (reg & STATUS_PCI66) ? 66 : 33;
@@ -3013,7 +3018,9 @@
static void
wm_reset(struct wm_softc *sc)
{
- uint32_t reg;
+ int phy_reset = 0;
+ uint32_t reg, func, mask;
+ int i;
/*
* Allocate on-chip memory according to the MTU size.
@@ -3074,6 +3081,37 @@
/* clear interrupt */
CSR_WRITE(sc, WMREG_IMC, 0xffffffffU);
+ /* Stop the transmit and receive processes. */
+ CSR_WRITE(sc, WMREG_RCTL, 0);
+ CSR_WRITE(sc, WMREG_TCTL, TCTL_PSP);
+
+ /* set_tbi_sbp_82543() */
+
+ delay(10*1000);
+
+ /* Must acquire the MDIO ownership before MAC reset */
+ switch(sc->sc_type) {
+ 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);
+ break;
+ default:
+ break;
+ }
+
/*
* 82541 Errata 29? & 82547 Errata 28?
* See also the description about PHY_RST bit in CTRL register
@@ -3086,12 +3124,11 @@
}
switch (sc->sc_type) {
- case WM_T_82544:
- case WM_T_82540:
- case WM_T_82545:
- case WM_T_82546:
+ case WM_T_82544: /* XXX check whether WM_F_IOH_VALID is set */
case WM_T_82541:
case WM_T_82541_2:
+ case WM_T_82547:
+ case WM_T_82547_2:
/*
* On some chipsets, a reset through a memory-mapped write
* cycle can cause the chip to reset before completing the
@@ -3108,26 +3145,51 @@
else
CSR_WRITE(sc, WMREG_CTRL, CTRL_RST);
break;
-
case WM_T_82545_3:
case WM_T_82546_3:
/* Use the shadow control register on these chips. */
CSR_WRITE(sc, WMREG_CTRL_SHADOW, CTRL_RST);
break;
-
+ case WM_T_80003:
+ func = (CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1;
+ mask = func ? SWFW_PHY1_SM : SWFW_PHY0_SM;
+ reg = CSR_READ(sc, WMREG_CTRL) | CTRL_RST;
+ wm_get_swfw_semaphore(sc, mask);
+ CSR_WRITE(sc, WMREG_CTRL, reg);
+ wm_put_swfw_semaphore(sc, mask);
+ break;
case WM_T_ICH8:
case WM_T_ICH9:
case WM_T_ICH10:
+ reg = CSR_READ(sc, WMREG_CTRL) | CTRL_RST;
+ if (wm_check_reset_block(sc) == 0) {
+ reg |= CTRL_PHY_RESET;
+ phy_reset = 1;
+ }
wm_get_swfwhw_semaphore(sc);
- CSR_WRITE(sc, WMREG_CTRL, CTRL_RST | CTRL_PHY_RESET);
- delay(10000);
+ CSR_WRITE(sc, WMREG_CTRL, reg);
+ delay(20*1000);
+ wm_put_swfwhw_semaphore(sc);
break;
+ case WM_T_82542_2_0:
+ case WM_T_82542_2_1:
+ case WM_T_82543:
+ case WM_T_82540:
+ case WM_T_82545:
+ case WM_T_82546:
+ case WM_T_82571:
+ case WM_T_82572:
+ case WM_T_82573:
+ case WM_T_82574:
+ case WM_T_82583:
default:
/* Everything else can safely use the documented method. */
- CSR_WRITE(sc, WMREG_CTRL, CTRL_RST);
+ CSR_WRITE(sc, WMREG_CTRL, CSR_READ(sc, WMREG_CTRL) | CTRL_RST);
break;
}
- delay(10000);
+
+ if (phy_reset != 0)
+ wm_get_cfg_done(sc);
/* reload EEPROM */
switch(sc->sc_type) {
@@ -3140,12 +3202,23 @@
CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
delay(2000);
break;
+ case WM_T_82540:
+ case WM_T_82545:
+ case WM_T_82545_3:
+ case WM_T_82546:
+ case WM_T_82546_3:
+ delay(5*1000);
+ /* XXX Disable HW ARPs on ASF enabled adapters */
+ break;
case WM_T_82541:
case WM_T_82541_2:
case WM_T_82547:
case WM_T_82547_2:
delay(20000);
+ /* XXX Disable HW ARPs on ASF enabled adapters */
break;
+ case WM_T_82571:
+ case WM_T_82572:
case WM_T_82573:
case WM_T_82574:
case WM_T_82583:
@@ -3154,10 +3227,27 @@
reg = CSR_READ(sc, WMREG_CTRL_EXT) | CTRL_EXT_EE_RST;
CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
}
- /* FALLTHROUGH */
- default:
/* check EECD_EE_AUTORD */
wm_get_auto_rd_done(sc);
+ /*
+ * Phy configuration from NVM just starts after EECD_AUTO_RD
+ * is set.
+ */
+ if ((sc->sc_type == WM_T_82573) || (sc->sc_type == WM_T_82574)
+ || (sc->sc_type == WM_T_82583))
+ delay(25*1000);
+ break;
+ case WM_T_80003:
+ case WM_T_ICH8:
+ case WM_T_ICH9:
+ /* check EECD_EE_AUTORD */
+ wm_get_auto_rd_done(sc);
+ break;
+ case WM_T_ICH10: /* & PCH */
+ wm_lan_init_done(sc);
+ break;
+ default:
+ panic("%s: unknown type\n", __func__);
}
/* reload sc_ctrl */
@@ -3648,12 +3738,12 @@
case WM_T_ICH8:
case WM_T_ICH9:
case WM_T_ICH10:
- for (i = 10; i > 0; i--) {
+ for (i = 0; i < 10; i++) {
if (CSR_READ(sc, WMREG_EECD) & EECD_EE_AUTORD)
break;
delay(1000);
}
- if (i == 0) {
+ if (i == 10) {
log(LOG_ERR, "%s: auto read from eeprom failed to "
"complete\n", device_xname(sc->sc_dev));
}
@@ -3662,11 +3752,95 @@
delay(5000);
break;
}
-
- /* Phy configuration starts after EECD_AUTO_RD is set */
- if (sc->sc_type == WM_T_82573 || sc->sc_type == WM_T_82574
- || sc->sc_type == WM_T_82574)
- delay(25000);
+}
+
+void
+wm_lan_init_done(struct wm_softc *sc)
+{
+ uint32_t reg = 0;
+ int i;
+
+ /* wait for eeprom to reload */
+ switch (sc->sc_type) {
+ case WM_T_ICH10: /* & PCH */
+ for (i = 0; i < WM_ICH8_LAN_INIT_TIMEOUT; i++) {
+ reg = CSR_READ(sc, WMREG_STATUS);
+ if ((reg & STATUS_LAN_INIT_DONE) != 0)
+ break;
+ delay(100);
+ }
+ if (i >= WM_ICH8_LAN_INIT_TIMEOUT) {
+ log(LOG_ERR, "%s: %s: lan_init_done failed to "
+ "complete\n", device_xname(sc->sc_dev), __func__);
+ }
+ break;
+ default:
+ panic("%s: %s: unknown type\n", device_xname(sc->sc_dev),
+ __func__);
+ break;
+ }
+
+ reg &= ~STATUS_LAN_INIT_DONE;
+ CSR_WRITE(sc, WMREG_STATUS, reg);
+}
+
+void
+wm_get_cfg_done(struct wm_softc *sc)
+{
+ int func = 0;
+ int mask;
+ int i;
+
+ /* wait for eeprom to reload */
+ switch (sc->sc_type) {
+ case WM_T_82542_2_0:
+ case WM_T_82542_2_1:
+ /* null */
+ break;
+ case WM_T_82543:
+ case WM_T_82544:
+ case WM_T_82540:
Home |
Main Index |
Thread Index |
Old Index