Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging

The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.

Check out The OSR Learning Library at:

NDIS DMA introduction

Chris_TroesterChris_Troester Member Posts: 22

I try to understand how I should implement an NDIS 6 miniport driver in respect to dma. It should be a simple driver, not high-performance. As far as i know, I should call NdisMRegisterScatterGatherDma during initialization. My hardware has bus-master dma. I set the ProcessSGListHandler. When a protocol driver sends frames, NDIS provides me the NET_BUFFER_LIST. When I call NdisMAllocateNetBufferSGList, NDIS converts a NET_BUFFER to a SGList. I configure the dma controller with the scatter gather elements for one frame and start the dma transfer to the device. The hardware notifies me via interrupt when the send has completed.

How should I implement the receive? I have a fixed number of rx descriptors in the dma controller, so I assume I should allocate a commonbuffer with size = MAX_SIZE_OF_ETHERNET_FRAME * NUMBER_OF_RX_DESCRIPTORS. How do I allocate this physical contiguous buffer? During initialization I would program the rx dma. The rx dma engine is a fifo. I configure each rx descriptor with the physical address in the common buffer.

The windows driver samples github repo did not contain an example that uses NdisMRegisterScatterGatherDma. In the repo I found the driver "Native Wi-Fi Miniport Sample Driver", but until now I could not find the way it allocates the rx buffer.


  • Pavel_APavel_A Member Posts: 2,729
    edited September 17

    Older Wi-Fi drivers (before high-performance modes) did quite complex manipulation on the data in software, and implementing SG DMA in hardware was not justified. New fast PCIe devices probably offload these manipulations to hardware and have SG DMA ability.
    The Atheros example was made in the old times. You're not finding the DMA details in that example because this is hidden in an export library (athhal.sys) which is provided only as binary + lib. And the example itself now seems to be removed from the gallery.
    I'm afraid there are no other public examples for Windows. Even Linux wi-fi divers are large and complicated (not even to mention the firmware).
    But you wrote ' It should be a simple driver' - so it isn't anything wireless?

    -- pa

  • Chris_TroesterChris_Troester Member Posts: 22

    Correct, I'm working on an ethernet driver. The "Native Wi-Fi Miniport Sample Driver" was the only NDIS 6 miniport driver with dma that I could find. It is still available in the repo. Here is the path:

    msdn-code-gallery-microsoft/Official Windows Driver Kit Sample/Windows Driver Kit (WDK) 8.1 Samples/[C++]-windows-driver-kit-81-cpp/WDK 8.1 C++ Samples/Native Wi-Fi Miniport Sample Driver/C++/

    git clone did not work for me, so I downloaded the driver via gitzip (

    I understood the general dma tx workflow in the wifi driver. It calls NdisMRegisterScatterGatherDma. In MPSendNetBufferLists the function NdisMAllocateNetBufferSGList is called. In the handler HWProcessSGList NDIS provides the scatter gather list for a NET_BUFFER . The driver fills the hardware address and length for each sg element into a descriptor. The descriptor is forwarded to the hidden export library.

    Rx is not clear to me yet.

  • Pavel_APavel_A Member Posts: 2,729

    For RX the driver usually keeps a pool of memory which it owns. If you want to do SG DMA on receive, allocate in advance some net buffers and SG lists for them. If you want to keep it simple (but lower performance), do RMA receive to a common buffer and fill NDIS net buffers later (in a DPC).
    -- pa

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Internals & Software Drivers 30 Nov 2020 LIVE ONLINE
Writing WDF Drivers 7 Dec 2020 LIVE ONLINE
Developing Minifilters Early 2021 LIVE ONLINE