Porting a TCP/IP Driver to the NAL

This topic describes the steps required to port an existing (pre-RTX64 4.0) TCP/IP Stack driver for use with the new network architecture in RTX64 4.0 and later where the RT-TCP/IP Stack is layered on the Network Abstraction Layer (NAL).

NOTE: Please refer to the source code of network drivers installed with RTX64 SDK for details of implementation.

NOTE: If you have written a custom NIC driver and use an existing NIC driver name, the RT64 Control Panel and other RTX64 tools will make assumptions on supported devices and defaults based on the original IntervalZero-provided driver.

Sections in this topic:


Step 1: Include the NAL Header File

  1. Open the driver’s source code in Visual Studio.
  2. Add #include rtNalApi.h after #include rtnapi.h.

 


Step 2: Link to the NAL Library File

  1. Open the driver’s project properties in Visual Studio.
  2. Under Linker/Input, replace rttcpip.lib with RTX64Nal.lib.

 


Step 3: DMA, Transmit DMA, IOCTL Locks

NOTE: If the driver supports multiple receive and transmit queues, separate locks must be used for each receive DMA ring and transmit DMA ring.

 


Step 4: Add New Fields to the Driver Structure

 


Step 5: Replace RtndInitialize with RtndInitializeInterface

RtndInitializeInterface uses a pointer to a structure RTNAL_INTERFACE in its third parameter, which is an input/output parameter. The driver should update the structure with the corrected configuration if the driver must change its configuration to run.

For instance, the driver might not support the suggested interrupt type, or it might not monitor the Ethernet link. It might support less than requested number of receive or transmit queues, or a packet size less than the maximum. It might support a smaller number of buffers, or must round up the number of buffers to meet some criteria.

The MaxPacketSize includes 14 byte Ethernet header and does not include the 4 byte FCS. If the driver requires the checksum in transmit or receive buffers, or any other additional space, it must account for FCS when it allocates its buffers. For instance, the 1500 RequestedMtu in RTNINTERFACE in the old driver is equivalent to 1514 MaxPacketSize in RTNAL_INTERFACE.

If the driver supports a single receive queue and transmit queue, it must set NumberOfRxQueues and NumberOfTxQueues to 1 and DefaultRxQueue to 0.

RtndInitializeInterface should set last error if it fails.

 


Step 6: Change RtndReceive, RtndTransmit, RtndIoctl, and Driver IST Functions

Changes to RtndReceive

Changes to RtndTransmit

Changes to RtndIoctl

See RtndIoctl for the list of additional optional IOCTL control codes.

Changes to the Driver IST Function

 


Step 7: Add Attach and Detach Functions

Add RtndAttachToReceiveQueue

  1. Lock the receive DMA ring.
  2. Store the application context pointer.
  3. Store the receive packet callback pointer.
  4. Set the flag to attach the receiving application.
  5. Count the number of waiting packets in the receive queue DMA ring.
  6. Unlock the receive DMA ring.

NOTE: The function must return the number of packets waiting to be received.

NOTE: If called with an invalid argument, the function must return -1 and set last error to ERROR_BAD_ARGUMENTS.

Add RtndDetachReceiveQueue

  1. Lock the device IOCTL lock.
  2. Clear a multicast flag for the queue
  3. Clear Multicast Promiscuous mode if multicast flags for all queues are 0.
  4. Clear all receive filters for the queue.
  5. Unlock the device IOCTL lock.
  6. Lock the receive DMA ring.
  7. Clear the application context pointer.
  8. Clear the receive packet callback pointer.
  9. Clear receive attach and receive notification flags.
  10. Discard all packets waiting in the receive DMA ring.
  11. Unlock the receive DMA ring.

NOTE: The function must return 0 if successful.

NOTE: If called with an invalid argument, the function must return -1 and set last error to ERROR_BAD_ARGUMENTS.

 


Step 8: Modify Functions to Set Last Error on Failure

Modify these functions to set last error on failure:

 


Step 9: Support Multiple Receive Queues

In order to support multiple receive queues (DMA rings) the device must support receive queue filtering. NAL APIs and RTX64 network drivers support Ethernet type receive filtering. If the driver implements different type of receive filtering, it should add custom IOCTL control codes to enable and disable it.

 

See Also: