aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/ndis/kern_ndis.c
diff options
context:
space:
mode:
authorBill Paul <wpaul@FreeBSD.org>2003-12-26 07:01:05 +0000
committerBill Paul <wpaul@FreeBSD.org>2003-12-26 07:01:05 +0000
commitca989c99d0898615bbca549246bd3c7630f2f6e6 (patch)
tree369c2b936158e3011feb06fb0c987635f7c72b48 /sys/compat/ndis/kern_ndis.c
parentba49ba35a6d4ceebfa1b35fe235d5f3e0098b227 (diff)
downloadsrc-ca989c99d0898615bbca549246bd3c7630f2f6e6.tar.gz
src-ca989c99d0898615bbca549246bd3c7630f2f6e6.zip
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.
Notes
Notes: svn path=/head/; revision=123858
Diffstat (limited to 'sys/compat/ndis/kern_ndis.c')
-rw-r--r--sys/compat/ndis/kern_ndis.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c
index 76a49d70e6ba..c88ea309eb3d 100644
--- a/sys/compat/ndis/kern_ndis.c
+++ b/sys/compat/ndis/kern_ndis.c
@@ -352,10 +352,9 @@ ndis_return_packet(buf, arg)
sc = p->np_softc;
returnfunc = sc->ndis_chars.nmc_return_packet_func;
adapter = sc->ndis_block.nmb_miniportadapterctx;
- if (returnfunc == NULL)
- ndis_free_packet(p);
- else
+ if (returnfunc != NULL)
returnfunc(adapter, p);
+
return;
}
@@ -654,12 +653,37 @@ ndis_send_packets(arg, packets, cnt)
struct ndis_softc *sc;
ndis_handle adapter;
__stdcall ndis_sendmulti_handler sendfunc;
+ int i, idx;
+ struct ifnet *ifp;
+ struct mbuf *m;
+ ndis_packet *p;
sc = arg;
adapter = sc->ndis_block.nmb_miniportadapterctx;
sendfunc = sc->ndis_chars.nmc_sendmulti_func;
sendfunc(adapter, packets, cnt);
+ for (i = 0; i < cnt; i++) {
+ p = packets[i];
+ if (p->np_oob.npo_status == NDIS_STATUS_PENDING)
+ continue;
+ idx = p->np_txidx;
+ m = p->np_m0;
+ ifp = &sc->arpcom.ac_if;
+ if (sc->ndis_sc)
+ bus_dmamap_unload(sc->ndis_ttag, sc->ndis_tmaps[idx]);
+ sc->ndis_txarray[idx] = NULL;
+ sc->ndis_txpending++;
+ m_freem(m);
+ ndis_free_packet(p);
+ if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS)
+ ifp->if_opackets++;
+ else
+ ifp->if_oerrors++;
+ ifp->if_timer = 0;
+ ifp->if_flags &= ~IFF_OACTIVE;
+ }
+
return(0);
}