svn commit: r201694 - stable/8/sys/dev/bge

Pyun YongHyeon yongari at FreeBSD.org
Wed Jan 6 23:34:54 UTC 2010


Author: yongari
Date: Wed Jan  6 23:34:53 2010
New Revision: 201694
URL: http://svn.freebsd.org/changeset/base/201694

Log:
  MFC 199663-199666
  
  r199663:
    Due to newly added PCIe capabilities fallback code for finding the
    PCIe capability did not work right on recent controllers. Remove
    FreeBSD 6.x support code.
  
  r199664:
    Use capability pointer to access PCIe registers rather than
    directly access them at fixed address. While I'm here don't touch
    other bits of PCIe device control register except max payload size.
  
  r199665:
    Controller does not write Rx descriptors, remove BUS_DMASYNC_PREREAD.
  
  r199666:
    Rearrange bge_start_locked to see we can send more frames by
    checking IFF_DRV_RUNNING and IFF_DRV_OACTIVE flags. Also if we
    have less than 16 free send BDs set IFF_DRV_OACTIVE and try it
    later. Previously bge(4) used to reserve 16 free send BDs after
    loading dma maps but hardware just need one reserved send BD. If
    prouder index has the same value of consumer index it means the Tx
    queue is empty.
    While I'm here check IFQ_DRV_IS_EMPTY first to save one lock
    operation.

Modified:
  stable/8/sys/dev/bge/if_bge.c
  stable/8/sys/dev/bge/if_bgereg.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/bge/if_bge.c
==============================================================================
--- stable/8/sys/dev/bge/if_bge.c	Wed Jan  6 23:28:39 2010	(r201693)
+++ stable/8/sys/dev/bge/if_bge.c	Wed Jan  6 23:34:53 2010	(r201694)
@@ -414,7 +414,7 @@ static uint32_t bge_readreg_ind(struct b
 #endif
 static void bge_writemem_direct(struct bge_softc *, int, int);
 static void bge_writereg_ind(struct bge_softc *, int, int);
-static void bge_set_max_readrq(struct bge_softc *, int);
+static void bge_set_max_readrq(struct bge_softc *);
 
 static int bge_miibus_readreg(device_t, int, int);
 static int bge_miibus_writereg(device_t, int, int, int);
@@ -558,25 +558,23 @@ bge_writemem_ind(struct bge_softc *sc, i
  * PCI Express only
  */
 static void
-bge_set_max_readrq(struct bge_softc *sc, int expr_ptr)
+bge_set_max_readrq(struct bge_softc *sc)
 {
 	device_t dev;
 	uint16_t val;
 
-	KASSERT((sc->bge_flags & BGE_FLAG_PCIE) && expr_ptr != 0,
-	    ("%s: not applicable", __func__));
-
 	dev = sc->bge_dev;
 
-	val = pci_read_config(dev, expr_ptr + BGE_PCIE_DEVCTL, 2);
-	if ((val & BGE_PCIE_DEVCTL_MAX_READRQ_MASK) !=
+	val = pci_read_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL, 2);
+	if ((val & PCIM_EXP_CTL_MAX_READ_REQUEST) !=
 	    BGE_PCIE_DEVCTL_MAX_READRQ_4096) {
 		if (bootverbose)
 			device_printf(dev, "adjust device control 0x%04x ",
 			    val);
-		val &= ~BGE_PCIE_DEVCTL_MAX_READRQ_MASK;
+		val &= ~PCIM_EXP_CTL_MAX_READ_REQUEST;
 		val |= BGE_PCIE_DEVCTL_MAX_READRQ_4096;
-		pci_write_config(dev, expr_ptr + BGE_PCIE_DEVCTL, val, 2);
+		pci_write_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL,
+		    val, 2);
 		if (bootverbose)
 			printf("-> 0x%04x\n", val);
 	}
@@ -1055,8 +1053,7 @@ bge_init_rx_ring_std(struct bge_softc *s
 	};
 
 	bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
-	    sc->bge_cdata.bge_rx_std_ring_map,
-	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+	    sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_PREWRITE);
 
 	sc->bge_std = i - 1;
 	bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
@@ -1099,8 +1096,7 @@ bge_init_rx_ring_jumbo(struct bge_softc 
 	};
 
 	bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
-	    sc->bge_cdata.bge_rx_jumbo_ring_map,
-	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+	    sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREWRITE);
 
 	sc->bge_jumbo = i - 1;
 
@@ -2413,7 +2409,6 @@ bge_dma_alloc(device_t dev)
 	return (0);
 }
 
-#if __FreeBSD_version > 602105
 /*
  * Return true if this device has more than one port.
  */
@@ -2462,7 +2457,6 @@ bge_can_use_msi(struct bge_softc *sc)
 	}
 	return (can_use_msi);
 }
-#endif
 
 static int
 bge_attach(device_t dev)
@@ -2471,7 +2465,7 @@ bge_attach(device_t dev)
 	struct bge_softc *sc;
 	uint32_t hwcfg = 0, misccfg;
 	u_char eaddr[ETHER_ADDR_LEN];
-	int error, reg, rid, trys;
+	int error, msicount, reg, rid, trys;
 
 	sc = device_get_softc(dev);
 	sc->bge_dev = dev;
@@ -2580,42 +2574,34 @@ bge_attach(device_t dev)
   	/*
 	 * Check if this is a PCI-X or PCI Express device.
   	 */
-#if __FreeBSD_version > 602101
 	if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
 		/*
 		 * Found a PCI Express capabilities register, this
 		 * must be a PCI Express device.
 		 */
-		if (reg != 0) {
-			sc->bge_flags |= BGE_FLAG_PCIE;
-#else
-	if (BGE_IS_5705_PLUS(sc)) {
-		reg = pci_read_config(dev, BGE_PCIE_CAPID_REG, 4);
-		if ((reg & 0xFF) == BGE_PCIE_CAPID) {
-			sc->bge_flags |= BGE_FLAG_PCIE;
-			reg = BGE_PCIE_CAPID;
-#endif
-			bge_set_max_readrq(sc, reg);
-		}
+		sc->bge_flags |= BGE_FLAG_PCIE;
+		sc->bge_expcap = reg;
+		bge_set_max_readrq(sc);
 	} else {
 		/*
 		 * Check if the device is in PCI-X Mode.
 		 * (This bit is not valid on PCI Express controllers.)
 		 */
+		if (pci_find_extcap(dev, PCIY_PCIX, &reg) == 0)
+			sc->bge_pcixcap = reg;
 		if ((pci_read_config(dev, BGE_PCI_PCISTATE, 4) &
 		    BGE_PCISTATE_PCI_BUSMODE) == 0)
 			sc->bge_flags |= BGE_FLAG_PCIX;
 	}
 
-#if __FreeBSD_version > 602105
-	{
-		int msicount;
-
-		/*
-		 * Allocate the interrupt, using MSI if possible.  These devices
-		 * support 8 MSI messages, but only the first one is used in
-		 * normal operation.
-		 */
+	/*
+	 * Allocate the interrupt, using MSI if possible.  These devices
+	 * support 8 MSI messages, but only the first one is used in
+	 * normal operation.
+	 */
+	rid = 0;
+	if (pci_find_extcap(sc->bge_dev, PCIY_MSI, &reg) != 0) {
+		sc->bge_msicap = reg;
 		if (bge_can_use_msi(sc)) {
 			msicount = pci_msi_count(dev);
 			if (msicount > 1)
@@ -2625,12 +2611,8 @@ bge_attach(device_t dev)
 		if (msicount == 1 && pci_alloc_msi(dev, &msicount) == 0) {
 			rid = 1;
 			sc->bge_flags |= BGE_FLAG_MSI;
-		} else
-			rid = 0;
+		}
 	}
-#else
-	rid = 0;
-#endif
 
 	sc->bge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
 	    RF_SHAREABLE | RF_ACTIVE);
@@ -2921,10 +2903,8 @@ bge_release_resources(struct bge_softc *
 		bus_release_resource(dev, SYS_RES_IRQ,
 		    sc->bge_flags & BGE_FLAG_MSI ? 1 : 0, sc->bge_irq);
 
-#if __FreeBSD_version > 602105
 	if (sc->bge_flags & BGE_FLAG_MSI)
 		pci_release_msi(dev);
-#endif
 
 	if (sc->bge_res != NULL)
 		bus_release_resource(dev, SYS_RES_MEMORY,
@@ -2945,6 +2925,7 @@ bge_reset(struct bge_softc *sc)
 	device_t dev;
 	uint32_t cachesize, command, pcistate, reset, val;
 	void (*write_op)(struct bge_softc *, int, int);
+	uint16_t devctl;
 	int i;
 
 	dev = sc->bge_dev;
@@ -3023,11 +3004,17 @@ bge_reset(struct bge_softc *sc)
 			val = pci_read_config(dev, 0xC4, 4);
 			pci_write_config(dev, 0xC4, val | (1 << 15), 4);
 		}
-		/*
-		 * Set PCIE max payload size to 128 bytes and clear error
-		 * status.
-		 */
-		pci_write_config(dev, 0xD8, 0xF5000, 4);
+		devctl = pci_read_config(dev,
+		    sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL, 2);
+		/* Clear enable no snoop and disable relaxed ordering. */
+		devctl &= ~(0x0010 | 0x0800);
+		/* Set PCIE max payload size to 128. */
+		devctl &= ~PCIM_EXP_CTL_MAX_PAYLOAD;
+		pci_write_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL,
+		    devctl, 2);
+		/* Clear error status. */
+		pci_write_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_STA,
+		    0, 2);
 	}
 
 	/* Reset some of the PCI state that got zapped by reset. */
@@ -3042,8 +3029,10 @@ bge_reset(struct bge_softc *sc)
 	if (BGE_IS_5714_FAMILY(sc)) {
 		/* This chip disables MSI on reset. */
 		if (sc->bge_flags & BGE_FLAG_MSI) {
-			val = pci_read_config(dev, BGE_PCI_MSI_CTL, 2);
-			pci_write_config(dev, BGE_PCI_MSI_CTL,
+			val = pci_read_config(dev,
+			    sc->bge_msicap + PCIR_MSI_CTRL, 2);
+			pci_write_config(dev,
+			    sc->bge_msicap + PCIR_MSI_CTRL,
 			    val | PCIM_MSICTRL_MSI_ENABLE, 2);
 			val = CSR_READ_4(sc, BGE_MSI_MODE);
 			CSR_WRITE_4(sc, BGE_MSI_MODE,
@@ -3694,11 +3683,8 @@ bge_encap(struct bge_softc *sc, struct m
 	} else if (error != 0)
 		return (error);
 
-	/*
-	 * Sanity check: avoid coming within 16 descriptors
-	 * of the end of the ring.
-	 */
-	if (nsegs > (BGE_TX_RING_CNT - sc->bge_txcnt - 16)) {
+	/* Check if we have enough free send BDs. */
+	if (sc->bge_txcnt + nsegs >= BGE_TX_RING_CNT) {
 		bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag, map);
 		return (ENOBUFS);
 	}
@@ -3763,18 +3749,25 @@ static void
 bge_start_locked(struct ifnet *ifp)
 {
 	struct bge_softc *sc;
-	struct mbuf *m_head = NULL;
+	struct mbuf *m_head;
 	uint32_t prodidx;
-	int count = 0;
+	int count;
 
 	sc = ifp->if_softc;
+	BGE_LOCK_ASSERT(sc);
 
-	if (!sc->bge_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+	if (!sc->bge_link ||
+	    (ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+	    IFF_DRV_RUNNING)
 		return;
 
 	prodidx = sc->bge_tx_prodidx;
 
-	while(sc->bge_cdata.bge_tx_chain[prodidx] == NULL) {
+	for (count = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd);) {
+		if (sc->bge_txcnt > BGE_TX_RING_CNT - 16) {
+			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+			break;
+		}
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
 		if (m_head == NULL)
 			break;
@@ -3827,24 +3820,22 @@ bge_start_locked(struct ifnet *ifp)
 #endif
 	}
 
-	if (count == 0)
-		/* No packets were dequeued. */
-		return;
-
-	bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
-	    sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE);
-	/* Transmit. */
-	bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
-	/* 5700 b2 errata */
-	if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
+	if (count > 0) {
+		bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
+		    sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE);
+		/* Transmit. */
 		bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
+		/* 5700 b2 errata */
+		if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
+			bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
 
-	sc->bge_tx_prodidx = prodidx;
+		sc->bge_tx_prodidx = prodidx;
 
-	/*
-	 * Set a timeout in case the chip goes out to lunch.
-	 */
-	sc->bge_timer = 5;
+		/*
+		 * Set a timeout in case the chip goes out to lunch.
+		 */
+		sc->bge_timer = 5;
+	}
 }
 
 /*

Modified: stable/8/sys/dev/bge/if_bgereg.h
==============================================================================
--- stable/8/sys/dev/bge/if_bgereg.h	Wed Jan  6 23:28:39 2010	(r201693)
+++ stable/8/sys/dev/bge/if_bgereg.h	Wed Jan  6 23:34:53 2010	(r201694)
@@ -2584,6 +2584,9 @@ struct bge_softc {
 	struct resource		*bge_irq;
 	struct resource		*bge_res;
 	struct ifmedia		bge_ifmedia;	/* TBI media info */
+	int			bge_expcap;
+	int			bge_msicap;
+	int			bge_pcixcap;
 	uint32_t		bge_flags;
 #define	BGE_FLAG_TBI		0x00000001
 #define	BGE_FLAG_JUMBO		0x00000002


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