Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci - Add i82567LM-2 i82567LM-4 i82567V-3 LAN contro...



details:   https://anonhg.NetBSD.org/src/rev/8a962704a600
branches:  trunk
changeset: 750748:8a962704a600
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Tue Jan 12 22:26:30 2010 +0000

description:
- 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.

diffstat:

 sys/dev/pci/if_wm.c    |  175 ++++++++++++++++++++++++++++++++++++++----------
 sys/dev/pci/if_wmreg.h |    4 +-
 2 files changed, 142 insertions(+), 37 deletions(-)

diffs (294 lines):

diff -r 82c02448f573 -r 8a962704a600 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Tue Jan 12 22:11:13 2010 +0000
+++ b/sys/dev/pci/if_wm.c       Tue Jan 12 22:26:30 2010 +0000
@@ -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.
diff -r 82c02448f573 -r 8a962704a600 sys/dev/pci/if_wmreg.h
--- a/sys/dev/pci/if_wmreg.h    Tue Jan 12 22:11:13 2010 +0000
+++ b/sys/dev/pci/if_wmreg.h    Tue Jan 12 22:26:30 2010 +0000
@@ -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 */



Home | Main Index | Thread Index | Old Index