aboutsummaryrefslogtreecommitdiff
path: root/sys/pci/if_fxp.c
diff options
context:
space:
mode:
authorDavid Greenman <dg@FreeBSD.org>1997-10-23 01:45:15 +0000
committerDavid Greenman <dg@FreeBSD.org>1997-10-23 01:45:15 +0000
commit483b9871ba6cd9c441171746ff84e2f15438c141 (patch)
treec8368bc85bf90cfb39c83584642f857f522248f8 /sys/pci/if_fxp.c
parent8b50620f9abf084b0c0289f9a10d6b278465c705 (diff)
downloadsrc-483b9871ba6cd9c441171746ff84e2f15438c141.tar.gz
src-483b9871ba6cd9c441171746ff84e2f15438c141.zip
Rewrote fxp_start() for better clarity and efficiency.
Notes
Notes: svn path=/head/; revision=30655
Diffstat (limited to 'sys/pci/if_fxp.c')
-rw-r--r--sys/pci/if_fxp.c202
1 files changed, 101 insertions, 101 deletions
diff --git a/sys/pci/if_fxp.c b/sys/pci/if_fxp.c
index e974f9d19451..43f03bcb49fa 100644
--- a/sys/pci/if_fxp.c
+++ b/sys/pci/if_fxp.c
@@ -27,7 +27,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_fxp.c,v 1.43 1997/09/30 11:28:24 davidg Exp $
+ * $Id: if_fxp.c,v 1.44 1997/10/17 06:27:44 davidg Exp $
*/
/*
@@ -388,6 +388,10 @@ fxp_attach(parent, self, aux)
* Attach the interface.
*/
if_attach(ifp);
+ /*
+ * Let the system queue as many packets as we have TX descriptors.
+ */
+ ifp->if_snd.ifq_maxlen = FXP_NTXCB;
ether_ifattach(ifp, enaddr);
#if NBPFILTER > 0
bpfattach(&sc->sc_ethercom.ec_if.if_bpf, ifp, DLT_EN10MB,
@@ -556,6 +560,10 @@ fxp_attach(config_id, unit)
* Attach the interface.
*/
if_attach(ifp);
+ /*
+ * Let the system queue as many packets as we have TX descriptors.
+ */
+ ifp->if_snd.ifq_maxlen = FXP_NTXCB;
ether_ifattach(ifp);
#if NBPFILTER > 0
bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
@@ -770,133 +778,125 @@ fxp_start(ifp)
{
struct fxp_softc *sc = ifp->if_softc;
struct fxp_cb_tx *txp;
- struct mbuf *m, *mb_head;
- int segment, first = 1;
-txloop:
/*
- * See if we're all filled up with buffers to transmit, or
- * if we need to suspend xmit until the multicast filter
- * has been reprogrammed (which can only be done at the
- * head of the command chain).
+ * See if we need to suspend xmit until the multicast filter
+ * has been reprogrammed (which can only be done at the head
+ * of the command chain).
*/
- if (sc->tx_queued >= FXP_NTXCB || sc->need_mcsetup)
+ if (sc->need_mcsetup)
return;
+ txp = NULL;
+
/*
- * Grab a packet to transmit.
+ * We're finished if there is nothing more to add to the list or if
+ * we're all filled up with buffers to transmit.
*/
- IF_DEQUEUE(&ifp->if_snd, mb_head);
- if (mb_head == NULL) {
+ while (ifp->if_snd.ifq_head != NULL && sc->tx_queued < FXP_NTXCB) {
+ struct mbuf *m, *mb_head;
+ int segment;
+
/*
- * No more packets to send.
+ * Grab a packet to transmit.
*/
- return;
- }
+ IF_DEQUEUE(&ifp->if_snd, mb_head);
- /*
- * Get pointer to next available (unused) descriptor.
- */
- txp = sc->cbl_last->next;
-
- /*
- * Go through each of the mbufs in the chain and initialize
- * the transmit buffers descriptors with the physical address
- * and size of the mbuf.
- */
-tbdinit:
- for (m = mb_head, segment = 0; m != NULL; m = m->m_next) {
- if (m->m_len != 0) {
- if (segment == FXP_NTXSEG)
- break;
- txp->tbd[segment].tb_addr =
- vtophys(mtod(m, vm_offset_t));
- txp->tbd[segment].tb_size = m->m_len;
- segment++;
- }
- }
- if (m != NULL) {
- struct mbuf *mn;
+ /*
+ * Get pointer to next available tx desc.
+ */
+ txp = sc->cbl_last->next;
/*
- * We ran out of segments. We have to recopy this mbuf
- * chain first.
+ * Go through each of the mbufs in the chain and initialize
+ * the transmit buffer descriptors with the physical address
+ * and size of the mbuf.
*/
- MGETHDR(mn, M_DONTWAIT, MT_DATA);
- if (mn == NULL) {
- m_freem(mb_head);
- return;
+tbdinit:
+ for (m = mb_head, segment = 0; m != NULL; m = m->m_next) {
+ if (m->m_len != 0) {
+ if (segment == FXP_NTXSEG)
+ break;
+ txp->tbd[segment].tb_addr =
+ vtophys(mtod(m, vm_offset_t));
+ txp->tbd[segment].tb_size = m->m_len;
+ segment++;
+ }
}
- if (mb_head->m_pkthdr.len > MHLEN) {
- MCLGET(mn, M_DONTWAIT);
- if ((mn->m_flags & M_EXT) == 0) {
- m_freem(mn);
+ if (m != NULL) {
+ struct mbuf *mn;
+
+ /*
+ * We ran out of segments. We have to recopy this mbuf
+ * chain first. Bail out if we can't get the new buffers.
+ */
+ MGETHDR(mn, M_DONTWAIT, MT_DATA);
+ if (mn == NULL) {
m_freem(mb_head);
- return;
+ break;
}
+ if (mb_head->m_pkthdr.len > MHLEN) {
+ MCLGET(mn, M_DONTWAIT);
+ if ((mn->m_flags & M_EXT) == 0) {
+ m_freem(mn);
+ m_freem(mb_head);
+ break;
+ }
+ }
+ m_copydata(mb_head, 0, mb_head->m_pkthdr.len,
+ mtod(mn, caddr_t));
+ mn->m_pkthdr.len = mn->m_len = mb_head->m_pkthdr.len;
+ m_freem(mb_head);
+ mb_head = mn;
+ goto tbdinit;
}
- m_copydata(mb_head, 0, mb_head->m_pkthdr.len,
- mtod(mn, caddr_t));
- mn->m_pkthdr.len = mn->m_len = mb_head->m_pkthdr.len;
- m_freem(mb_head);
- mb_head = mn;
- goto tbdinit;
- }
- txp->tbd_number = segment;
- txp->mb_head = mb_head;
-
- /*
- * Finish the initialization of this TxCB.
- */
- txp->cb_status = 0;
- txp->cb_command =
- FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF | FXP_CB_COMMAND_S;
- txp->tx_threshold = tx_threshold;
+ txp->tbd_number = segment;
+ txp->mb_head = mb_head;
+ txp->cb_status = 0;
+ txp->cb_command =
+ FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF | FXP_CB_COMMAND_S;
+ txp->tx_threshold = tx_threshold;
- /*
- * Advance the end-of-list forward.
- */
- sc->cbl_last->cb_command &= ~FXP_CB_COMMAND_S;
- sc->cbl_last = txp;
-
- /*
- * 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)
- sc->cbl_first = txp;
-
- sc->tx_queued++;
+ /*
+ * Advance the end of list forward.
+ */
+ sc->cbl_last->cb_command &= ~FXP_CB_COMMAND_S;
+ sc->cbl_last = txp;
- /*
- * Only need to wait prior to the first resume command.
- */
- if (first) {
- first--;
- fxp_scb_wait(sc);
- }
+ /*
+ * 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)
+ sc->cbl_first = txp;
- /*
- * Resume transmission if suspended.
- */
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_RESUME);
+ sc->tx_queued++;
#if NBPFILTER > 0
- /*
- * Pass packet to bpf if there is a listener.
- */
- if (ifp->if_bpf)
- bpf_mtap(FXP_BPFTAP_ARG(ifp), mb_head);
+ /*
+ * Pass packet to bpf if there is a listener.
+ */
+ if (ifp->if_bpf)
+ bpf_mtap(FXP_BPFTAP_ARG(ifp), mb_head);
#endif
+ }
+
/*
- * Set a 5 second timer just in case we don't hear from the
- * card again.
+ * We're finished. If we added to the list, issue a RESUME to get DMA
+ * going again if suspended.
*/
- ifp->if_timer = 5;
+ if (txp != NULL) {
+ fxp_scb_wait(sc);
+ CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_RESUME);
- goto txloop;
+ /*
+ * Set a 5 second timer just in case we don't hear from the
+ * card again.
+ */
+ ifp->if_timer = 5;
+ }
}
/*