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, Universitaetstrasse 6, 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, 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