Module Name:    src
Committed By:   snj
Date:           Sun May  3 17:51:03 UTC 2009

Modified Files:
        src/sys/dev/pci [netbsd-5]: if_wm.c if_wmreg.h

Log Message:
Pull up following revision(s) (requested by spz in ticket #621):
        sys/dev/pci/if_wm.c: revisions 1.168, 1.169 via patch
        sys/dev/pci/if_wmreg.h: revision 1.26 via patch
On i82563, the em driver says that the ready bit in the MDIC register may be
incorrectly set. Insert delay(200) like the em driver.
--
Examine the management mode and mark DRV_LOAD (for ICH{8,9,10},80003,
8257{1,2,3,4}).
Add some error's printf().
Make the bank detect routine into the function.


To generate a diff of this commit:
cvs rdiff -u -r1.162.4.3 -r1.162.4.4 src/sys/dev/pci/if_wm.c
cvs rdiff -u -r1.24 -r1.24.20.1 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.162.4.3 src/sys/dev/pci/if_wm.c:1.162.4.4
--- src/sys/dev/pci/if_wm.c:1.162.4.3	Fri Mar 20 13:01:35 2009
+++ src/sys/dev/pci/if_wm.c	Sun May  3 17:51:02 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wm.c,v 1.162.4.3 2009/03/20 13:01:35 msaitoh Exp $	*/
+/*	$NetBSD: if_wm.c,v 1.162.4.4 2009/05/03 17:51:02 snj Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -79,7 +79,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.162.4.3 2009/03/20 13:01:35 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.162.4.4 2009/05/03 17:51:02 snj Exp $");
 
 #include "bpfilter.h"
 #include "rnd.h"
@@ -581,11 +581,16 @@
 static int32_t	wm_read_ich8_data(struct wm_softc *, uint32_t,
 		     uint32_t, uint16_t *);
 static int32_t	wm_read_ich8_word(struct wm_softc *sc, uint32_t, uint16_t *);
+static void	wm_82547_txfifo_stall(void *);
+static int	wm_check_mng_mode(struct wm_softc *);
+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 void	wm_get_hw_control(struct wm_softc *);
 
 CFATTACH_DECL_NEW(wm, sizeof(struct wm_softc),
     wm_match, wm_attach, NULL, NULL);
 
-static void	wm_82547_txfifo_stall(void *);
 
 /*
  * Devices supported by this driver.
@@ -1266,6 +1271,17 @@
 	 */
 	wm_reset(sc);
 
+	switch (sc->sc_type) {
+	case WM_T_82573:
+	case WM_T_ICH8:
+	case WM_T_ICH9:
+		if (wm_check_mng_mode(sc) != 0)
+			wm_get_hw_control(sc);
+		break;
+	default:
+		break;
+	}
+
 	/*
 	 * Get some information about the EEPROM.
 	 */
@@ -1328,13 +1344,18 @@
 	 * that no EEPROM is attached.
 	 */
 
- 
 	/*
 	 * Validate the EEPROM checksum. If the checksum fails, flag this for
 	 * later, so we can fail future reads from the EEPROM.
 	 */
-	if (wm_validate_eeprom_checksum(sc))
-		sc->sc_flags |= WM_F_EEPROM_INVALID;
+	if (wm_validate_eeprom_checksum(sc)) {
+		/*
+		 * Read twice again because some PCI-e parts fail the first
+		 * check due to the link being in sleep state.
+		 */
+		if (wm_validate_eeprom_checksum(sc))
+			sc->sc_flags |= WM_F_EEPROM_INVALID;
+	}
 
 	if (sc->sc_flags & WM_F_EEPROM_INVALID)
 		aprint_verbose_dev(sc->sc_dev, "No EEPROM\n");
@@ -3048,6 +3069,17 @@
 	/* Reset the chip to a known state. */
 	wm_reset(sc);
 
+	switch (sc->sc_type) {
+	case WM_T_82573:
+	case WM_T_ICH8:
+	case WM_T_ICH9:
+		if (wm_check_mng_mode(sc) != 0)
+			wm_get_hw_control(sc);
+		break;
+	default:
+		break;
+	}
+
 	/* Initialize the transmit descriptor ring. */
 	memset(sc->sc_txdescs, 0, WM_TXDESCSIZE(sc));
 	WM_CDTXSYNC(sc, 0, WM_NTXDESC(sc),
@@ -3463,8 +3495,11 @@
 		ret = wm_get_swsm_semaphore(sc);
 	}
 
-	if (ret)
+	if (ret) {
+		aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
+			__func__);
 		return 1;
+	}
 
 	if (sc->sc_flags & WM_F_EEPROM_HANDSHAKE)  {
 		reg = CSR_READ(sc, WMREG_EECD);
@@ -4260,14 +4295,20 @@
 	int func = 0; /* XXX gcc */
 
 	if ((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9)) {
-		if (wm_get_swfwhw_semaphore(sc))
+		if (wm_get_swfwhw_semaphore(sc)) {
+			aprint_error_dev(sc->sc_dev,
+			    "%s: failed to get semaphore\n", __func__);
 			return;
+		}
 	}
 	if (sc->sc_type == WM_T_80003) {
 		func = (CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1;
 		if (wm_get_swfw_semaphore(sc,
-		    func ? SWFW_PHY1_SM : SWFW_PHY0_SM))
+			func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) {
+			aprint_error_dev(sc->sc_dev,
+			    "%s: failed to get semaphore\n", __func__);
 			return;
+		}
 	}
 	if (sc->sc_type >= WM_T_82544) {
 		CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_PHY_RESET);
@@ -4622,8 +4663,11 @@
 	if (phy != 1) /* only one PHY on kumeran bus */
 		return 0;
 
-	if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM))
+	if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) {
+		aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
+		    __func__);
 		return 0;
+	}
 
 	if ((reg & GG82563_MAX_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
 		wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT,
@@ -4633,7 +4677,11 @@
 		    reg >> GG82563_PAGE_SHIFT);
 	}
 
+	/* Wait more 200us for a bug of the ready bit in the MDIC register */
+	delay(200);
+
 	rv = wm_gmii_i82544_readreg(self, phy, reg & GG82563_MAX_REG_ADDRESS);
+	delay(200);
 	wm_put_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM);
 	return (rv);
 }
@@ -4654,8 +4702,11 @@
 	if (phy != 1) /* only one PHY on kumeran bus */
 		return;
 
-	if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM))
+	if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) {
+		aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
+		    __func__);
 		return;
+	}
 
 	if ((reg & GG82563_MAX_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
 		wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT,
@@ -4665,7 +4716,11 @@
 		    reg >> GG82563_PAGE_SHIFT);
 	}
 
+	/* Wait more 200us for a bug of the ready bit in the MDIC register */
+	delay(200);
+
 	wm_gmii_i82544_writereg(self, phy, reg & GG82563_MAX_REG_ADDRESS, val);
+	delay(200);
 	wm_put_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM);
 }
 
@@ -4744,8 +4799,11 @@
 	int func = ((CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1);
 	int rv;
 
-	if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM))
+	if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) {
+		aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
+		    __func__);
 		return 0;
+	}
 
 	CSR_WRITE(sc, WMREG_KUMCTRLSTA,
 	    ((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) |
@@ -4767,8 +4825,11 @@
 {
 	int func = ((CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1);
 
-	if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM))
+	if (wm_get_swfw_semaphore(sc, func ? SWFW_PHY1_SM : SWFW_PHY0_SM)) {
+		aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
+		    __func__);
 		return;
+	}
 
 	CSR_WRITE(sc, WMREG_KUMCTRLSTA,
 	    ((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) |
@@ -4845,8 +4906,12 @@
 
 	for(timeout = 0; timeout < 200; timeout++) {
 		if (sc->sc_flags & WM_F_EEPROM_SEMAPHORE) {
-			if (wm_get_swsm_semaphore(sc))
+			if (wm_get_swsm_semaphore(sc)) {
+				aprint_error_dev(sc->sc_dev,
+				    "%s: failed to get semaphore\n",
+				    __func__);
 				return 1;
+			}
 		}
 		swfw_sync = CSR_READ(sc, WMREG_SW_FW_SYNC);
 		if ((swfw_sync & (swmask | fwmask)) == 0) {
@@ -4942,15 +5007,21 @@
     bank_offset = flash_bank * (sc->sc_ich8_flash_bank_size * 2);
 
     error = wm_get_swfwhw_semaphore(sc);
-    if (error)
+    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);
             error = wm_read_ich8_word(sc, act_offset, &word);
-            if (error)
+            if (error) {
+		aprint_error_dev(sc->sc_dev, "%s: failed to read NVM\n",
+		    __func__);
                 break;
+	    }
             data[i] = word;
     }
 
@@ -5166,3 +5237,88 @@
     status = wm_read_ich8_data(sc, index, 2, data);
     return status;
 }
+
+static int
+wm_check_mng_mode(struct wm_softc *sc)
+{
+	int rv;
+
+	switch (sc->sc_type) {
+	case WM_T_ICH8:
+	case WM_T_ICH9:
+		rv = wm_check_mng_mode_ich8lan(sc);
+		break;
+	case WM_T_82574:
+		rv = wm_check_mng_mode_82574(sc);
+		break;
+	default:
+		rv = wm_check_mng_mode_generic(sc);
+		break;
+	}
+
+	printf("XXXXXXXXXXXXX mng=%d ===============\n", rv);
+	return rv;
+}
+
+static int
+wm_check_mng_mode_ich8lan(struct wm_softc *sc)
+{
+	uint32_t fwsm;
+
+	fwsm = CSR_READ(sc, WMREG_FWSM);
+
+	if ((fwsm & FWSM_MODE_MASK) == (MNG_ICH_IAMT_MODE << FWSM_MODE_SHIFT))
+		return 1;
+
+	return 0;
+}
+
+static int
+wm_check_mng_mode_82574(struct wm_softc *sc)
+{
+	uint16_t data;
+
+	wm_read_eeprom(sc, NVM_INIT_CONTROL2_REG, 1, &data);
+
+	if ((data & NVM_INIT_CTRL2_MNGM) != 0)
+		return 1;
+
+	return 0;
+}
+
+static int
+wm_check_mng_mode_generic(struct wm_softc *sc)
+{
+	uint32_t fwsm;
+
+	fwsm = CSR_READ(sc, WMREG_FWSM);
+
+	if ((fwsm & FWSM_MODE_MASK) == (MNG_IAMT_MODE << FWSM_MODE_SHIFT))
+		return 1;
+
+	return 0;
+}
+
+static void
+wm_get_hw_control(struct wm_softc *sc)
+{
+	uint32_t reg;
+
+	switch (sc->sc_type) {
+	case WM_T_82573:
+		reg = CSR_READ(sc, WMREG_SWSM);
+		CSR_WRITE(sc, WMREG_SWSM, reg | SWSM_DRV_LOAD);
+		break;
+	case WM_T_82571:
+	case WM_T_82572:
+	case WM_T_80003:
+	case WM_T_ICH8:
+	case WM_T_ICH9:
+		printf("YYYYYYYYYYYYYY load drv YYYYYYYYYYYYYYY\n");
+		reg = CSR_READ(sc, WMREG_CTRL_EXT);
+		CSR_WRITE(sc, WMREG_CTRL_EXT, reg | CTRL_EXT_DRV_LOAD);
+		break;
+	default:
+		break;
+	}
+}

Index: src/sys/dev/pci/if_wmreg.h
diff -u src/sys/dev/pci/if_wmreg.h:1.24 src/sys/dev/pci/if_wmreg.h:1.24.20.1
--- src/sys/dev/pci/if_wmreg.h:1.24	Tue Dec 25 18:33:41 2007
+++ src/sys/dev/pci/if_wmreg.h	Sun May  3 17:51:02 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wmreg.h,v 1.24 2007/12/25 18:33:41 perry Exp $	*/
+/*	$NetBSD: if_wmreg.h,v 1.24.20.1 2009/05/03 17:51:02 snj Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -334,6 +334,7 @@
 #define	CTRL_EXT_LINK_MODE_TBI	0x00C00000
 #define	CTRL_EXT_LINK_MODE_KMRN	0x00000000
 #define	CTRL_EXT_LINK_MODE_SERDES 0x00C00000
+#define	CTRL_EXT_DRV_LOAD	0x10000000
 
 
 #define	WMREG_MDIC	0x0020	/* MDI Control Register */
@@ -664,6 +665,12 @@
 #define	SWSM_WMNG	0x00000004	/* Wake MNG Clock */
 #define	SWSM_DRV_LOAD	0x00000008	/* Driver Loaded Bit */
 
+#define	WMREG_FWSM	0x5b54	/* FW Semaphore */
+#define	FWSM_MODE_MASK		0xe
+#define	FWSM_MODE_SHIFT		0x1
+#define	MNG_ICH_IAMT_MODE	0x2
+#define	MNG_IAMT_MODE		0x3
+
 #define	WMREG_SW_FW_SYNC 0x5b5c	/* software-firmware semaphore */
 #define	SWFW_EEP_SM		0x0001 /* eeprom access */
 #define	SWFW_PHY0_SM		0x0002 /* first ctrl phy access */
@@ -731,3 +738,6 @@
 #define ICH_FLASH_SECTOR_SIZE      4096
 #define ICH_GFPREG_BASE_MASK       0x1FFF
 #define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
+
+#define	NVM_INIT_CONTROL2_REG	0x000f
+#define	NVM_INIT_CTRL2_MNGM	0x6000

Reply via email to