source: trunk/kernel/devices/dev_nic.h @ 438

Last change on this file since 438 was 437, checked in by alain, 6 years ago

Fix various bugs

File size: 11.7 KB
RevLine 
[1]1/*
2 * dev_nic.h - NIC (Network Controler) generic device API definition.
3 *
[437]4 * Author  Alain Greiner    (2016,2017,2018)
[1]5 *
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#ifndef _DEV_NIC_H
25#define _DEV_NIC_H
26
[14]27#include <kernel_config.h>
[1]28#include <hal_types.h>
29
30/*****************************************************************************************
31 *     Generic Network Interface Controler definition
32 *
33 * This device provide access to an external Gigabit Ethernet network controler.
34 * It assume that the NIC hardware peripheral handles two packets queues for sent (TX)
35 * and received (RX) packets. Packets are (Ethernet/IPV4).
36 *
37 * The NIC device is handling an (infinite) stream of packets to or from the network.
38 * It is the driver responsibility to move the RX packets from the NIC to the RX queue,
39 * and the TX packets from the TX queue to the NIC.
40 *
41 * AS the RX and TX queues are independant, there is one NIC-RX device descriptor
42 * to handle RX packets, and another NIC-TX device descriptor to handle TX packets.
43 * In order to improve throughput, the hardware NIC controller can optionnally implement
44 * multiple channels:
45 * - The RX channels are indexed by an hash key derived from the source IP address.
46 * - The TX channels are indexed by an hash key derived from the destination IP address.
47 * These 2*N devices, and 2*N associated server threads, are distributed in 2*N clusters.
48 * The  2*N server threads implement the protocols stack. The RX server threads block
49 * and deschedule when the RX queue is empty. The TX server stack block and deschedule
50 * when the queue is full.
51 *
52 * It is the driver responsibily to re-activate a blocked server thread when
53 * the queue state is modified: not full for TX, or not empty for RX.
54 *
55 * WARNING: the WTI mailboxes used by the driver ro receive events from the hardware
56 * (available RX packet, or available free TX slot, for a given channel), must be
57 * statically allocated during the kernel initialisation phase, and must be
58 * routed to the cluster containing the associated device descriptor and server thread.
59 * to simplify the server thread re-activation.
60 *
61 * Finally, the generic NIC device API defines the following commands:
62 * - READABLE : returns true if at least one RX paquet is available in RX queue.
63 * - WRITABLE : returns true if atleast one empty slot is available in TX queue.
64 * - READ     : consume one packet from the RX queue.
65 * - WRITE    : produce one packet fto the TX queue.
66 * All RX or TX paquets are sent or received in standard 2 Kbytes kernel buffers,
67 * that are dynamically allocated by the protocols stack. The structure pkd_t
68 * defining a packet descriptor is defined below, and contain the buffer pointer
69 * and the actual Ethernet packet Length.
70 *
71 * The actual TX an RX queues structures depends on the hardware NIC implementation,
72 * and are defined in the driver code.
73 *****************************************************************************************/
74
75/****  Forward declarations  ****/
76
[3]77struct chdev_s;
[1]78
79/******************************************************************************************
80 * This defines the extension for the generic IOC device.
81 * The actual queue descriptor depends on the implementation.
82 *****************************************************************************************/
83
84typedef struct nic_extend_s
85{
86    void     * queue;     /*! local pointer on the packets queue descriptor (RX or TX)   */
87}
88nic_extend_t;
89
90/******************************************************************************************
91 * This structure defines the Ethernet/IPV4 packet descriptor, that is sent to,
92 * or received from, the protocols stack.
93 *****************************************************************************************/
94
95typedef struct pkd_s
96{
97    char      * buffer;   /*! local pointer on 2 Kbytes buffer containing packet         */ 
98    uint32_t    length;   /*! actual number of bytes                                     */
99}
100pkd_t;
101
102/******************************************************************************************
103 * This enum defines the various implementations of the generic NIC peripheral.
104 * This array must be kept consistent with the define in the arch_info.h file.
105 *****************************************************************************************/
106
107enum nic_impl_e
108{
[407]109    IMPL_NIC_CBF =   0,     
[1]110    IMPL_NIC_I86 =   1,
111}
112nic_impl_t;
113
114/******************************************************************************************
115 * This defines the (implementation independant) command  passed to the NIC driver.
116 *****************************************************************************************/
117
118typedef enum nic_cmd_e
119{
120    NIC_CMD_WRITABLE = 0,  /*! test TX queue not full (for a given length packet)        */
121    NIC_CMD_WRITE    = 1,  /*! put one (given length) packet to TX queue                 */
122    NIC_CMD_READABLE = 2,  /*! test RX queue not empty (for any length packet)           */
123    NIC_CMD_READ     = 3,  /*! get one (any length) packet from RX queue                 */
124}
125nic_cmd_t;
126
127typedef struct nic_command_s
128{
129    xptr_t      dev_xp;   /*! extended pointer on device descriptor                      */
130    nic_cmd_t   cmd;      /*! requested operation type                                   */
131    char      * buffer;   /*! local pointer on 2 Kbytes buffer containing packet         */ 
132    uint32_t    length;   /*! actual number of bytes                                     */
133    bool_t      status;   /*! return true if writable or readable (depend on command)    */
134    uint32_t    error;    /*! return an error from the hardware (0 if no error)          */
135}
136nic_command_t;
137
138/******************************************************************************************
[3]139 * This function completes the NIC-RX and NIC-TX chdev descriptors initialisation.
140 * namely the link with the implementation specific driver.
141 * The func, impl, channel, is_rx, base fields have been previously initialised.
142 * It calls the specific driver initialisation function, to initialise the hardware
143 * device and the specific data structures when required.
144 * It creates the associated server thread and allocates a WTI from local ICU.
145 * It must de executed by a local thread.
[1]146 ******************************************************************************************
[3]147 * @ chdev    : local pointer on NIC chdev descriptor.
[1]148 *****************************************************************************************/
[3]149void dev_nic_init( struct chdev_s * chdev );
[1]150
151/******************************************************************************************
152 * This blocking function must be called by the kernel thread running in the cluster
153 * containing the NIC_RX channel device descriptor.
154 * It read one packet (Ethernet/IPV4) from the NIC_RX queue associated to the NIC channel.
155 * It calls directly the NIC driver, without registering in a waiting queue, because
156 * only this NIC_RX thread can access this packets queue.
157 * 1) It test the packets queue status, using the NIC_CMD_WRITABLE command.
158 *    If it is empty, it unmask the NIC-RX channel IRQ, blocks and deschedule.
159 *    It is re-activated by the NIC-RX ISR (generated by the NIC) as soon as the queue
160 *    becomes not empty.
161 * 2) if the queue is not empty, it get one packet, using the driver NIC_CMD_READ command.
162 * Both commands are successively registered in the NIC-RX server thread descriptor
163 * to be passed to the driver.
164 *
165 * WARNING : for a RX packet the initiator is the NIC hardware, and the protocols
166 * stack is traversed upward, from the point of view of function calls.
167 ******************************************************************************************
168 * @ pkd     : pointer on packet descriptor (expected).
169 * @ returns 0 if success / returns non zero if ENOMEM, or error reported from NIC.
170 *****************************************************************************************/
171error_t dev_nic_read( pkd_t * pkd );
172
173/******************************************************************************************
174 * This blocking function must be called by the kernel thread running in the cluster
175 * containing the NIC_TX channel device descriptor.
176 * It writes one packet (Ethernet/IPV4) to the NIC_RX queue associated to the NIC channel.
177 * It calls directly the NIC driver, without registering in a waiting queue, because
178 * only this NIC_TX thread can access this packets queue.
179 * 1) It test the packets queue status, using the NIC_CMD_READABLE command.
180 *    If it is full, it unmask the NIC-TX channel IRQ, blocks and deschedule.
181 *    It is re-activated by the NIC-TX ISR (generated by the NIC) as soon as the queue
182 *    is not full.
183 * 2) If the queue is not empty, it put one packet, using the driver NIC_CMD_WRITE command.
184 * Both commands are successively registered in the NIC-TX server thread descriptor
185 * to be passed to the driver.
186 *
187 * WARNING : for a TX packet the initiator is the "client" thread, and the protocols
188 * stack is traversed downward from the point of view of function calls.
189 ******************************************************************************************
190 * @ pkd     : pointer on packet descriptor (to be filed).
191 * @ returns 0 if success / returns if length > 2K, undefined key, or error from NIC.
192 *****************************************************************************************/
193error_t dev_nic_write( pkd_t * pkd );
194
195
196/******************************************************************************************
197 * This function is executed by the server thread associated to a NIC channel device
198 * descriptor (RX or TX). This thread is created by the dev_nic_init() function.
199 * It executes an infinite loop, handling one packet per iteration.
200 *
201 * -- For a TX channel --
202 * 1) It allocates a 2 Kbytes buffer.
203 * 2) It copies the client TCP/UDP packet in this buffer.
204 * 3) It calls the IP layer to add the IP header.
205 * 4) It calls the ETH layer to add the ETH header.
206 * 5) It calls the dev_nic_write() blocking function to move the packet to the TX queue.
207 * 6) It releases the 2 Kbytes buffer.
208 *
209 * When the waiting threads queue is empty, it blocks on the THREAD_BLOCKED_IO_CMD
210 * condition and deschedule. It is re-activated by a client thread registering a command.
211 *
212 * -- For a RX channel --
213 * 1) It allocates a 2 Kbytes buffer.
214 * 2  It calls the dev_nic_read() blocking function to move the ETH packet to this buffer.
215 * 3) It calls the ETH layer to analyse the ETH header.
216 * 4) It calls the IP layer to analyse the IP header. TODO ???
217 * 5) It calls the transport (TCP/UDP) layer. TODO ???
218 * 5) It deliver the packet to the client thread. TODO ???
219 * 6) It releases the 2 Kbytes buffer.
220 *
221 * When the RX packets queue is empty, it blocks on the THREAD_BLOCKED_IO_CMD
222 * condition and deschedule. It is re-activated by the NIC driver when this queue
223 * becomes non empty.
224 ******************************************************************************************
[3]225 * @ dev     : local pointer on NIC chdev descriptor.
[1]226 *****************************************************************************************/
[3]227void dev_nic_server( struct chdev_s * chdev );
[1]228
229
230#endif  /* _DEV_NIC_H */
Note: See TracBrowser for help on using the repository browser.