Optim and Fix for mge driver:

- add missing rcvif in mbuf
- add missing ipacket stat
- remove uncessary mbuf copy on output path
- fix deadlock of the TX engine in case of error

Obtained from:	NETASQ
MFC after:	2 weeks
This commit is contained in:
Fabien Thomas 2014-07-07 08:22:39 +00:00
parent 99f8c067e6
commit b8fad6c0ef
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=268359

View File

@ -1140,6 +1140,8 @@ mge_intr_rx_locked(struct mge_softc *sc, int count)
mb->m_pkthdr.len -= 2;
mb->m_data += 2;
mb->m_pkthdr.rcvif = ifp;
mge_offload_process_frame(ifp, mb, status,
bufsize);
@ -1159,6 +1161,8 @@ mge_intr_rx_locked(struct mge_softc *sc, int count)
count -= 1;
}
ifp->if_ipackets += rx_npkts;
return (rx_npkts);
}
@ -1437,12 +1441,6 @@ mge_encap(struct mge_softc *sc, struct mbuf *m0)
ifp = sc->ifp;
/* Check for free descriptors */
if (sc->tx_desc_used_count + 1 >= MGE_TX_DESC_NUM) {
/* No free descriptors */
return (-1);
}
/* Fetch unused map */
desc_no = sc->tx_desc_curr;
dw = &sc->mge_tx_desc[desc_no];
@ -1451,9 +1449,16 @@ mge_encap(struct mge_softc *sc, struct mbuf *m0)
/* Create mapping in DMA memory */
error = bus_dmamap_load_mbuf_sg(sc->mge_tx_dtag, mapp, m0, segs, &nsegs,
BUS_DMA_NOWAIT);
if (error != 0 || nsegs != 1 ) {
if (error != 0) {
m_freem(m0);
return (error);
}
/* Only one segment is supported. */
if (nsegs != 1) {
bus_dmamap_unload(sc->mge_tx_dtag, mapp);
return ((error != 0) ? error : -1);
m_freem(m0);
return (-1);
}
bus_dmamap_sync(sc->mge_tx_dtag, mapp, BUS_DMASYNC_PREWRITE);
@ -1553,15 +1558,33 @@ mge_start_locked(struct ifnet *ifp)
if (m0 == NULL)
break;
mtmp = m_defrag(m0, M_NOWAIT);
if (mtmp)
m0 = mtmp;
if (m0->m_pkthdr.csum_flags & (CSUM_IP|CSUM_TCP|CSUM_UDP) ||
m0->m_flags & M_VLANTAG) {
if (M_WRITABLE(m0) == 0) {
mtmp = m_dup(m0, M_NOWAIT);
m_freem(m0);
if (mtmp == NULL)
continue;
m0 = mtmp;
}
}
/* The driver support only one DMA fragment. */
if (m0->m_next != NULL) {
mtmp = m_defrag(m0, M_NOWAIT);
if (mtmp)
m0 = mtmp;
}
if (mge_encap(sc, m0)) {
/* Check for free descriptors */
if (sc->tx_desc_used_count + 1 >= MGE_TX_DESC_NUM) {
IF_PREPEND(&ifp->if_snd, m0);
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
if (mge_encap(sc, m0) != 0)
break;
queued++;
BPF_MTAP(ifp, m0);
}