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

Last change on this file since 1 was 1, checked in by alain, 7 years ago

First import

File size: 11.5 KB
Line 
1/*
2 * dev_nic.h - NIC (Network Controler) generic device API definition.
3 *
4 * Author  Alain Greiner    (2016)
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 <almos_config.h>
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
77struct device_s;
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{
109    IMPL_NIC_SOC =   0,     
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/******************************************************************************************
139 * This function completes the NIC-RX and NIC-TX devices descriptors initialisation.
140 * The func, impl, channel, is_rx, base, and size have been previously initialised.
141 * It calls the driver initialisation function.
142 ******************************************************************************************
143 * @ dev_xp     : extended pointer on NIC-RX or NIC-TX device descriptor.
144 *****************************************************************************************/
145void dev_nic_init( xptr_t  dev_xp );
146
147/******************************************************************************************
148 * This blocking function must be called by the kernel thread running in the cluster
149 * containing the NIC_RX channel device descriptor.
150 * It read one packet (Ethernet/IPV4) from the NIC_RX queue associated to the NIC channel.
151 * It calls directly the NIC driver, without registering in a waiting queue, because
152 * only this NIC_RX thread can access this packets queue.
153 * 1) It test the packets queue status, using the NIC_CMD_WRITABLE command.
154 *    If it is empty, it unmask the NIC-RX channel IRQ, blocks and deschedule.
155 *    It is re-activated by the NIC-RX ISR (generated by the NIC) as soon as the queue
156 *    becomes not empty.
157 * 2) if the queue is not empty, it get one packet, using the driver NIC_CMD_READ command.
158 * Both commands are successively registered in the NIC-RX server thread descriptor
159 * to be passed to the driver.
160 *
161 * WARNING : for a RX packet the initiator is the NIC hardware, and the protocols
162 * stack is traversed upward, from the point of view of function calls.
163 ******************************************************************************************
164 * @ pkd     : pointer on packet descriptor (expected).
165 * @ returns 0 if success / returns non zero if ENOMEM, or error reported from NIC.
166 *****************************************************************************************/
167error_t dev_nic_read( pkd_t * pkd );
168
169/******************************************************************************************
170 * This blocking function must be called by the kernel thread running in the cluster
171 * containing the NIC_TX channel device descriptor.
172 * It writes one packet (Ethernet/IPV4) to the NIC_RX queue associated to the NIC channel.
173 * It calls directly the NIC driver, without registering in a waiting queue, because
174 * only this NIC_TX thread can access this packets queue.
175 * 1) It test the packets queue status, using the NIC_CMD_READABLE command.
176 *    If it is full, it unmask the NIC-TX channel IRQ, blocks and deschedule.
177 *    It is re-activated by the NIC-TX ISR (generated by the NIC) as soon as the queue
178 *    is not full.
179 * 2) If the queue is not empty, it put one packet, using the driver NIC_CMD_WRITE command.
180 * Both commands are successively registered in the NIC-TX server thread descriptor
181 * to be passed to the driver.
182 *
183 * WARNING : for a TX packet the initiator is the "client" thread, and the protocols
184 * stack is traversed downward from the point of view of function calls.
185 ******************************************************************************************
186 * @ pkd     : pointer on packet descriptor (to be filed).
187 * @ returns 0 if success / returns if length > 2K, undefined key, or error from NIC.
188 *****************************************************************************************/
189error_t dev_nic_write( pkd_t * pkd );
190
191
192/******************************************************************************************
193 * This function is executed by the server thread associated to a NIC channel device
194 * descriptor (RX or TX). This thread is created by the dev_nic_init() function.
195 * It executes an infinite loop, handling one packet per iteration.
196 *
197 * -- For a TX channel --
198 * 1) It allocates a 2 Kbytes buffer.
199 * 2) It copies the client TCP/UDP packet in this buffer.
200 * 3) It calls the IP layer to add the IP header.
201 * 4) It calls the ETH layer to add the ETH header.
202 * 5) It calls the dev_nic_write() blocking function to move the packet to the TX queue.
203 * 6) It releases the 2 Kbytes buffer.
204 *
205 * When the waiting threads queue is empty, it blocks on the THREAD_BLOCKED_IO_CMD
206 * condition and deschedule. It is re-activated by a client thread registering a command.
207 *
208 * -- For a RX channel --
209 * 1) It allocates a 2 Kbytes buffer.
210 * 2  It calls the dev_nic_read() blocking function to move the ETH packet to this buffer.
211 * 3) It calls the ETH layer to analyse the ETH header.
212 * 4) It calls the IP layer to analyse the IP header. TODO ???
213 * 5) It calls the transport (TCP/UDP) layer. TODO ???
214 * 5) It deliver the packet to the client thread. TODO ???
215 * 6) It releases the 2 Kbytes buffer.
216 *
217 * When the RX packets queue is empty, it blocks on the THREAD_BLOCKED_IO_CMD
218 * condition and deschedule. It is re-activated by the NIC driver when this queue
219 * becomes non empty.
220 ******************************************************************************************
221 * @ dev     : local pointer on NIC channel device descriptor.
222 *****************************************************************************************/
223void dev_nic_server( struct device_s * dev );
224
225
226#endif  /* _DEV_NIC_H */
Note: See TracBrowser for help on using the repository browser.