1/**
2 * \file
3 * \brief Unidirectional bulk data transfer via shared memory
4 */
5
6/*
7 * Copyright (c) 2009, 2010, 2011, 2012, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#ifndef BULK_NET_BACKEND_H
16#define BULK_NET_BACKEND_H
17
18#include <if/e10k_defs.h>
19#include <dev/e10k_dev.h>
20
21#include <bulk_transfer/bulk_net_proxy.h>
22
23#include "e10k_queue.h"
24
25
26/*
27 * DEFINES FOR DEBUG OUTPUT
28 */
29/// enables/disables the entire debug outputs of the bulk net backend
30#define BULK_NET_ENABLE_DEBUG 1
31
32/// enables/disables status messages
33#define BULK_NET_ENABLE_STATUS 1
34
35/// enables/disables the tracing debug output
36#define BULK_NET_ENABLE_TRACE 0
37
38/// enables/disables the debug output for the e10k module
39#define BULK_NET_ENABLE_DEBUG_E10K 0
40#define BULK_NET_ENABLE_STATUS_E10K 0
41
42/// enables/disables the debug output for the transfer module
43#define BULK_NET_ENABLE_DEBUG_TRANSF 0
44#define BULK_NET_ENABLE_STATUS_TRANSF 0
45
46/// enables/disables the debug output for the backend module
47#define BULK_NET_ENABLE_DEBUG_BACKEND 1
48#define BULK_NET_ENABLE_STATUS_BACKEND 1
49
50#if BULK_NET_ENABLE_DEBUG
51#define BULK_NET_DEBUG(fmt, msg...) debug_printf("%s(): "fmt"\n", __func__,  msg);
52#else
53#define BULK_NET_DEBUG(x...) do {} while(0);
54#endif
55
56#if BULK_NET_ENABLE_STATUS
57#define BULK_NET_STATUS(fmt, msg...) debug_printf("%s(): "fmt"\n", __func__,  msg);
58#else
59#define BULK_NET_STATUS(x...) do {} while(0);
60#endif
61
62#if BULK_NET_ENABLE_DEBUG && BULK_NET_ENABLE_TRACE
63#define BULK_NET_TRACE debug_printf("%s\n", __func__);
64#else
65#define BULK_NET_TRACE do{} while(0);
66#endif
67
68
69/*
70 * the following values are used in the endpoint creation
71 */
72#define BULK_NET_DEFAULT_BUFFER_SIZE 0x1000
73#define BULK_NET_DEFAULT_BUFFER_COUNT 0xFF
74#define BULK_NET_NOCOPY_SPARE_BUFFERS 1.5
75#define BULK_NET_DEFAULT_QUEUES 2
76
77#define BULK_NET_NOCOPY_META_BUFFER_SIZE 512
78
79#define BULK_NET_TRANSFER_NUM_DESCS 1024
80
81#define BULK_NET_TRANSFER_DESCLEN 4
82
83#define BULK_NET_INTERNAL_BUFER_SIZE 512
84
85struct bulk_implementation *bulk_net_get_impl(void);
86struct bulk_implementation *bulk_net_get_impl_no_copy(void);
87
88
89
90/// switch to turn on message dumping
91#define DO_MSG_DUMP 0
92
93
94#define BULK_NET_DESCLEN 4
95
96struct receive_buffer {
97    void     *hdr_virt;
98    uintptr_t hdr_phys;
99
100    void     *virt;
101    uintptr_t phys;
102
103    struct bulk_buffer *buffer;
104    bool                is_meta;
105};
106
107#define INT_BUFSZ 512
108struct transmit_buffer {
109    void     *hdr_virt;
110    uintptr_t hdr_phys;
111
112    bool is_copy;
113    struct bulk_buffer *buffer;
114    struct bulk_continuation cont;
115
116    void *int_virt;
117    uintptr_t int_phys;
118};
119
120
121struct packet_header {
122    struct {
123        uint8_t dmac[6];
124        uint8_t smac[6];
125        uint16_t type;
126    } __attribute__((packed)) l2;
127    struct {
128        uint8_t ver_ihl;
129        uint8_t dscp;
130        uint16_t len;
131        uint16_t id;
132        uint16_t offset;
133        uint8_t ttl;
134        uint8_t proto;
135        uint16_t checksum;
136        uint32_t s_ip;
137        uint32_t d_ip;
138    } __attribute__((packed)) l3;
139    struct {
140        uint16_t s_port;
141        uint16_t d_port;
142        uint16_t len;
143        uint16_t checksum;
144    } __attribute__((packed)) l4;
145} __attribute__((packed));
146
147
148/**
149 * Descriptor for passing around buffer chains with a reasonable length. Note
150 * that only the parts up to the first one with size == 0 are considered.
151 */
152struct bulk_net_msgdesc {
153    struct {
154        uint64_t phys;
155        size_t   size;
156        void    *opaque;
157    } parts[BULK_NET_DESCLEN];
158};
159
160
161#define E10K_HDRSZ 128
162#define E10K_DESCSZ (sizeof(e10k_q_tdesc_adv_wb_array_t))
163
164
165void stack_alloc_init(struct stack_allocator *alloc, size_t size);
166bool stack_alloc_free(struct stack_allocator *alloc, void *el);
167void *stack_alloc_alloc(struct stack_allocator *alloc);
168
169
170
171/******************************************************************************/
172/* e10k direct access channel */
173
174/**
175 * Initialize directly mapped RX/TX queue pair with e10k NIC.
176 *
177 * @param bu          Channel struct
178 * @param ws          Waitset
179 * @param card        Card name
180 * @param queue       Queue ID to use
181 * @param buffer_size Size of receive buffers in bytes
182 * @param ring_size   Number of descriptors in the RX/TX rings
183 * @param received    Callback for a received packet
184 * @param transmitted Callback for a transmitted packet
185 */
186errval_t bulk_e10k_init(struct bulk_e10k *bu,
187                        struct waitset *ws,
188                        const char *card,
189                        uint8_t queue,
190                        size_t buffer_size,
191                        size_t ring_size,
192                        void (*received)(struct bulk_e10k *,
193                                         struct bulk_net_msgdesc *),
194                        void (*transmitted)(struct bulk_e10k *, void *));
195
196/**
197 * Add a buffer to the receive queue.
198 *
199 * @param bu     Channel struct
200 * @param phys   Physical address of buffer
201 * @param header Physical address of header buffer (needs E10K_HDRSZ bytes)
202 * @param opaque User-Data for this buffer, will be returned when it is used in
203 *               a received packet.
204 */
205errval_t bulk_e10k_rx_add(struct bulk_e10k *bu, uint64_t phys, uint64_t header,
206                          void *opaque);
207
208/**
209 * Send out a packet.
210 *
211 * @param bu   Channel struct
212 * @param decs Descriptor for buffer chain to transmit
213 */
214errval_t bulk_e10k_send(struct bulk_e10k *bu, struct bulk_net_msgdesc *desc);
215
216
217/**
218 * Steer a specific UDP port to this queue.
219 *
220 * @param bu   Channel struct
221 * @param port Port to allocate (in host byte order)
222 */
223errval_t bulk_e10k_port_add(struct bulk_e10k *bu, uint16_t port);
224
225/**
226 * Allocate an unused UDP port and steer it to this queue.
227 *
228 * @param bu   Channel struct
229 * @param port Pointer to variable where port number will be stored (host byte
230 *             order)
231 */
232errval_t bulk_e10k_port_alloc(struct bulk_e10k *bu, uint16_t *port);
233
234/**
235 * Get IP address configured for this interface.
236 *
237 * @param bu Channel struct
238 * @param ip Pointer to variable where IP will be stored (host byte order)
239 */
240errval_t bulk_e10k_ip_info(struct bulk_e10k *bu, uint32_t *ip);
241
242/**
243 * Do an ARP lookup on this interface
244 *
245 * @param bu  Channnel struct
246 * @param ip  IP address to resolve (in host byte order)
247 * @param mac Pointer to variable where MAC address will be stored
248 */
249errval_t bulk_e10k_arp_lookup(struct bulk_e10k *bu, uint32_t ip, uint64_t *mac);
250
251/******************************************************************************/
252
253
254/** Allocate and map a frame */
255static inline errval_t allocmap_frame(size_t size, void **virt, uintptr_t *phys,
256                                      struct capref *cap)
257{
258    errval_t err;
259    struct frame_identity fid = { 0, 0 };
260    struct capref c;
261
262
263    err = frame_alloc(&c, size, NULL);
264    assert(err_is_ok(err));
265
266    if (phys) {
267        frame_identify(c, &fid);
268        *phys = fid.base;
269    }
270
271    err = vspace_map_one_frame_attr(virt, size, c,
272            VREGION_FLAGS_READ_WRITE, NULL, NULL);
273
274    if (cap != NULL) {
275        *cap = c;
276    }
277    return err;
278
279}
280
281
282#endif /* BULK_NET_BACKEND_H */
283