This article summaries the important steps towards porting NDIS 5.1 wireless driver to NDIS 6.0 wireless driver in Windows Embedded Compact 13 platform.

More Information about NDIS

The Network Driver Interface Specification (NDIS) is an application programming interface (API) for network interface cards (NICs). developed jointly by Microsoft and 3Com Corporation and is mostly used in Microsoft Windows. NDIS facilitates communication between the Windows Embedded Compact operating system (OS) and network adapter and protocol drivers. NDIS 6.0 and higher versions have lot of advantages over lower versions. They are, Advantages

  • Higher performance.
  • Better manageability.
  • Reduced complexity.
  • Simplified driver models.

Architecture of network packet data

NDIS 6.0 represents the network packet data as below.

  • Net Buffer Lists (NBLs)- A single network packet.
  • Net Buffers (NBs)- A group of packets with common out of band (OOB) data.
  • Memory Descriptor Lists (MDLs) - A single virtually contiguous data buffer. complexity.

Overview

In NDIS 5.X, packets are presented with an array of pointers to NDIS_PACKET structures such that they could perform multi-packet sends and receives. In NDIS 6.0, multi-packet sends and receives are facilitated by providing drivers with a single pointer that points to a chain of NBLs. The following are the steps in porting NDIS 5.1 driver to NDIS 6.0 version. Since wireless drivers involve lot of complex memory operations and important cases, it is required to understand the actual NDIS 5.1 driver and then start with porting.

Changes in the the Build Files for NDIS 6.0

Change the Sources file to define the constant NDIS60_MINIPORT from NDIS51_MINIPORT as below.

CDEFINES=$(CDEFINES) -DNDIS_MINIPORT_DRIVER -DNDIS60_MINIPORT=1

Port Miniport Driver Initialization to NDIS 6.0

Initialize the miniport driver characteristics structure.All the obsolete function calls in your DriverEntry routine has to be replaced with new function call supported by NDIS 6.0 After this steps, register your miniport driver’s entry point functions with NDIS 6.0 NdisMRegisterMiniportDriver function.

Below is the sample code snippets to register NDIS 6.0 driver.

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
    NDIS_STATUS Status;
    NDIS_HANDLE NdisWrapperHandle;

    NDIS_MINIPORT_DRIVER_CHARACTERISTICS MrvDrvNMC;
    NdisZeroMemory(&MrvDrvNMC, sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS));

    // Set the type and version of this structure
    MrvDrvNMC.Header.Type     = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
    MrvDrvNMC.Header.Size     = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS);
    MrvDrvNMC.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;

    MrvDrvNMC.MajorNdisVersion         = MRVDRV_NDIS_MAJOR_VERSION; //6
    MrvDrvNMC.MinorNdisVersion         = MRVDRV_NDIS_MINOR_VERSION; //0
 
    MrvDrvNMC.MajorDriverVersion       = MRVDRV_DRIVER_MAJOR_VERSION;//3
    MrvDrvNMC.MinorDriverVersion       = MRVDRV_DRIVER_MINOR_VERSION;//1 

 
    MrvDrvNMC.InitializeHandlerEx          = MrvDrvInitializeEx;
    MrvDrvNMC.RestartHandler               = MrvRestart;
    MrvDrvNMC.PauseHandler                 = MrvPause;
    MrvDrvNMC.ShutdownHandlerEx            = MrvDrvShutdownHandler;
    MrvDrvNMC.DevicePnPEventNotifyHandler  = MrvDrvPnPEventNotify;
    MrvDrvNMC.HaltHandlerEx                = MrvDrvHalt; 
    MrvDrvNMC.UnloadHandler                = MrvDrvUnload;
 
 
    // Query/Set/Method requests handlers
 
    MrvDrvNMC.OidRequestHandler        = MPRequest;
    MrvDrvNMC.CancelOidRequestHandler  = MrvCancelRequest;
 

    // Set optional miniport services handler

     MrvDrvNMC.SetOptionsHandler        = MrvSetOption;
 
    // Send/Receive handlers
     
     MrvDrvNMC.SendNetBufferListsHandler    = MrvDrvSend;
     MrvDrvNMC.CancelSendHandler            = MrvCancelNetBufferList;
     MrvDrvNMC.ReturnNetBufferListsHandler  = MrvDrvReturnPacket; 
   
   
 
    // Fault handling handlers
     MrvDrvNMC.CheckForHangHandlerEx      = MrvDrvCheckForHang; 
     MrvDrvNMC.ResetHandlerEx             = MrvDrvReset;
   

    //  Register this driver with the NDIS wrapper
    //  This will cause MrvDrvInitializeEx to be called before returning
 
    // Register driver
    Status = NdisMRegisterMiniportDriver (
         DriverObject, RegistryPath, MiniportDriverContext,
         &MrvDrvNMC, &NdisMiniportDriverHandle);

    return Status;
} 

Once you have successfully registered the NDIS 6.0 driver, you need to implement/modify all the function callbacks to NDIS 6.0 compatibility.

InitializeHandlerEx

Once your NDIS 6.0 is registered by calling NdisMRegisterMiniportDriver function, this function will be called from NDIS. This function is equivalent to MiniportInitialize in NDIS 5.1. But it does not have the same parameter like NDIS 5.1. So your main task is to replace all the deprecated function call with NDIS 6.0 functions. This steps mainly involves.

  1. Updating the MiniportInitialize Function for NDIS 6.0.
  2. Setting the NDIS 6.0 Miniport Adapter Attributes
  3. Reading the Registry in an NDIS 6.0 Miniport Driver
  4. Allocating Memory in an NDIS 6.0 Miniport Driver
  5. Updating Bus-Specific Configuration Space Access for NDIS 6.0

For more information, you can refer this msdn link.

Changes to other callbacks functions

After InitializeHandlerEx, below function has to be replaced with NDIS 6.0 functions.

  • In NDIS 6.0 and later, the MiniportHaltEx function replaces the NDIS 5.x MiniportHalt function.
  • NDIS 6.0 calls a miniport driver’s MiniportPause function to stop data flow before performing a Plug and Play operation.
  • NDIS calls the miniport driver’s MiniportRestart function to return the miniport adapter to the Running state. This miniport adaptor pause and restart capabilities are new features that are introduced in NDIS 6.0.
  • The NDIS 6.0 or later miniport driver’s shutdown function, MiniportShutdownEx, replaced the NDIS 5.x MiniportShutdown function.
  • NDIS 6.0 drivers do not call the NdisMRegisterUnloadHandler function. Instead it calls, MiniportDriverUnload function.
  • MiniportDevicePnPEventNotify function has to be implemented.
  • Implement MiniportInitializeEx to initialize the adapter
  • Implement MiniportHaltEx to halt the adapter.
  • Implement MiniportShutdownEx to restore adapter hardware to a known state.

Port Miniport Driver Send and Receive Operations to NDIS 6.0

NDIS 6.0 replaces the major change in this send and receive operation.It replaces NDIS_PACKET with NET_BUFFFER_LIST.To port, send and receive operations, replace all the NDIS_PACKET data structure with NET_BUFFER_LIST data structure.Also you need to allocate NET_BUFFER pool and NET_BUFFER_LIST pool before using it in the driver.This can be done by NdisAllocateNetBufferListPool and NdisAllocateNetBufferPool functions. Each NET_BUFFER_LIST structure that your driver uses to indicate received network data has at least one associated NET_BUFFER structure. A driver that indicates received data should therefore allocate a NET_BUFFER_LIST pool with a preallocated NET_BUFFER in each NET_BUFFER_LIST. To create such a pool, call the NdisAllocateNetBufferListPool function with the fAllocateNetBuffer member of the NET_BUFFER_LIST_POOL_PARAMETERS structure set to TRUE. Your miniport driver’s MiniportHaltEx function calls the NdisFreeNetBufferListPool and NdisFreeNetBufferPool functions to free the NET_BUFFER_LIST and NET_BUFFER pools, respectively. These functions replace the NDIS 5.x NdisFreePacketPool function. When you call these functions, you pass the pool handle that the associated allocation functions return.