[75] | 1 | /* |
---|
| 2 | * soclib_nic.h - SOCLIB_NIC (Network Interface Controler) driver definition. |
---|
| 3 | * |
---|
[658] | 4 | * Author Alain Greiner (2016,2017,2018,2019,2020) |
---|
[75] | 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-MKH; if not, write to the Free Software Foundation, |
---|
| 21 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
---|
| 22 | */ |
---|
| 23 | |
---|
| 24 | #ifndef _SOCLIB_NIC_H_ |
---|
| 25 | #define _SOCLIB_NIC_H_ |
---|
| 26 | |
---|
| 27 | #include <chdev.h> |
---|
[451] | 28 | #include <hal_kernel_types.h> |
---|
[75] | 29 | |
---|
| 30 | /******************************************************************************************** |
---|
| 31 | * This driver supports the Soclib VciMasterNic component, that is a GMII compliant |
---|
[658] | 32 | * multi-channels Gigabit Ethernet controler with a DMA capability. |
---|
[75] | 33 | * |
---|
[658] | 34 | * To improve the throughput, this component supports several channels. |
---|
| 35 | * The channel index is derived from the (source) remote IP address and port |
---|
| 36 | * for the received (RX) packets, and from the (destination) remote IP address |
---|
| 37 | * and port for the sent (TX) packets. The actual number of channels is an |
---|
| 38 | * hardware parameter that cannot be larger than 8. |
---|
| 39 | * |
---|
| 40 | * The Ethernet packet length can have any value, in range [42,1538] bytes. |
---|
[75] | 41 | * |
---|
[658] | 42 | * For each channel, the received packets (RX) and the sent packets (TX) are stored |
---|
| 43 | * in two memory mapped software FIFOs, called NIC_TX_QUEUE and NIC_RX_QUEUE, implemented |
---|
| 44 | * as chained buffers (chbuf). Each slot in these FIFOs is a container, containing one |
---|
| 45 | * single packet. The number of containers, defining the queue depth, is a software defined |
---|
| 46 | * parameter. The data transfer unit between is a container (one single packet). |
---|
[75] | 47 | * |
---|
[658] | 48 | * - The "container" structure contains a 2040 bytes data buffer, the packet length, and |
---|
| 49 | * the container state : full (owned by the reader) / empty (owned by the writer). |
---|
| 50 | * For each container, the state variable is used as a SET/RESET flip-flop to synchronize |
---|
| 51 | * the software server thread, and the hardware NIC DMA engines. |
---|
[75] | 52 | * |
---|
[658] | 53 | * - The "chbuf" descriptor contains an array of local pointers on the containers, used |
---|
| 54 | * by the software driver, an array of physical addresses, used by the DMA engines and |
---|
| 55 | * two "pointers", defining the current container to be written (wid) by the writer, |
---|
| 56 | * and the current container to be read (rid) by the reader. |
---|
[75] | 57 | * |
---|
[658] | 58 | * WARNING : Both the chbuf descriptor (containing the <rid> and wid> indexes), and the |
---|
| 59 | * containers themselve containing the <data> and the <sts> are shared variables |
---|
| 60 | * accessed by the server threads (accessing the L2 caches), and by the NIC_DMA |
---|
| 61 | * engines (accessing directly the L3 caches). |
---|
| 62 | * Therefore, the L2/L3 cache coherence must be handled by this NIC driver for |
---|
| 63 | * the INIT, READ & WRITE commands, using the MMC SYNC & INVAL commands. |
---|
[75] | 64 | *******************************************************************************************/ |
---|
| 65 | |
---|
| 66 | /******************************************************************************************** |
---|
[658] | 67 | * This section defines the NIC device addressable registers offsets: |
---|
| 68 | * - The 8 channels registers are stored in the first 512 bytes (8 * 64 bytes). |
---|
| 69 | * - The global registers are stored in the next 256 bytes (global offset is 512 bytes). |
---|
| 70 | * All values defined below are number of words (one word = 4 bytes). |
---|
[75] | 71 | *******************************************************************************************/ |
---|
| 72 | |
---|
| 73 | enum SoclibMasterNicGlobalRegisters |
---|
| 74 | { |
---|
[658] | 75 | NIC_G_CHANNELS = 1, /*! read_only : number of channels */ |
---|
| 76 | NIC_G_NPKT_RESET = 2, /*! write-only : reset packets counters */ |
---|
[75] | 77 | |
---|
| 78 | NIC_G_NPKT_RX_G2S_RECEIVED = 10, /*! number of packets received */ |
---|
| 79 | NIC_G_NPKT_RX_G2S_DISCARDED = 11, /*! number of RX packets discarded by RX_G2S */ |
---|
[658] | 80 | |
---|
[75] | 81 | NIC_G_NPKT_RX_DES_SUCCESS = 12, /*! number of RX packets transmited by RX_DES */ |
---|
| 82 | NIC_G_NPKT_RX_DES_TOO_SMALL = 13, /*! number of discarded too small RX packets */ |
---|
| 83 | NIC_G_NPKT_RX_DES_TOO_BIG = 14, /*! number of discarded too big RX packets */ |
---|
| 84 | NIC_G_NPKT_RX_DES_MFIFO_FULL = 15, /*! number of discarded RX packets fifo full */ |
---|
| 85 | NIC_G_NPKT_RX_DES_CRC_FAIL = 16, /*! number of discarded RX packets CRC32 */ |
---|
| 86 | |
---|
[658] | 87 | NIC_G_NPKT_RX_DISP_RECEIVED = 17, /*! number of packets received by RX_DISPATCH */ |
---|
| 88 | NIC_G_NPKT_RX_DISP_DST_FAIL = 18, /*! number of discarded RX packets for DST MAC */ |
---|
| 89 | NIC_G_NPKT_RX_DISP_CH_FULL = 19, /*! number of discarded RX packets cont full */ |
---|
[75] | 90 | |
---|
[658] | 91 | NIC_G_NPKT_TX_DISP_RECEIVED = 41, /*! number of packets received by TX_DISPATCH */ |
---|
| 92 | NIC_G_NPKT_TX_DISP_TOO_SMALL = 42, /*! number of discarded too small TX packets */ |
---|
| 93 | NIC_G_NPKT_TX_DISP_TOO_BIG = 43, /*! number of discarded too big TX packets */ |
---|
| 94 | NIC_G_NPKT_TX_DISP_TRANSMIT = 44, /*! number of discarded TX packets for SRC MAC */ |
---|
| 95 | |
---|
| 96 | NIC_GLOBAL_OFFSET = 128, /*! 512 bytes reserved for channel registers */ |
---|
[75] | 97 | }; |
---|
| 98 | |
---|
| 99 | enum SoclibMasterNicChannelRegisters |
---|
| 100 | { |
---|
[658] | 101 | NIC_RX_CHANNEL_RUN = 0, /*! write-only : RX channel activation/desactivation */ |
---|
| 102 | NIC_RX_CHBUF_DESC_LO = 1, /*! read-write : RX chbuf descriptor 32 LSB bits */ |
---|
| 103 | NIC_RX_CHBUF_DESC_HI = 2, /*! read-write : RX chbuf descriptor 32 MSB bits */ |
---|
[75] | 104 | NIC_RX_CHBUF_NBUFS = 3, /*! read-write : RX chbuf depth (number of buffers) */ |
---|
[658] | 105 | NIC_RX_CHANNEL_STATE = 4, /*! read-only : RX channel status */ |
---|
| 106 | |
---|
| 107 | NIC_TX_CHANNEL_RUN = 8, /*! write-only : TX channel activation */ |
---|
| 108 | NIC_TX_CHBUF_DESC_LO = 9, /*! read-write : TX chbuf descriptor 32 LSB bits */ |
---|
| 109 | NIC_TX_CHBUF_DESC_HI = 10, /*! read-write : TX chbuf descriptor 32 MSB bits */ |
---|
[75] | 110 | NIC_TX_CHBUF_NBUFS = 11, /*! read-write : TX chbuf depth (number of buffers) */ |
---|
[658] | 111 | NIC_TX_CHANNEL_STATE = 12, /*! read-only : TX channel status */ |
---|
[75] | 112 | |
---|
| 113 | NIC_CHANNEL_SPAN = 16 /*! 64 bytes per channel */ |
---|
| 114 | }; |
---|
| 115 | |
---|
[658] | 116 | /******************************************************************************************** |
---|
| 117 | * Return values for the RX/TX channel master FSM status |
---|
| 118 | *******************************************************************************************/ |
---|
[75] | 119 | |
---|
[658] | 120 | enum SoclibMasterNicStatusValues |
---|
| 121 | { |
---|
| 122 | NIC_CHANNEL_STATUS_IDLE = 0, |
---|
| 123 | NIC_CHANNEL_STATUS_ERROR = 1, |
---|
| 124 | NIC_CHANNEL_STATUS_BUSY = 2, // busy for any value >= 2 |
---|
| 125 | }; |
---|
| 126 | |
---|
[75] | 127 | /******************************************************************************************** |
---|
[658] | 128 | * This structure defines the chbuf descriptor, used to implement both the RX and TX packets |
---|
| 129 | * queues. Each container contains one single packet, and has only two states (full/empty). |
---|
| 130 | * All containers are allocated in the same cluster as the associated NIC chdev descriptor. |
---|
| 131 | * The chbuf descriptor contains: |
---|
| 132 | * - an array of containers physical addresses cont_pad[], used by the DMA engines. |
---|
| 133 | * - an array of container pointers cont_ptr[], used by the kernel threads. |
---|
| 134 | * - two indexes rid and wid, defining the next container for read & write respectively. |
---|
| 135 | * WARNING : dont modify this structure, used by the DMA engines. |
---|
[75] | 136 | *******************************************************************************************/ |
---|
| 137 | |
---|
[658] | 138 | #define SOCLIB_NIC_CHBUF_DEPTH 8 |
---|
| 139 | |
---|
[75] | 140 | typedef struct nic_chbuf_s |
---|
| 141 | { |
---|
[658] | 142 | uint32_t wid; /*! current container write index */ |
---|
| 143 | uint32_t rid; /*! current container read index */ |
---|
| 144 | uint64_t cont_pad[SOCLIB_NIC_CHBUF_DEPTH]; /*! containers physical base addresses */ |
---|
| 145 | uint32_t * cont_ptr[SOCLIB_NIC_CHBUF_DEPTH]; /*! containers virtual base addresses */ |
---|
[75] | 146 | } |
---|
| 147 | nic_chbuf_t; |
---|
| 148 | |
---|
| 149 | /******************************************************************************************** |
---|
[658] | 150 | * This structure defines the container descriptor format. |
---|
[75] | 151 | *******************************************************************************************/ |
---|
| 152 | |
---|
[658] | 153 | typedef struct nic_cont_s |
---|
| 154 | { |
---|
| 155 | uint8_t buf[2040]; /*! Ethernet packet (42 to 1538 bytes */ |
---|
| 156 | uint32_t length; /*! actual packet length in bytes */ |
---|
| 157 | uint32_t state; /*! zero == empty / non zero == full */ |
---|
| 158 | } |
---|
| 159 | nic_cont_t; |
---|
| 160 | |
---|
[75] | 161 | /******************************************************************************************** |
---|
[658] | 162 | * Driver access functions |
---|
| 163 | *******************************************************************************************/ |
---|
| 164 | |
---|
| 165 | /******************************************************************************************** |
---|
| 166 | * This function initializes the SOCLIB_NIC hardware registers, for one NIC chdev |
---|
| 167 | * (one direction of one channel). It allocates memory for the RX and TX containers, |
---|
| 168 | * it allocates and initializes the RX and TX chbuf descriptors. |
---|
[75] | 169 | * It allocates one WTI mailbox for the IRQ signaling availability of an RX full container, |
---|
| 170 | * or a TX empty container, and route the WTI IRQ to the core running the server thread. |
---|
[658] | 171 | * It activates the TX and RX DMA engines. |
---|
[75] | 172 | ******************************************************************************************** |
---|
| 173 | * @ chdev : pointer on NIC chdev descriptor. |
---|
| 174 | *******************************************************************************************/ |
---|
| 175 | extern void soclib_nic_init( chdev_t * chdev ); |
---|
| 176 | |
---|
| 177 | /******************************************************************************************** |
---|
[658] | 178 | * 1) This function implement the READ & WRITE commands, used by the local server threads |
---|
| 179 | * to access the NIC_TX & NIC_RX packets queues. These commands don't access the NIC |
---|
| 180 | * registers but only the TX and RX chbufs implementing the queues: |
---|
| 181 | * |
---|
| 182 | * <READ> |
---|
| 183 | * Move a packet from the NIC_RX queue to the command "buffer". |
---|
| 184 | * Return 0 in "status" if queue empty / return length in "status" if success. |
---|
| 185 | * |
---|
| 186 | * <WRITE> |
---|
[75] | 187 | * Move a packet of a given "length" from the command "buffer" to the TX queue. |
---|
[658] | 188 | * Return 0 in "status" if queue full / return length in "status" if success. |
---|
| 189 | * |
---|
| 190 | * 2) It implements the GET_KEY / SET_RUN / GET_INSTRU / CLEAR_INSTRU commands, |
---|
| 191 | * directly called by any thread running in any cluster to access the NIC registers : |
---|
| 192 | * |
---|
| 193 | * <GET_KEY> |
---|
| 194 | * Return in "status" argument the channel index (key) computed from the IP address |
---|
| 195 | * defined in the "buffer" argument, and from the port defined by the "length" argument. |
---|
| 196 | * |
---|
| 197 | * <SET_RUN> |
---|
| 198 | * Enable/disable the NIC_TX_CHANNEL_RUN & NIC_RX_CHANNEL_RUN registers.The channel |
---|
| 199 | * is defined in the "length" argument / run value defined in the "status" argument. |
---|
| 200 | * |
---|
| 201 | * <GET_INSTRU> |
---|
| 202 | * Display on kernel TXT0 the contaent of all NIC instrumentation registers. |
---|
| 203 | * |
---|
| 204 | * <CLEAR_INSTRU> |
---|
| 205 | * Reset all NIC instrumentation registers. |
---|
| 206 | * |
---|
| 207 | * Note (i) For the NIC device, the command arguments are always registered in the calling |
---|
| 208 | * thread descriptor (i.e. the calling thread is always the client thread). |
---|
| 209 | * Note (ii) The actual command mnemonics are defined in the <dev_nic.h> file. |
---|
[75] | 210 | *******************************************************************************************/ |
---|
| 211 | extern void soclib_nic_cmd( xptr_t thread_xp ); |
---|
| 212 | |
---|
| 213 | /******************************************************************************************** |
---|
[658] | 214 | * This ISR is executed when a new RX container has been moved to an empty TX queue, |
---|
| 215 | * or when a TX container has been removed from a full TX queue. In both cases, it |
---|
| 216 | * reactivate the corresponding server thread from the BLOCKED_ISR condition. |
---|
| 217 | * It is also executed in case of error reported by the DMA engines accessing the TX or RX |
---|
| 218 | * queues. It simply print an error message on the kernel terminal. |
---|
| 219 | * TODO improve this error handling... |
---|
[75] | 220 | ******************************************************************************************** |
---|
| 221 | * @ chdev : local pointer on NIC chdev descriptor. |
---|
| 222 | *******************************************************************************************/ |
---|
| 223 | extern void soclib_nic_isr( chdev_t * chdev ); |
---|
| 224 | |
---|
| 225 | |
---|
| 226 | #endif /* _BLOCK_H_ */ |
---|