netmap_kern.h (2e159ef0b597a1f1b78c02b771524eabfa502626) | netmap_kern.h (17885a7bfde9d164e45a9833bb172215c55739f9) |
---|---|
1/* | 1/* |
2 * Copyright (C) 2011-2013 Matteo Landi, Luigi Rizzo. All rights reserved. 3 * Copyright (C) 2013 Universita` di Pisa. All rights reserved. | 2 * Copyright (C) 2011-2014 Matteo Landi, Luigi Rizzo. All rights reserved. 3 * Copyright (C) 2013-2014 Universita` di Pisa. All rights reserved. |
4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the --- 36 unchanged lines hidden (view full) --- 48#define NMG_LOCK_DESTROY() mtx_destroy(&netmap_global_lock) 49#define NMG_LOCK() mtx_lock(&netmap_global_lock) 50#define NMG_UNLOCK() mtx_unlock(&netmap_global_lock) 51#define NMG_LOCK_ASSERT() mtx_assert(&netmap_global_lock, MA_OWNED) 52 53#define NM_SELINFO_T struct selinfo 54#define MBUF_LEN(m) ((m)->m_pkthdr.len) 55#define MBUF_IFP(m) ((m)->m_pkthdr.rcvif) | 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the --- 36 unchanged lines hidden (view full) --- 48#define NMG_LOCK_DESTROY() mtx_destroy(&netmap_global_lock) 49#define NMG_LOCK() mtx_lock(&netmap_global_lock) 50#define NMG_UNLOCK() mtx_unlock(&netmap_global_lock) 51#define NMG_LOCK_ASSERT() mtx_assert(&netmap_global_lock, MA_OWNED) 52 53#define NM_SELINFO_T struct selinfo 54#define MBUF_LEN(m) ((m)->m_pkthdr.len) 55#define MBUF_IFP(m) ((m)->m_pkthdr.rcvif) |
56#define NM_SEND_UP(ifp, m) ((ifp)->if_input)(ifp, m) | 56#define NM_SEND_UP(ifp, m) ((NA(ifp))->if_input)(ifp, m) |
57 58#define NM_ATOMIC_T volatile int // XXX ? 59/* atomic operations */ 60#include <machine/atomic.h> 61#define NM_ATOMIC_TEST_AND_SET(p) (!atomic_cmpset_acq_int((p), 0, 1)) 62#define NM_ATOMIC_CLEAR(p) atomic_store_rel_int((p), 0) 63 64 --- 6 unchanged lines hidden (view full) --- 71}; 72 73#elif defined (linux) 74 75#define NM_LOCK_T safe_spinlock_t // see bsd_glue.h 76#define NM_SELINFO_T wait_queue_head_t 77#define MBUF_LEN(m) ((m)->len) 78#define MBUF_IFP(m) ((m)->dev) | 57 58#define NM_ATOMIC_T volatile int // XXX ? 59/* atomic operations */ 60#include <machine/atomic.h> 61#define NM_ATOMIC_TEST_AND_SET(p) (!atomic_cmpset_acq_int((p), 0, 1)) 62#define NM_ATOMIC_CLEAR(p) atomic_store_rel_int((p), 0) 63 64 --- 6 unchanged lines hidden (view full) --- 71}; 72 73#elif defined (linux) 74 75#define NM_LOCK_T safe_spinlock_t // see bsd_glue.h 76#define NM_SELINFO_T wait_queue_head_t 77#define MBUF_LEN(m) ((m)->len) 78#define MBUF_IFP(m) ((m)->dev) |
79#define NM_SEND_UP(ifp, m) netif_rx(m) | 79#define NM_SEND_UP(ifp, m) \ 80 do { \ 81 m->priority = NM_MAGIC_PRIORITY; \ 82 netif_rx(m); \ 83 } while (0) |
80 81#define NM_ATOMIC_T volatile long unsigned int 82 83// XXX a mtx would suffice here too 20130404 gl 84#define NMG_LOCK_T struct semaphore 85#define NMG_LOCK_INIT() sema_init(&netmap_global_lock, 1) 86#define NMG_LOCK_DESTROY() 87#define NMG_LOCK() down(&netmap_global_lock) --- 32 unchanged lines hidden (view full) --- 120 121#endif /* end - platform-specific code */ 122 123#define ND(format, ...) 124#define D(format, ...) \ 125 do { \ 126 struct timeval __xxts; \ 127 microtime(&__xxts); \ | 84 85#define NM_ATOMIC_T volatile long unsigned int 86 87// XXX a mtx would suffice here too 20130404 gl 88#define NMG_LOCK_T struct semaphore 89#define NMG_LOCK_INIT() sema_init(&netmap_global_lock, 1) 90#define NMG_LOCK_DESTROY() 91#define NMG_LOCK() down(&netmap_global_lock) --- 32 unchanged lines hidden (view full) --- 124 125#endif /* end - platform-specific code */ 126 127#define ND(format, ...) 128#define D(format, ...) \ 129 do { \ 130 struct timeval __xxts; \ 131 microtime(&__xxts); \ |
128 printf("%03d.%06d %s [%d] " format "\n", \ | 132 printf("%03d.%06d [%4d] %-25s " format "\n", \ |
129 (int)__xxts.tv_sec % 1000, (int)__xxts.tv_usec, \ | 133 (int)__xxts.tv_sec % 1000, (int)__xxts.tv_usec, \ |
130 __FUNCTION__, __LINE__, ##__VA_ARGS__); \ | 134 __LINE__, __FUNCTION__, ##__VA_ARGS__); \ |
131 } while (0) 132 133/* rate limited, lps indicates how many per second */ 134#define RD(lps, format, ...) \ 135 do { \ 136 static int t0, __cnt; \ 137 if (t0 != time_second) { \ 138 t0 = time_second; \ --- 14 unchanged lines hidden (view full) --- 153 154extern NMG_LOCK_T netmap_global_lock; 155 156/* 157 * private, kernel view of a ring. Keeps track of the status of 158 * a ring across system calls. 159 * 160 * nr_hwcur index of the next buffer to refill. | 135 } while (0) 136 137/* rate limited, lps indicates how many per second */ 138#define RD(lps, format, ...) \ 139 do { \ 140 static int t0, __cnt; \ 141 if (t0 != time_second) { \ 142 t0 = time_second; \ --- 14 unchanged lines hidden (view full) --- 157 158extern NMG_LOCK_T netmap_global_lock; 159 160/* 161 * private, kernel view of a ring. Keeps track of the status of 162 * a ring across system calls. 163 * 164 * nr_hwcur index of the next buffer to refill. |
161 * It corresponds to ring->cur - ring->reserved | 165 * It corresponds to ring->head 166 * at the time the system call returns. |
162 * | 167 * |
163 * nr_hwavail the number of slots "owned" by userspace. 164 * nr_hwavail =:= ring->avail + ring->reserved | 168 * nr_hwtail index of the first buffer owned by the kernel. 169 * On RX, hwcur->hwtail are receive buffers 170 * not yet released. hwcur is advanced following 171 * ring->head, hwtail is advanced on incoming packets, 172 * and a wakeup is generated when hwtail passes ring->cur 173 * On TX, hwcur->rcur have been filled by the sender 174 * but not sent yet to the NIC; rcur->hwtail are available 175 * for new transmissions, and hwtail->hwcur-1 are pending 176 * transmissions not yet acknowledged. |
165 * 166 * The indexes in the NIC and netmap rings are offset by nkr_hwofs slots. 167 * This is so that, on a reset, buffers owned by userspace are not 168 * modified by the kernel. In particular: | 177 * 178 * The indexes in the NIC and netmap rings are offset by nkr_hwofs slots. 179 * This is so that, on a reset, buffers owned by userspace are not 180 * modified by the kernel. In particular: |
169 * RX rings: the next empty buffer (hwcur + hwavail + hwofs) coincides with | 181 * RX rings: the next empty buffer (hwtail + hwofs) coincides with |
170 * the next empty buffer as known by the hardware (next_to_check or so). 171 * TX rings: hwcur + hwofs coincides with next_to_send 172 * 173 * Clients cannot issue concurrent syscall on a ring. The system 174 * detects this and reports an error using two flags, 175 * NKR_WBUSY and NKR_RBUSY 176 * For received packets, slot->flags is set to nkr_slot_flags 177 * so we can provide a proper initial value (e.g. set NS_FORWARD 178 * when operating in 'transparent' mode). 179 * 180 * The following fields are used to implement lock-free copy of packets 181 * from input to output ports in VALE switch: 182 * nkr_hwlease buffer after the last one being copied. 183 * A writer in nm_bdg_flush reserves N buffers 184 * from nr_hwlease, advances it, then does the 185 * copy outside the lock. 186 * In RX rings (used for VALE ports), | 182 * the next empty buffer as known by the hardware (next_to_check or so). 183 * TX rings: hwcur + hwofs coincides with next_to_send 184 * 185 * Clients cannot issue concurrent syscall on a ring. The system 186 * detects this and reports an error using two flags, 187 * NKR_WBUSY and NKR_RBUSY 188 * For received packets, slot->flags is set to nkr_slot_flags 189 * so we can provide a proper initial value (e.g. set NS_FORWARD 190 * when operating in 'transparent' mode). 191 * 192 * The following fields are used to implement lock-free copy of packets 193 * from input to output ports in VALE switch: 194 * nkr_hwlease buffer after the last one being copied. 195 * A writer in nm_bdg_flush reserves N buffers 196 * from nr_hwlease, advances it, then does the 197 * copy outside the lock. 198 * In RX rings (used for VALE ports), |
187 * nkr_hwcur + nkr_hwavail <= nkr_hwlease < nkr_hwcur+N-1 | 199 * nkr_hwtail <= nkr_hwlease < nkr_hwcur+N-1 |
188 * In TX rings (used for NIC or host stack ports) | 200 * In TX rings (used for NIC or host stack ports) |
189 * nkr_hwcur <= nkr_hwlease < nkr_hwcur+ nkr_hwavail | 201 * nkr_hwcur <= nkr_hwlease < nkr_hwtail |
190 * nkr_leases array of nkr_num_slots where writers can report 191 * completion of their block. NR_NOSLOT (~0) indicates 192 * that the writer has not finished yet 193 * nkr_lease_idx index of next free slot in nr_leases, to be assigned 194 * 195 * The kring is manipulated by txsync/rxsync and generic netmap function. | 202 * nkr_leases array of nkr_num_slots where writers can report 203 * completion of their block. NR_NOSLOT (~0) indicates 204 * that the writer has not finished yet 205 * nkr_lease_idx index of next free slot in nr_leases, to be assigned 206 * 207 * The kring is manipulated by txsync/rxsync and generic netmap function. |
196 * q_lock is used to arbitrate access to the kring from within the netmap 197 * code, and this and other protections guarantee that there is never 198 * more than 1 concurrent call to txsync or rxsync. So we are free 199 * to manipulate the kring from within txsync/rxsync without any extra 200 * locks. | 208 * 209 * Concurrent rxsync or txsync on the same ring are prevented through 210 * by nm_kr_lock() which in turn uses nr_busy. This is all we need 211 * for NIC rings, and for TX rings attached to the host stack. 212 * 213 * RX rings attached to the host stack use an mbq (rx_queue) on both 214 * rxsync_from_host() and netmap_transmit(). The mbq is protected 215 * by its internal lock. 216 * 217 * RX rings attached to the VALE switch are accessed by both sender 218 * and receiver. They are protected through the q_lock on the RX ring. |
201 */ 202struct netmap_kring { | 219 */ 220struct netmap_kring { |
203 struct netmap_ring *ring; 204 uint32_t nr_hwcur; 205 uint32_t nr_hwavail; 206 uint32_t nr_kflags; /* private driver flags */ 207 int32_t nr_hwreserved; 208#define NKR_PENDINTR 0x1 // Pending interrupt. 209 uint32_t nkr_num_slots; 210 int32_t nkr_hwofs; /* offset between NIC and netmap ring */ | 221 struct netmap_ring *ring; |
211 | 222 |
223 uint32_t nr_hwcur; 224 uint32_t nr_hwtail; 225 226 /* 227 * Copies of values in user rings, so we do not need to look 228 * at the ring (which could be modified). These are set in the 229 * *sync_prologue()/finalize() routines. 230 */ 231 uint32_t rhead; 232 uint32_t rcur; 233 uint32_t rtail; 234 235 uint32_t nr_kflags; /* private driver flags */ 236#define NKR_PENDINTR 0x1 // Pending interrupt. 237 uint32_t nkr_num_slots; 238 239 /* 240 * On a NIC reset, the NIC ring indexes may be reset but the 241 * indexes in the netmap rings remain the same. nkr_hwofs 242 * keeps track of the offset between the two. 243 */ 244 int32_t nkr_hwofs; 245 |
|
212 uint16_t nkr_slot_flags; /* initial value for flags */ | 246 uint16_t nkr_slot_flags; /* initial value for flags */ |
247 248 /* last_reclaim is opaque marker to help reduce the frequency 249 * of operations such as reclaiming tx buffers. A possible use 250 * is set it to ticks and do the reclaim only once per tick. 251 */ 252 uint64_t last_reclaim; 253 254 255 NM_SELINFO_T si; /* poll/select wait queue */ 256 NM_LOCK_T q_lock; /* protects kring and ring. */ 257 NM_ATOMIC_T nr_busy; /* prevent concurrent syscalls */ 258 |
|
213 struct netmap_adapter *na; | 259 struct netmap_adapter *na; |
260 261 /* The folloiwing fields are for VALE switch support */ |
|
214 struct nm_bdg_fwd *nkr_ft; | 262 struct nm_bdg_fwd *nkr_ft; |
215 uint32_t *nkr_leases; 216#define NR_NOSLOT ((uint32_t)~0) 217 uint32_t nkr_hwlease; 218 uint32_t nkr_lease_idx; | 263 uint32_t *nkr_leases; 264#define NR_NOSLOT ((uint32_t)~0) /* used in nkr_*lease* */ 265 uint32_t nkr_hwlease; 266 uint32_t nkr_lease_idx; |
219 | 267 |
220 NM_SELINFO_T si; /* poll/select wait queue */ 221 NM_LOCK_T q_lock; /* protects kring and ring. */ 222 NM_ATOMIC_T nr_busy; /* prevent concurrent syscalls */ | 268 volatile int nkr_stopped; // XXX what for ? |
223 | 269 |
224 volatile int nkr_stopped; 225 | |
226 /* support for adapters without native netmap support. 227 * On tx rings we preallocate an array of tx buffers 228 * (same size as the netmap ring), on rx rings we 229 * store incoming packets in a queue. 230 * XXX who writes to the rx queue ? 231 */ 232 struct mbuf **tx_pool; | 270 /* support for adapters without native netmap support. 271 * On tx rings we preallocate an array of tx buffers 272 * (same size as the netmap ring), on rx rings we 273 * store incoming packets in a queue. 274 * XXX who writes to the rx queue ? 275 */ 276 struct mbuf **tx_pool; |
233 u_int nr_ntc; /* Emulation of a next-to-clean RX ring pointer. */ 234 struct mbq rx_queue; /* A queue for intercepted rx mbufs. */ | 277 // u_int nr_ntc; /* Emulation of a next-to-clean RX ring pointer. */ 278 struct mbq rx_queue; /* intercepted rx mbufs. */ |
235 | 279 |
280 uint32_t ring_id; /* debugging */ 281 char name[64]; /* diagnostic */ 282 |
|
236} __attribute__((__aligned__(64))); 237 238 239/* return the next index, with wraparound */ 240static inline uint32_t 241nm_next(uint32_t i, uint32_t lim) 242{ 243 return unlikely (i == lim) ? 0 : i + 1; 244} 245 | 283} __attribute__((__aligned__(64))); 284 285 286/* return the next index, with wraparound */ 287static inline uint32_t 288nm_next(uint32_t i, uint32_t lim) 289{ 290 return unlikely (i == lim) ? 0 : i + 1; 291} 292 |
293 294/* return the previous index, with wraparound */ 295static inline uint32_t 296nm_prev(uint32_t i, uint32_t lim) 297{ 298 return unlikely (i == 0) ? lim : i - 1; 299} 300 301 |
|
246/* 247 * 248 * Here is the layout for the Rx and Tx rings. 249 250 RxRING TxRING 251 252 +-----------------+ +-----------------+ 253 | | | | 254 |XXX free slot XXX| |XXX free slot XXX| 255 +-----------------+ +-----------------+ | 302/* 303 * 304 * Here is the layout for the Rx and Tx rings. 305 306 RxRING TxRING 307 308 +-----------------+ +-----------------+ 309 | | | | 310 |XXX free slot XXX| |XXX free slot XXX| 311 +-----------------+ +-----------------+ |
256 | |<-hwcur | |<-hwcur 257 | reserved h | | (ready | 258 +----------- w -+ | to be | 259 cur->| a | | sent) h | 260 | v | +---------- w | 261 | a | cur->| (being a | 262 | i | | prepared) v | 263 | avail l | | a | 264 +-----------------+ + a ------ i + 265 | | ... | v l |<-hwlease 266 | (being | ... | a | ... 267 | prepared) | ... | i | ... 268 +-----------------+ ... | l | ... | 312head->| owned by user |<-hwcur | not sent to nic |<-hwcur 313 | | | yet | 314 +-----------------+ | | 315 cur->| available to | | | 316 | user, not read | +-----------------+ 317 | yet | cur->| (being | 318 | | | prepared) | 319 | | | | 320 +-----------------+ + ------ + 321tail->| |<-hwtail | |<-hwlease 322 | (being | ... | | ... 323 | prepared) | ... | | ... 324 +-----------------+ ... | | ... |
269 | |<-hwlease +-----------------+ | 325 | |<-hwlease +-----------------+ |
326 | | tail->| |<-hwtail |
|
270 | | | | 271 | | | | 272 | | | | | 327 | | | | 328 | | | | 329 | | | | |
273 | | | | | |
274 +-----------------+ +-----------------+ 275 | 330 +-----------------+ +-----------------+ 331 |
276 * The cur/avail (user view) and hwcur/hwavail (kernel view) | 332 * The cur/tail (user view) and hwcur/hwtail (kernel view) |
277 * are used in the normal operation of the card. 278 * 279 * When a ring is the output of a switch port (Rx ring for 280 * a VALE port, Tx ring for the host stack or NIC), slots 281 * are reserved in blocks through 'hwlease' which points 282 * to the next unused slot. | 333 * are used in the normal operation of the card. 334 * 335 * When a ring is the output of a switch port (Rx ring for 336 * a VALE port, Tx ring for the host stack or NIC), slots 337 * are reserved in blocks through 'hwlease' which points 338 * to the next unused slot. |
283 * On an Rx ring, hwlease is always after hwavail, 284 * and completions cause avail to advance. 285 * On a Tx ring, hwlease is always between cur and hwavail, | 339 * On an Rx ring, hwlease is always after hwtail, 340 * and completions cause hwtail to advance. 341 * On a Tx ring, hwlease is always between cur and hwtail, |
286 * and completions cause cur to advance. 287 * 288 * nm_kr_space() returns the maximum number of slots that 289 * can be assigned. 290 * nm_kr_lease() reserves the required number of buffers, 291 * advances nkr_hwlease and also returns an entry in 292 * a circular array where completions should be reported. 293 */ 294 295 296 | 342 * and completions cause cur to advance. 343 * 344 * nm_kr_space() returns the maximum number of slots that 345 * can be assigned. 346 * nm_kr_lease() reserves the required number of buffers, 347 * advances nkr_hwlease and also returns an entry in 348 * a circular array where completions should be reported. 349 */ 350 351 352 |
297 | |
298enum txrx { NR_RX = 0, NR_TX = 1 }; 299 300/* 301 * The "struct netmap_adapter" extends the "struct adapter" 302 * (or equivalent) device descriptor. 303 * It contains all base fields needed to support netmap operation. 304 * There are in fact different types of netmap adapters 305 * (native, generic, VALE switch...) so a netmap_adapter is --- 38 unchanged lines hidden (view full) --- 344 u_int num_rx_desc; 345 346 /* tx_rings and rx_rings are private but allocated 347 * as a contiguous chunk of memory. Each array has 348 * N+1 entries, for the adapter queues and for the host queue. 349 */ 350 struct netmap_kring *tx_rings; /* array of TX rings. */ 351 struct netmap_kring *rx_rings; /* array of RX rings. */ | 353enum txrx { NR_RX = 0, NR_TX = 1 }; 354 355/* 356 * The "struct netmap_adapter" extends the "struct adapter" 357 * (or equivalent) device descriptor. 358 * It contains all base fields needed to support netmap operation. 359 * There are in fact different types of netmap adapters 360 * (native, generic, VALE switch...) so a netmap_adapter is --- 38 unchanged lines hidden (view full) --- 399 u_int num_rx_desc; 400 401 /* tx_rings and rx_rings are private but allocated 402 * as a contiguous chunk of memory. Each array has 403 * N+1 entries, for the adapter queues and for the host queue. 404 */ 405 struct netmap_kring *tx_rings; /* array of TX rings. */ 406 struct netmap_kring *rx_rings; /* array of RX rings. */ |
407 |
|
352 void *tailroom; /* space below the rings array */ 353 /* (used for leases) */ 354 355 356 NM_SELINFO_T tx_si, rx_si; /* global wait queues */ 357 358 /* copy of if_qflush and if_transmit pointers, to intercept 359 * packets from the network stack when netmap is active. 360 */ 361 int (*if_transmit)(struct ifnet *, struct mbuf *); 362 | 408 void *tailroom; /* space below the rings array */ 409 /* (used for leases) */ 410 411 412 NM_SELINFO_T tx_si, rx_si; /* global wait queues */ 413 414 /* copy of if_qflush and if_transmit pointers, to intercept 415 * packets from the network stack when netmap is active. 416 */ 417 int (*if_transmit)(struct ifnet *, struct mbuf *); 418 |
419 /* copy of if_input for netmap_send_up() */ 420 void (*if_input)(struct ifnet *, struct mbuf *); 421 |
|
363 /* references to the ifnet and device routines, used by 364 * the generic netmap functions. 365 */ 366 struct ifnet *ifp; /* adapter is ifp->if_softc */ 367 | 422 /* references to the ifnet and device routines, used by 423 * the generic netmap functions. 424 */ 425 struct ifnet *ifp; /* adapter is ifp->if_softc */ 426 |
427 /*---- callbacks for this netmap adapter -----*/ 428 /* 429 * nm_dtor() is the cleanup routine called when destroying 430 * the adapter. 431 * 432 * nm_register() is called on NIOCREGIF and close() to enter 433 * or exit netmap mode on the NIC 434 * 435 * nm_txsync() pushes packets to the underlying hw/switch 436 * 437 * nm_rxsync() collects packets from the underlying hw/switch 438 * 439 * nm_config() returns configuration information from the OS 440 * 441 * nm_krings_create() XXX 442 * 443 * nm_krings_delete() XXX 444 * 445 * nm_notify() is used to act after data have become available. 446 * For hw devices this is typically a selwakeup(), 447 * but for NIC/host ports attached to a switch (or vice-versa) 448 * we also need to invoke the 'txsync' code downstream. 449 */ 450 |
|
368 /* private cleanup */ 369 void (*nm_dtor)(struct netmap_adapter *); 370 371 int (*nm_register)(struct netmap_adapter *, int onoff); 372 373 int (*nm_txsync)(struct netmap_adapter *, u_int ring, int flags); 374 int (*nm_rxsync)(struct netmap_adapter *, u_int ring, int flags); 375#define NAF_FORCE_READ 1 --- 22 unchanged lines hidden (view full) --- 398 uint32_t na_lut_objtotal; /* max buffer index */ 399 400 /* used internally. If non-null, the interface cannot be bound 401 * from userspace 402 */ 403 void *na_private; 404}; 405 | 451 /* private cleanup */ 452 void (*nm_dtor)(struct netmap_adapter *); 453 454 int (*nm_register)(struct netmap_adapter *, int onoff); 455 456 int (*nm_txsync)(struct netmap_adapter *, u_int ring, int flags); 457 int (*nm_rxsync)(struct netmap_adapter *, u_int ring, int flags); 458#define NAF_FORCE_READ 1 --- 22 unchanged lines hidden (view full) --- 481 uint32_t na_lut_objtotal; /* max buffer index */ 482 483 /* used internally. If non-null, the interface cannot be bound 484 * from userspace 485 */ 486 void *na_private; 487}; 488 |
489 |
|
406/* 407 * If the NIC is owned by the kernel 408 * (i.e., bridge), neither another bridge nor user can use it; 409 * if the NIC is owned by a user, only users can share it. 410 * Evaluation must be done under NMG_LOCK(). 411 */ 412#define NETMAP_OWNED_BY_KERN(na) (na->na_private) 413#define NETMAP_OWNED_BY_ANY(na) \ --- 14 unchanged lines hidden (view full) --- 428 */ 429 int bdg_port; 430 struct nm_bridge *na_bdg; 431 int retry; 432 433 u_int offset; /* Offset of ethernet header for each packet. */ 434}; 435 | 490/* 491 * If the NIC is owned by the kernel 492 * (i.e., bridge), neither another bridge nor user can use it; 493 * if the NIC is owned by a user, only users can share it. 494 * Evaluation must be done under NMG_LOCK(). 495 */ 496#define NETMAP_OWNED_BY_KERN(na) (na->na_private) 497#define NETMAP_OWNED_BY_ANY(na) \ --- 14 unchanged lines hidden (view full) --- 512 */ 513 int bdg_port; 514 struct nm_bridge *na_bdg; 515 int retry; 516 517 u_int offset; /* Offset of ethernet header for each packet. */ 518}; 519 |
520 |
|
436struct netmap_hw_adapter { /* physical device */ 437 struct netmap_adapter up; 438 439 struct net_device_ops nm_ndo; // XXX linux only 440}; 441 | 521struct netmap_hw_adapter { /* physical device */ 522 struct netmap_adapter up; 523 524 struct net_device_ops nm_ndo; // XXX linux only 525}; 526 |
442struct netmap_generic_adapter { /* non-native device */ | 527 528struct netmap_generic_adapter { /* emulated device */ |
443 struct netmap_hw_adapter up; 444 445 /* Pointer to a previously used netmap adapter. */ 446 struct netmap_adapter *prev; 447 448 /* generic netmap adapters support: 449 * a net_device_ops struct overrides ndo_select_queue(), 450 * save_if_input saves the if_input hook (FreeBSD), 451 * mit_timer and mit_pending implement rx interrupt mitigation, 452 */ 453 struct net_device_ops generic_ndo; 454 void (*save_if_input)(struct ifnet *, struct mbuf *); 455 456 struct hrtimer mit_timer; 457 int mit_pending; | 529 struct netmap_hw_adapter up; 530 531 /* Pointer to a previously used netmap adapter. */ 532 struct netmap_adapter *prev; 533 534 /* generic netmap adapters support: 535 * a net_device_ops struct overrides ndo_select_queue(), 536 * save_if_input saves the if_input hook (FreeBSD), 537 * mit_timer and mit_pending implement rx interrupt mitigation, 538 */ 539 struct net_device_ops generic_ndo; 540 void (*save_if_input)(struct ifnet *, struct mbuf *); 541 542 struct hrtimer mit_timer; 543 int mit_pending; |
544#ifdef linux 545 netdev_tx_t (*save_start_xmit)(struct mbuf *, struct ifnet *); 546#endif |
|
458}; 459 460#ifdef WITH_VALE 461 | 547}; 548 549#ifdef WITH_VALE 550 |
462/* bridge wrapper for non VALE ports. It is used to connect real devices to the bridge. | 551/* 552 * Bridge wrapper for non VALE ports attached to a VALE switch. |
463 * | 553 * |
464 * The real device must already have its own netmap adapter (hwna). The 465 * bridge wrapper and the hwna adapter share the same set of netmap rings and 466 * buffers, but they have two separate sets of krings descriptors, with tx/rx 467 * meanings swapped: | 554 * The real device must already have its own netmap adapter (hwna). 555 * The bridge wrapper and the hwna adapter share the same set of 556 * netmap rings and buffers, but they have two separate sets of 557 * krings descriptors, with tx/rx meanings swapped: |
468 * 469 * netmap 470 * bwrap krings rings krings hwna 471 * +------+ +------+ +-----+ +------+ +------+ 472 * |tx_rings->| |\ /| |----| |<-tx_rings| 473 * | | +------+ \ / +-----+ +------+ | | 474 * | | X | | 475 * | | / \ | | 476 * | | +------+/ \+-----+ +------+ | | 477 * |rx_rings->| | | |----| |<-rx_rings| 478 * | | +------+ +-----+ +------+ | | 479 * +------+ +------+ 480 * | 558 * 559 * netmap 560 * bwrap krings rings krings hwna 561 * +------+ +------+ +-----+ +------+ +------+ 562 * |tx_rings->| |\ /| |----| |<-tx_rings| 563 * | | +------+ \ / +-----+ +------+ | | 564 * | | X | | 565 * | | / \ | | 566 * | | +------+/ \+-----+ +------+ | | 567 * |rx_rings->| | | |----| |<-rx_rings| 568 * | | +------+ +-----+ +------+ | | 569 * +------+ +------+ 570 * |
481 * - packets coming from the bridge go to the brwap rx rings, which are also the 482 * hwna tx rings. The bwrap notify callback will then complete the hwna tx 483 * (see netmap_bwrap_notify). 484 * - packets coming from the outside go to the hwna rx rings, which are also the 485 * bwrap tx rings. The (overwritten) hwna notify method will then complete 486 * the bridge tx (see netmap_bwrap_intr_notify). | 571 * - packets coming from the bridge go to the brwap rx rings, 572 * which are also the hwna tx rings. The bwrap notify callback 573 * will then complete the hwna tx (see netmap_bwrap_notify). |
487 * | 574 * |
488 * The bridge wrapper may optionally connect the hwna 'host' rings to the 489 * bridge. This is done by using a second port in the bridge and connecting it 490 * to the 'host' netmap_vp_adapter contained in the netmap_bwrap_adapter. 491 * The brwap host adapter cross-links the hwna host rings in the same way as shown above. | 575 * - packets coming from the outside go to the hwna rx rings, 576 * which are also the bwrap tx rings. The (overwritten) hwna 577 * notify method will then complete the bridge tx 578 * (see netmap_bwrap_intr_notify). |
492 * | 579 * |
493 * - packets coming from the bridge and directed to host stack are handled by the 494 * bwrap host notify callback (see netmap_bwrap_host_notify) 495 * - packets coming from the host stack are still handled by the overwritten 496 * hwna notify callback (netmap_bwrap_intr_notify), but are diverted to the 497 * host adapter depending on the ring number. | 580 * The bridge wrapper may optionally connect the hwna 'host' rings 581 * to the bridge. This is done by using a second port in the 582 * bridge and connecting it to the 'host' netmap_vp_adapter 583 * contained in the netmap_bwrap_adapter. The brwap host adapter 584 * cross-links the hwna host rings in the same way as shown above. |
498 * | 585 * |
586 * - packets coming from the bridge and directed to the host stack 587 * are handled by the bwrap host notify callback 588 * (see netmap_bwrap_host_notify) 589 * 590 * - packets coming from the host stack are still handled by the 591 * overwritten hwna notify callback (netmap_bwrap_intr_notify), 592 * but are diverted to the host adapter depending on the ring number. 593 * |
|
499 */ 500struct netmap_bwrap_adapter { 501 struct netmap_vp_adapter up; 502 struct netmap_vp_adapter host; /* for host rings */ 503 struct netmap_adapter *hwna; /* the underlying device */ 504 505 /* backup of the hwna notify callback */ 506 int (*save_notify)(struct netmap_adapter *, 507 u_int ring, enum txrx, int flags); | 594 */ 595struct netmap_bwrap_adapter { 596 struct netmap_vp_adapter up; 597 struct netmap_vp_adapter host; /* for host rings */ 598 struct netmap_adapter *hwna; /* the underlying device */ 599 600 /* backup of the hwna notify callback */ 601 int (*save_notify)(struct netmap_adapter *, 602 u_int ring, enum txrx, int flags); |
508 /* When we attach a physical interface to the bridge, we | 603 604 /* 605 * When we attach a physical interface to the bridge, we |
509 * allow the controlling process to terminate, so we need 510 * a place to store the netmap_priv_d data structure. | 606 * allow the controlling process to terminate, so we need 607 * a place to store the netmap_priv_d data structure. |
511 * This is only done when physical interfaces are attached to a bridge. | 608 * This is only done when physical interfaces 609 * are attached to a bridge. |
512 */ 513 struct netmap_priv_d *na_kpriv; 514}; 515 516 | 610 */ 611 struct netmap_priv_d *na_kpriv; 612}; 613 614 |
517/* 518 * Available space in the ring. Only used in VALE code 519 */ 520static inline uint32_t 521nm_kr_space(struct netmap_kring *k, int is_rx) 522{ 523 int space; | 615#endif /* WITH_VALE */ |
524 | 616 |
525 if (is_rx) { 526 int busy = k->nkr_hwlease - k->nr_hwcur + k->nr_hwreserved; 527 if (busy < 0) 528 busy += k->nkr_num_slots; 529 space = k->nkr_num_slots - 1 - busy; 530 } else { 531 space = k->nr_hwcur + k->nr_hwavail - k->nkr_hwlease; 532 if (space < 0) 533 space += k->nkr_num_slots; 534 } 535#if 0 536 // sanity check 537 if (k->nkr_hwlease >= k->nkr_num_slots || 538 k->nr_hwcur >= k->nkr_num_slots || 539 k->nr_hwavail >= k->nkr_num_slots || 540 busy < 0 || 541 busy >= k->nkr_num_slots) { 542 D("invalid kring, cur %d avail %d lease %d lease_idx %d lim %d", k->nr_hwcur, k->nr_hwavail, k->nkr_hwlease, 543 k->nkr_lease_idx, k->nkr_num_slots); 544 } 545#endif 546 return space; 547} | |
548 | 617 |
549 550 551 552/* make a lease on the kring for N positions. return the 553 * lease index 554 */ | 618/* return slots reserved to rx clients; used in drivers */ |
555static inline uint32_t | 619static inline uint32_t |
556nm_kr_lease(struct netmap_kring *k, u_int n, int is_rx) | 620nm_kr_rxspace(struct netmap_kring *k) |
557{ | 621{ |
558 uint32_t lim = k->nkr_num_slots - 1; 559 uint32_t lease_idx = k->nkr_lease_idx; | 622 int space = k->nr_hwtail - k->nr_hwcur; 623 if (space < 0) 624 space += k->nkr_num_slots; 625 ND("preserving %d rx slots %d -> %d", space, k->nr_hwcur, k->nr_hwtail); |
560 | 626 |
561 k->nkr_leases[lease_idx] = NR_NOSLOT; 562 k->nkr_lease_idx = nm_next(lease_idx, lim); 563 564 if (n > nm_kr_space(k, is_rx)) { 565 D("invalid request for %d slots", n); 566 panic("x"); 567 } 568 /* XXX verify that there are n slots */ 569 k->nkr_hwlease += n; 570 if (k->nkr_hwlease > lim) 571 k->nkr_hwlease -= lim + 1; 572 573 if (k->nkr_hwlease >= k->nkr_num_slots || 574 k->nr_hwcur >= k->nkr_num_slots || 575 k->nr_hwavail >= k->nkr_num_slots || 576 k->nkr_lease_idx >= k->nkr_num_slots) { 577 D("invalid kring %s, cur %d avail %d lease %d lease_idx %d lim %d", 578 k->na->ifp->if_xname, 579 k->nr_hwcur, k->nr_hwavail, k->nkr_hwlease, 580 k->nkr_lease_idx, k->nkr_num_slots); 581 } 582 return lease_idx; | 627 return space; |
583} 584 | 628} 629 |
585#endif /* WITH_VALE */ | |
586 | 630 |
587/* return update position */ 588static inline uint32_t 589nm_kr_rxpos(struct netmap_kring *k) | 631/* True if no space in the tx ring. only valid after txsync_prologue */ 632static inline int 633nm_kr_txempty(struct netmap_kring *kring) |
590{ | 634{ |
591 uint32_t pos = k->nr_hwcur + k->nr_hwavail; 592 if (pos >= k->nkr_num_slots) 593 pos -= k->nkr_num_slots; 594#if 0 595 if (pos >= k->nkr_num_slots || 596 k->nkr_hwlease >= k->nkr_num_slots || 597 k->nr_hwcur >= k->nkr_num_slots || 598 k->nr_hwavail >= k->nkr_num_slots || 599 k->nkr_lease_idx >= k->nkr_num_slots) { 600 D("invalid kring, cur %d avail %d lease %d lease_idx %d lim %d", k->nr_hwcur, k->nr_hwavail, k->nkr_hwlease, 601 k->nkr_lease_idx, k->nkr_num_slots); 602 } 603#endif 604 return pos; | 635 return kring->rcur == kring->nr_hwtail; |
605} 606 607 608/* 609 * protect against multiple threads using the same ring. 610 * also check that the ring has not been stopped. 611 * We only care for 0 or !=0 as a return code. 612 */ 613#define NM_KR_BUSY 1 614#define NM_KR_STOPPED 2 615 | 636} 637 638 639/* 640 * protect against multiple threads using the same ring. 641 * also check that the ring has not been stopped. 642 * We only care for 0 or !=0 as a return code. 643 */ 644#define NM_KR_BUSY 1 645#define NM_KR_STOPPED 2 646 |
647 |
|
616static __inline void nm_kr_put(struct netmap_kring *kr) 617{ 618 NM_ATOMIC_CLEAR(&kr->nr_busy); 619} 620 | 648static __inline void nm_kr_put(struct netmap_kring *kr) 649{ 650 NM_ATOMIC_CLEAR(&kr->nr_busy); 651} 652 |
653 |
|
621static __inline int nm_kr_tryget(struct netmap_kring *kr) 622{ 623 /* check a first time without taking the lock 624 * to avoid starvation for nm_kr_get() 625 */ 626 if (unlikely(kr->nkr_stopped)) { 627 ND("ring %p stopped (%d)", kr, kr->nkr_stopped); 628 return NM_KR_STOPPED; --- 6 unchanged lines hidden (view full) --- 635 nm_kr_put(kr); 636 return NM_KR_STOPPED; 637 } 638 return 0; 639} 640 641 642/* | 654static __inline int nm_kr_tryget(struct netmap_kring *kr) 655{ 656 /* check a first time without taking the lock 657 * to avoid starvation for nm_kr_get() 658 */ 659 if (unlikely(kr->nkr_stopped)) { 660 ND("ring %p stopped (%d)", kr, kr->nkr_stopped); 661 return NM_KR_STOPPED; --- 6 unchanged lines hidden (view full) --- 668 nm_kr_put(kr); 669 return NM_KR_STOPPED; 670 } 671 return 0; 672} 673 674 675/* |
643 * The following are support routines used by individual drivers to | 676 * The following functions are used by individual drivers to |
644 * support netmap operation. 645 * 646 * netmap_attach() initializes a struct netmap_adapter, allocating the 647 * struct netmap_ring's and the struct selinfo. 648 * 649 * netmap_detach() frees the memory allocated by netmap_attach(). 650 * 651 * netmap_transmit() replaces the if_transmit routine of the interface, --- 9 unchanged lines hidden (view full) --- 661int netmap_attach_common(struct netmap_adapter *); 662void netmap_detach_common(struct netmap_adapter *na); 663void netmap_detach(struct ifnet *); 664int netmap_transmit(struct ifnet *, struct mbuf *); 665struct netmap_slot *netmap_reset(struct netmap_adapter *na, 666 enum txrx tx, u_int n, u_int new_cur); 667int netmap_ring_reinit(struct netmap_kring *); 668 | 677 * support netmap operation. 678 * 679 * netmap_attach() initializes a struct netmap_adapter, allocating the 680 * struct netmap_ring's and the struct selinfo. 681 * 682 * netmap_detach() frees the memory allocated by netmap_attach(). 683 * 684 * netmap_transmit() replaces the if_transmit routine of the interface, --- 9 unchanged lines hidden (view full) --- 694int netmap_attach_common(struct netmap_adapter *); 695void netmap_detach_common(struct netmap_adapter *na); 696void netmap_detach(struct ifnet *); 697int netmap_transmit(struct ifnet *, struct mbuf *); 698struct netmap_slot *netmap_reset(struct netmap_adapter *na, 699 enum txrx tx, u_int n, u_int new_cur); 700int netmap_ring_reinit(struct netmap_kring *); 701 |
669/* set/clear native flags. XXX maybe also if_transmit ? */ | 702/* default functions to handle rx/tx interrupts */ 703int netmap_rx_irq(struct ifnet *, u_int, u_int *); 704#define netmap_tx_irq(_n, _q) netmap_rx_irq(_n, _q, NULL) 705void netmap_common_irq(struct ifnet *, u_int, u_int *work_done); 706 707void netmap_disable_all_rings(struct ifnet *); 708void netmap_enable_all_rings(struct ifnet *); 709void netmap_disable_ring(struct netmap_kring *kr); 710 711 712/* set/clear native flags and if_transmit/netdev_ops */ |
670static inline void 671nm_set_native_flags(struct netmap_adapter *na) 672{ 673 struct ifnet *ifp = na->ifp; 674 675 na->na_flags |= (NAF_NATIVE_ON | NAF_NETMAP_ON); 676#ifdef IFCAP_NETMAP /* or FreeBSD ? */ 677 ifp->if_capenable |= IFCAP_NETMAP; 678#endif 679#ifdef __FreeBSD__ 680 na->if_transmit = ifp->if_transmit; 681 ifp->if_transmit = netmap_transmit; 682#else 683 na->if_transmit = (void *)ifp->netdev_ops; 684 ifp->netdev_ops = &((struct netmap_hw_adapter *)na)->nm_ndo; 685#endif 686} 687 | 713static inline void 714nm_set_native_flags(struct netmap_adapter *na) 715{ 716 struct ifnet *ifp = na->ifp; 717 718 na->na_flags |= (NAF_NATIVE_ON | NAF_NETMAP_ON); 719#ifdef IFCAP_NETMAP /* or FreeBSD ? */ 720 ifp->if_capenable |= IFCAP_NETMAP; 721#endif 722#ifdef __FreeBSD__ 723 na->if_transmit = ifp->if_transmit; 724 ifp->if_transmit = netmap_transmit; 725#else 726 na->if_transmit = (void *)ifp->netdev_ops; 727 ifp->netdev_ops = &((struct netmap_hw_adapter *)na)->nm_ndo; 728#endif 729} 730 |
731 |
|
688static inline void 689nm_clear_native_flags(struct netmap_adapter *na) 690{ 691 struct ifnet *ifp = na->ifp; 692 693#ifdef __FreeBSD__ 694 ifp->if_transmit = na->if_transmit; 695#else 696 ifp->netdev_ops = (void *)na->if_transmit; 697#endif 698 na->na_flags &= ~(NAF_NATIVE_ON | NAF_NETMAP_ON); 699#ifdef IFCAP_NETMAP /* or FreeBSD ? */ 700 ifp->if_capenable &= ~IFCAP_NETMAP; 701#endif 702} 703 | 732static inline void 733nm_clear_native_flags(struct netmap_adapter *na) 734{ 735 struct ifnet *ifp = na->ifp; 736 737#ifdef __FreeBSD__ 738 ifp->if_transmit = na->if_transmit; 739#else 740 ifp->netdev_ops = (void *)na->if_transmit; 741#endif 742 na->na_flags &= ~(NAF_NATIVE_ON | NAF_NETMAP_ON); 743#ifdef IFCAP_NETMAP /* or FreeBSD ? */ 744 ifp->if_capenable &= ~IFCAP_NETMAP; 745#endif 746} 747 |
748 |
|
704/* | 749/* |
705 * validates parameters in the ring/kring, returns a value for cur, 706 * and the 'new_slots' value in the argument. 707 * If any error, returns cur > lim to force a reinit. | 750 * validates parameters in the ring/kring, returns a value for head 751 * If any error, returns ring_size to force a reinit. |
708 */ | 752 */ |
709u_int nm_txsync_prologue(struct netmap_kring *, u_int *); | 753uint32_t nm_txsync_prologue(struct netmap_kring *); |
710 | 754 |
755 |
|
711/* | 756/* |
712 * validates parameters in the ring/kring, returns a value for cur, | 757 * validates parameters in the ring/kring, returns a value for head, |
713 * and the 'reserved' value in the argument. | 758 * and the 'reserved' value in the argument. |
714 * If any error, returns cur > lim to force a reinit. | 759 * If any error, returns ring_size lim to force a reinit. |
715 */ | 760 */ |
716u_int nm_rxsync_prologue(struct netmap_kring *, u_int *); | 761uint32_t nm_rxsync_prologue(struct netmap_kring *); |
717 | 762 |
763 |
|
718/* | 764/* |
719 * update kring and ring at the end of txsync | 765 * update kring and ring at the end of txsync. |
720 */ 721static inline void | 766 */ 767static inline void |
722nm_txsync_finalize(struct netmap_kring *kring, u_int cur) | 768nm_txsync_finalize(struct netmap_kring *kring) |
723{ | 769{ |
724 /* recompute hwreserved */ 725 kring->nr_hwreserved = cur - kring->nr_hwcur; 726 if (kring->nr_hwreserved < 0) 727 kring->nr_hwreserved += kring->nkr_num_slots; | 770 /* update ring head/tail to what the kernel knows */ 771 kring->ring->tail = kring->rtail = kring->nr_hwtail; 772 kring->ring->head = kring->rhead = kring->nr_hwcur; 773 774 /* note, head/rhead/hwcur might be behind cur/rcur 775 * if no carrier 776 */ 777 ND(5, "%s now hwcur %d hwtail %d head %d cur %d tail %d", 778 kring->name, kring->nr_hwcur, kring->nr_hwtail, 779 kring->rhead, kring->rcur, kring->rtail); 780} |
728 | 781 |
729 /* update avail and reserved to what the kernel knows */ 730 kring->ring->avail = kring->nr_hwavail; 731 kring->ring->reserved = kring->nr_hwreserved; | 782 783/* 784 * update kring and ring at the end of rxsync 785 */ 786static inline void 787nm_rxsync_finalize(struct netmap_kring *kring) 788{ 789 /* tell userspace that there might be new packets */ 790 //struct netmap_ring *ring = kring->ring; 791 ND("head %d cur %d tail %d -> %d", ring->head, ring->cur, ring->tail, 792 kring->nr_hwtail); 793 kring->ring->tail = kring->rtail = kring->nr_hwtail; 794 /* make a copy of the state for next round */ 795 kring->rhead = kring->ring->head; 796 kring->rcur = kring->ring->cur; |
732} 733 | 797} 798 |
799 |
|
734/* check/fix address and len in tx rings */ 735#if 1 /* debug version */ 736#define NM_CHECK_ADDR_LEN(_a, _l) do { \ 737 if (_a == netmap_buffer_base || _l > NETMAP_BUF_SIZE) { \ 738 RD(5, "bad addr/len ring %d slot %d idx %d len %d", \ 739 ring_nr, nm_i, slot->buf_idx, len); \ 740 if (_l > NETMAP_BUF_SIZE) \ 741 _l = NETMAP_BUF_SIZE; \ --- 8 unchanged lines hidden (view full) --- 750 751/*---------------------------------------------------------------*/ 752/* 753 * Support routines to be used with the VALE switch 754 */ 755int netmap_update_config(struct netmap_adapter *na); 756int netmap_krings_create(struct netmap_adapter *na, u_int ntx, u_int nrx, u_int tailroom); 757void netmap_krings_delete(struct netmap_adapter *na); | 800/* check/fix address and len in tx rings */ 801#if 1 /* debug version */ 802#define NM_CHECK_ADDR_LEN(_a, _l) do { \ 803 if (_a == netmap_buffer_base || _l > NETMAP_BUF_SIZE) { \ 804 RD(5, "bad addr/len ring %d slot %d idx %d len %d", \ 805 ring_nr, nm_i, slot->buf_idx, len); \ 806 if (_l > NETMAP_BUF_SIZE) \ 807 _l = NETMAP_BUF_SIZE; \ --- 8 unchanged lines hidden (view full) --- 816 817/*---------------------------------------------------------------*/ 818/* 819 * Support routines to be used with the VALE switch 820 */ 821int netmap_update_config(struct netmap_adapter *na); 822int netmap_krings_create(struct netmap_adapter *na, u_int ntx, u_int nrx, u_int tailroom); 823void netmap_krings_delete(struct netmap_adapter *na); |
824int netmap_rxsync_from_host(struct netmap_adapter *na, struct thread *td, void *pwait); |
|
758 | 825 |
826 |
|
759struct netmap_if * 760netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na, 761 uint16_t ringid, int *err); 762 763 764 765u_int nm_bound_var(u_int *v, u_int dflt, u_int lo, u_int hi, const char *msg); 766int netmap_get_na(struct nmreq *nmr, struct netmap_adapter **na, int create); 767int netmap_get_hw_na(struct ifnet *ifp, struct netmap_adapter **na); 768 | 827struct netmap_if * 828netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na, 829 uint16_t ringid, int *err); 830 831 832 833u_int nm_bound_var(u_int *v, u_int dflt, u_int lo, u_int hi, const char *msg); 834int netmap_get_na(struct nmreq *nmr, struct netmap_adapter **na, int create); 835int netmap_get_hw_na(struct ifnet *ifp, struct netmap_adapter **na); 836 |
837 |
|
769#ifdef WITH_VALE 770/* | 838#ifdef WITH_VALE 839/* |
771 * The following bridge-related interfaces are used by other kernel modules 772 * In the version that only supports unicast or broadcast, the lookup | 840 * The following bridge-related functions are used by other 841 * kernel modules. 842 * 843 * VALE only supports unicast or broadcast. The lookup |
773 * function can return 0 .. NM_BDG_MAXPORTS-1 for regular ports, 774 * NM_BDG_MAXPORTS for broadcast, NM_BDG_MAXPORTS+1 for unknown. 775 * XXX in practice "unknown" might be handled same as broadcast. 776 */ 777typedef u_int (*bdg_lookup_fn_t)(char *buf, u_int len, 778 uint8_t *ring_nr, struct netmap_vp_adapter *); 779u_int netmap_bdg_learning(char *, u_int, uint8_t *, 780 struct netmap_vp_adapter *); --- 13 unchanged lines hidden (view full) --- 794#else /* !WITH_VALE */ 795#define netmap_get_bdg_na(_1, _2, _3) 0 796#define netmap_init_bridges(_1) 797#define netmap_bdg_ctl(_1, _2) EINVAL 798#endif /* !WITH_VALE */ 799 800/* Various prototypes */ 801int netmap_poll(struct cdev *dev, int events, struct thread *td); | 844 * function can return 0 .. NM_BDG_MAXPORTS-1 for regular ports, 845 * NM_BDG_MAXPORTS for broadcast, NM_BDG_MAXPORTS+1 for unknown. 846 * XXX in practice "unknown" might be handled same as broadcast. 847 */ 848typedef u_int (*bdg_lookup_fn_t)(char *buf, u_int len, 849 uint8_t *ring_nr, struct netmap_vp_adapter *); 850u_int netmap_bdg_learning(char *, u_int, uint8_t *, 851 struct netmap_vp_adapter *); --- 13 unchanged lines hidden (view full) --- 865#else /* !WITH_VALE */ 866#define netmap_get_bdg_na(_1, _2, _3) 0 867#define netmap_init_bridges(_1) 868#define netmap_bdg_ctl(_1, _2) EINVAL 869#endif /* !WITH_VALE */ 870 871/* Various prototypes */ 872int netmap_poll(struct cdev *dev, int events, struct thread *td); |
802 803 | |
804int netmap_init(void); 805void netmap_fini(void); 806int netmap_get_memory(struct netmap_priv_d* p); 807void netmap_dtor(void *data); 808int netmap_dtor_locked(struct netmap_priv_d *priv); 809 810int netmap_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td); 811 812/* netmap_adapter creation/destruction */ 813#define NM_IFPNAME(ifp) ((ifp) ? (ifp)->if_xname : "zombie") | 873int netmap_init(void); 874void netmap_fini(void); 875int netmap_get_memory(struct netmap_priv_d* p); 876void netmap_dtor(void *data); 877int netmap_dtor_locked(struct netmap_priv_d *priv); 878 879int netmap_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td); 880 881/* netmap_adapter creation/destruction */ 882#define NM_IFPNAME(ifp) ((ifp) ? (ifp)->if_xname : "zombie") |
814#define NM_DEBUG_PUTGET 1 | |
815 | 883 |
884// #define NM_DEBUG_PUTGET 1 885 |
|
816#ifdef NM_DEBUG_PUTGET 817 818#define NM_DBG(f) __##f 819 820void __netmap_adapter_get(struct netmap_adapter *na); 821 822#define netmap_adapter_get(na) \ 823 do { \ --- 15 unchanged lines hidden (view full) --- 839 840#define NM_DBG(f) f 841void netmap_adapter_get(struct netmap_adapter *na); 842int netmap_adapter_put(struct netmap_adapter *na); 843 844#endif /* !NM_DEBUG_PUTGET */ 845 846 | 886#ifdef NM_DEBUG_PUTGET 887 888#define NM_DBG(f) __##f 889 890void __netmap_adapter_get(struct netmap_adapter *na); 891 892#define netmap_adapter_get(na) \ 893 do { \ --- 15 unchanged lines hidden (view full) --- 909 910#define NM_DBG(f) f 911void netmap_adapter_get(struct netmap_adapter *na); 912int netmap_adapter_put(struct netmap_adapter *na); 913 914#endif /* !NM_DEBUG_PUTGET */ 915 916 |
917/* 918 * module variables 919 */ |
|
847extern u_int netmap_buf_size; 848#define NETMAP_BUF_SIZE netmap_buf_size // XXX remove | 920extern u_int netmap_buf_size; 921#define NETMAP_BUF_SIZE netmap_buf_size // XXX remove |
849extern int netmap_mitigate; | 922extern int netmap_mitigate; // XXX not really used |
850extern int netmap_no_pendintr; | 923extern int netmap_no_pendintr; |
851extern u_int netmap_total_buffers; 852extern char *netmap_buffer_base; | 924extern u_int netmap_total_buffers; // global allocator 925extern char *netmap_buffer_base; // global allocator |
853extern int netmap_verbose; // XXX debugging 854enum { /* verbose flags */ 855 NM_VERB_ON = 1, /* generic verbose */ 856 NM_VERB_HOST = 0x2, /* verbose host stack */ 857 NM_VERB_RXSYNC = 0x10, /* verbose on rxsync/txsync */ 858 NM_VERB_TXSYNC = 0x20, 859 NM_VERB_RXINTR = 0x100, /* verbose on rx/tx intr (driver) */ 860 NM_VERB_TXINTR = 0x200, --- 42 unchanged lines hidden (view full) --- 903 904#define NETMAP_SET_CAPABLE(ifp) \ 905 NA(ifp)->magic = ((uint32_t)(uintptr_t)NA(ifp)) ^ NETMAP_MAGIC 906 907#endif /* linux */ 908 909#ifdef __FreeBSD__ 910 | 926extern int netmap_verbose; // XXX debugging 927enum { /* verbose flags */ 928 NM_VERB_ON = 1, /* generic verbose */ 929 NM_VERB_HOST = 0x2, /* verbose host stack */ 930 NM_VERB_RXSYNC = 0x10, /* verbose on rxsync/txsync */ 931 NM_VERB_TXSYNC = 0x20, 932 NM_VERB_RXINTR = 0x100, /* verbose on rx/tx intr (driver) */ 933 NM_VERB_TXINTR = 0x200, --- 42 unchanged lines hidden (view full) --- 976 977#define NETMAP_SET_CAPABLE(ifp) \ 978 NA(ifp)->magic = ((uint32_t)(uintptr_t)NA(ifp)) ^ NETMAP_MAGIC 979 980#endif /* linux */ 981 982#ifdef __FreeBSD__ 983 |
911/* Callback invoked by the dma machinery after a successfull dmamap_load */ | 984/* Callback invoked by the dma machinery after a successful dmamap_load */ |
912static void netmap_dmamap_cb(__unused void *arg, 913 __unused bus_dma_segment_t * segs, __unused int nseg, __unused int error) 914{ 915} 916 917/* bus_dmamap_load wrapper: call aforementioned function if map != NULL. 918 * XXX can we do it without a callback ? 919 */ --- 128 unchanged lines hidden (view full) --- 1048BDG_NMB(struct netmap_adapter *na, struct netmap_slot *slot) 1049{ 1050 struct lut_entry *lut = na->na_lut; 1051 uint32_t i = slot->buf_idx; 1052 return (unlikely(i >= na->na_lut_objtotal)) ? 1053 lut[0].vaddr : lut[i].vaddr; 1054} 1055 | 985static void netmap_dmamap_cb(__unused void *arg, 986 __unused bus_dma_segment_t * segs, __unused int nseg, __unused int error) 987{ 988} 989 990/* bus_dmamap_load wrapper: call aforementioned function if map != NULL. 991 * XXX can we do it without a callback ? 992 */ --- 128 unchanged lines hidden (view full) --- 1121BDG_NMB(struct netmap_adapter *na, struct netmap_slot *slot) 1122{ 1123 struct lut_entry *lut = na->na_lut; 1124 uint32_t i = slot->buf_idx; 1125 return (unlikely(i >= na->na_lut_objtotal)) ? 1126 lut[0].vaddr : lut[i].vaddr; 1127} 1128 |
1056/* default functions to handle rx/tx interrupts */ 1057int netmap_rx_irq(struct ifnet *, u_int, u_int *); 1058#define netmap_tx_irq(_n, _q) netmap_rx_irq(_n, _q, NULL) 1059void netmap_common_irq(struct ifnet *, u_int, u_int *work_done); | |
1060 1061 1062void netmap_txsync_to_host(struct netmap_adapter *na); | 1129 1130 1131void netmap_txsync_to_host(struct netmap_adapter *na); |
1063void netmap_disable_all_rings(struct ifnet *); 1064void netmap_enable_all_rings(struct ifnet *); 1065void netmap_disable_ring(struct netmap_kring *kr); | |
1066 1067 | 1132 1133 |
1068/* Structure associated to each thread which registered an interface. | 1134/* 1135 * Structure associated to each thread which registered an interface. |
1069 * 1070 * The first 4 fields of this structure are written by NIOCREGIF and 1071 * read by poll() and NIOC?XSYNC. | 1136 * 1137 * The first 4 fields of this structure are written by NIOCREGIF and 1138 * read by poll() and NIOC?XSYNC. |
1072 * There is low contention among writers (actually, a correct user program 1073 * should have no contention among writers) and among writers and readers, 1074 * so we use a single global lock to protect the structure initialization. 1075 * Since initialization involves the allocation of memory, we reuse the memory 1076 * allocator lock. | 1139 * 1140 * There is low contention among writers (a correct user program 1141 * should have none) and among writers and readers, so we use a 1142 * single global lock to protect the structure initialization; 1143 * since initialization involves the allocation of memory, 1144 * we reuse the memory allocator lock. 1145 * |
1077 * Read access to the structure is lock free. Readers must check that 1078 * np_nifp is not NULL before using the other fields. | 1146 * Read access to the structure is lock free. Readers must check that 1147 * np_nifp is not NULL before using the other fields. |
1079 * If np_nifp is NULL initialization has not been performed, so they should 1080 * return an error to userlevel. | 1148 * If np_nifp is NULL initialization has not been performed, 1149 * so they should return an error to userspace. |
1081 * 1082 * The ref_done field is used to regulate access to the refcount in the 1083 * memory allocator. The refcount must be incremented at most once for 1084 * each open("/dev/netmap"). The increment is performed by the first 1085 * function that calls netmap_get_memory() (currently called by 1086 * mmap(), NIOCGINFO and NIOCREGIF). 1087 * If the refcount is incremented, it is then decremented when the 1088 * private structure is destroyed. 1089 */ 1090struct netmap_priv_d { 1091 struct netmap_if * volatile np_nifp; /* netmap if descriptor. */ 1092 1093 struct netmap_adapter *np_na; | 1150 * 1151 * The ref_done field is used to regulate access to the refcount in the 1152 * memory allocator. The refcount must be incremented at most once for 1153 * each open("/dev/netmap"). The increment is performed by the first 1154 * function that calls netmap_get_memory() (currently called by 1155 * mmap(), NIOCGINFO and NIOCREGIF). 1156 * If the refcount is incremented, it is then decremented when the 1157 * private structure is destroyed. 1158 */ 1159struct netmap_priv_d { 1160 struct netmap_if * volatile np_nifp; /* netmap if descriptor. */ 1161 1162 struct netmap_adapter *np_na; |
1094 int np_ringid; /* from the ioctl */ 1095 u_int np_qfirst, np_qlast; /* range of rings to scan */ 1096 uint16_t np_txpoll; | 1163 int np_ringid; /* from the ioctl */ 1164 u_int np_qfirst, np_qlast; /* range of rings to scan */ 1165 uint16_t np_txpoll; |
1097 1098 struct netmap_mem_d *np_mref; /* use with NMG_LOCK held */ 1099 /* np_refcount is only used on FreeBSD */ | 1166 1167 struct netmap_mem_d *np_mref; /* use with NMG_LOCK held */ 1168 /* np_refcount is only used on FreeBSD */ |
1100 int np_refcount; /* use with NMG_LOCK held */ | 1169 int np_refcount; /* use with NMG_LOCK held */ |
1101}; 1102 1103 1104/* 1105 * generic netmap emulation for devices that do not have 1106 * native netmap support. | 1170}; 1171 1172 1173/* 1174 * generic netmap emulation for devices that do not have 1175 * native netmap support. |
1107 * XXX generic_netmap_register() is only exported to implement 1108 * nma_is_generic(). | |
1109 */ | 1176 */ |
1110int generic_netmap_register(struct netmap_adapter *na, int enable); | |
1111int generic_netmap_attach(struct ifnet *ifp); 1112 1113int netmap_catch_rx(struct netmap_adapter *na, int intercept); 1114void generic_rx_handler(struct ifnet *ifp, struct mbuf *m);; | 1177int generic_netmap_attach(struct ifnet *ifp); 1178 1179int netmap_catch_rx(struct netmap_adapter *na, int intercept); 1180void generic_rx_handler(struct ifnet *ifp, struct mbuf *m);; |
1115void netmap_catch_packet_steering(struct netmap_generic_adapter *na, int enable); | 1181void netmap_catch_tx(struct netmap_generic_adapter *na, int enable); |
1116int generic_xmit_frame(struct ifnet *ifp, struct mbuf *m, void *addr, u_int len, u_int ring_nr); 1117int generic_find_num_desc(struct ifnet *ifp, u_int *tx, u_int *rx); 1118void generic_find_num_queues(struct ifnet *ifp, u_int *txq, u_int *rxq); 1119 | 1182int generic_xmit_frame(struct ifnet *ifp, struct mbuf *m, void *addr, u_int len, u_int ring_nr); 1183int generic_find_num_desc(struct ifnet *ifp, u_int *tx, u_int *rx); 1184void generic_find_num_queues(struct ifnet *ifp, u_int *txq, u_int *rxq); 1185 |
1120static __inline int 1121nma_is_generic(struct netmap_adapter *na) 1122{ 1123 return na->nm_register == generic_netmap_register; 1124} 1125 | |
1126/* 1127 * netmap_mitigation API. This is used by the generic adapter 1128 * to reduce the number of interrupt requests/selwakeup 1129 * to clients on incoming packets. 1130 */ 1131void netmap_mitigation_init(struct netmap_generic_adapter *na); 1132void netmap_mitigation_start(struct netmap_generic_adapter *na); 1133void netmap_mitigation_restart(struct netmap_generic_adapter *na); 1134int netmap_mitigation_active(struct netmap_generic_adapter *na); 1135void netmap_mitigation_cleanup(struct netmap_generic_adapter *na); 1136 | 1186/* 1187 * netmap_mitigation API. This is used by the generic adapter 1188 * to reduce the number of interrupt requests/selwakeup 1189 * to clients on incoming packets. 1190 */ 1191void netmap_mitigation_init(struct netmap_generic_adapter *na); 1192void netmap_mitigation_start(struct netmap_generic_adapter *na); 1193void netmap_mitigation_restart(struct netmap_generic_adapter *na); 1194int netmap_mitigation_active(struct netmap_generic_adapter *na); 1195void netmap_mitigation_cleanup(struct netmap_generic_adapter *na); 1196 |
1137// int generic_timer_handler(struct hrtimer *t); 1138 | |
1139#endif /* _NET_NETMAP_KERN_H_ */ | 1197#endif /* _NET_NETMAP_KERN_H_ */ |