Author: yongari
Date: Fri Jan  8 22:28:54 2010
New Revision: 201841
URL: http://svn.freebsd.org/changeset/base/201841

Log:
  MFC r200538,200540-200541,200543,200545,200548
  
  r200538:
    Introduce vge_flags member in softc. The vge_flags member will
    record device specific bits. Remove vge_link and use vge_flags.
    While here, move clearing link state before mii_mediachg() as
    mii_mediachg() may affect link state.
  
  r200540:
    Save PHY address by reading VGE_MIICFG register. For PCIe
    controllers(VT613x), we assume the PHY address is 1.
    Use the saved PHY address in MII register access routines and
    remove accessing VGE_MIICFG register.
    While I'm here save PCI express capability register which will be
    used in near future.
  
  r200541:
    Add MSI support for VT613x controllers.
  
  r200543:
    Increase output queue size from 64 to 255.
  
  r200545:
    We don't have to reload EEPROM in vge_reset(). Because vge_reset()
    is called in vge_init_lock(), vge(4) always used to reload EEPROM.
    Also add more comment why vge(4) clears VGE_CHIPCFG0_PACPI bit.
    While I'm here add missing new line in vge_reset().
  
  r200548:
    Sort function prototyes.

Modified:
  stable/7/sys/dev/vge/if_vge.c
  stable/7/sys/dev/vge/if_vgevar.h
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/vge/if_vge.c
==============================================================================
--- stable/7/sys/dev/vge/if_vge.c       Fri Jan  8 22:26:24 2010        
(r201840)
+++ stable/7/sys/dev/vge/if_vge.c       Fri Jan  8 22:28:54 2010        
(r201841)
@@ -127,6 +127,10 @@ MODULE_DEPEND(vge, miibus, 1, 1, 1);
 
 #define VGE_CSUM_FEATURES    (CSUM_IP | CSUM_TCP | CSUM_UDP)
 
+/* Tunables */
+static int msi_disable = 0;
+TUNABLE_INT("hw.vge.msi_disable", &msi_disable);
+
 /*
  * Various supported device vendors/types and their names.
  */
@@ -136,56 +140,52 @@ static struct vge_type vge_devs[] = {
        { 0, 0, NULL }
 };
 
-static int vge_probe           (device_t);
-static int vge_attach          (device_t);
-static int vge_detach          (device_t);
-
-static int vge_encap           (struct vge_softc *, struct mbuf **);
-
-static void vge_dmamap_cb      (void *, bus_dma_segment_t *, int, int);
-static int vge_dma_alloc       (struct vge_softc *);
-static void vge_dma_free       (struct vge_softc *);
-static void vge_discard_rxbuf  (struct vge_softc *, int);
-static int vge_newbuf          (struct vge_softc *, int);
-static int vge_rx_list_init    (struct vge_softc *);
-static int vge_tx_list_init    (struct vge_softc *);
-static void vge_freebufs       (struct vge_softc *);
-#ifndef __NO_STRICT_ALIGNMENT
-static __inline void vge_fixup_rx
-                               (struct mbuf *);
-#endif
-static int vge_rxeof           (struct vge_softc *, int);
-static void vge_txeof          (struct vge_softc *);
-static void vge_intr           (void *);
-static void vge_tick           (void *);
-static void vge_start          (struct ifnet *);
-static void vge_start_locked   (struct ifnet *);
-static int vge_ioctl           (struct ifnet *, u_long, caddr_t);
-static void vge_init           (void *);
-static void vge_init_locked    (struct vge_softc *);
-static void vge_stop           (struct vge_softc *);
-static void vge_watchdog       (void *);
-static int vge_suspend         (device_t);
-static int vge_resume          (device_t);
-static int vge_shutdown                (device_t);
-static int vge_ifmedia_upd     (struct ifnet *);
-static void vge_ifmedia_sts    (struct ifnet *, struct ifmediareq *);
-
+static int     vge_attach(device_t);
+static int     vge_detach(device_t);
+static int     vge_probe(device_t);
+static int     vge_resume(device_t);
+static int     vge_shutdown(device_t);
+static int     vge_suspend(device_t);
+
+static void    vge_cam_clear(struct vge_softc *);
+static int     vge_cam_set(struct vge_softc *, uint8_t *);
+static void    vge_discard_rxbuf(struct vge_softc *, int);
+static int     vge_dma_alloc(struct vge_softc *);
+static void    vge_dma_free(struct vge_softc *);
+static void    vge_dmamap_cb(void *, bus_dma_segment_t *, int, int);
 #ifdef VGE_EEPROM
-static void vge_eeprom_getword (struct vge_softc *, int, uint16_t *);
+static void    vge_eeprom_getword(struct vge_softc *, int, uint16_t *);
 #endif
-static void vge_read_eeprom    (struct vge_softc *, caddr_t, int, int, int);
-
-static void vge_miipoll_start  (struct vge_softc *);
-static void vge_miipoll_stop   (struct vge_softc *);
-static int vge_miibus_readreg  (device_t, int, int);
-static int vge_miibus_writereg (device_t, int, int, int);
-static void vge_miibus_statchg (device_t);
-
-static void vge_cam_clear      (struct vge_softc *);
-static int vge_cam_set         (struct vge_softc *, uint8_t *);
-static void vge_setmulti       (struct vge_softc *);
-static void vge_reset          (struct vge_softc *);
+static int     vge_encap(struct vge_softc *, struct mbuf **);
+#ifndef __NO_STRICT_ALIGNMENT
+static __inline void
+               vge_fixup_rx(struct mbuf *);
+#endif
+static void    vge_freebufs(struct vge_softc *);
+static void    vge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+static int     vge_ifmedia_upd(struct ifnet *);
+static void    vge_init(void *);
+static void    vge_init_locked(struct vge_softc *);
+static void    vge_intr(void *);
+static int     vge_ioctl(struct ifnet *, u_long, caddr_t);
+static int     vge_miibus_readreg(device_t, int, int);
+static void    vge_miibus_statchg(device_t);
+static int     vge_miibus_writereg(device_t, int, int, int);
+static void    vge_miipoll_start(struct vge_softc *);
+static void    vge_miipoll_stop(struct vge_softc *);
+static int     vge_newbuf(struct vge_softc *, int);
+static void    vge_read_eeprom(struct vge_softc *, caddr_t, int, int, int);
+static void    vge_reset(struct vge_softc *);
+static int     vge_rx_list_init(struct vge_softc *);
+static int     vge_rxeof(struct vge_softc *, int);
+static void    vge_setmulti(struct vge_softc *);
+static void    vge_start(struct ifnet *);
+static void    vge_start_locked(struct ifnet *);
+static void    vge_stop(struct vge_softc *);
+static void    vge_tick(void *);
+static int     vge_tx_list_init(struct vge_softc *);
+static void    vge_txeof(struct vge_softc *);
+static void    vge_watchdog(void *);
 
 static device_method_t vge_methods[] = {
        /* Device interface */
@@ -354,7 +354,7 @@ vge_miibus_readreg(device_t dev, int phy
 
        sc = device_get_softc(dev);
 
-       if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
+       if (phy != sc->vge_phyaddr)
                return (0);
 
        vge_miipoll_stop(sc);
@@ -390,7 +390,7 @@ vge_miibus_writereg(device_t dev, int ph
 
        sc = device_get_softc(dev);
 
-       if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
+       if (phy != sc->vge_phyaddr)
                return (0);
 
        vge_miipoll_stop(sc);
@@ -583,27 +583,12 @@ vge_reset(struct vge_softc *sc)
        }
 
        if (i == VGE_TIMEOUT) {
-               device_printf(sc->vge_dev, "soft reset timed out");
+               device_printf(sc->vge_dev, "soft reset timed out\n");
                CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_STOP_FORCE);
                DELAY(2000);
        }
 
        DELAY(5000);
-
-       CSR_SETBIT_1(sc, VGE_EECSR, VGE_EECSR_RELOAD);
-
-       for (i = 0; i < VGE_TIMEOUT; i++) {
-               DELAY(5);
-               if ((CSR_READ_1(sc, VGE_EECSR) & VGE_EECSR_RELOAD) == 0)
-                       break;
-       }
-
-       if (i == VGE_TIMEOUT) {
-               device_printf(sc->vge_dev, "EEPROM reload timed out\n");
-               return;
-       }
-
-       CSR_CLRBIT_1(sc, VGE_CHIPCFG0, VGE_CHIPCFG0_PACPI);
 }
 
 /*
@@ -957,7 +942,7 @@ vge_attach(device_t dev)
        u_char eaddr[ETHER_ADDR_LEN];
        struct vge_softc *sc;
        struct ifnet *ifp;
-       int error = 0, rid;
+       int error = 0, cap, i, msic, rid;
 
        sc = device_get_softc(dev);
        sc->vge_dev = dev;
@@ -981,11 +966,28 @@ vge_attach(device_t dev)
                goto fail;
        }
 
-       /* Allocate interrupt */
+       if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) == 0) {
+               sc->vge_flags |= VGE_FLAG_PCIE;
+               sc->vge_expcap = cap;
+       }
        rid = 0;
-       sc->vge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
-           RF_SHAREABLE | RF_ACTIVE);
+       msic = pci_msi_count(dev);
+       if (msi_disable == 0 && msic > 0) {
+               msic = 1;
+               if (pci_alloc_msi(dev, &msic) == 0) {
+                       if (msic == 1) {
+                               sc->vge_flags |= VGE_FLAG_MSI;
+                               device_printf(dev, "Using %d MSI message\n",
+                                   msic);
+                               rid = 1;
+                       } else
+                               pci_release_msi(dev);
+               }
+       }
 
+       /* Allocate interrupt */
+       sc->vge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+           ((sc->vge_flags & VGE_FLAG_MSI) ? 0 : RF_SHAREABLE) | RF_ACTIVE);
        if (sc->vge_irq == NULL) {
                device_printf(dev, "couldn't map interrupt\n");
                error = ENXIO;
@@ -994,12 +996,37 @@ vge_attach(device_t dev)
 
        /* Reset the adapter. */
        vge_reset(sc);
+       /* Reload EEPROM. */
+       CSR_WRITE_1(sc, VGE_EECSR, VGE_EECSR_RELOAD);
+       for (i = 0; i < VGE_TIMEOUT; i++) {
+               DELAY(5);
+               if ((CSR_READ_1(sc, VGE_EECSR) & VGE_EECSR_RELOAD) == 0)
+                       break;
+       }
+       if (i == VGE_TIMEOUT)
+               device_printf(dev, "EEPROM reload timed out\n");
+       /*
+        * Clear PACPI as EEPROM reload will set the bit. Otherwise
+        * MAC will receive magic packet which in turn confuses
+        * controller.
+        */
+       CSR_CLRBIT_1(sc, VGE_CHIPCFG0, VGE_CHIPCFG0_PACPI);
 
        /*
         * Get station address from the EEPROM.
         */
        vge_read_eeprom(sc, (caddr_t)eaddr, VGE_EE_EADDR, 3, 0);
-
+       /*
+        * Save configured PHY address.
+        * It seems the PHY address of PCIe controllers just
+        * reflects media jump strapping status so we assume the
+        * internal PHY address of PCIe controller is at 1.
+        */
+       if ((sc->vge_flags & VGE_FLAG_PCIE) != 0)
+               sc->vge_phyaddr = 1;
+       else
+               sc->vge_phyaddr = CSR_READ_1(sc, VGE_MIICFG) &
+                   VGE_MIICFG_PHYADDR;
        error = vge_dma_alloc(sc);
        if (error)
                goto fail;
@@ -1033,8 +1060,8 @@ vge_attach(device_t dev)
        ifp->if_capabilities |= IFCAP_POLLING;
 #endif
        ifp->if_init = vge_init;
-       IFQ_SET_MAXLEN(&ifp->if_snd, VGE_IFQ_MAXLEN);
-       ifp->if_snd.ifq_drv_maxlen = VGE_IFQ_MAXLEN;
+       IFQ_SET_MAXLEN(&ifp->if_snd, VGE_TX_DESC_CNT - 1);
+       ifp->if_snd.ifq_drv_maxlen = VGE_TX_DESC_CNT - 1;
        IFQ_SET_READY(&ifp->if_snd);
 
        /*
@@ -1096,7 +1123,10 @@ vge_detach(device_t dev)
        if (sc->vge_intrhand)
                bus_teardown_intr(dev, sc->vge_irq, sc->vge_intrhand);
        if (sc->vge_irq)
-               bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vge_irq);
+               bus_release_resource(dev, SYS_RES_IRQ,
+                   sc->vge_flags & VGE_FLAG_MSI ? 1 : 0, sc->vge_irq);
+       if (sc->vge_flags & VGE_FLAG_MSI)
+               pci_release_msi(dev);
        if (sc->vge_res)
                bus_release_resource(dev, SYS_RES_MEMORY,
                    PCIR_BAR(1), sc->vge_res);
@@ -1580,16 +1610,16 @@ vge_tick(void *xsc)
        mii = device_get_softc(sc->vge_miibus);
 
        mii_tick(mii);
-       if (sc->vge_link) {
+       if ((sc->vge_flags & VGE_FLAG_LINK) != 0) {
                if (!(mii->mii_media_status & IFM_ACTIVE)) {
-                       sc->vge_link = 0;
+                       sc->vge_flags &= ~VGE_FLAG_LINK;
                        if_link_state_change(sc->vge_ifp,
                            LINK_STATE_DOWN);
                }
        } else {
                if (mii->mii_media_status & IFM_ACTIVE &&
                    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
-                       sc->vge_link = 1;
+                       sc->vge_flags |= VGE_FLAG_LINK;
                        if_link_state_change(sc->vge_ifp,
                            LINK_STATE_UP);
                        if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
@@ -1869,7 +1899,7 @@ vge_start_locked(struct ifnet *ifp)
 
        VGE_LOCK_ASSERT(sc);
 
-       if (sc->vge_link == 0 ||
+       if ((sc->vge_flags & VGE_FLAG_LINK) == 0 ||
            (ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
            IFF_DRV_RUNNING)
                return;
@@ -2108,13 +2138,12 @@ vge_init_locked(struct vge_softc *sc)
                CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK);
        }
 
+       sc->vge_flags &= ~VGE_FLAG_LINK;
        mii_mediachg(mii);
 
        ifp->if_drv_flags |= IFF_DRV_RUNNING;
        ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
        callout_reset(&sc->vge_watchdog, hz, vge_watchdog, sc);
-
-       sc->vge_link = 0;
 }
 
 /*

Modified: stable/7/sys/dev/vge/if_vgevar.h
==============================================================================
--- stable/7/sys/dev/vge/if_vgevar.h    Fri Jan  8 22:26:24 2010        
(r201840)
+++ stable/7/sys/dev/vge/if_vgevar.h    Fri Jan  8 22:28:54 2010        
(r201841)
@@ -34,8 +34,6 @@
 
 #define VGE_JUMBO_MTU  9000
 
-#define VGE_IFQ_MAXLEN 64
-
 #define VGE_TX_DESC_CNT                256
 #define VGE_RX_DESC_CNT                252     /* Must be a multiple of 4!! */
 #define VGE_TX_RING_ALIGN      64
@@ -141,7 +139,12 @@ struct vge_softc {
        device_t                vge_miibus;
        uint8_t                 vge_type;
        int                     vge_if_flags;
-       int                     vge_link;
+       int                     vge_phyaddr;
+       int                     vge_flags;
+#define        VGE_FLAG_PCIE           0x0001
+#define        VGE_FLAG_MSI            0x0002
+#define        VGE_FLAG_LINK           0x8000
+       int                     vge_expcap;
        int                     vge_camidx;
        struct mtx              vge_mtx;
        struct callout          vge_watchdog;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to