22 | | Finally, the generic NIC device "kernel" API defines four command types, that are detailed in section C. |
23 | | * '''READABLE''' : returns true if at least one RX paquet is available in RX queue. |
24 | | * '''WRITABLE : returns true if at least one empty slot is available in TX queue. |
25 | | * '''READ''' : consume one packet from the RX queue. |
26 | | * '''WRITE''' : produce one packet to the TX queue. |
| 22 | The generic NIC device "kernel" API defines two functions: |
| 23 | * the '''read()''' function is called by the RX server thread to get one paquet from the RX queue. |
| 24 | * the '''write()''' function is called by the TX server thread to put one packet to the TX queue. |
| 25 | This "kernel" API is detailed in section C below. |
| 34 | |
| 35 | == __B) Initialisation__ == |
| 36 | |
| 37 | The '''dev_nic_init()''' function makes the following initializations for given NIC chdev: |
| 38 | * It selects a core in cluster containing the N chdev to execute the server thread. |
| 39 | * it links the NIC IRQ to the core executing the server thread. |
| 40 | * it initialises the NIC specific fields of the chdev descriptor. |
| 41 | * it calls the nic_driver_init() function to initialize the NIC hardware device, |
| 42 | * it initializes the specific software data structures required by the hardware implementation. |
| 43 | It must be called by a local thread. |
| 44 | |
| 45 | == __C) The "kernel" API__ == |
| 46 | |
| 47 | The ''read'' function is always called by the DEV server thread associated to a given NIC_RX chdev. The ''write'' function is always called by the DEV server thread associated to a given NIC_TX chdev. For both functions, the local pointer on the chdev descriptor is registered in the server thread descriptor, and the channel index is registered in the chdev descriptor. |
| 48 | |
| 49 | These two functions are blocking and return only when the transfer is completed. |
| 50 | |
| 51 | * The '''dev_nic_read( pkd_t * pkd )''' read one Ethernet/IPv4 packet from the NIC_RX queue associated to the NIC channel. It calls directly the NIC driver, without registering in a waiting queue, because only one dedicated NIC_RX thread can access a given NIC_RX queue. |
| 52 | 1. It test the NIC_RX queue status, using the NIC_CMD_READABLE driver command. If the NIC_RX queue is empty, it unmasks the NIC-RX_IRQ, blocks and deschedules. It is re-activated by the nic_driver_isr() function (activated by the NIC_RX_IRQ) as soon as the queue becomes not empty. |
| 53 | 1. If the queue is not empty, it get one packet, using the NIC_CMD_READ driver command and returns. |
| 54 | Both commands are successively registered in the NIC-RX server thread descriptor to be passed to the driver. |
| 55 | |
| 56 | WARNING : for a RX packet, the initiator is the NIC hardware, and the protocols stack executed by the RX thread is traversed upward, from the point of view of function calls. |
| 57 | |
| 58 | * The '''dev_nic_write( pkd_t * pkd )''' function writes one Ethernet/IPv4 packet to the NIC_TX queue associated to the NIC channel. It calls directly the NIC driver, without registering in a waiting queue, because only one dedicated NIC_TX thread can access this NIC_TX queue. |
| 59 | 1. It test the NIC_RX queue status, using the NIC_CMD_WRITABLE driver command. If the NIC_TX queue is full, it unmasks the NIC-TX_IRQ, blocks and deschedules. It is re-activated by the nic_driver_isr() function (activated by the NIC_TX_IRQ) as soon as the queue becomes not full. |
| 60 | 1. If the queue is not full, it put one packet, using the NIC_CMD_WRITE driver command. |
| 61 | Both commands are successively registered in the NIC-TX server thread descriptor to be passed to the driver. |
| 62 | |
| 63 | WARNING : for a TX packet, the initiator is the client thread, and the protocols stack executed by the TX thread is traversed downward, from the point of view of function calls. |
| 64 | |
| 65 | == __D) The "driver" API__ == |
| 66 | |
| 67 | All NIC drivers must define three functions : |
| 68 | * void '''nic_driver_init( chdev_t * chdev )''' |
| 69 | * void '''nic_driver_cmd( xptr_t thread_xp )''' |
| 70 | * void '''nic_driver_isr( chdev_t * chdev )''' |
| 71 | |
| 72 | The ''nic_driver_cmd()'' function arguments are actually defined in the ''nic_command_t'' structure embedded in the server thread descriptor. One command contains four informations: |
| 73 | - '''type''' : operation type (defined below) |
| 74 | - '''buffer''' : local pointer on kernel buffer containing one packet. |
| 75 | - '''length''' : packet length (in bytes). |
| 76 | - '''status''' : return value for READABLE and WRITABLE |
| 77 | |
| 78 | The four command types for the NIC driver(s) are the following: |
| 79 | * '''NIC_CMD_READABLE''' : returns true if at least one RX paquet is available in RX queue. |
| 80 | * '''NIC_CMD_WRITABLE''' : returns true if at least one empty slot is available in TX queue. |
| 81 | * '''NIC_CMD_READ''' : consume one packet from the RX queue. |
| 82 | * '''NIC_CMD_WRITE''' : produce one packet to the TX queue. |
| 83 | |