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:
jonathan 2005-11-15 06:05:44 +00:00
parent 483900aec9
commit de85711ee1
2 changed files with 15 additions and 8 deletions

View File

@ -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.
*/

View File

@ -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;