question NDIS Receive processing

On receive, if driver posts receive buffer that are smaller than size of packet received on the wire, certain hardware can split up the frame into multiple buffers. It would be drivers responsibility to indicate this packet in multiple buffers as a single packet to the stack.

can this be supported in NDIS NIC driver?

The sample driver (10G xframe) seems to post buffers that are as big as frame size. It is not clear what happens if hardware splits a single packet into multiple buffers. One other driver in fact explicitly raises an assert in such a condition.

Thanks,

  • Sarvesh

>

On receive, if driver posts receive buffer that are smaller than size
of
packet received on the wire, certain hardware can split up the frame
into
multiple buffers. It would be drivers responsibility to indicate this
packet
in multiple buffers as a single packet to the stack.

can this be supported in NDIS NIC driver?

The sample driver (10G xframe) seems to post buffers that are as big
as frame
size. It is not clear what happens if hardware splits a single packet
into
multiple buffers. One other driver in fact explicitly raises an assert
in such
a condition.

NDIS5 had a few limitations about this. Have a look at
http://msdn.microsoft.com/en-us/library/ff553533(v=vs.85).aspx down
near the bottom. Aside from the notes on XP and 2003, I think you also
have to have at least the number of bytes in the first buffer that were
set in the lookahead oid, and definitely at least the whole eth/ip/tcp
header.

I don’t think that NDIS6 has such a limitation though. In my driver I
would often see up to 18 MDL’s in a receive packet which I link to an
NBL and pass to NdisMIndicateReceiveNetBufferLists without it being a
problem.

If some other drivers in your stack have bugs in them then you might
encounter them this way though.

James

James,

I am writing driver for NDIS6. Looks like there are no examples to look up.

If i were to post buffers assuming one packet per NBL , then i could end up with a packet spread over two NBLs. Would it be possible to disconnect MDL from second NBL and link it to the MBL being pointed to by first NBL? Can you point me to some calls that will help me do this?

Thanks,
Sarvesh

one packet can never span multiple NBL. A packet can only be in ONE and ONLY
ONE NBL. IN your case, you want one NB with multiple MDLs chained.

On Wed, Jul 6, 2011 at 8:48 AM, wrote:

> James,
>
> I am writing driver for NDIS6. Looks like there are no examples to look
> up.
>
> If i were to post buffers assuming one packet per NBL , then i could end up
> with a packet spread over two NBLs. Would it be possible to disconnect MDL
> from second NBL and link it to the MBL being pointed to by first NBL? Can
> you point me to some calls that will help me do this?
>
> Thanks,
> Sarvesh
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

You’re writing a miniport driver?

It’s legal to split the receives into multiple MDLs (and in the case of header-data split, it’s even required). But most of the time, miniports just give an MTU-sized buffer of contiguous memory to the hardware. Then they indicate up a NBL with one NB with one MDL. This is the easiest thing to do, and easy is good.

In most cases, miniports are *required* to indicate a packet with the entire Ethernet header in the first MDL [1]. Additionally, the entire lookahead size [2] must be in the first MDL. (Usually this amounts to including all IP headers in the first MDL).

[1] http://msdn.microsoft.com/en-us/library/ff554851(VS.85).aspx
[2] http://msdn.microsoft.com/en-us/library/ff567260

For the sake of completeness, it’s worth adding that shooting a NBL with
multiple NBs up is a dumb idea. It will not work.

On Wed, Jul 6, 2011 at 11:02 AM, Jeffrey Tippet <
xxxxx@microsoft.com> wrote:

You’re writing a miniport driver?

It’s legal to split the receives into multiple MDLs (and in the case of
header-data split, it’s even required). But most of the time, miniports
just give an MTU-sized buffer of contiguous memory to the hardware. Then
they indicate up a NBL with one NB with one MDL. This is the easiest thing
to do, and easy is good.

In most cases, miniports are *required* to indicate a packet with the
entire Ethernet header in the first MDL [1]. Additionally, the entire
lookahead size [2] must be in the first MDL. (Usually this amounts to
including all IP headers in the first MDL).

[1] http://msdn.microsoft.com/en-us/library/ff554851(VS.85).aspx
[2] http://msdn.microsoft.com/en-us/library/ff567260


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> James,

I am writing driver for NDIS6. Looks like there are no examples to
look up.

There is an e100bx driver sample in the WDK, in 6001.18002 at least. It
might have been left out of 7001 though.

If i were to post buffers assuming one packet per NBL , then i could
end up
with a packet spread over two NBLs. Would it be possible to disconnect
MDL
from second NBL and link it to the MBL being pointed to by first NBL?
Can you
point me to some calls that will help me do this?

For indicating packets, you want one NB per NBL. That NB can have
multiple MDL’s though, which is what I thought you were asking. While it
seems like you could indicate a chained list of NBL’s, each with
multiple NB’s, you can’t. NDIS can give you multiple NB’s per NBL when
sending packets though.

Maybe you have the various structures confused? I know I did when I
first looked at NDIS6:

NBL - NET_BUFFER_LIST - contains a list of ‘packets’. Can also be linked
to more NBL’s when indicating and when sending.
NB - NET_BUFFER - basically a packet, contains a list of MDL’s. Can also
be linked to more NB’s but only when NDIS gives you packets.
MDL - if you are familiar with NDIS5 this is an NDIS_BUFFER (literally -
NDIS_BUFFER was a typedef to an MDL)

In my drivers, I fill up a ring with MDL’s and xen fills those with
network data. I then chain all those MDL’s to an NB, coalescing enough
data into the first MDL to satisfy ETH+IP+TCP header size and also
lookahead requirements.

James