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

Last change on this file since 683 was 683, checked in by alain, 3 years ago

All modifications required to support the <tcp_chat> application
including error recovery in case of packet loss.A

File size: 17.6 KB
Line 
1/*
2 * dev_nic.h - NIC (Network Controler) generic device API definition.
3 *
4 * Author  Alain Greiner    (2016,2017,2018,2019,2020)
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
27#include <kernel_config.h>
28#include <hal_kernel_types.h>
29#include <remote_busylock.h>
30#include <remote_buf.h>
31#include <xlist.h>
32
33/****  Forward declarations  ****/
34
35struct chdev_s;
36
37/*****************************************************************************************
38 *     Generic Network Interface Controler definition
39 *
40 * This device provides access to a generic Gigabit Ethernet network controler.
41 * It assumes that the NIC hardware peripheral handles two packets queues for sent (TX)
42 * and received (RX) packets.
43 *
44 * The supported protocols stack is : Ethernet / IPV4 / TCP or UDP
45 *
46 * 1) hardware assumptions
47 *
48 * The NIC device is handling two (infinite) streams of packets to or from the network.
49 * It is the driver responsibility to move the RX packets from the NIC to the RX queue,
50 * and the TX packets from the TX queue to the NIC.
51 *
52 * AS the RX and TX queues are independant, there is one NIC_RX device descriptor
53 * to handle RX packets, and another NIC_TX device descriptor to handle TX packets.
54 *
55 * In order to improve throughput, the NIC controller can implement multiple (N) channels.
56 * In this case, the channel index is defined by an hash function computed from the remote
57 * IP address and port. This index is computed by the hardware for an RX packet, and is
58 * computed by the kernel for a TX packet, using a specific driver function.
59 * The 2*N chdevs, and the associated server threads implementing the protocols stack,
60 * are distributed in 2*N different clusters.
61 *
62 * 2) User API
63 *
64 * On the user side, ALMOS-MKH implements the POSIX socket API.
65 * The following kernel functions implement the socket related syscalls :
66 * - socket_build()     : create a local socket registered in process fd_array[].
67 * - socket_bind()      : attach a local IP address and port to a local socket.
68 * - socket_listen()    : local server makes a passive open.
69 * - socket_connect()   : local client makes an active open to a remote server.
70 * - socket_accept()    : local server accept a new remote client.
71 * - socket_send()      : send data on a connected socket.
72 * - socket_recv()      : receive data on a connected socket.
73 * - socket_sendto()    : send a packet to a remote (IP address/port).
74 * - socket_recvfrom()  : receive a paket from a remote (IP address/port).
75 *
76 * 3) NIC TX and NIC_RX server threads
77 *
78 * The dev_nic_tx_server() & dev_nic_rx_server() functions defined below execute
79 * the user commands stored in the sockets to implement the [ETH / IP / TCP or UDP]
80 * protocols stack, as defined in the <ksocket.c> and <ksocket.h> files.
81 *
82 * 4) NIC driver API
83 *
84 * The generic NIC device "driver" API defines the following commands, used by the
85 * NIC_TX and NIC_RX server threads, running in the cluster containing the relevant chdev,
86 * to access the NIC_TX and NIC_RX packets queues:
87 *
88 * - READ     : consume one packet from the NIC_RX queue.
89 * - WRITE    : produce one packet to the NIC_TX queue.
90 *
91 * All RX or TX paquets are sent or received in standard 2 Kbytes kernel buffers,
92 * that are dynamically allocated by the protocols stack.
93 * The actual TX an RX queues structures depends on the hardware NIC implementation,
94 * and are defined in the HAL specific driver code.
95 *
96 * Moreover, the generic NIC device "driver" API defines the following commands,
97 * used directly by a client thread running in any cluster, to access the NIC device
98 * configuration or status registers:
99 *
100 * - GET_KEY      : get channel index from remote IP address and port
101 * - SET_RUN      : activate/desactivate one channel (both directions)
102 * - GET_INSTRU   : get one instrumentation counter value
103 * - CLEAR_INSTRU : reset all instrumentation counters
104 *
105 * WARNING: the WTI mailboxes used by the driver ro receive events from the hardware
106 * (available RX packet, or available free TX slot, for a given channel), must be
107 * statically allocated during the kernel initialisation phase, and must be
108 * routed to the cluster containing the associated TX/RX chdev and server thread.
109 *
110 *****************************************************************************************/
111
112/****  Forward declarations  ****/
113
114struct chdev_s;
115
116/*****************************************************************************************
117 *   Various constants used by the protocols stack
118 ****************************************************************************************/
119
120#define SRC_MAC_5              0x66         // This is a temporary short-cut for debug
121#define SRC_MAC_4              0x55
122#define SRC_MAC_3              0x44
123#define SRC_MAC_2              0x33
124#define SRC_MAC_1              0x22
125#define SRC_MAC_0              0x11
126
127#define DST_MAC_5              0x66         // This is a temporary short-cut for debug
128#define DST_MAC_4              0x55
129#define DST_MAC_3              0x44
130#define DST_MAC_2              0x33
131#define DST_MAC_1              0x22
132#define DST_MAC_0              0x11
133
134#define TCP_HEAD_LEN           20
135#define UDP_HEAD_LEN           8
136#define IP_HEAD_LEN            20
137#define ETH_HEAD_LEN           14
138
139#define PROTOCOL_UDP           0x11
140#define PROTOCOL_TCP           0x06
141
142#define TCP_FLAG_FIN           0x01
143#define TCP_FLAG_SYN           0x02
144#define TCP_FLAG_RST           0x04
145#define TCP_FLAG_PSH           0x08
146#define TCP_FLAG_ACK           0x10
147#define TCP_FLAG_URG           0x20
148
149/*****************************************************************************************
150 * This structure defines the specific chdev extension for NIC device:
151 * - queue : local pointer on the memory mapped queue of TX or RX packets, used
152 *   by the NIC driver to move packets to/from the NIC hardware. The actual descriptor
153 *   depends on the NIC implementation.
154 * - root  : root of an xlist of sockets that are in the LISTEN state, waiting one or
155 *   several TCP connection requests from remote processes. It is only used by the
156 *   NIC_RX server thread attached to a NIC_RX chdev.
157 * - lock  : lock protecting concurrent access to the litening sockets list.
158 ****************************************************************************************/
159
160typedef struct nic_extend_s
161{
162    void            * queue;    /*! pointer on NIC packets queue descriptor (RX or TX)  */
163    xlist_entry_t     root;     /*! root of listening sockets list (only used in RX[0]) */
164    remote_busylock_t lock;     /*! lock protecting this list  (only used in RX[0]      */
165}
166nic_extend_t;
167
168/*****************************************************************************************
169 * This enum defines the various implementations of the generic NIC peripheral.
170 * This array must be kept consistent with the define in the arch_info.h file.
171 ****************************************************************************************/
172
173typedef enum nic_impl_e
174{
175    IMPL_NIC_CBF =   0,     
176    IMPL_NIC_I86 =   1,
177}
178nic_impl_t;
179
180/****************************************************************************************
181 * This defines the (implementation independant) commands to access the NIC hardware.
182 * There is two types of commands
183 * - The first 2 commands are used by the NIC_TX and NIC_RX server threads, and stored
184 *   in the server thread descriptor, to access the NIC_RX & NIC_TX packet queues.
185 *   The buffer is always a 2K bytes kernel buffer, containing an Ethernet packet.
186 * - The next 4 synchronous commands are used by the client thread, and stored in the
187 *   client thread descriptor, to directly access the NIC registers.
188 ****************************************************************************************/
189
190typedef enum nic_cmd_e
191{
192    NIC_CMD_WRITE        = 10,  /*! put one (given length) packet to TX queue           */
193    NIC_CMD_READ         = 11,  /*! get one (any length) packet from RX queue           */
194
195    NIC_CMD_GET_KEY      = 20,  /*! return channel index from IP address and port       */ 
196    NIC_CMD_SET_RUN      = 21,  /*! enable/disable one NIC channel                      */
197    NIC_CMD_GET_INSTRU   = 22,  /*! return one intrumentation register value            */
198    NIC_CMD_CLEAR_INSTRU = 23,  /*! reset all instrumentation registers                 */
199}
200nic_cmd_t;
201
202typedef struct nic_command_s
203{
204    xptr_t      dev_xp;       /*! extended pointer on NIC chdev descriptor              */
205    nic_cmd_t   type;         /*! command type                                          */
206    uint8_t   * buffer;       /*! local pointer on kernel buffer (when READ / WRITE)    */ 
207    uint32_t    length;       /*! number of bytes in buffer (when READ / WRITE )        */
208    uint32_t    status;       /*! return value (depends on command type)                */
209    uint32_t    error;        /*! return an error from the hardware (0 if no error)     */
210}
211nic_command_t;
212
213/******************************************************************************************
214 * This function completes the NIC-RX and NIC-TX chdev descriptors initialisation.
215 * namely the link with the implementation specific driver.
216 * The func, impl, channel, is_rx, base fields have been previously initialised.
217 * It calls the specific driver initialisation function, to initialise the hardware
218 * device and the specific data structures when required.
219 * It creates the associated server thread and allocates a WTI from local ICU.
220 * For a TX_NIC chedv, it allocates and initializes the R2T queue used by the
221 * NIC_RX[channel] server to send direct requests to the NIC_TX[channel] server,
222 * and the CRQ queue used to register connection requests.
223 * It must de executed by a local thread.
224 * For NIC_TX and NIC_RX chdevs, the "wait_root" field is actually a list of sockets.
225 ******************************************************************************************
226 * @ chdev    : local pointer on NIC chdev descriptor.
227 *****************************************************************************************/
228void dev_nic_init( struct chdev_s * chdev );
229
230/* Functions directly called by a client thread in any cluster */
231 
232/******************************************************************************************
233 * This function compute a channel index in range [0,nic_channels[ from the remote IP
234 * address <addr> and <port>, by calling the relevant driver command.
235 ******************************************************************************************
236 * @ addr     : [in] IP address.
237 * @ port     : [in] TCP/UDP port.
238 * @ return the selected channel index
239 *****************************************************************************************/
240uint32_t dev_nic_get_key( uint32_t addr,
241                          uint16_t port );
242
243/******************************************************************************************
244 * This function activate / de-activate a NIC channel DMA engine identified by the
245 * <channel> argument, as defined by the <run> argument.
246 ******************************************************************************************
247 * @ channel  : [in] NIC channel index.
248 * @ run      : [in] activate if non-zero / desactivate if zero.
249 * @ return 0 if success / return -1 if error.
250 *****************************************************************************************/
251error_t dev_nic_set_run( uint32_t channel,
252                         uint32_t run );
253
254/******************************************************************************************
255 * This instrumentation function displays on the TXT0 kernel terminal the content
256 * of the instrumentation registers contained in the NIC device.
257 ******************************************************************************************
258 * @ return 0 if success / return -1 if error.
259 *****************************************************************************************/
260error_t dev_nic_get_instru( void );
261
262/******************************************************************************************
263 * This instrumentation function reset all instrumentation registers contained
264 * in the NIC device.
265 ******************************************************************************************
266 * @ return 0 if success / return -1 if error.
267 *****************************************************************************************/
268error_t dev_nic_clear_instru( void );
269
270/* Functions executed by the TX and RX server threads */ 
271 
272/******************************************************************************************
273 * This function is executed by the server thread associated to a NIC_TX[channel] chdev.
274 * This TX server thread is created by the dev_nic_init() function.
275 * It build and send UDP packets or TCP segments for all clients threads registered in
276 * the NIC_TX[channel] chdev. The command types are (CONNECT / ACCEPT / CLOSE / SEND).
277 * It takes into account the request registered by the RX server thread in the R2T queues.
278 * The loop on registered sockets implements a round-robin priority between sockets.
279 * When no registered socket is active, it blocks on the THREAD_BLOCKED_CLIENT condition
280 * and deschedules. It is re-activated by a client thread registering a command.
281 * When the NIC_TX packet queue is full, it blocks on the THREAD_BLOCKED_ISR condition
282 * and deschedules. It is reactivated by the NIC_TX DMA engine.
283 ******************************************************************************************
284 * Implementation note:
285 * At each iteration in the infinite loop, it takes the lock protecting the registered
286 * client sockets queue to find one active socket (tx_valid or r2t_valid flags set).
287 * For each registered socket, it takes the lock protecting the socket state, and
288 * exit the scan when an active socket has been found, without releasing the socket state.
289 * When the scan is completed, it release the lock protecting the queue, before handling
290 * the found active socket. The socket lock is released only when the requested packet
291 * has been build, and the active socket state has been updated.
292 * To handle a socket request, it calls the transport layer to build the UDP packet or
293 * TCP segment in a local 2K bytes kernel buffer, calls the IP layer to add the IP header,
294 * calls the ETH layer to add the ETH header, and moves the packet to the NIC_TX_QUEUE.
295 ******************************************************************************************
296 * @ chdev    : [in] local pointer on one local NIC_TX[channel] chdev descriptor.
297 *****************************************************************************************/
298void dev_nic_tx_server( struct chdev_s * chdev );
299
300
301/******************************************************************************************
302 * This function is executed by the server thread associated to a NIC_RX[channel] chdev.
303 * This RX server thread is created by the dev_nic_init() function.
304 * It handles all UDP packets or TCP segments received by the sockets attached to
305 * the NIC_RX[channel] chdev. It writes the received data in the socket rcv_buf, and
306 * unblocks the client thread waiting on a RECV command.
307 * To implement the three steps handshahke required by a TCP connection, it posts direct
308 * requests to the TX server, using the R2T queue attached to the involved socket.
309 * It blocks on the THREAD_BLOCKED_ISR condition and deschedules when the NIC_RX_QUEUE
310 * is empty, and is re-activated by the NIC_RX_ISR, when the queue becomes non empty.
311 ******************************************************************************************
312 * Implementation note:
313 * It executes an infinite loop in which it extracts one packet from the NIC_RX_QUEUE
314 * of received packets, copies this packet in a local 2 kbytes kernel buffer, checks
315 * the Ethernet header, checks the IP header, calls the relevant (TCP or UDP) transport
316 * protocol that search a matching socket for the received packet. It copies the payload
317 * to the relevant socket rcv_buf when the packet is acceptable, and unblocks the client
318 * thread. It discard the packet if no socket found.
319 ******************************************************************************************
320 * @ chdev    : [in] local pointer on one local NIC_RX[channel] chdev descriptor.
321 *****************************************************************************************/
322void dev_nic_rx_server( struct chdev_s * chdev );
323
324/******************************************************************************************
325 * This debug function can be called by the dev_nic_tx_server() function to display
326 * on TXT0 the header of a TX [ETH/IP/TCP] segment or [ETH/IP/UDP] packet.
327 ******************************************************************************************
328 * @ pid     : [in] process identifier.
329 * @ fdid    : [in] socket identifier.
330 * @ cycle   : [in] date (number of cycles).
331 * @ buf     : [in] local pointer on kernel buffer containing the packet.
332 *****************************************************************************************/
333void dev_nic_packet_display( pid_t     pid,
334                             uint32_t  fdid,
335                             uint32_t  cycle,
336                             uint8_t * buf );
337
338#endif  /* _DEV_NIC_H */
Note: See TracBrowser for help on using the repository browser.