1*68b8534bSLuigi Rizzo /* 2*68b8534bSLuigi Rizzo * Copyright (C) 2011 Matteo Landi, Luigi Rizzo. All rights reserved. 3*68b8534bSLuigi Rizzo * 4*68b8534bSLuigi Rizzo * Redistribution and use in source and binary forms, with or without 5*68b8534bSLuigi Rizzo * modification, are permitted provided that the following conditions 6*68b8534bSLuigi Rizzo * are met: 7*68b8534bSLuigi Rizzo * 1. Redistributions of source code must retain the above copyright 8*68b8534bSLuigi Rizzo * notice, this list of conditions and the following disclaimer. 9*68b8534bSLuigi Rizzo * 2. Redistributions in binary form must reproduce the above copyright 10*68b8534bSLuigi Rizzo * notice, this list of conditions and the following disclaimer in the 11*68b8534bSLuigi Rizzo * documentation and/or other materials provided with the distribution. 12*68b8534bSLuigi Rizzo * 13*68b8534bSLuigi Rizzo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14*68b8534bSLuigi Rizzo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15*68b8534bSLuigi Rizzo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16*68b8534bSLuigi Rizzo * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17*68b8534bSLuigi Rizzo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18*68b8534bSLuigi Rizzo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19*68b8534bSLuigi Rizzo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20*68b8534bSLuigi Rizzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21*68b8534bSLuigi Rizzo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22*68b8534bSLuigi Rizzo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23*68b8534bSLuigi Rizzo * SUCH DAMAGE. 24*68b8534bSLuigi Rizzo */ 25*68b8534bSLuigi Rizzo 26*68b8534bSLuigi Rizzo /* 27*68b8534bSLuigi Rizzo * $FreeBSD$ 28*68b8534bSLuigi Rizzo * $Id: netmap_kern.h 9662 2011-11-16 13:18:06Z luigi $ 29*68b8534bSLuigi Rizzo * 30*68b8534bSLuigi Rizzo * The header contains the definitions of constants and function 31*68b8534bSLuigi Rizzo * prototypes used only in kernelspace. 32*68b8534bSLuigi Rizzo */ 33*68b8534bSLuigi Rizzo 34*68b8534bSLuigi Rizzo #ifndef _NET_NETMAP_KERN_H_ 35*68b8534bSLuigi Rizzo #define _NET_NETMAP_KERN_H_ 36*68b8534bSLuigi Rizzo 37*68b8534bSLuigi Rizzo #ifdef MALLOC_DECLARE 38*68b8534bSLuigi Rizzo MALLOC_DECLARE(M_NETMAP); 39*68b8534bSLuigi Rizzo #endif 40*68b8534bSLuigi Rizzo 41*68b8534bSLuigi Rizzo #define ND(format, ...) 42*68b8534bSLuigi Rizzo #define D(format, ...) \ 43*68b8534bSLuigi Rizzo do { \ 44*68b8534bSLuigi Rizzo struct timeval __xxts; \ 45*68b8534bSLuigi Rizzo microtime(&__xxts); \ 46*68b8534bSLuigi Rizzo printf("%03d.%06d %s [%d] " format "\n",\ 47*68b8534bSLuigi Rizzo (int)__xxts.tv_sec % 1000, (int)__xxts.tv_usec, \ 48*68b8534bSLuigi Rizzo __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 49*68b8534bSLuigi Rizzo } while (0) 50*68b8534bSLuigi Rizzo 51*68b8534bSLuigi Rizzo struct netmap_adapter; 52*68b8534bSLuigi Rizzo 53*68b8534bSLuigi Rizzo /* 54*68b8534bSLuigi Rizzo * private, kernel view of a ring. 55*68b8534bSLuigi Rizzo * 56*68b8534bSLuigi Rizzo * XXX 20110627-todo 57*68b8534bSLuigi Rizzo * The index in the NIC and netmap ring is offset by nkr_hwofs slots. 58*68b8534bSLuigi Rizzo * This is so that, on a reset, buffers owned by userspace are not 59*68b8534bSLuigi Rizzo * modified by the kernel. In particular: 60*68b8534bSLuigi Rizzo * RX rings: the next empty buffer (hwcur + hwavail + hwofs) coincides 61*68b8534bSLuigi Rizzo * the next empty buffer as known by the hardware (next_to_check or so). 62*68b8534bSLuigi Rizzo * TX rings: hwcur + hwofs coincides with next_to_send 63*68b8534bSLuigi Rizzo */ 64*68b8534bSLuigi Rizzo struct netmap_kring { 65*68b8534bSLuigi Rizzo struct netmap_ring *ring; 66*68b8534bSLuigi Rizzo u_int nr_hwcur; 67*68b8534bSLuigi Rizzo int nr_hwavail; 68*68b8534bSLuigi Rizzo u_int nr_kflags; 69*68b8534bSLuigi Rizzo u_int nkr_num_slots; 70*68b8534bSLuigi Rizzo 71*68b8534bSLuigi Rizzo u_int nkr_hwofs; /* offset between NIC and netmap ring */ 72*68b8534bSLuigi Rizzo struct netmap_adapter *na; // debugging 73*68b8534bSLuigi Rizzo struct selinfo si; /* poll/select wait queue */ 74*68b8534bSLuigi Rizzo }; 75*68b8534bSLuigi Rizzo 76*68b8534bSLuigi Rizzo /* 77*68b8534bSLuigi Rizzo * This struct is part of and extends the 'struct adapter' (or 78*68b8534bSLuigi Rizzo * equivalent) device descriptor. It contains all fields needed to 79*68b8534bSLuigi Rizzo * support netmap operation. 80*68b8534bSLuigi Rizzo */ 81*68b8534bSLuigi Rizzo struct netmap_adapter { 82*68b8534bSLuigi Rizzo int refcount; /* number of user-space descriptors using this 83*68b8534bSLuigi Rizzo interface, which is equal to the number of 84*68b8534bSLuigi Rizzo struct netmap_if objs in the mapped region. */ 85*68b8534bSLuigi Rizzo 86*68b8534bSLuigi Rizzo int separate_locks; /* set if the interface suports different 87*68b8534bSLuigi Rizzo locks for rx, tx and core. */ 88*68b8534bSLuigi Rizzo 89*68b8534bSLuigi Rizzo u_int num_queues; /* number of tx/rx queue pairs: this is 90*68b8534bSLuigi Rizzo a duplicate field needed to simplify the 91*68b8534bSLuigi Rizzo signature of ``netmap_detach``. */ 92*68b8534bSLuigi Rizzo 93*68b8534bSLuigi Rizzo u_int num_tx_desc; /* number of descriptor in each queue */ 94*68b8534bSLuigi Rizzo u_int num_rx_desc; 95*68b8534bSLuigi Rizzo u_int buff_size; 96*68b8534bSLuigi Rizzo 97*68b8534bSLuigi Rizzo u_int flags; /* NR_REINIT */ 98*68b8534bSLuigi Rizzo /* tx_rings and rx_rings are private but allocated 99*68b8534bSLuigi Rizzo * as a contiguous chunk of memory. Each array has 100*68b8534bSLuigi Rizzo * N+1 entries, for the adapter queues and for the host queue. 101*68b8534bSLuigi Rizzo */ 102*68b8534bSLuigi Rizzo struct netmap_kring *tx_rings; /* array of TX rings. */ 103*68b8534bSLuigi Rizzo struct netmap_kring *rx_rings; /* array of RX rings. */ 104*68b8534bSLuigi Rizzo 105*68b8534bSLuigi Rizzo /* copy of if_qflush and if_transmit pointers, to intercept 106*68b8534bSLuigi Rizzo * packets from the network stack when netmap is active. 107*68b8534bSLuigi Rizzo * XXX probably if_qflush is not necessary. 108*68b8534bSLuigi Rizzo */ 109*68b8534bSLuigi Rizzo void (*if_qflush)(struct ifnet *); 110*68b8534bSLuigi Rizzo int (*if_transmit)(struct ifnet *, struct mbuf *); 111*68b8534bSLuigi Rizzo 112*68b8534bSLuigi Rizzo /* references to the ifnet and device routines, used by 113*68b8534bSLuigi Rizzo * the generic netmap functions. 114*68b8534bSLuigi Rizzo */ 115*68b8534bSLuigi Rizzo struct ifnet *ifp; /* adapter is ifp->if_softc */ 116*68b8534bSLuigi Rizzo 117*68b8534bSLuigi Rizzo int (*nm_register)(struct ifnet *, int onoff); 118*68b8534bSLuigi Rizzo void (*nm_lock)(void *, int what, u_int ringid); 119*68b8534bSLuigi Rizzo int (*nm_txsync)(void *, u_int ring, int lock); 120*68b8534bSLuigi Rizzo int (*nm_rxsync)(void *, u_int ring, int lock); 121*68b8534bSLuigi Rizzo }; 122*68b8534bSLuigi Rizzo 123*68b8534bSLuigi Rizzo /* 124*68b8534bSLuigi Rizzo * The combination of "enable" (ifp->if_capabilities &IFCAP_NETMAP) 125*68b8534bSLuigi Rizzo * and refcount gives the status of the interface, namely: 126*68b8534bSLuigi Rizzo * 127*68b8534bSLuigi Rizzo * enable refcount Status 128*68b8534bSLuigi Rizzo * 129*68b8534bSLuigi Rizzo * FALSE 0 normal operation 130*68b8534bSLuigi Rizzo * FALSE != 0 -- (impossible) 131*68b8534bSLuigi Rizzo * TRUE 1 netmap mode 132*68b8534bSLuigi Rizzo * TRUE 0 being deleted. 133*68b8534bSLuigi Rizzo */ 134*68b8534bSLuigi Rizzo 135*68b8534bSLuigi Rizzo #define NETMAP_DELETING(_na) ( ((_na)->refcount == 0) && \ 136*68b8534bSLuigi Rizzo ( (_na)->ifp->if_capenable & IFCAP_NETMAP) ) 137*68b8534bSLuigi Rizzo 138*68b8534bSLuigi Rizzo /* 139*68b8534bSLuigi Rizzo * parameters for (*nm_lock)(adapter, what, index) 140*68b8534bSLuigi Rizzo */ 141*68b8534bSLuigi Rizzo enum { 142*68b8534bSLuigi Rizzo NETMAP_NO_LOCK = 0, 143*68b8534bSLuigi Rizzo NETMAP_CORE_LOCK, NETMAP_CORE_UNLOCK, 144*68b8534bSLuigi Rizzo NETMAP_TX_LOCK, NETMAP_TX_UNLOCK, 145*68b8534bSLuigi Rizzo NETMAP_RX_LOCK, NETMAP_RX_UNLOCK, 146*68b8534bSLuigi Rizzo }; 147*68b8534bSLuigi Rizzo 148*68b8534bSLuigi Rizzo /* 149*68b8534bSLuigi Rizzo * The following are support routines used by individual drivers to 150*68b8534bSLuigi Rizzo * support netmap operation. 151*68b8534bSLuigi Rizzo * 152*68b8534bSLuigi Rizzo * netmap_attach() initializes a struct netmap_adapter, allocating the 153*68b8534bSLuigi Rizzo * struct netmap_ring's and the struct selinfo. 154*68b8534bSLuigi Rizzo * 155*68b8534bSLuigi Rizzo * netmap_detach() frees the memory allocated by netmap_attach(). 156*68b8534bSLuigi Rizzo * 157*68b8534bSLuigi Rizzo * netmap_start() replaces the if_transmit routine of the interface, 158*68b8534bSLuigi Rizzo * and is used to intercept packets coming from the stack. 159*68b8534bSLuigi Rizzo * 160*68b8534bSLuigi Rizzo * netmap_load_map/netmap_reload_map are helper routines to set/reset 161*68b8534bSLuigi Rizzo * the dmamap for a packet buffer 162*68b8534bSLuigi Rizzo * 163*68b8534bSLuigi Rizzo * netmap_reset() is a helper routine to be called in the driver 164*68b8534bSLuigi Rizzo * when reinitializing a ring. 165*68b8534bSLuigi Rizzo */ 166*68b8534bSLuigi Rizzo int netmap_attach(struct netmap_adapter *, int); 167*68b8534bSLuigi Rizzo void netmap_detach(struct ifnet *); 168*68b8534bSLuigi Rizzo int netmap_start(struct ifnet *, struct mbuf *); 169*68b8534bSLuigi Rizzo enum txrx { NR_RX = 0, NR_TX = 1 }; 170*68b8534bSLuigi Rizzo struct netmap_slot *netmap_reset(struct netmap_adapter *na, 171*68b8534bSLuigi Rizzo enum txrx tx, int n, u_int new_cur); 172*68b8534bSLuigi Rizzo void netmap_load_map(bus_dma_tag_t tag, bus_dmamap_t map, 173*68b8534bSLuigi Rizzo void *buf, bus_size_t buflen); 174*68b8534bSLuigi Rizzo void netmap_reload_map(bus_dma_tag_t tag, bus_dmamap_t map, 175*68b8534bSLuigi Rizzo void *buf, bus_size_t buflen); 176*68b8534bSLuigi Rizzo int netmap_ring_reinit(struct netmap_kring *); 177*68b8534bSLuigi Rizzo 178*68b8534bSLuigi Rizzo /* 179*68b8534bSLuigi Rizzo * XXX eventually, get rid of netmap_total_buffers and netmap_buffer_base 180*68b8534bSLuigi Rizzo * in favour of the structure 181*68b8534bSLuigi Rizzo */ 182*68b8534bSLuigi Rizzo // struct netmap_buf_pool; 183*68b8534bSLuigi Rizzo // extern struct netmap_buf_pool nm_buf_pool; 184*68b8534bSLuigi Rizzo extern u_int netmap_total_buffers; 185*68b8534bSLuigi Rizzo extern char *netmap_buffer_base; 186*68b8534bSLuigi Rizzo extern int netmap_verbose; // XXX debugging 187*68b8534bSLuigi Rizzo enum { /* verbose flags */ 188*68b8534bSLuigi Rizzo NM_VERB_ON = 1, /* generic verbose */ 189*68b8534bSLuigi Rizzo NM_VERB_HOST = 0x2, /* verbose host stack */ 190*68b8534bSLuigi Rizzo NM_VERB_RXSYNC = 0x10, /* verbose on rxsync/txsync */ 191*68b8534bSLuigi Rizzo NM_VERB_TXSYNC = 0x20, 192*68b8534bSLuigi Rizzo NM_VERB_RXINTR = 0x100, /* verbose on rx/tx intr (driver) */ 193*68b8534bSLuigi Rizzo NM_VERB_TXINTR = 0x200, 194*68b8534bSLuigi Rizzo NM_VERB_NIC_RXSYNC = 0x1000, /* verbose on rx/tx intr (driver) */ 195*68b8534bSLuigi Rizzo NM_VERB_NIC_TXSYNC = 0x2000, 196*68b8534bSLuigi Rizzo }; 197*68b8534bSLuigi Rizzo 198*68b8534bSLuigi Rizzo /* 199*68b8534bSLuigi Rizzo * return a pointer to the struct netmap adapter from the ifp 200*68b8534bSLuigi Rizzo */ 201*68b8534bSLuigi Rizzo #define NA(_ifp) ((struct netmap_adapter *)(_ifp)->if_pspare[0]) 202*68b8534bSLuigi Rizzo 203*68b8534bSLuigi Rizzo 204*68b8534bSLuigi Rizzo /* 205*68b8534bSLuigi Rizzo * return the address of a buffer. 206*68b8534bSLuigi Rizzo * XXX this is a special version with hardwired 2k bufs 207*68b8534bSLuigi Rizzo * On error return netmap_buffer_base which is detected as a bad pointer. 208*68b8534bSLuigi Rizzo */ 209*68b8534bSLuigi Rizzo static inline char * 210*68b8534bSLuigi Rizzo NMB(struct netmap_slot *slot) 211*68b8534bSLuigi Rizzo { 212*68b8534bSLuigi Rizzo uint32_t i = slot->buf_idx; 213*68b8534bSLuigi Rizzo return (i >= netmap_total_buffers) ? netmap_buffer_base : 214*68b8534bSLuigi Rizzo #if NETMAP_BUF_SIZE == 2048 215*68b8534bSLuigi Rizzo netmap_buffer_base + (i << 11); 216*68b8534bSLuigi Rizzo #else 217*68b8534bSLuigi Rizzo netmap_buffer_base + (i *NETMAP_BUF_SIZE); 218*68b8534bSLuigi Rizzo #endif 219*68b8534bSLuigi Rizzo } 220*68b8534bSLuigi Rizzo 221*68b8534bSLuigi Rizzo #endif /* _NET_NETMAP_KERN_H_ */ 222