diff options
author | wpaul <wpaul@FreeBSD.org> | 2003-12-26 07:01:05 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2003-12-26 07:01:05 +0000 |
commit | 57cde0f9a725c266d83624b53174fd6d15564985 (patch) | |
tree | 369c2b936158e3011feb06fb0c987635f7c72b48 /sys/dev/if_ndis/if_ndis.c | |
parent | ebda8238cd6c308fee05639feb3a0614f972e7db (diff) | |
download | FreeBSD-src-57cde0f9a725c266d83624b53174fd6d15564985.zip FreeBSD-src-57cde0f9a725c266d83624b53174fd6d15564985.tar.gz |
Attempt to handle the status field in the ndis_packet oob area correctly.
For received packets, an status of NDIS_STATUS_RESOURCES means we need
to copy the packet data and return the ndis_packet to the driver immediatel.
NDIS_STATUS_SUCCESS means we get to hold onto the packet, but we have
to set the status to NDIS_STATUS_PENDING so the driver knows we're
going to hang onto it for a while.
For transmit packets, NDIS_STATUS_PENDING means the driver will
asynchronously return the packet to us via the ndis_txeof() routine,
and NDIS_STATUS_SUCCESS means the driver sent the frame, and NDIS
(i.e. the OS) retains ownership of the packet and can free it
right away.
Diffstat (limited to 'sys/dev/if_ndis/if_ndis.c')
-rw-r--r-- | sys/dev/if_ndis/if_ndis.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 6ee63b1..e9e756d 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -633,6 +633,21 @@ ndis_detach(dev) /* * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. + * + * When handling received NDIS packets, the 'status' field in the + * out-of-band portion of the ndis_packet has special meaning. In the + * most common case, the underlying NDIS driver will set this field + * to NDIS_STATUS_SUCCESS, which indicates that it's ok for us to + * take posession of it. We then change the status field to + * NDIS_STATUS_PENDING to tell the driver that we now own the packet, + * and that we will return it at some point in the future via the + * return packet handler. + * + * If the driver hands us a packet with a status of NDIS_STATUS_RESOURCES, + * this means the driver is running out of packet/buffer resources and + * wants to maintain ownership of the packet. In this case, we have to + * copy the packet data into local storage and let the driver keep the + * packet. */ __stdcall static void ndis_rxeof(adapter, packets, pktcnt) @@ -644,7 +659,7 @@ ndis_rxeof(adapter, packets, pktcnt) ndis_miniport_block *block; ndis_packet *p; struct ifnet *ifp; - struct mbuf *m0; + struct mbuf *m0, *m; int i; block = (ndis_miniport_block *)adapter; @@ -657,8 +672,18 @@ ndis_rxeof(adapter, packets, pktcnt) p->np_softc = sc; if (ndis_ptom(&m0, p)) { printf ("ndis%d: ptom failed\n", sc->ndis_unit); - ndis_return_packet(sc, p); + if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS) + ndis_return_packet(sc, p); } else { + if (p->np_oob.npo_status == NDIS_STATUS_RESOURCES) { + m = m_dup(m0, M_DONTWAIT); + m_freem(m0); + if (m == NULL) + ifp->if_ierrors++; + else + m0 = m; + } else + p->np_oob.npo_status = NDIS_STATUS_PENDING; m0->m_pkthdr.rcvif = ifp; ifp->if_ipackets++; (*ifp->if_input)(ifp, m0); |