summaryrefslogtreecommitdiffstats
path: root/sys/dev/et
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2011-12-05 22:55:52 +0000
committeryongari <yongari@FreeBSD.org>2011-12-05 22:55:52 +0000
commit30ed24b5a9194e21eedb4b1a2652577d964fedcc (patch)
treee487182c93f59140b5acd4aac86389f4738eacd4 /sys/dev/et
parent382389d916d86cd17ad904aafc983bfc3f07d7f0 (diff)
downloadFreeBSD-src-30ed24b5a9194e21eedb4b1a2652577d964fedcc.zip
FreeBSD-src-30ed24b5a9194e21eedb4b1a2652577d964fedcc.tar.gz
Fix alt(4) support. Also add check for number of available TX
descriptors before trying to send frames. If we're not able to send a frame, make sure to prepend it to if_snd queue such that alt(4) should work. While I'm here prefer ETHER_BPF_MTAP to BPF_MTAP. ETHER_BPF_MTAP should be used for controllers that support VLAN hardware tag insertion. The controller supports VLAN tag insertion but lacks VLAN tag stripping in RX path though.
Diffstat (limited to 'sys/dev/et')
-rw-r--r--sys/dev/et/if_et.c40
1 files changed, 22 insertions, 18 deletions
diff --git a/sys/dev/et/if_et.c b/sys/dev/et/if_et.c
index 565eee3..8138d90 100644
--- a/sys/dev/et/if_et.c
+++ b/sys/dev/et/if_et.c
@@ -338,7 +338,8 @@ et_attach(device_t dev)
ifp->if_mtu = ETHERMTU;
ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_VLAN_MTU;
ifp->if_capenable = ifp->if_capabilities;
- IFQ_SET_MAXLEN(&ifp->if_snd, ET_TX_NDESC);
+ ifp->if_snd.ifq_drv_maxlen = ET_TX_NDESC - 1;
+ IFQ_SET_MAXLEN(&ifp->if_snd, ET_TX_NDESC - 1);
IFQ_SET_READY(&ifp->if_snd);
et_chip_attach(sc);
@@ -1257,12 +1258,13 @@ et_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
static void
et_start_locked(struct ifnet *ifp)
{
- struct et_softc *sc = ifp->if_softc;
+ struct et_softc *sc;
+ struct mbuf *m_head = NULL;
struct et_txbuf_data *tbd;
- int trans;
+ int enq;
+ sc = ifp->if_softc;
ET_LOCK_ASSERT(sc);
- tbd = &sc->sc_tx_data;
if ((sc->sc_flags & ET_FLAG_TXRX_ENABLED) == 0)
return;
@@ -1270,30 +1272,32 @@ et_start_locked(struct ifnet *ifp)
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING)
return;
- trans = 0;
- for (;;) {
- struct mbuf *m;
-
- if ((tbd->tbd_used + ET_NSEG_SPARE) > ET_TX_NDESC) {
+ tbd = &sc->sc_tx_data;
+ for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd); ) {
+ if (tbd->tbd_used + ET_NSEG_SPARE >= ET_TX_NDESC) {
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
- IFQ_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
+ if (m_head == NULL)
break;
- if (et_encap(sc, &m)) {
- ifp->if_oerrors++;
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ if (et_encap(sc, &m_head)) {
+ if (m_head == NULL) {
+ ifp->if_oerrors++;
+ break;
+ }
+ IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
+ if (tbd->tbd_used > 0)
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
- trans = 1;
-
- BPF_MTAP(ifp, m);
+ enq++;
+ ETHER_BPF_MTAP(ifp, m_head);
}
- if (trans)
+ if (enq > 0)
sc->watchdog_timer = 5;
}
OpenPOWER on IntegriCloud