Correct a performance bug from Bill Paul's original FreeBSD bge(4) driver:
Each call to the FreeBSD bge_start() routine the transmit producer pointer index from the chip mailbox register BGE_MBX_TX_HOST_PROD0_LO. The local copy of that value is then updated by bge_encap() as bge_encap() encapsulates packets in the Tx ring. If bge_encap() succeds in encpuslating one or more packets, bge_start() tells the chip to start sending the newly-encinitiates writes the new value back to the chip mailbox register. However, comparison of the Linux drivers (Broadcom-supplied and open-source tg3.c) and to the OpenSolaris driver confirms that register BGE_MBX_TX_HOST_PROD0_LO is write-only to software. Thus, we can just keep a copy in the softc, and eliminate the (expensive) PCI register write on each call to bge_start(). ``Make it so''.
This commit is contained in:
parent
483900aec9
commit
de85711ee1
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_bge.c,v 1.93 2005/09/06 15:42:21 tsarna Exp $ */
|
||||
/* $NetBSD: if_bge.c,v 1.94 2005/11/15 06:05:44 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Wind River Systems
|
||||
|
@ -79,7 +79,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.93 2005/09/06 15:42:21 tsarna Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.94 2005/11/15 06:05:44 jonathan Exp $");
|
||||
|
||||
#include "bpfilter.h"
|
||||
#include "vlan.h"
|
||||
|
@ -1128,10 +1128,14 @@ bge_init_tx_ring(sc)
|
|||
|
||||
sc->bge_txcnt = 0;
|
||||
sc->bge_tx_saved_considx = 0;
|
||||
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, 0);
|
||||
if (sc->bge_quirks & BGE_QUIRK_PRODUCER_BUG) /* 5700 b2 errata */
|
||||
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, 0);
|
||||
|
||||
/* Initialize transmit producer index for host-memory send ring. */
|
||||
sc->bge_tx_prodidx = 0;
|
||||
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
|
||||
if (sc->bge_quirks & BGE_QUIRK_PRODUCER_BUG) /* 5700 b2 errata */
|
||||
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
|
||||
|
||||
/* NIC-memory send ring not used; initialize to zero. */
|
||||
CSR_WRITE_4(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
|
||||
if (sc->bge_quirks & BGE_QUIRK_PRODUCER_BUG) /* 5700 b2 errata */
|
||||
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, 0);
|
||||
|
@ -3471,7 +3475,7 @@ bge_start(ifp)
|
|||
{
|
||||
struct bge_softc *sc;
|
||||
struct mbuf *m_head = NULL;
|
||||
u_int32_t prodidx = 0;
|
||||
u_int32_t prodidx;
|
||||
int pkts = 0;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
|
@ -3479,7 +3483,7 @@ bge_start(ifp)
|
|||
if (!sc->bge_link && ifp->if_snd.ifq_len < 10)
|
||||
return;
|
||||
|
||||
prodidx = CSR_READ_4(sc, BGE_MBX_TX_HOST_PROD0_LO);
|
||||
prodidx = sc->bge_tx_prodidx;
|
||||
|
||||
while(sc->bge_cdata.bge_tx_chain[prodidx] == NULL) {
|
||||
IFQ_POLL(&ifp->if_snd, m_head);
|
||||
|
@ -3536,6 +3540,8 @@ bge_start(ifp)
|
|||
if (sc->bge_quirks & BGE_QUIRK_PRODUCER_BUG) /* 5700 b2 errata */
|
||||
CSR_WRITE_4(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
|
||||
|
||||
sc->bge_tx_prodidx = prodidx;
|
||||
|
||||
/*
|
||||
* Set a timeout in case the chip goes out to lunch.
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_bgereg.h,v 1.26 2005/08/28 19:24:57 thorpej Exp $ */
|
||||
/* $NetBSD: if_bgereg.h,v 1.27 2005/11/15 06:05:44 jonathan Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Wind River Systems
|
||||
* Copyright (c) 1997, 1998, 1999, 2001
|
||||
|
@ -2326,6 +2326,7 @@ struct bge_softc {
|
|||
u_int8_t bge_rx_alignment_bug;
|
||||
u_int8_t bge_pcie; /* on a PCI Express port */
|
||||
u_int32_t bge_return_ring_cnt;
|
||||
u_int32_t bge_tx_prodidx;
|
||||
bus_dma_tag_t bge_dmatag;
|
||||
u_int32_t bge_chipid;
|
||||
u_int32_t bge_quirks;
|
||||
|
|
Loading…
Reference in New Issue