summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1996-09-22 11:48:54 +0000
committerdg <dg@FreeBSD.org>1996-09-22 11:48:54 +0000
commite461bbf70be1241a12b5a05c454e29cc5638b254 (patch)
tree3d415de9b7a301a16c7a3445ec17d6d6f63d3d9e /sys
parent68bee81cc1effa7158ee2b766d466ac4b6f5c26c (diff)
downloadFreeBSD-src-e461bbf70be1241a12b5a05c454e29cc5638b254.zip
FreeBSD-src-e461bbf70be1241a12b5a05c454e29cc5638b254.tar.gz
Fixed a bug with the management of the pointer to the first TxCB in the
ring that caused wrong things to happen sometimes. Doubled the number of transmit descriptors to 128 so that the internal FIFO in the NIC can be fully filled when dealing with small packets. Several minor performance improvements.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/fxp/if_fxp.c87
-rw-r--r--sys/pci/if_fxp.c87
2 files changed, 76 insertions, 98 deletions
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 7a4c452..7d6d646 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_fxp.c,v 1.17 1996/09/20 04:11:53 davidg Exp $
+ * $Id: if_fxp.c,v 1.18 1996/09/20 11:05:39 davidg Exp $
*/
/*
@@ -124,7 +124,7 @@ static u_char fxp_cb_config_template[] = {
0x0, 0x0
};
-static inline int fxp_scb_wait __P((struct fxp_csr *));
+static inline void fxp_scb_wait __P((struct fxp_csr *));
static char *fxp_probe __P((pcici_t, pcidi_t));
static void fxp_attach __P((pcici_t, int));
static void fxp_intr __P((void *));
@@ -160,7 +160,7 @@ static int tx_threshold = 64;
* of transmit buffers that can be chained in the CB list.
* This must be a power of two.
*/
-#define FXP_NTXCB 64
+#define FXP_NTXCB 128
/*
* TxCB list index mask. This is used to do list wrap-around.
@@ -188,14 +188,13 @@ static int tx_threshold = 64;
* Wait for the previous command to be accepted (but not necessarily
* completed).
*/
-static inline int
+static inline void
fxp_scb_wait(csr)
struct fxp_csr *csr;
{
int i = 10000;
while ((csr->scb_command & FXP_SCB_COMMAND_MASK) && --i);
- return (i);
}
/*
@@ -423,13 +422,11 @@ fxp_start(ifp)
txloop:
/*
- * See if a TxCB is available. If not, indicate this to the
- * outside world and exit.
+ * See if we're all filled up with buffers to transmit.
*/
- if (sc->tx_queued >= FXP_NTXCB) {
- ifp->if_flags |= IFF_OACTIVE;
+ if (sc->tx_queued >= FXP_NTXCB)
return;
- }
+
/*
* Grab a packet to transmit.
*/
@@ -490,6 +487,7 @@ tbdinit:
}
txp->tbd_number = segment;
+ txp->mb_head = mb_head;
/*
* Finish the initialization of this TxCB.
@@ -498,7 +496,6 @@ tbdinit:
txp->cb_command =
FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF | FXP_CB_COMMAND_S;
txp->tx_threshold = tx_threshold;
- txp->mb_head = mb_head;
/*
* Advance the end-of-list forward.
@@ -507,26 +504,24 @@ tbdinit:
sc->cbl_last = txp;
/*
- * If no packets were previously queued then advance the first
- * pointer to this TxCB.
+ * Advance the beginning of the list forward if there are
+ * no other packets queued (when nothing is queued, cbl_first
+ * sits on the last TxCB that was sent out)..
*/
- if (sc->tx_queued++ == 0) {
+ if (sc->tx_queued == 0)
sc->cbl_first = txp;
- }
- if (!fxp_scb_wait(csr)) {
+ sc->tx_queued++;
+
+ if (csr->scb_cus == FXP_SCB_CUS_SUSPENDED) {
+ fxp_scb_wait(csr);
+
/*
- * Hmmm, card has gone out to lunch
+ * Resume transmission.
*/
- fxp_init(ifp);
- goto txloop;
+ csr->scb_command = FXP_SCB_COMMAND_CU_RESUME;
}
- /*
- * Resume transmission if suspended.
- */
- csr->scb_command = FXP_SCB_COMMAND_CU_RESUME;
-
#if NBPFILTER > 0
/*
* Pass packet to bpf if there is a listener.
@@ -554,7 +549,7 @@ fxp_intr(arg)
struct fxp_softc *sc = arg;
struct fxp_csr *csr = sc->csr;
struct ifnet *ifp = &sc->arpcom.ac_if;
- u_char statack;
+ u_int8_t statack;
while ((statack = csr->scb_statack) != 0) {
/*
@@ -569,24 +564,18 @@ fxp_intr(arg)
struct fxp_cb_tx *txp;
for (txp = sc->cbl_first;
- (txp->cb_status & FXP_CB_STATUS_C) &&
- txp->mb_head != NULL;
+ (txp->cb_status & FXP_CB_STATUS_C) != 0;
txp = txp->next) {
- m_freem(txp->mb_head);
- txp->mb_head = NULL;
- sc->tx_queued--;
+ if (txp->mb_head != NULL) {
+ m_freem(txp->mb_head);
+ txp->mb_head = NULL;
+ sc->tx_queued--;
+ }
+ if (txp->cb_command & FXP_CB_COMMAND_S)
+ break;
}
sc->cbl_first = txp;
/*
- * We unconditionally clear IFF_OACTIVE since it
- * doesn't hurt to do so even if the tx queue is
- * still full - it will just get set again in
- * fxp_start(). If we get a CNA interrupt, it is
- * (almost?) certain that we've freed up space for
- * at least one more packet.
- */
- ifp->if_flags &= ~IFF_OACTIVE;
- /*
* Clear watchdog timer. It may or may not be set
* again in fxp_start().
*/
@@ -647,7 +636,7 @@ rcvloop:
if (statack & FXP_SCB_STATACK_RNR) {
struct fxp_csr *csr = sc->csr;
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_general = vtophys(sc->rfa_headm->m_ext.ext_buf);
csr->scb_command = FXP_SCB_COMMAND_RU_START;
}
@@ -703,7 +692,7 @@ fxp_stats_update(arg)
* writing scb_command in other parts of the driver.
*/
sc->csr->scb_command = FXP_SCB_COMMAND_CU_DUMPRESET;
- (void) fxp_scb_wait(sc->csr);
+ fxp_scb_wait(sc->csr);
} else {
/*
* A previous command is still waiting to be accepted.
@@ -831,13 +820,13 @@ fxp_init(ifp)
csr->scb_general = 0;
csr->scb_command = FXP_SCB_COMMAND_CU_BASE;
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_command = FXP_SCB_COMMAND_RU_BASE;
/*
* Initialize base of dump-stats buffer.
*/
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_general = vtophys(sc->fxp_stats);
csr->scb_command = FXP_SCB_COMMAND_CU_DUMP_ADR;
@@ -862,8 +851,8 @@ fxp_init(ifp)
cbp->rx_fifo_limit = 8; /* rx fifo threshold */
cbp->tx_fifo_limit = 0; /* tx fifo threshold */
cbp->adaptive_ifs = 0; /* (no) adaptive interframe spacing */
- cbp->rx_dma_bytecount = 0; /* (no) rx DMA max */
- cbp->tx_dma_bytecount = 0; /* (no) tx DMA max */
+ cbp->rx_dma_bytecount = 16; /* (no) rx DMA max */
+ cbp->tx_dma_bytecount = 16; /* (no) tx DMA max */
cbp->dma_bce = 1; /* (enable) dma max counters */
cbp->late_scb = 0; /* (don't) defer SCB update */
cbp->tno_int = 0; /* (disable) tx not okay interrupt */
@@ -892,7 +881,7 @@ fxp_init(ifp)
/*
* Start the config command/DMA.
*/
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_general = vtophys(cbp);
csr->scb_command = FXP_SCB_COMMAND_CU_START;
/* ...and wait for it to complete. */
@@ -912,7 +901,7 @@ fxp_init(ifp)
/*
* Start the IAS (Individual Address Setup) command/DMA.
*/
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_command = FXP_SCB_COMMAND_CU_START;
/* ...and wait for it to complete. */
while (!(cb_ias->cb_status & FXP_CB_STATUS_C));
@@ -938,13 +927,13 @@ fxp_init(ifp)
sc->cbl_first = sc->cbl_last = txp;
sc->tx_queued = 0;
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_command = FXP_SCB_COMMAND_CU_START;
/*
* Initialize receiver buffer area - RFA.
*/
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_general = vtophys(sc->rfa_headm->m_ext.ext_buf);
csr->scb_command = FXP_SCB_COMMAND_RU_START;
diff --git a/sys/pci/if_fxp.c b/sys/pci/if_fxp.c
index 7a4c452..7d6d646 100644
--- a/sys/pci/if_fxp.c
+++ b/sys/pci/if_fxp.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_fxp.c,v 1.17 1996/09/20 04:11:53 davidg Exp $
+ * $Id: if_fxp.c,v 1.18 1996/09/20 11:05:39 davidg Exp $
*/
/*
@@ -124,7 +124,7 @@ static u_char fxp_cb_config_template[] = {
0x0, 0x0
};
-static inline int fxp_scb_wait __P((struct fxp_csr *));
+static inline void fxp_scb_wait __P((struct fxp_csr *));
static char *fxp_probe __P((pcici_t, pcidi_t));
static void fxp_attach __P((pcici_t, int));
static void fxp_intr __P((void *));
@@ -160,7 +160,7 @@ static int tx_threshold = 64;
* of transmit buffers that can be chained in the CB list.
* This must be a power of two.
*/
-#define FXP_NTXCB 64
+#define FXP_NTXCB 128
/*
* TxCB list index mask. This is used to do list wrap-around.
@@ -188,14 +188,13 @@ static int tx_threshold = 64;
* Wait for the previous command to be accepted (but not necessarily
* completed).
*/
-static inline int
+static inline void
fxp_scb_wait(csr)
struct fxp_csr *csr;
{
int i = 10000;
while ((csr->scb_command & FXP_SCB_COMMAND_MASK) && --i);
- return (i);
}
/*
@@ -423,13 +422,11 @@ fxp_start(ifp)
txloop:
/*
- * See if a TxCB is available. If not, indicate this to the
- * outside world and exit.
+ * See if we're all filled up with buffers to transmit.
*/
- if (sc->tx_queued >= FXP_NTXCB) {
- ifp->if_flags |= IFF_OACTIVE;
+ if (sc->tx_queued >= FXP_NTXCB)
return;
- }
+
/*
* Grab a packet to transmit.
*/
@@ -490,6 +487,7 @@ tbdinit:
}
txp->tbd_number = segment;
+ txp->mb_head = mb_head;
/*
* Finish the initialization of this TxCB.
@@ -498,7 +496,6 @@ tbdinit:
txp->cb_command =
FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF | FXP_CB_COMMAND_S;
txp->tx_threshold = tx_threshold;
- txp->mb_head = mb_head;
/*
* Advance the end-of-list forward.
@@ -507,26 +504,24 @@ tbdinit:
sc->cbl_last = txp;
/*
- * If no packets were previously queued then advance the first
- * pointer to this TxCB.
+ * Advance the beginning of the list forward if there are
+ * no other packets queued (when nothing is queued, cbl_first
+ * sits on the last TxCB that was sent out)..
*/
- if (sc->tx_queued++ == 0) {
+ if (sc->tx_queued == 0)
sc->cbl_first = txp;
- }
- if (!fxp_scb_wait(csr)) {
+ sc->tx_queued++;
+
+ if (csr->scb_cus == FXP_SCB_CUS_SUSPENDED) {
+ fxp_scb_wait(csr);
+
/*
- * Hmmm, card has gone out to lunch
+ * Resume transmission.
*/
- fxp_init(ifp);
- goto txloop;
+ csr->scb_command = FXP_SCB_COMMAND_CU_RESUME;
}
- /*
- * Resume transmission if suspended.
- */
- csr->scb_command = FXP_SCB_COMMAND_CU_RESUME;
-
#if NBPFILTER > 0
/*
* Pass packet to bpf if there is a listener.
@@ -554,7 +549,7 @@ fxp_intr(arg)
struct fxp_softc *sc = arg;
struct fxp_csr *csr = sc->csr;
struct ifnet *ifp = &sc->arpcom.ac_if;
- u_char statack;
+ u_int8_t statack;
while ((statack = csr->scb_statack) != 0) {
/*
@@ -569,24 +564,18 @@ fxp_intr(arg)
struct fxp_cb_tx *txp;
for (txp = sc->cbl_first;
- (txp->cb_status & FXP_CB_STATUS_C) &&
- txp->mb_head != NULL;
+ (txp->cb_status & FXP_CB_STATUS_C) != 0;
txp = txp->next) {
- m_freem(txp->mb_head);
- txp->mb_head = NULL;
- sc->tx_queued--;
+ if (txp->mb_head != NULL) {
+ m_freem(txp->mb_head);
+ txp->mb_head = NULL;
+ sc->tx_queued--;
+ }
+ if (txp->cb_command & FXP_CB_COMMAND_S)
+ break;
}
sc->cbl_first = txp;
/*
- * We unconditionally clear IFF_OACTIVE since it
- * doesn't hurt to do so even if the tx queue is
- * still full - it will just get set again in
- * fxp_start(). If we get a CNA interrupt, it is
- * (almost?) certain that we've freed up space for
- * at least one more packet.
- */
- ifp->if_flags &= ~IFF_OACTIVE;
- /*
* Clear watchdog timer. It may or may not be set
* again in fxp_start().
*/
@@ -647,7 +636,7 @@ rcvloop:
if (statack & FXP_SCB_STATACK_RNR) {
struct fxp_csr *csr = sc->csr;
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_general = vtophys(sc->rfa_headm->m_ext.ext_buf);
csr->scb_command = FXP_SCB_COMMAND_RU_START;
}
@@ -703,7 +692,7 @@ fxp_stats_update(arg)
* writing scb_command in other parts of the driver.
*/
sc->csr->scb_command = FXP_SCB_COMMAND_CU_DUMPRESET;
- (void) fxp_scb_wait(sc->csr);
+ fxp_scb_wait(sc->csr);
} else {
/*
* A previous command is still waiting to be accepted.
@@ -831,13 +820,13 @@ fxp_init(ifp)
csr->scb_general = 0;
csr->scb_command = FXP_SCB_COMMAND_CU_BASE;
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_command = FXP_SCB_COMMAND_RU_BASE;
/*
* Initialize base of dump-stats buffer.
*/
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_general = vtophys(sc->fxp_stats);
csr->scb_command = FXP_SCB_COMMAND_CU_DUMP_ADR;
@@ -862,8 +851,8 @@ fxp_init(ifp)
cbp->rx_fifo_limit = 8; /* rx fifo threshold */
cbp->tx_fifo_limit = 0; /* tx fifo threshold */
cbp->adaptive_ifs = 0; /* (no) adaptive interframe spacing */
- cbp->rx_dma_bytecount = 0; /* (no) rx DMA max */
- cbp->tx_dma_bytecount = 0; /* (no) tx DMA max */
+ cbp->rx_dma_bytecount = 16; /* (no) rx DMA max */
+ cbp->tx_dma_bytecount = 16; /* (no) tx DMA max */
cbp->dma_bce = 1; /* (enable) dma max counters */
cbp->late_scb = 0; /* (don't) defer SCB update */
cbp->tno_int = 0; /* (disable) tx not okay interrupt */
@@ -892,7 +881,7 @@ fxp_init(ifp)
/*
* Start the config command/DMA.
*/
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_general = vtophys(cbp);
csr->scb_command = FXP_SCB_COMMAND_CU_START;
/* ...and wait for it to complete. */
@@ -912,7 +901,7 @@ fxp_init(ifp)
/*
* Start the IAS (Individual Address Setup) command/DMA.
*/
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_command = FXP_SCB_COMMAND_CU_START;
/* ...and wait for it to complete. */
while (!(cb_ias->cb_status & FXP_CB_STATUS_C));
@@ -938,13 +927,13 @@ fxp_init(ifp)
sc->cbl_first = sc->cbl_last = txp;
sc->tx_queued = 0;
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_command = FXP_SCB_COMMAND_CU_START;
/*
* Initialize receiver buffer area - RFA.
*/
- (void) fxp_scb_wait(csr);
+ fxp_scb_wait(csr);
csr->scb_general = vtophys(sc->rfa_headm->m_ext.ext_buf);
csr->scb_command = FXP_SCB_COMMAND_RU_START;
OpenPOWER on IntegriCloud