svn commit: r201840 - stable/8/sys/dev/vge

Pyun YongHyeon yongari at FreeBSD.org
Fri Jan 8 22:26:25 UTC 2010


Author: yongari
Date: Fri Jan  8 22:26:24 2010
New Revision: 201840
URL: http://svn.freebsd.org/changeset/base/201840

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/8/sys/dev/vge/if_vge.c
  stable/8/sys/dev/vge/if_vgevar.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/dev/vge/if_vge.c
==============================================================================
--- stable/8/sys/dev/vge/if_vge.c	Fri Jan  8 22:18:15 2010	(r201839)
+++ stable/8/sys/dev/vge/if_vge.c	Fri Jan  8 22:26:24 2010	(r201840)
@@ -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 */
@@ -353,7 +353,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);
@@ -389,7 +389,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);
@@ -582,27 +582,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);
 }
 
 /*
@@ -954,7 +939,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;
@@ -978,11 +963,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;
@@ -991,12 +993,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;
@@ -1030,8 +1057,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);
 
 	/*
@@ -1093,7 +1120,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);
@@ -1577,16 +1607,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))
@@ -1868,7 +1898,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;
@@ -2107,13 +2137,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/8/sys/dev/vge/if_vgevar.h
==============================================================================
--- stable/8/sys/dev/vge/if_vgevar.h	Fri Jan  8 22:18:15 2010	(r201839)
+++ stable/8/sys/dev/vge/if_vgevar.h	Fri Jan  8 22:26:24 2010	(r201840)
@@ -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;


More information about the svn-src-stable-8 mailing list