Module Name:    src
Committed By:   msaitoh
Date:           Tue Jan 12 22:26:30 UTC 2010

Modified Files:
        src/sys/dev/pci: if_wm.c if_wmreg.h

Log Message:
- Add i82567LM-2 i82567LM-4 i82567V-3 LAN controller.
- Reset GMII interface after wm_reset() in wm_init().
- Rework for assigning mii_{read,write}reg(). Use PCI product ID to identify
  the PHY.
- Add code about LPLU(Low Power Link Up) function. Now we can linkup 1000BaseT
  on PCH. It seems that we have to do the same work for ICH9.


To generate a diff of this commit:
cvs rdiff -u -r1.190 -r1.191 src/sys/dev/pci/if_wm.c
cvs rdiff -u -r1.33 -r1.34 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.190 src/sys/dev/pci/if_wm.c:1.191
--- src/sys/dev/pci/if_wm.c:1.190	Mon Jan 11 12:29:28 2010
+++ src/sys/dev/pci/if_wm.c	Tue Jan 12 22:26:30 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wm.c,v 1.190 2010/01/11 12:29:28 msaitoh Exp $	*/
+/*	$NetBSD: if_wm.c,v 1.191 2010/01/12 22:26:30 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.190 2010/01/11 12:29:28 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.191 2010/01/12 22:26:30 msaitoh Exp $");
 
 #include "bpfilter.h"
 #include "rnd.h"
@@ -123,6 +123,7 @@
 #include <dev/mii/miivar.h>
 #include <dev/mii/mii_bitbang.h>
 #include <dev/mii/ikphyreg.h>
+#include <dev/mii/igphyreg.h>
 
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
@@ -517,13 +518,14 @@
 
 static int	wm_gmii_i80003_readreg(device_t, int, int);
 static void	wm_gmii_i80003_writereg(device_t, int, int, int);
-
 static int	wm_gmii_bm_readreg(device_t, int, int);
 static void	wm_gmii_bm_writereg(device_t, int, int, int);
+static int	wm_gmii_kv_readreg(device_t, int, int);
+static void	wm_gmii_kv_writereg(device_t, int, int, int);
 
 static void	wm_gmii_statchg(device_t);
 
-static void	wm_gmii_mediainit(struct wm_softc *);
+static void	wm_gmii_mediainit(struct wm_softc *, pci_product_id_t);
 static int	wm_gmii_mediachange(struct ifnet *);
 static void	wm_gmii_mediastatus(struct ifnet *, struct ifmediareq *);
 
@@ -843,14 +845,26 @@
 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801I_IGP_M_AMT,
 	  "82801I mobile (AMT) LAN Controller",
 	  WM_T_ICH9,		WMP_F_1000T },
-	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82567LM_3,
+	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801I_BM,
+	  "82567LM-4 LAN Controller",
+	  WM_T_ICH9,		WMP_F_1000T },
+	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801I_82567V_3,
+	  "82567V-3 LAN Controller",
+	  WM_T_ICH9,		WMP_F_1000T },
+	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801J_R_BM_LM,
+	  "82567LM-2 LAN Controller",
+	  WM_T_ICH10,		WMP_F_1000T },
+	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801J_R_BM_LF,
+	  "82567LF-2 LAN Controller",
+	  WM_T_ICH10,		WMP_F_1000T },
+	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801J_D_BM_LM,
 	  "82567LM-3 LAN Controller",
 	  WM_T_ICH10,		WMP_F_1000T },
-	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82567LF_3,
+	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801J_D_BM_LF,
 	  "82567LF-3 LAN Controller",
 	  WM_T_ICH10,		WMP_F_1000T },
-	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801J_D_BM_LF,
-	  "i82801J (LF) LAN Controller",
+	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801J_R_BM_V,
+	  "82567V-2 LAN Controller",
 	  WM_T_ICH10,		WMP_F_1000T },
 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_PCH_M_LM,
 	  "PCH LAN (82578LM) Controller",
@@ -1570,7 +1584,7 @@
 	    || 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);
+		wm_gmii_mediainit(sc, wmp->wmp_product);
 	} else if (sc->sc_type < WM_T_82543 ||
 	    (CSR_READ(sc, WMREG_STATUS) & STATUS_TBIMODE) != 0) {
 		if (wmp->wmp_flags & WMP_F_1000T)
@@ -1581,7 +1595,7 @@
 		if (wmp->wmp_flags & WMP_F_1000X)
 			aprint_error_dev(sc->sc_dev,
 			    "WARNING: TBIMODE clear on 1000BASE-X product!\n");
-		wm_gmii_mediainit(sc);
+		wm_gmii_mediainit(sc, wmp->wmp_product);
 	}
 
 	ifp = &sc->sc_ethercom.ec_if;
@@ -3372,6 +3386,10 @@
 		break;
 	}
 
+	/* Reset the PHY. */
+	if (sc->sc_flags & WM_F_HAS_MII)
+		wm_gmii_reset(sc);
+
 	/* Initialize the transmit descriptor ring. */
 	memset(sc->sc_txdescs, 0, WM_TXDESCSIZE(sc));
 	WM_CDTXSYNC(sc, 0, WM_NTXDESC(sc),
@@ -4936,6 +4954,25 @@
 
 		if (sc->sc_type == WM_T_PCH) {
 			/* XXX Configure the LCD with the OEM bits in NVM */
+
+#if 1
+			/*
+			 * We shlould make the new driver for 8257[78] and
+			 * move these code into it.
+			 */
+#define HV_OEM_BITS	((0 << 5) | 25)
+#define HV_OEM_BITS_LPLU	(1 << 2)
+#define HV_OEM_BITS_A1KDIS	(1 << 6)
+#define HV_OEM_BITS_ANEGNOW	(1 << 10)
+#endif
+			/*
+			 * Disable LPLU.
+			 * XXX It seems that 82567 has LPLU, too.
+			 */
+			reg = wm_gmii_kv_readreg(sc->sc_dev, 1, HV_OEM_BITS);
+			reg &= ~(HV_OEM_BITS_A1KDIS| HV_OEM_BITS_LPLU);
+			reg |= HV_OEM_BITS_ANEGNOW;
+			wm_gmii_kv_writereg(sc->sc_dev, 1, HV_OEM_BITS, reg);
 		}
 		break;
 	default:
@@ -4950,7 +4987,7 @@
  *	Initialize media for use on 1000BASE-T devices.
  */
 static void
-wm_gmii_mediainit(struct wm_softc *sc)
+wm_gmii_mediainit(struct wm_softc *sc, pci_product_id_t prodid)
 {
 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 
@@ -4974,15 +5011,38 @@
 	/* Initialize our media structures and probe the GMII. */
 	sc->sc_mii.mii_ifp = ifp;
 
-	if (sc->sc_type >= WM_T_80003) {
-		sc->sc_mii.mii_readreg = wm_gmii_i80003_readreg;
-		sc->sc_mii.mii_writereg = wm_gmii_i80003_writereg;
-	} else if (sc->sc_type >= WM_T_82544) {
-		sc->sc_mii.mii_readreg = wm_gmii_i82544_readreg;
-		sc->sc_mii.mii_writereg = wm_gmii_i82544_writereg;
-	} else {
-		sc->sc_mii.mii_readreg = wm_gmii_i82543_readreg;
-		sc->sc_mii.mii_writereg = wm_gmii_i82543_writereg;
+	switch (prodid) {
+	case PCI_PRODUCT_INTEL_PCH_M_LM:
+	case PCI_PRODUCT_INTEL_PCH_M_LC:
+	case PCI_PRODUCT_INTEL_PCH_D_DM:
+	case PCI_PRODUCT_INTEL_PCH_D_DC:
+		/* 82577 or 82578 */
+		sc->sc_mii.mii_readreg = wm_gmii_kv_readreg;
+		sc->sc_mii.mii_writereg = wm_gmii_kv_writereg;
+		break;
+	case PCI_PRODUCT_INTEL_82801I_BM:
+	case PCI_PRODUCT_INTEL_82801J_R_BM_LM:
+	case PCI_PRODUCT_INTEL_82801J_R_BM_LF:
+	case PCI_PRODUCT_INTEL_82801J_D_BM_LM:
+	case PCI_PRODUCT_INTEL_82801J_D_BM_LF:
+	case PCI_PRODUCT_INTEL_82801J_R_BM_V:
+		/* 82567 */
+		sc->sc_mii.mii_readreg = wm_gmii_bm_readreg;
+		sc->sc_mii.mii_writereg = wm_gmii_bm_writereg;
+		break;
+	default:
+		if (sc->sc_type >= WM_T_80003) {
+			sc->sc_mii.mii_readreg = wm_gmii_i80003_readreg;
+			sc->sc_mii.mii_writereg = wm_gmii_i80003_writereg;
+		} else if (sc->sc_type >= WM_T_82544) {
+			sc->sc_mii.mii_readreg = wm_gmii_i82544_readreg;
+			sc->sc_mii.mii_writereg = wm_gmii_i82544_writereg;
+		} else {
+			sc->sc_mii.mii_readreg = wm_gmii_i82543_readreg;
+			sc->sc_mii.mii_writereg = wm_gmii_i82543_writereg;
+		}
+		break;
+		
 	}
 	sc->sc_mii.mii_statchg = wm_gmii_statchg;
 
@@ -5006,23 +5066,8 @@
 	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
 		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
 		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
-	} else {
-		if (sc->sc_type >= WM_T_82574) {
-			struct mii_softc *child;
-
-			child = LIST_FIRST(&sc->sc_mii.mii_phys);
-			/* fix read/write functions as e1000 driver */
-			if (device_is_a(child->mii_dev, "igphy")) {
-				sc->sc_mii.mii_readreg = wm_gmii_i80003_readreg;
-				sc->sc_mii.mii_writereg = wm_gmii_i80003_writereg;
-			} else {
-				sc->sc_mii.mii_readreg = wm_gmii_bm_readreg;
-				sc->sc_mii.mii_writereg = wm_gmii_bm_writereg;
-			}
-		}
-
+	} else
 		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
-	}
 }
 
 /*
@@ -5409,6 +5454,64 @@
 }
 
 /*
+ * wm_gmii_kv_readreg:	[mii interface function]
+ *
+ *	Read a PHY register on the kumeran
+ * This could be handled by the PHY layer if we didn't have to lock the
+ * ressource ...
+ */
+static int
+wm_gmii_kv_readreg(device_t self, int phy, int reg)
+{
+	struct wm_softc *sc = device_private(self);
+	int rv;
+
+	if (wm_get_swfw_semaphore(sc, SWFW_PHY0_SM)) {
+		aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
+		    __func__);
+		return 0;
+	}
+
+	if (reg > GG82563_MAX_REG_ADDRESS) {
+		printf("XXX rd pagesel\n");
+		wm_gmii_i82544_writereg(self, 1, MII_IGPHY_PAGE_SELECT,
+		    reg & IGPHY_PAGEMASK);
+	}
+
+	rv = wm_gmii_i82544_readreg(self, phy, reg & IGPHY_MAXREGADDR);
+	wm_put_swfw_semaphore(sc, SWFW_PHY0_SM);
+	return (rv);
+}
+
+/*
+ * wm_gmii_kv_writereg:	[mii interface function]
+ *
+ *	Write a PHY register on the kumeran.
+ * This could be handled by the PHY layer if we didn't have to lock the
+ * ressource ...
+ */
+static void
+wm_gmii_kv_writereg(device_t self, int phy, int reg, int val)
+{
+	struct wm_softc *sc = device_private(self);
+
+	if (wm_get_swfw_semaphore(sc, SWFW_PHY0_SM)) {
+		aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
+		    __func__);
+		return;
+	}
+
+	if (reg > GG82563_MAX_REG_ADDRESS) {
+		printf("XXX wr pagesel\n");
+		wm_gmii_i82544_writereg(self, 1, MII_IGPHY_PAGE_SELECT,
+		    reg & IGPHY_PAGEMASK);
+	}
+
+	wm_gmii_i82544_writereg(self, phy, reg & IGPHY_MAXREGADDR, val);
+	wm_put_swfw_semaphore(sc, SWFW_PHY0_SM);
+}
+
+/*
  * wm_gmii_statchg:	[mii interface function]
  *
  *	Callback from MII layer when media changes.

Index: src/sys/dev/pci/if_wmreg.h
diff -u src/sys/dev/pci/if_wmreg.h:1.33 src/sys/dev/pci/if_wmreg.h:1.34
--- src/sys/dev/pci/if_wmreg.h:1.33	Mon Jan 11 12:29:28 2010
+++ src/sys/dev/pci/if_wmreg.h	Tue Jan 12 22:26:30 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wmreg.h,v 1.33 2010/01/11 12:29:28 msaitoh Exp $	*/
+/*	$NetBSD: if_wmreg.h,v 1.34 2010/01/12 22:26:30 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -715,6 +715,8 @@
 #define EXTCNFCTR_EXT_CNF_POINTER	0x0FFF0000
 #define E1000_EXTCNF_CTRL_SWFLAG	EXTCNFCTR_MDIO_SW_OWNERSHIP
 
+#define	WMREG_PHY_CTRL	0x0f10	/* PHY control */
+
 /* ich8 flash control */
 #define ICH_FLASH_COMMAND_TIMEOUT            5000    /* 5000 uSecs - adjusted */
 #define ICH_FLASH_ERASE_TIMEOUT              3000000 /* Up to 3 seconds - worst case */

Reply via email to