1227614Sluigi/*
2262151Sluigi * Copyright (C) 2011-2014 Matteo Landi, Luigi Rizzo. All rights reserved.
3262151Sluigi * Copyright (C) 2013-2014 Universita` di Pisa. All rights reserved.
4241719Sluigi *
5227614Sluigi * Redistribution and use in source and binary forms, with or without
6227614Sluigi * modification, are permitted provided that the following conditions
7227614Sluigi * are met:
8228276Sluigi *   1. Redistributions of source code must retain the above copyright
9228276Sluigi *      notice, this list of conditions and the following disclaimer.
10228276Sluigi *   2. Redistributions in binary form must reproduce the above copyright
11228276Sluigi *      notice, this list of conditions and the following disclaimer in the
12227614Sluigi *    documentation and/or other materials provided with the distribution.
13241719Sluigi *
14227614Sluigi * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15227614Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16227614Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17227614Sluigi * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18227614Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19227614Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20227614Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21227614Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22227614Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23227614Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24227614Sluigi * SUCH DAMAGE.
25227614Sluigi */
26227614Sluigi
27227614Sluigi/*
28227614Sluigi * $FreeBSD$
29227614Sluigi *
30227614Sluigi * The header contains the definitions of constants and function
31227614Sluigi * prototypes used only in kernelspace.
32227614Sluigi */
33227614Sluigi
34227614Sluigi#ifndef _NET_NETMAP_KERN_H_
35227614Sluigi#define _NET_NETMAP_KERN_H_
36227614Sluigi
37262151Sluigi#define WITH_VALE	// comment out to disable VALE support
38262151Sluigi#define WITH_PIPES
39270252Sluigi#define WITH_MONITOR
40262151Sluigi
41231594Sluigi#if defined(__FreeBSD__)
42250052Sluigi
43262151Sluigi#define likely(x)	__builtin_expect((long)!!(x), 1L)
44262151Sluigi#define unlikely(x)	__builtin_expect((long)!!(x), 0L)
45238812Sluigi
46231594Sluigi#define	NM_LOCK_T	struct mtx
47270298Snp#define	NMG_LOCK_T	struct sx
48270298Snp#define NMG_LOCK_INIT()	sx_init(&netmap_global_lock, \
49270298Snp				"netmap global lock")
50270298Snp#define NMG_LOCK_DESTROY()	sx_destroy(&netmap_global_lock)
51270298Snp#define NMG_LOCK()	sx_xlock(&netmap_global_lock)
52270298Snp#define NMG_UNLOCK()	sx_xunlock(&netmap_global_lock)
53270298Snp#define NMG_LOCK_ASSERT()	sx_assert(&netmap_global_lock, SA_XLOCKED)
54262151Sluigi
55231594Sluigi#define	NM_SELINFO_T	struct selinfo
56231594Sluigi#define	MBUF_LEN(m)	((m)->m_pkthdr.len)
57262151Sluigi#define	MBUF_IFP(m)	((m)->m_pkthdr.rcvif)
58262151Sluigi#define	NM_SEND_UP(ifp, m)	((NA(ifp))->if_input)(ifp, m)
59250052Sluigi
60262151Sluigi#define NM_ATOMIC_T	volatile int	// XXX ?
61262151Sluigi/* atomic operations */
62262151Sluigi#include <machine/atomic.h>
63262151Sluigi#define NM_ATOMIC_TEST_AND_SET(p)       (!atomic_cmpset_acq_int((p), 0, 1))
64262151Sluigi#define NM_ATOMIC_CLEAR(p)              atomic_store_rel_int((p), 0)
65262151Sluigi
66267282Sluigi#if __FreeBSD_version >= 1100005
67267282Sluigistruct netmap_adapter *netmap_getna(if_t ifp);
68267282Sluigi#endif
69262151Sluigi
70270252Sluigi#if __FreeBSD_version >= 1100027
71270252Sluigi#define GET_MBUF_REFCNT(m)      ((m)->m_ext.ext_cnt ? *((m)->m_ext.ext_cnt) : -1)
72270252Sluigi#define SET_MBUF_REFCNT(m, x)   *((m)->m_ext.ext_cnt) = x
73270252Sluigi#define PNT_MBUF_REFCNT(m)      ((m)->m_ext.ext_cnt)
74270252Sluigi#else
75270252Sluigi#define GET_MBUF_REFCNT(m)      ((m)->m_ext.ref_cnt ? *((m)->m_ext.ref_cnt) : -1)
76270252Sluigi#define SET_MBUF_REFCNT(m, x)   *((m)->m_ext.ref_cnt) = x
77270252Sluigi#define PNT_MBUF_REFCNT(m)      ((m)->m_ext.ref_cnt)
78270252Sluigi#endif
79270252Sluigi
80262151SluigiMALLOC_DECLARE(M_NETMAP);
81262151Sluigi
82262151Sluigi// XXX linux struct, not used in FreeBSD
83262151Sluigistruct net_device_ops {
84262151Sluigi};
85270252Sluigistruct ethtool_ops {
86270252Sluigi};
87262151Sluigistruct hrtimer {
88262151Sluigi};
89262151Sluigi
90232238Sluigi#elif defined (linux)
91250052Sluigi
92250052Sluigi#define	NM_LOCK_T	safe_spinlock_t	// see bsd_glue.h
93231594Sluigi#define	NM_SELINFO_T	wait_queue_head_t
94231594Sluigi#define	MBUF_LEN(m)	((m)->len)
95262151Sluigi#define	MBUF_IFP(m)	((m)->dev)
96262151Sluigi#define	NM_SEND_UP(ifp, m)  \
97262151Sluigi                        do { \
98270252Sluigi                            m->priority = NM_MAGIC_PRIORITY_RX; \
99262151Sluigi                            netif_rx(m); \
100262151Sluigi                        } while (0)
101238812Sluigi
102262151Sluigi#define NM_ATOMIC_T	volatile long unsigned int
103262151Sluigi
104262151Sluigi// XXX a mtx would suffice here too 20130404 gl
105262151Sluigi#define NMG_LOCK_T		struct semaphore
106262151Sluigi#define NMG_LOCK_INIT()		sema_init(&netmap_global_lock, 1)
107262151Sluigi#define NMG_LOCK_DESTROY()
108262151Sluigi#define NMG_LOCK()		down(&netmap_global_lock)
109262151Sluigi#define NMG_UNLOCK()		up(&netmap_global_lock)
110262151Sluigi#define NMG_LOCK_ASSERT()	//	XXX to be completed
111262151Sluigi
112238812Sluigi#ifndef DEV_NETMAP
113238812Sluigi#define DEV_NETMAP
114262151Sluigi#endif /* DEV_NETMAP */
115238812Sluigi
116238812Sluigi#elif defined (__APPLE__)
117250052Sluigi
118241719Sluigi#warning apple support is incomplete.
119238812Sluigi#define likely(x)	__builtin_expect(!!(x), 1)
120238812Sluigi#define unlikely(x)	__builtin_expect(!!(x), 0)
121238812Sluigi#define	NM_LOCK_T	IOLock *
122238812Sluigi#define	NM_SELINFO_T	struct selinfo
123238812Sluigi#define	MBUF_LEN(m)	((m)->m_pkthdr.len)
124238812Sluigi#define	NM_SEND_UP(ifp, m)	((ifp)->if_input)(ifp, m)
125238812Sluigi
126238812Sluigi#else
127250052Sluigi
128231594Sluigi#error unsupported platform
129231594Sluigi
130250052Sluigi#endif /* end - platform-specific code */
131250052Sluigi
132227614Sluigi#define ND(format, ...)
133230058Sluigi#define D(format, ...)						\
134230058Sluigi	do {							\
135230058Sluigi		struct timeval __xxts;				\
136227614Sluigi		microtime(&__xxts);				\
137262151Sluigi		printf("%03d.%06d [%4d] %-25s " format "\n",	\
138230058Sluigi		(int)__xxts.tv_sec % 1000, (int)__xxts.tv_usec,	\
139262151Sluigi		__LINE__, __FUNCTION__, ##__VA_ARGS__);		\
140227614Sluigi	} while (0)
141241719Sluigi
142241719Sluigi/* rate limited, lps indicates how many per second */
143241719Sluigi#define RD(lps, format, ...)					\
144241719Sluigi	do {							\
145241719Sluigi		static int t0, __cnt;				\
146241719Sluigi		if (t0 != time_second) {			\
147241719Sluigi			t0 = time_second;			\
148241719Sluigi			__cnt = 0;				\
149241719Sluigi		}						\
150241719Sluigi		if (__cnt++ < lps)				\
151241719Sluigi			D(format, ##__VA_ARGS__);		\
152241719Sluigi	} while (0)
153241719Sluigi
154227614Sluigistruct netmap_adapter;
155251139Sluigistruct nm_bdg_fwd;
156251139Sluigistruct nm_bridge;
157251139Sluigistruct netmap_priv_d;
158227614Sluigi
159262151Sluigiconst char *nm_dump_buf(char *p, int len, int lim, char *dst);
160262151Sluigi
161262151Sluigi#include "netmap_mbq.h"
162262151Sluigi
163262151Sluigiextern NMG_LOCK_T	netmap_global_lock;
164262151Sluigi
165227614Sluigi/*
166232238Sluigi * private, kernel view of a ring. Keeps track of the status of
167232238Sluigi * a ring across system calls.
168227614Sluigi *
169232238Sluigi *	nr_hwcur	index of the next buffer to refill.
170262151Sluigi *			It corresponds to ring->head
171262151Sluigi *			at the time the system call returns.
172232238Sluigi *
173262151Sluigi *	nr_hwtail	index of the first buffer owned by the kernel.
174262151Sluigi *			On RX, hwcur->hwtail are receive buffers
175262151Sluigi *			not yet released. hwcur is advanced following
176262151Sluigi *			ring->head, hwtail is advanced on incoming packets,
177262151Sluigi *			and a wakeup is generated when hwtail passes ring->cur
178262151Sluigi *			    On TX, hwcur->rcur have been filled by the sender
179262151Sluigi *			but not sent yet to the NIC; rcur->hwtail are available
180262151Sluigi *			for new transmissions, and hwtail->hwcur-1 are pending
181262151Sluigi *			transmissions not yet acknowledged.
182232238Sluigi *
183231594Sluigi * The indexes in the NIC and netmap rings are offset by nkr_hwofs slots.
184227614Sluigi * This is so that, on a reset, buffers owned by userspace are not
185227614Sluigi * modified by the kernel. In particular:
186262151Sluigi * RX rings: the next empty buffer (hwtail + hwofs) coincides with
187227614Sluigi * 	the next empty buffer as known by the hardware (next_to_check or so).
188227614Sluigi * TX rings: hwcur + hwofs coincides with next_to_send
189245579Sluigi *
190245579Sluigi * For received packets, slot->flags is set to nkr_slot_flags
191245579Sluigi * so we can provide a proper initial value (e.g. set NS_FORWARD
192245579Sluigi * when operating in 'transparent' mode).
193262151Sluigi *
194262151Sluigi * The following fields are used to implement lock-free copy of packets
195262151Sluigi * from input to output ports in VALE switch:
196262151Sluigi *	nkr_hwlease	buffer after the last one being copied.
197262151Sluigi *			A writer in nm_bdg_flush reserves N buffers
198262151Sluigi *			from nr_hwlease, advances it, then does the
199262151Sluigi *			copy outside the lock.
200262151Sluigi *			In RX rings (used for VALE ports),
201262151Sluigi *			nkr_hwtail <= nkr_hwlease < nkr_hwcur+N-1
202262151Sluigi *			In TX rings (used for NIC or host stack ports)
203262151Sluigi *			nkr_hwcur <= nkr_hwlease < nkr_hwtail
204262151Sluigi *	nkr_leases	array of nkr_num_slots where writers can report
205262151Sluigi *			completion of their block. NR_NOSLOT (~0) indicates
206262151Sluigi *			that the writer has not finished yet
207262151Sluigi *	nkr_lease_idx	index of next free slot in nr_leases, to be assigned
208262151Sluigi *
209262151Sluigi * The kring is manipulated by txsync/rxsync and generic netmap function.
210262151Sluigi *
211262151Sluigi * Concurrent rxsync or txsync on the same ring are prevented through
212267282Sluigi * by nm_kr_(try)lock() which in turn uses nr_busy. This is all we need
213262151Sluigi * for NIC rings, and for TX rings attached to the host stack.
214262151Sluigi *
215262151Sluigi * RX rings attached to the host stack use an mbq (rx_queue) on both
216262151Sluigi * rxsync_from_host() and netmap_transmit(). The mbq is protected
217262151Sluigi * by its internal lock.
218262151Sluigi *
219270252Sluigi * RX rings attached to the VALE switch are accessed by both senders
220262151Sluigi * and receiver. They are protected through the q_lock on the RX ring.
221227614Sluigi */
222227614Sluigistruct netmap_kring {
223262151Sluigi	struct netmap_ring	*ring;
224227614Sluigi
225262151Sluigi	uint32_t	nr_hwcur;
226262151Sluigi	uint32_t	nr_hwtail;
227262151Sluigi
228262151Sluigi	/*
229262151Sluigi	 * Copies of values in user rings, so we do not need to look
230262151Sluigi	 * at the ring (which could be modified). These are set in the
231262151Sluigi	 * *sync_prologue()/finalize() routines.
232262151Sluigi	 */
233262151Sluigi	uint32_t	rhead;
234262151Sluigi	uint32_t	rcur;
235262151Sluigi	uint32_t	rtail;
236262151Sluigi
237262151Sluigi	uint32_t	nr_kflags;	/* private driver flags */
238262151Sluigi#define NKR_PENDINTR	0x1		// Pending interrupt.
239262151Sluigi	uint32_t	nkr_num_slots;
240262151Sluigi
241262151Sluigi	/*
242262151Sluigi	 * On a NIC reset, the NIC ring indexes may be reset but the
243262151Sluigi	 * indexes in the netmap rings remain the same. nkr_hwofs
244262151Sluigi	 * keeps track of the offset between the two.
245262151Sluigi	 */
246262151Sluigi	int32_t		nkr_hwofs;
247262151Sluigi
248245579Sluigi	uint16_t	nkr_slot_flags;	/* initial value for flags */
249262151Sluigi
250262151Sluigi	/* last_reclaim is opaque marker to help reduce the frequency
251262151Sluigi	 * of operations such as reclaiming tx buffers. A possible use
252262151Sluigi	 * is set it to ticks and do the reclaim only once per tick.
253262151Sluigi	 */
254262151Sluigi	uint64_t	last_reclaim;
255262151Sluigi
256262151Sluigi
257262151Sluigi	NM_SELINFO_T	si;		/* poll/select wait queue */
258262151Sluigi	NM_LOCK_T	q_lock;		/* protects kring and ring. */
259262151Sluigi	NM_ATOMIC_T	nr_busy;	/* prevent concurrent syscalls */
260262151Sluigi
261231594Sluigi	struct netmap_adapter *na;
262262151Sluigi
263262151Sluigi	/* The folloiwing fields are for VALE switch support */
264251139Sluigi	struct nm_bdg_fwd *nkr_ft;
265262151Sluigi	uint32_t	*nkr_leases;
266262151Sluigi#define NR_NOSLOT	((uint32_t)~0)	/* used in nkr_*lease* */
267262151Sluigi	uint32_t	nkr_hwlease;
268262151Sluigi	uint32_t	nkr_lease_idx;
269262151Sluigi
270270252Sluigi	/* while nkr_stopped is set, no new [tr]xsync operations can
271270252Sluigi	 * be started on this kring.
272270252Sluigi	 * This is used by netmap_disable_all_rings()
273270252Sluigi	 * to find a synchronization point where critical data
274270252Sluigi	 * structures pointed to by the kring can be added or removed
275270252Sluigi	 */
276270252Sluigi	volatile int nkr_stopped;
277262151Sluigi
278262151Sluigi	/* Support for adapters without native netmap support.
279262151Sluigi	 * On tx rings we preallocate an array of tx buffers
280262151Sluigi	 * (same size as the netmap ring), on rx rings we
281262151Sluigi	 * store incoming mbufs in a queue that is drained by
282262151Sluigi	 * a rxsync.
283262151Sluigi	 */
284262151Sluigi	struct mbuf **tx_pool;
285262151Sluigi	// u_int nr_ntc;		/* Emulation of a next-to-clean RX ring pointer. */
286262151Sluigi	struct mbq rx_queue;            /* intercepted rx mbufs. */
287262151Sluigi
288262151Sluigi	uint32_t	ring_id;	/* debugging */
289262151Sluigi	char name[64];			/* diagnostic */
290262151Sluigi
291270252Sluigi	/* [tx]sync callback for this kring.
292270252Sluigi	 * The default nm_kring_create callback (netmap_krings_create)
293270252Sluigi	 * sets the nm_sync callback of each hardware tx(rx) kring to
294270252Sluigi	 * the corresponding nm_txsync(nm_rxsync) taken from the
295270252Sluigi	 * netmap_adapter; moreover, it sets the sync callback
296270252Sluigi	 * of the host tx(rx) ring to netmap_txsync_to_host
297270252Sluigi	 * (netmap_rxsync_from_host).
298270252Sluigi	 *
299270252Sluigi	 * Overrides: the above configuration is not changed by
300270252Sluigi	 * any of the nm_krings_create callbacks.
301270252Sluigi	 */
302262151Sluigi	int (*nm_sync)(struct netmap_kring *kring, int flags);
303262151Sluigi
304262151Sluigi#ifdef WITH_PIPES
305270252Sluigi	struct netmap_kring *pipe;	/* if this is a pipe ring,
306270252Sluigi					 * pointer to the other end
307270252Sluigi					 */
308270252Sluigi	struct netmap_ring *save_ring;	/* pointer to hidden rings
309270252Sluigi       					 * (see netmap_pipe.c for details)
310270252Sluigi					 */
311262151Sluigi#endif /* WITH_PIPES */
312262151Sluigi
313270252Sluigi#ifdef WITH_MONITOR
314270252Sluigi	/* pointer to the adapter that is monitoring this kring (if any)
315270252Sluigi	 */
316270252Sluigi	struct netmap_monitor_adapter *monitor;
317270252Sluigi	/*
318270252Sluigi	 * Monitors work by intercepting the txsync and/or rxsync of the
319270252Sluigi	 * monitored krings. This is implemented by replacing
320270252Sluigi	 * the nm_sync pointer above and saving the previous
321270252Sluigi	 * one in save_sync below.
322270252Sluigi	 */
323270252Sluigi	int (*save_sync)(struct netmap_kring *kring, int flags);
324270252Sluigi#endif
325230572Sluigi} __attribute__((__aligned__(64)));
326227614Sluigi
327262151Sluigi
328262151Sluigi/* return the next index, with wraparound */
329262151Sluigistatic inline uint32_t
330262151Sluiginm_next(uint32_t i, uint32_t lim)
331262151Sluigi{
332262151Sluigi	return unlikely (i == lim) ? 0 : i + 1;
333262151Sluigi}
334262151Sluigi
335262151Sluigi
336262151Sluigi/* return the previous index, with wraparound */
337262151Sluigistatic inline uint32_t
338262151Sluiginm_prev(uint32_t i, uint32_t lim)
339262151Sluigi{
340262151Sluigi	return unlikely (i == 0) ? lim : i - 1;
341262151Sluigi}
342262151Sluigi
343262151Sluigi
344227614Sluigi/*
345262151Sluigi *
346262151Sluigi * Here is the layout for the Rx and Tx rings.
347262151Sluigi
348262151Sluigi       RxRING                            TxRING
349262151Sluigi
350262151Sluigi      +-----------------+            +-----------------+
351262151Sluigi      |                 |            |                 |
352262151Sluigi      |XXX free slot XXX|            |XXX free slot XXX|
353262151Sluigi      +-----------------+            +-----------------+
354262151Sluigihead->| owned by user   |<-hwcur     | not sent to nic |<-hwcur
355262151Sluigi      |                 |            | yet             |
356262151Sluigi      +-----------------+            |                 |
357262151Sluigi cur->| available to    |            |                 |
358262151Sluigi      | user, not read  |            +-----------------+
359262151Sluigi      | yet             |       cur->| (being          |
360262151Sluigi      |                 |            |  prepared)      |
361262151Sluigi      |                 |            |                 |
362262151Sluigi      +-----------------+            +     ------      +
363262151Sluigitail->|                 |<-hwtail    |                 |<-hwlease
364262151Sluigi      | (being          | ...        |                 | ...
365262151Sluigi      |  prepared)      | ...        |                 | ...
366262151Sluigi      +-----------------+ ...        |                 | ...
367262151Sluigi      |                 |<-hwlease   +-----------------+
368262151Sluigi      |                 |      tail->|                 |<-hwtail
369262151Sluigi      |                 |            |                 |
370262151Sluigi      |                 |            |                 |
371262151Sluigi      |                 |            |                 |
372262151Sluigi      +-----------------+            +-----------------+
373262151Sluigi
374262151Sluigi * The cur/tail (user view) and hwcur/hwtail (kernel view)
375262151Sluigi * are used in the normal operation of the card.
376262151Sluigi *
377262151Sluigi * When a ring is the output of a switch port (Rx ring for
378262151Sluigi * a VALE port, Tx ring for the host stack or NIC), slots
379262151Sluigi * are reserved in blocks through 'hwlease' which points
380262151Sluigi * to the next unused slot.
381262151Sluigi * On an Rx ring, hwlease is always after hwtail,
382262151Sluigi * and completions cause hwtail to advance.
383262151Sluigi * On a Tx ring, hwlease is always between cur and hwtail,
384262151Sluigi * and completions cause cur to advance.
385262151Sluigi *
386262151Sluigi * nm_kr_space() returns the maximum number of slots that
387262151Sluigi * can be assigned.
388262151Sluigi * nm_kr_lease() reserves the required number of buffers,
389262151Sluigi *    advances nkr_hwlease and also returns an entry in
390262151Sluigi *    a circular array where completions should be reported.
391227614Sluigi */
392262151Sluigi
393262151Sluigi
394262151Sluigi
395262151Sluigienum txrx { NR_RX = 0, NR_TX = 1 };
396262151Sluigi
397270252Sluigistruct netmap_vp_adapter; // forward
398270252Sluigi
399262151Sluigi/*
400262151Sluigi * The "struct netmap_adapter" extends the "struct adapter"
401262151Sluigi * (or equivalent) device descriptor.
402262151Sluigi * It contains all base fields needed to support netmap operation.
403262151Sluigi * There are in fact different types of netmap adapters
404262151Sluigi * (native, generic, VALE switch...) so a netmap_adapter is
405262151Sluigi * just the first field in the derived type.
406262151Sluigi */
407227614Sluigistruct netmap_adapter {
408241719Sluigi	/*
409241719Sluigi	 * On linux we do not have a good way to tell if an interface
410262151Sluigi	 * is netmap-capable. So we always use the following trick:
411241719Sluigi	 * NA(ifp) points here, and the first entry (which hopefully
412241719Sluigi	 * always exists and is at least 32 bits) contains a magic
413241719Sluigi	 * value which we can use to detect that the interface is good.
414241719Sluigi	 */
415241719Sluigi	uint32_t magic;
416262151Sluigi	uint32_t na_flags;	/* enabled, and other flags */
417241719Sluigi#define NAF_SKIP_INTR	1	/* use the regular interrupt handler.
418241719Sluigi				 * useful during initialization
419241719Sluigi				 */
420251139Sluigi#define NAF_SW_ONLY	2	/* forward packets only to sw adapter */
421262151Sluigi#define NAF_BDG_MAYSLEEP 4	/* the bridge is allowed to sleep when
422262151Sluigi				 * forwarding packets coming from this
423262151Sluigi				 * interface
424262151Sluigi				 */
425262151Sluigi#define NAF_MEM_OWNER	8	/* the adapter is responsible for the
426262151Sluigi				 * deallocation of the memory allocator
427262151Sluigi				 */
428262151Sluigi#define NAF_NATIVE_ON   16      /* the adapter is native and the attached
429270252Sluigi				 * interface is in netmap mode.
430270252Sluigi				 * Virtual ports (vale, pipe, monitor...)
431270252Sluigi				 * should never use this flag.
432262151Sluigi				 */
433262151Sluigi#define	NAF_NETMAP_ON	32	/* netmap is active (either native or
434270252Sluigi				 * emulated). Where possible (e.g. FreeBSD)
435262151Sluigi				 * IFCAP_NETMAP also mirrors this flag.
436262151Sluigi				 */
437262151Sluigi#define NAF_HOST_RINGS  64	/* the adapter supports the host rings */
438270252Sluigi#define NAF_FORCE_NATIVE 128	/* the adapter is always NATIVE */
439270252Sluigi#define	NAF_BUSY	(1U<<31) /* the adapter is used internally and
440270252Sluigi				  * cannot be registered from userspace
441270252Sluigi				  */
442262151Sluigi	int active_fds; /* number of user-space descriptors using this
443227614Sluigi			 interface, which is equal to the number of
444227614Sluigi			 struct netmap_if objs in the mapped region. */
445227614Sluigi
446239140Semaste	u_int num_rx_rings; /* number of adapter receive rings */
447239140Semaste	u_int num_tx_rings; /* number of adapter transmit rings */
448227614Sluigi
449227614Sluigi	u_int num_tx_desc; /* number of descriptor in each queue */
450227614Sluigi	u_int num_rx_desc;
451227614Sluigi
452227614Sluigi	/* tx_rings and rx_rings are private but allocated
453227614Sluigi	 * as a contiguous chunk of memory. Each array has
454227614Sluigi	 * N+1 entries, for the adapter queues and for the host queue.
455227614Sluigi	 */
456227614Sluigi	struct netmap_kring *tx_rings; /* array of TX rings. */
457227614Sluigi	struct netmap_kring *rx_rings; /* array of RX rings. */
458227614Sluigi
459262151Sluigi	void *tailroom;		       /* space below the rings array */
460262151Sluigi				       /* (used for leases) */
461262151Sluigi
462262151Sluigi
463232238Sluigi	NM_SELINFO_T tx_si, rx_si;	/* global wait queues */
464232238Sluigi
465262151Sluigi	/* count users of the global wait queues */
466262151Sluigi	int tx_si_users, rx_si_users;
467262151Sluigi
468270252Sluigi	void *pdev; /* used to store pci device */
469270252Sluigi
470227614Sluigi	/* copy of if_qflush and if_transmit pointers, to intercept
471227614Sluigi	 * packets from the network stack when netmap is active.
472227614Sluigi	 */
473227614Sluigi	int     (*if_transmit)(struct ifnet *, struct mbuf *);
474227614Sluigi
475262151Sluigi	/* copy of if_input for netmap_send_up() */
476262151Sluigi	void     (*if_input)(struct ifnet *, struct mbuf *);
477262151Sluigi
478227614Sluigi	/* references to the ifnet and device routines, used by
479227614Sluigi	 * the generic netmap functions.
480227614Sluigi	 */
481227614Sluigi	struct ifnet *ifp; /* adapter is ifp->if_softc */
482227614Sluigi
483262151Sluigi	/*---- callbacks for this netmap adapter -----*/
484262151Sluigi	/*
485262151Sluigi	 * nm_dtor() is the cleanup routine called when destroying
486262151Sluigi	 *	the adapter.
487267282Sluigi	 *	Called with NMG_LOCK held.
488262151Sluigi	 *
489262151Sluigi	 * nm_register() is called on NIOCREGIF and close() to enter
490262151Sluigi	 *	or exit netmap mode on the NIC
491270252Sluigi	 *	Called with NNG_LOCK held.
492262151Sluigi	 *
493262151Sluigi	 * nm_txsync() pushes packets to the underlying hw/switch
494262151Sluigi	 *
495262151Sluigi	 * nm_rxsync() collects packets from the underlying hw/switch
496262151Sluigi	 *
497262151Sluigi	 * nm_config() returns configuration information from the OS
498267282Sluigi	 *	Called with NMG_LOCK held.
499262151Sluigi	 *
500270252Sluigi	 * nm_krings_create() create and init the tx_rings and
501270252Sluigi	 * 	rx_rings arrays of kring structures. In particular,
502270252Sluigi	 * 	set the nm_sync callbacks for each ring.
503270252Sluigi	 * 	There is no need to also allocate the corresponding
504270252Sluigi	 * 	netmap_rings, since netmap_mem_rings_create() will always
505270252Sluigi	 * 	be called to provide the missing ones.
506270252Sluigi	 *	Called with NNG_LOCK held.
507262151Sluigi	 *
508270252Sluigi	 * nm_krings_delete() cleanup and delete the tx_rings and rx_rings
509270252Sluigi	 * 	arrays
510270252Sluigi	 *	Called with NMG_LOCK held.
511262151Sluigi	 *
512267282Sluigi	 * nm_notify() is used to act after data have become available
513270252Sluigi	 * 	(or the stopped state of the ring has changed)
514262151Sluigi	 *	For hw devices this is typically a selwakeup(),
515262151Sluigi	 *	but for NIC/host ports attached to a switch (or vice-versa)
516262151Sluigi	 *	we also need to invoke the 'txsync' code downstream.
517262151Sluigi	 */
518262151Sluigi	void (*nm_dtor)(struct netmap_adapter *);
519262151Sluigi
520262151Sluigi	int (*nm_register)(struct netmap_adapter *, int onoff);
521262151Sluigi
522270252Sluigi	int (*nm_txsync)(struct netmap_kring *kring, int flags);
523270252Sluigi	int (*nm_rxsync)(struct netmap_kring *kring, int flags);
524262151Sluigi#define NAF_FORCE_READ    1
525262151Sluigi#define NAF_FORCE_RECLAIM 2
526245835Sluigi	/* return configuration information */
527262151Sluigi	int (*nm_config)(struct netmap_adapter *,
528262151Sluigi		u_int *txr, u_int *txd, u_int *rxr, u_int *rxd);
529262151Sluigi	int (*nm_krings_create)(struct netmap_adapter *);
530262151Sluigi	void (*nm_krings_delete)(struct netmap_adapter *);
531262151Sluigi	int (*nm_notify)(struct netmap_adapter *,
532262151Sluigi		u_int ring, enum txrx, int flags);
533270252Sluigi#define NAF_DISABLE_NOTIFY 8	/* notify that the stopped state of the
534270252Sluigi				 * ring has changed (kring->nkr_stopped)
535270252Sluigi				 */
536238812Sluigi
537270252Sluigi#ifdef WITH_VALE
538270252Sluigi	/*
539270252Sluigi	 * nm_bdg_attach() initializes the na_vp field to point
540270252Sluigi	 *      to an adapter that can be attached to a VALE switch. If the
541270252Sluigi	 *      current adapter is already a VALE port, na_vp is simply a cast;
542270252Sluigi	 *      otherwise, na_vp points to a netmap_bwrap_adapter.
543270252Sluigi	 *      If applicable, this callback also initializes na_hostvp,
544270252Sluigi	 *      that can be used to connect the adapter host rings to the
545270252Sluigi	 *      switch.
546270252Sluigi	 *      Called with NMG_LOCK held.
547270252Sluigi	 *
548270252Sluigi	 * nm_bdg_ctl() is called on the actual attach/detach to/from
549270252Sluigi	 *      to/from the switch, to perform adapter-specific
550270252Sluigi	 *      initializations
551270252Sluigi	 *      Called with NMG_LOCK held.
552270252Sluigi	 */
553270252Sluigi	int (*nm_bdg_attach)(const char *bdg_name, struct netmap_adapter *);
554270252Sluigi	int (*nm_bdg_ctl)(struct netmap_adapter *, struct nmreq *, int);
555270252Sluigi
556270252Sluigi	/* adapter used to attach this adapter to a VALE switch (if any) */
557270252Sluigi	struct netmap_vp_adapter *na_vp;
558270252Sluigi	/* adapter used to attach the host rings of this adapter
559270252Sluigi	 * to a VALE switch (if any) */
560270252Sluigi	struct netmap_vp_adapter *na_hostvp;
561270252Sluigi#endif
562270252Sluigi
563262151Sluigi	/* standard refcount to control the lifetime of the adapter
564262151Sluigi	 * (it should be equal to the lifetime of the corresponding ifp)
565262151Sluigi	 */
566262151Sluigi	int na_refcount;
567262151Sluigi
568262151Sluigi	/* memory allocator (opaque)
569262151Sluigi	 * We also cache a pointer to the lut_entry for translating
570262151Sluigi	 * buffer addresses, and the total number of buffers.
571262151Sluigi	 */
572262151Sluigi 	struct netmap_mem_d *nm_mem;
573262151Sluigi	struct lut_entry *na_lut;
574262151Sluigi	uint32_t na_lut_objtotal;	/* max buffer index */
575270252Sluigi	uint32_t na_lut_objsize;	/* buffer size */
576262151Sluigi
577270252Sluigi	/* additional information attached to this adapter
578270252Sluigi	 * by other netmap subsystems. Currently used by
579270252Sluigi	 * bwrap and LINUX/v1000.
580262151Sluigi	 */
581262151Sluigi	void *na_private;
582262151Sluigi
583262151Sluigi#ifdef WITH_PIPES
584270252Sluigi	/* array of pipes that have this adapter as a parent */
585262151Sluigi	struct netmap_pipe_adapter **na_pipes;
586270252Sluigi	int na_next_pipe;	/* next free slot in the array */
587270252Sluigi	int na_max_pipes;	/* size of the array */
588262151Sluigi#endif /* WITH_PIPES */
589270252Sluigi
590270252Sluigi	char name[64];
591262151Sluigi};
592262151Sluigi
593262151Sluigi
594262151Sluigi/*
595262151Sluigi * If the NIC is owned by the kernel
596262151Sluigi * (i.e., bridge), neither another bridge nor user can use it;
597262151Sluigi * if the NIC is owned by a user, only users can share it.
598262151Sluigi * Evaluation must be done under NMG_LOCK().
599262151Sluigi */
600270252Sluigi#define NETMAP_OWNED_BY_KERN(na)	((na)->na_flags & NAF_BUSY)
601262151Sluigi#define NETMAP_OWNED_BY_ANY(na) \
602270252Sluigi	(NETMAP_OWNED_BY_KERN(na) || ((na)->active_fds > 0))
603262151Sluigi
604262151Sluigi
605262151Sluigi/*
606262151Sluigi * derived netmap adapters for various types of ports
607262151Sluigi */
608262151Sluigistruct netmap_vp_adapter {	/* VALE software port */
609262151Sluigi	struct netmap_adapter up;
610262151Sluigi
611250107Sluigi	/*
612250107Sluigi	 * Bridge support:
613250107Sluigi	 *
614250107Sluigi	 * bdg_port is the port number used in the bridge;
615251139Sluigi	 * na_bdg points to the bridge this NA is attached to.
616250107Sluigi	 */
617238812Sluigi	int bdg_port;
618251139Sluigi	struct nm_bridge *na_bdg;
619262151Sluigi	int retry;
620262151Sluigi
621262151Sluigi	/* Offset of ethernet header for each packet. */
622262151Sluigi	u_int virt_hdr_len;
623262151Sluigi	/* Maximum Frame Size, used in bdg_mismatch_datapath() */
624262151Sluigi	u_int mfs;
625262151Sluigi};
626262151Sluigi
627262151Sluigi
628262151Sluigistruct netmap_hw_adapter {	/* physical device */
629262151Sluigi	struct netmap_adapter up;
630262151Sluigi
631262151Sluigi	struct net_device_ops nm_ndo;	// XXX linux only
632270252Sluigi	struct ethtool_ops    nm_eto;	// XXX linux only
633270252Sluigi	const struct ethtool_ops*   save_ethtool;
634270252Sluigi
635270252Sluigi	int (*nm_hw_register)(struct netmap_adapter *, int onoff);
636262151Sluigi};
637262151Sluigi
638262151Sluigi/* Mitigation support. */
639262151Sluigistruct nm_generic_mit {
640262151Sluigi	struct hrtimer mit_timer;
641262151Sluigi	int mit_pending;
642270252Sluigi	int mit_ring_idx;  /* index of the ring being mitigated */
643262151Sluigi	struct netmap_adapter *mit_na;  /* backpointer */
644262151Sluigi};
645262151Sluigi
646262151Sluigistruct netmap_generic_adapter {	/* emulated device */
647262151Sluigi	struct netmap_hw_adapter up;
648262151Sluigi
649262151Sluigi	/* Pointer to a previously used netmap adapter. */
650262151Sluigi	struct netmap_adapter *prev;
651262151Sluigi
652262151Sluigi	/* generic netmap adapters support:
653262151Sluigi	 * a net_device_ops struct overrides ndo_select_queue(),
654262151Sluigi	 * save_if_input saves the if_input hook (FreeBSD),
655262151Sluigi	 * mit implements rx interrupt mitigation,
656251139Sluigi	 */
657262151Sluigi	struct net_device_ops generic_ndo;
658262151Sluigi	void (*save_if_input)(struct ifnet *, struct mbuf *);
659262151Sluigi
660262151Sluigi	struct nm_generic_mit *mit;
661232238Sluigi#ifdef linux
662262151Sluigi        netdev_tx_t (*save_start_xmit)(struct mbuf *, struct ifnet *);
663262151Sluigi#endif
664227614Sluigi};
665227614Sluigi
666262151Sluigistatic __inline int
667262151Sluiginetmap_real_tx_rings(struct netmap_adapter *na)
668262151Sluigi{
669262151Sluigi	return na->num_tx_rings + !!(na->na_flags & NAF_HOST_RINGS);
670262151Sluigi}
671262151Sluigi
672262151Sluigistatic __inline int
673262151Sluiginetmap_real_rx_rings(struct netmap_adapter *na)
674262151Sluigi{
675262151Sluigi	return na->num_rx_rings + !!(na->na_flags & NAF_HOST_RINGS);
676262151Sluigi}
677262151Sluigi
678262151Sluigi#ifdef WITH_VALE
679262151Sluigi
680227614Sluigi/*
681262151Sluigi * Bridge wrapper for non VALE ports attached to a VALE switch.
682227614Sluigi *
683262151Sluigi * The real device must already have its own netmap adapter (hwna).
684262151Sluigi * The bridge wrapper and the hwna adapter share the same set of
685262151Sluigi * netmap rings and buffers, but they have two separate sets of
686262151Sluigi * krings descriptors, with tx/rx meanings swapped:
687227614Sluigi *
688262151Sluigi *                                  netmap
689262151Sluigi *           bwrap     krings       rings      krings      hwna
690262151Sluigi *         +------+   +------+     +-----+    +------+   +------+
691262151Sluigi *         |tx_rings->|      |\   /|     |----|      |<-tx_rings|
692262151Sluigi *         |      |   +------+ \ / +-----+    +------+   |      |
693262151Sluigi *         |      |             X                        |      |
694262151Sluigi *         |      |            / \                       |      |
695262151Sluigi *         |      |   +------+/   \+-----+    +------+   |      |
696262151Sluigi *         |rx_rings->|      |     |     |----|      |<-rx_rings|
697262151Sluigi *         |      |   +------+     +-----+    +------+   |      |
698262151Sluigi *         +------+                                      +------+
699262151Sluigi *
700262151Sluigi * - packets coming from the bridge go to the brwap rx rings,
701262151Sluigi *   which are also the hwna tx rings.  The bwrap notify callback
702262151Sluigi *   will then complete the hwna tx (see netmap_bwrap_notify).
703262151Sluigi *
704262151Sluigi * - packets coming from the outside go to the hwna rx rings,
705262151Sluigi *   which are also the bwrap tx rings.  The (overwritten) hwna
706262151Sluigi *   notify method will then complete the bridge tx
707262151Sluigi *   (see netmap_bwrap_intr_notify).
708262151Sluigi *
709262151Sluigi *   The bridge wrapper may optionally connect the hwna 'host' rings
710262151Sluigi *   to the bridge. This is done by using a second port in the
711262151Sluigi *   bridge and connecting it to the 'host' netmap_vp_adapter
712262151Sluigi *   contained in the netmap_bwrap_adapter. The brwap host adapter
713262151Sluigi *   cross-links the hwna host rings in the same way as shown above.
714262151Sluigi *
715262151Sluigi * - packets coming from the bridge and directed to the host stack
716262151Sluigi *   are handled by the bwrap host notify callback
717262151Sluigi *   (see netmap_bwrap_host_notify)
718262151Sluigi *
719262151Sluigi * - packets coming from the host stack are still handled by the
720262151Sluigi *   overwritten hwna notify callback (netmap_bwrap_intr_notify),
721262151Sluigi *   but are diverted to the host adapter depending on the ring number.
722262151Sluigi *
723227614Sluigi */
724262151Sluigistruct netmap_bwrap_adapter {
725262151Sluigi	struct netmap_vp_adapter up;
726262151Sluigi	struct netmap_vp_adapter host;  /* for host rings */
727262151Sluigi	struct netmap_adapter *hwna;	/* the underlying device */
728227614Sluigi
729262151Sluigi	/* backup of the hwna notify callback */
730262151Sluigi	int (*save_notify)(struct netmap_adapter *,
731262151Sluigi			u_int ring, enum txrx, int flags);
732270252Sluigi	/* backup of the hwna memory allocator */
733270252Sluigi	struct netmap_mem_d *save_nmd;
734227614Sluigi
735262151Sluigi	/*
736262151Sluigi	 * When we attach a physical interface to the bridge, we
737262151Sluigi	 * allow the controlling process to terminate, so we need
738270252Sluigi	 * a place to store the n_detmap_priv_d data structure.
739262151Sluigi	 * This is only done when physical interfaces
740262151Sluigi	 * are attached to a bridge.
741262151Sluigi	 */
742262151Sluigi	struct netmap_priv_d *na_kpriv;
743262151Sluigi};
744270252Sluigiint netmap_bwrap_attach(const char *name, struct netmap_adapter *);
745262151Sluigi
746262151Sluigi
747262151Sluigi#endif /* WITH_VALE */
748262151Sluigi
749262151Sluigi#ifdef WITH_PIPES
750262151Sluigi
751262151Sluigi#define NM_MAXPIPES 	64	/* max number of pipes per adapter */
752262151Sluigi
753262151Sluigistruct netmap_pipe_adapter {
754262151Sluigi	struct netmap_adapter up;
755262151Sluigi
756262151Sluigi	u_int id; 	/* pipe identifier */
757262151Sluigi	int role;	/* either NR_REG_PIPE_MASTER or NR_REG_PIPE_SLAVE */
758262151Sluigi
759262151Sluigi	struct netmap_adapter *parent; /* adapter that owns the memory */
760262151Sluigi	struct netmap_pipe_adapter *peer; /* the other end of the pipe */
761262151Sluigi	int peer_ref;		/* 1 iff we are holding a ref to the peer */
762262151Sluigi
763262151Sluigi	u_int parent_slot; /* index in the parent pipe array */
764262151Sluigi};
765262151Sluigi
766262151Sluigi#endif /* WITH_PIPES */
767262151Sluigi
768262151Sluigi
769262151Sluigi/* return slots reserved to rx clients; used in drivers */
770262151Sluigistatic inline uint32_t
771262151Sluiginm_kr_rxspace(struct netmap_kring *k)
772262151Sluigi{
773262151Sluigi	int space = k->nr_hwtail - k->nr_hwcur;
774267282Sluigi	if (space < 0)
775262151Sluigi		space += k->nkr_num_slots;
776262151Sluigi	ND("preserving %d rx slots %d -> %d", space, k->nr_hwcur, k->nr_hwtail);
777262151Sluigi
778262151Sluigi	return space;
779262151Sluigi}
780262151Sluigi
781262151Sluigi
782262151Sluigi/* True if no space in the tx ring. only valid after txsync_prologue */
783262151Sluigistatic inline int
784262151Sluiginm_kr_txempty(struct netmap_kring *kring)
785262151Sluigi{
786262151Sluigi	return kring->rcur == kring->nr_hwtail;
787262151Sluigi}
788262151Sluigi
789262151Sluigi
790227614Sluigi/*
791262151Sluigi * protect against multiple threads using the same ring.
792262151Sluigi * also check that the ring has not been stopped.
793262151Sluigi * We only care for 0 or !=0 as a return code.
794227614Sluigi */
795262151Sluigi#define NM_KR_BUSY	1
796262151Sluigi#define NM_KR_STOPPED	2
797227614Sluigi
798250107Sluigi
799262151Sluigistatic __inline void nm_kr_put(struct netmap_kring *kr)
800262151Sluigi{
801262151Sluigi	NM_ATOMIC_CLEAR(&kr->nr_busy);
802262151Sluigi}
803262151Sluigi
804262151Sluigi
805262151Sluigistatic __inline int nm_kr_tryget(struct netmap_kring *kr)
806262151Sluigi{
807262151Sluigi	/* check a first time without taking the lock
808262151Sluigi	 * to avoid starvation for nm_kr_get()
809262151Sluigi	 */
810262151Sluigi	if (unlikely(kr->nkr_stopped)) {
811262151Sluigi		ND("ring %p stopped (%d)", kr, kr->nkr_stopped);
812262151Sluigi		return NM_KR_STOPPED;
813262151Sluigi	}
814262151Sluigi	if (unlikely(NM_ATOMIC_TEST_AND_SET(&kr->nr_busy)))
815262151Sluigi		return NM_KR_BUSY;
816262151Sluigi	/* check a second time with lock held */
817262151Sluigi	if (unlikely(kr->nkr_stopped)) {
818262151Sluigi		ND("ring %p stopped (%d)", kr, kr->nkr_stopped);
819262151Sluigi		nm_kr_put(kr);
820262151Sluigi		return NM_KR_STOPPED;
821262151Sluigi	}
822262151Sluigi	return 0;
823262151Sluigi}
824262151Sluigi
825262151Sluigi
826227614Sluigi/*
827262151Sluigi * The following functions are used by individual drivers to
828227614Sluigi * support netmap operation.
829227614Sluigi *
830227614Sluigi * netmap_attach() initializes a struct netmap_adapter, allocating the
831227614Sluigi * 	struct netmap_ring's and the struct selinfo.
832227614Sluigi *
833227614Sluigi * netmap_detach() frees the memory allocated by netmap_attach().
834227614Sluigi *
835262151Sluigi * netmap_transmit() replaces the if_transmit routine of the interface,
836227614Sluigi *	and is used to intercept packets coming from the stack.
837227614Sluigi *
838227614Sluigi * netmap_load_map/netmap_reload_map are helper routines to set/reset
839227614Sluigi *	the dmamap for a packet buffer
840227614Sluigi *
841270252Sluigi * netmap_reset() is a helper routine to be called in the hw driver
842270252Sluigi *	when reinitializing a ring. It should not be called by
843270252Sluigi *	virtual ports (vale, pipes, monitor)
844227614Sluigi */
845262151Sluigiint netmap_attach(struct netmap_adapter *);
846227614Sluigivoid netmap_detach(struct ifnet *);
847262151Sluigiint netmap_transmit(struct ifnet *, struct mbuf *);
848227614Sluigistruct netmap_slot *netmap_reset(struct netmap_adapter *na,
849262151Sluigi	enum txrx tx, u_int n, u_int new_cur);
850227614Sluigiint netmap_ring_reinit(struct netmap_kring *);
851227614Sluigi
852262151Sluigi/* default functions to handle rx/tx interrupts */
853262151Sluigiint netmap_rx_irq(struct ifnet *, u_int, u_int *);
854262151Sluigi#define netmap_tx_irq(_n, _q) netmap_rx_irq(_n, _q, NULL)
855262151Sluigivoid netmap_common_irq(struct ifnet *, u_int, u_int *work_done);
856262151Sluigi
857262151Sluigi
858270252Sluigi#ifdef WITH_VALE
859270252Sluigi/* functions used by external modules to interface with VALE */
860270252Sluigi#define netmap_vp_to_ifp(_vp)	((_vp)->up.ifp)
861270252Sluigi#define netmap_ifp_to_vp(_ifp)	(NA(_ifp)->na_vp)
862270252Sluigi#define netmap_ifp_to_host_vp(_ifp) (NA(_ifp)->na_hostvp)
863270252Sluigi#define netmap_bdg_idx(_vp)	((_vp)->bdg_port)
864270252Sluigiconst char *netmap_bdg_name(struct netmap_vp_adapter *);
865270252Sluigi#else /* !WITH_VALE */
866270252Sluigi#define netmap_vp_to_ifp(_vp)	NULL
867270252Sluigi#define netmap_ifp_to_vp(_ifp)	NULL
868270252Sluigi#define netmap_ifp_to_host_vp(_ifp) NULL
869270252Sluigi#define netmap_bdg_idx(_vp)	-1
870270252Sluigi#define netmap_bdg_name(_vp)	NULL
871270252Sluigi#endif /* WITH_VALE */
872262151Sluigi
873270252Sluigistatic inline int
874270252Sluiginm_native_on(struct netmap_adapter *na)
875270252Sluigi{
876270252Sluigi	return na && na->na_flags & NAF_NATIVE_ON;
877270252Sluigi}
878270252Sluigi
879270252Sluigistatic inline int
880270252Sluiginm_netmap_on(struct netmap_adapter *na)
881270252Sluigi{
882270252Sluigi	return na && na->na_flags & NAF_NETMAP_ON;
883270252Sluigi}
884270252Sluigi
885262151Sluigi/* set/clear native flags and if_transmit/netdev_ops */
886262151Sluigistatic inline void
887262151Sluiginm_set_native_flags(struct netmap_adapter *na)
888262151Sluigi{
889262151Sluigi	struct ifnet *ifp = na->ifp;
890262151Sluigi
891262151Sluigi	na->na_flags |= (NAF_NATIVE_ON | NAF_NETMAP_ON);
892262151Sluigi#ifdef IFCAP_NETMAP /* or FreeBSD ? */
893262151Sluigi	ifp->if_capenable |= IFCAP_NETMAP;
894262151Sluigi#endif
895262151Sluigi#ifdef __FreeBSD__
896262151Sluigi	na->if_transmit = ifp->if_transmit;
897262151Sluigi	ifp->if_transmit = netmap_transmit;
898262151Sluigi#else
899262151Sluigi	na->if_transmit = (void *)ifp->netdev_ops;
900262151Sluigi	ifp->netdev_ops = &((struct netmap_hw_adapter *)na)->nm_ndo;
901270252Sluigi	((struct netmap_hw_adapter *)na)->save_ethtool = ifp->ethtool_ops;
902270252Sluigi	ifp->ethtool_ops = &((struct netmap_hw_adapter*)na)->nm_eto;
903262151Sluigi#endif
904262151Sluigi}
905262151Sluigi
906262151Sluigi
907262151Sluigistatic inline void
908262151Sluiginm_clear_native_flags(struct netmap_adapter *na)
909262151Sluigi{
910262151Sluigi	struct ifnet *ifp = na->ifp;
911262151Sluigi
912262151Sluigi#ifdef __FreeBSD__
913262151Sluigi	ifp->if_transmit = na->if_transmit;
914262151Sluigi#else
915262151Sluigi	ifp->netdev_ops = (void *)na->if_transmit;
916270252Sluigi	ifp->ethtool_ops = ((struct netmap_hw_adapter*)na)->save_ethtool;
917262151Sluigi#endif
918262151Sluigi	na->na_flags &= ~(NAF_NATIVE_ON | NAF_NETMAP_ON);
919262151Sluigi#ifdef IFCAP_NETMAP /* or FreeBSD ? */
920262151Sluigi	ifp->if_capenable &= ~IFCAP_NETMAP;
921262151Sluigi#endif
922262151Sluigi}
923262151Sluigi
924262151Sluigi
925251139Sluigi/*
926262151Sluigi * validates parameters in the ring/kring, returns a value for head
927262151Sluigi * If any error, returns ring_size to force a reinit.
928262151Sluigi */
929262151Sluigiuint32_t nm_txsync_prologue(struct netmap_kring *);
930262151Sluigi
931262151Sluigi
932262151Sluigi/*
933262151Sluigi * validates parameters in the ring/kring, returns a value for head,
934262151Sluigi * and the 'reserved' value in the argument.
935262151Sluigi * If any error, returns ring_size lim to force a reinit.
936262151Sluigi */
937262151Sluigiuint32_t nm_rxsync_prologue(struct netmap_kring *);
938262151Sluigi
939262151Sluigi
940262151Sluigi/*
941262151Sluigi * update kring and ring at the end of txsync.
942262151Sluigi */
943262151Sluigistatic inline void
944262151Sluiginm_txsync_finalize(struct netmap_kring *kring)
945262151Sluigi{
946262151Sluigi	/* update ring tail to what the kernel knows */
947262151Sluigi	kring->ring->tail = kring->rtail = kring->nr_hwtail;
948267282Sluigi
949262151Sluigi	/* note, head/rhead/hwcur might be behind cur/rcur
950262151Sluigi	 * if no carrier
951262151Sluigi	 */
952262151Sluigi	ND(5, "%s now hwcur %d hwtail %d head %d cur %d tail %d",
953262151Sluigi		kring->name, kring->nr_hwcur, kring->nr_hwtail,
954262151Sluigi		kring->rhead, kring->rcur, kring->rtail);
955262151Sluigi}
956262151Sluigi
957262151Sluigi
958262151Sluigi/*
959262151Sluigi * update kring and ring at the end of rxsync
960262151Sluigi */
961262151Sluigistatic inline void
962262151Sluiginm_rxsync_finalize(struct netmap_kring *kring)
963262151Sluigi{
964262151Sluigi	/* tell userspace that there might be new packets */
965262151Sluigi	//struct netmap_ring *ring = kring->ring;
966262151Sluigi	ND("head %d cur %d tail %d -> %d", ring->head, ring->cur, ring->tail,
967262151Sluigi		kring->nr_hwtail);
968262151Sluigi	kring->ring->tail = kring->rtail = kring->nr_hwtail;
969262151Sluigi	/* make a copy of the state for next round */
970262151Sluigi	kring->rhead = kring->ring->head;
971262151Sluigi	kring->rcur = kring->ring->cur;
972262151Sluigi}
973262151Sluigi
974262151Sluigi
975262151Sluigi/* check/fix address and len in tx rings */
976262151Sluigi#if 1 /* debug version */
977270252Sluigi#define	NM_CHECK_ADDR_LEN(_na, _a, _l)	do {				\
978270252Sluigi	if (_a == NETMAP_BUF_BASE(_na) || _l > NETMAP_BUF_SIZE(_na)) {	\
979262151Sluigi		RD(5, "bad addr/len ring %d slot %d idx %d len %d",	\
980270252Sluigi			kring->ring_id, nm_i, slot->buf_idx, len);	\
981270252Sluigi		if (_l > NETMAP_BUF_SIZE(_na))				\
982270252Sluigi			_l = NETMAP_BUF_SIZE(_na);			\
983262151Sluigi	} } while (0)
984262151Sluigi#else /* no debug version */
985270252Sluigi#define	NM_CHECK_ADDR_LEN(_na, _a, _l)	do {				\
986270252Sluigi		if (_l > NETMAP_BUF_SIZE(_na))				\
987270252Sluigi			_l = NETMAP_BUF_SIZE(_na);			\
988262151Sluigi	} while (0)
989262151Sluigi#endif
990262151Sluigi
991262151Sluigi
992262151Sluigi/*---------------------------------------------------------------*/
993262151Sluigi/*
994270252Sluigi * Support routines used by netmap subsystems
995270252Sluigi * (native drivers, VALE, generic, pipes, monitors, ...)
996262151Sluigi */
997270252Sluigi
998270252Sluigi
999270252Sluigi/* common routine for all functions that create a netmap adapter. It performs
1000270252Sluigi * two main tasks:
1001270252Sluigi * - if the na points to an ifp, mark the ifp as netmap capable
1002270252Sluigi *   using na as its native adapter;
1003270252Sluigi * - provide defaults for the setup callbacks and the memory allocator
1004270252Sluigi */
1005270252Sluigiint netmap_attach_common(struct netmap_adapter *);
1006270252Sluigi/* common actions to be performed on netmap adapter destruction */
1007270252Sluigivoid netmap_detach_common(struct netmap_adapter *);
1008270252Sluigi/* fill priv->np_[tr]xq{first,last} using the ringid and flags information
1009270252Sluigi * coming from a struct nmreq
1010270252Sluigi */
1011270252Sluigiint netmap_interp_ringid(struct netmap_priv_d *priv, uint16_t ringid, uint32_t flags);
1012270252Sluigi/* update the ring parameters (number and size of tx and rx rings).
1013270252Sluigi * It calls the nm_config callback, if available.
1014270252Sluigi */
1015262151Sluigiint netmap_update_config(struct netmap_adapter *na);
1016270252Sluigi/* create and initialize the common fields of the krings array.
1017270252Sluigi * using the information that must be already available in the na.
1018270252Sluigi * tailroom can be used to request the allocation of additional
1019270252Sluigi * tailroom bytes after the krings array. This is used by
1020270252Sluigi * netmap_vp_adapter's (i.e., VALE ports) to make room for
1021270252Sluigi * leasing-related data structures
1022270252Sluigi */
1023262151Sluigiint netmap_krings_create(struct netmap_adapter *na, u_int tailroom);
1024270252Sluigi/* deletes the kring array of the adapter. The array must have
1025270252Sluigi * been created using netmap_krings_create
1026270252Sluigi */
1027262151Sluigivoid netmap_krings_delete(struct netmap_adapter *na);
1028270252Sluigi
1029270252Sluigi/* set the stopped/enabled status of ring
1030270252Sluigi * When stopping, they also wait for all current activity on the ring to
1031270252Sluigi * terminate. The status change is then notified using the na nm_notify
1032270252Sluigi * callback.
1033270252Sluigi */
1034270252Sluigivoid netmap_set_txring(struct netmap_adapter *, u_int ring_id, int stopped);
1035270252Sluigivoid netmap_set_rxring(struct netmap_adapter *, u_int ring_id, int stopped);
1036270252Sluigi/* set the stopped/enabled status of all rings of the adapter. */
1037270252Sluigivoid netmap_set_all_rings(struct netmap_adapter *, int stopped);
1038270252Sluigi/* convenience wrappers for netmap_set_all_rings, used in drivers */
1039270252Sluigivoid netmap_disable_all_rings(struct ifnet *);
1040270252Sluigivoid netmap_enable_all_rings(struct ifnet *);
1041270252Sluigi
1042262151Sluigiint netmap_rxsync_from_host(struct netmap_adapter *na, struct thread *td, void *pwait);
1043262151Sluigi
1044262151Sluigistruct netmap_if *
1045262151Sluiginetmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na,
1046262151Sluigi	uint16_t ringid, uint32_t flags, int *err);
1047262151Sluigi
1048262151Sluigi
1049262151Sluigi
1050262151Sluigiu_int nm_bound_var(u_int *v, u_int dflt, u_int lo, u_int hi, const char *msg);
1051262151Sluigiint netmap_get_na(struct nmreq *nmr, struct netmap_adapter **na, int create);
1052262151Sluigiint netmap_get_hw_na(struct ifnet *ifp, struct netmap_adapter **na);
1053262151Sluigi
1054262151Sluigi
1055262151Sluigi#ifdef WITH_VALE
1056262151Sluigi/*
1057262151Sluigi * The following bridge-related functions are used by other
1058262151Sluigi * kernel modules.
1059262151Sluigi *
1060262151Sluigi * VALE only supports unicast or broadcast. The lookup
1061251139Sluigi * function can return 0 .. NM_BDG_MAXPORTS-1 for regular ports,
1062251139Sluigi * NM_BDG_MAXPORTS for broadcast, NM_BDG_MAXPORTS+1 for unknown.
1063251139Sluigi * XXX in practice "unknown" might be handled same as broadcast.
1064251139Sluigi */
1065270252Sluigitypedef u_int (*bdg_lookup_fn_t)(struct nm_bdg_fwd *ft, uint8_t *ring_nr,
1066270252Sluigi		const struct netmap_vp_adapter *);
1067270252Sluigitypedef int (*bdg_config_fn_t)(struct nm_ifreq *);
1068270252Sluigitypedef void (*bdg_dtor_fn_t)(const struct netmap_vp_adapter *);
1069270252Sluigistruct netmap_bdg_ops {
1070270252Sluigi	bdg_lookup_fn_t lookup;
1071270252Sluigi	bdg_config_fn_t config;
1072270252Sluigi	bdg_dtor_fn_t	dtor;
1073270252Sluigi};
1074262151Sluigi
1075270252Sluigiu_int netmap_bdg_learning(struct nm_bdg_fwd *ft, uint8_t *dst_ring,
1076270252Sluigi		const struct netmap_vp_adapter *);
1077270252Sluigi
1078262151Sluigi#define	NM_BDG_MAXPORTS		254	/* up to 254 */
1079251139Sluigi#define	NM_BDG_BROADCAST	NM_BDG_MAXPORTS
1080251139Sluigi#define	NM_BDG_NOPORT		(NM_BDG_MAXPORTS+1)
1081251139Sluigi
1082262151Sluigi#define	NM_NAME			"vale"	/* prefix for bridge port name */
1083262151Sluigi
1084262151Sluigi/* these are redefined in case of no VALE support */
1085262151Sluigiint netmap_get_bdg_na(struct nmreq *nmr, struct netmap_adapter **na, int create);
1086262151Sluigivoid netmap_init_bridges(void);
1087270252Sluigiint netmap_bdg_ctl(struct nmreq *nmr, struct netmap_bdg_ops *bdg_ops);
1088270252Sluigiint netmap_bdg_config(struct nmreq *nmr);
1089262151Sluigi
1090262151Sluigi#else /* !WITH_VALE */
1091262151Sluigi#define	netmap_get_bdg_na(_1, _2, _3)	0
1092262151Sluigi#define netmap_init_bridges(_1)
1093262151Sluigi#define	netmap_bdg_ctl(_1, _2)	EINVAL
1094262151Sluigi#endif /* !WITH_VALE */
1095262151Sluigi
1096262151Sluigi#ifdef WITH_PIPES
1097262151Sluigi/* max number of pipes per device */
1098262151Sluigi#define NM_MAXPIPES	64	/* XXX how many? */
1099262151Sluigi/* in case of no error, returns the actual number of pipes in nmr->nr_arg1 */
1100262151Sluigiint netmap_pipe_alloc(struct netmap_adapter *, struct nmreq *nmr);
1101262151Sluigivoid netmap_pipe_dealloc(struct netmap_adapter *);
1102262151Sluigiint netmap_get_pipe_na(struct nmreq *nmr, struct netmap_adapter **na, int create);
1103262151Sluigi#else /* !WITH_PIPES */
1104262151Sluigi#define NM_MAXPIPES	0
1105262151Sluigi#define netmap_pipe_alloc(_1, _2) 	EOPNOTSUPP
1106262151Sluigi#define netmap_pipe_dealloc(_1)
1107262151Sluigi#define netmap_get_pipe_na(_1, _2, _3)	0
1108262151Sluigi#endif
1109262151Sluigi
1110270252Sluigi#ifdef WITH_MONITOR
1111270252Sluigiint netmap_get_monitor_na(struct nmreq *nmr, struct netmap_adapter **na, int create);
1112270252Sluigi#else
1113270252Sluigi#define netmap_get_monitor_na(_1, _2, _3) 0
1114270252Sluigi#endif
1115270252Sluigi
1116262151Sluigi/* Various prototypes */
1117262151Sluigiint netmap_poll(struct cdev *dev, int events, struct thread *td);
1118262151Sluigiint netmap_init(void);
1119262151Sluigivoid netmap_fini(void);
1120262151Sluigiint netmap_get_memory(struct netmap_priv_d* p);
1121262151Sluigivoid netmap_dtor(void *data);
1122262151Sluigiint netmap_dtor_locked(struct netmap_priv_d *priv);
1123262151Sluigi
1124262151Sluigiint netmap_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td);
1125262151Sluigi
1126262151Sluigi/* netmap_adapter creation/destruction */
1127262151Sluigi
1128262151Sluigi// #define NM_DEBUG_PUTGET 1
1129262151Sluigi
1130262151Sluigi#ifdef NM_DEBUG_PUTGET
1131262151Sluigi
1132262151Sluigi#define NM_DBG(f) __##f
1133262151Sluigi
1134262151Sluigivoid __netmap_adapter_get(struct netmap_adapter *na);
1135262151Sluigi
1136262151Sluigi#define netmap_adapter_get(na) 				\
1137262151Sluigi	do {						\
1138262151Sluigi		struct netmap_adapter *__na = na;	\
1139270252Sluigi		D("getting %p:%s (%d)", __na, (__na)->name, (__na)->na_refcount);	\
1140262151Sluigi		__netmap_adapter_get(__na);		\
1141262151Sluigi	} while (0)
1142262151Sluigi
1143262151Sluigiint __netmap_adapter_put(struct netmap_adapter *na);
1144262151Sluigi
1145262151Sluigi#define netmap_adapter_put(na)				\
1146262151Sluigi	({						\
1147262151Sluigi		struct netmap_adapter *__na = na;	\
1148270252Sluigi		D("putting %p:%s (%d)", __na, (__na)->name, (__na)->na_refcount);	\
1149262151Sluigi		__netmap_adapter_put(__na);		\
1150262151Sluigi	})
1151262151Sluigi
1152262151Sluigi#else /* !NM_DEBUG_PUTGET */
1153262151Sluigi
1154262151Sluigi#define NM_DBG(f) f
1155262151Sluigivoid netmap_adapter_get(struct netmap_adapter *na);
1156262151Sluigiint netmap_adapter_put(struct netmap_adapter *na);
1157262151Sluigi
1158262151Sluigi#endif /* !NM_DEBUG_PUTGET */
1159262151Sluigi
1160262151Sluigi
1161262151Sluigi/*
1162262151Sluigi * module variables
1163262151Sluigi */
1164270252Sluigi#define NETMAP_BUF_BASE(na)	((na)->na_lut[0].vaddr)
1165270252Sluigi#define NETMAP_BUF_SIZE(na)	((na)->na_lut_objsize)
1166262151Sluigiextern int netmap_mitigate;	// XXX not really used
1167231198Sluigiextern int netmap_no_pendintr;
1168227614Sluigiextern int netmap_verbose;	// XXX debugging
1169227614Sluigienum {                                  /* verbose flags */
1170227614Sluigi	NM_VERB_ON = 1,                 /* generic verbose */
1171227614Sluigi	NM_VERB_HOST = 0x2,             /* verbose host stack */
1172227614Sluigi	NM_VERB_RXSYNC = 0x10,          /* verbose on rxsync/txsync */
1173227614Sluigi	NM_VERB_TXSYNC = 0x20,
1174227614Sluigi	NM_VERB_RXINTR = 0x100,         /* verbose on rx/tx intr (driver) */
1175227614Sluigi	NM_VERB_TXINTR = 0x200,
1176227614Sluigi	NM_VERB_NIC_RXSYNC = 0x1000,    /* verbose on rx/tx intr (driver) */
1177227614Sluigi	NM_VERB_NIC_TXSYNC = 0x2000,
1178227614Sluigi};
1179227614Sluigi
1180262151Sluigiextern int netmap_txsync_retry;
1181262151Sluigiextern int netmap_generic_mit;
1182262151Sluigiextern int netmap_generic_ringsize;
1183262151Sluigiextern int netmap_generic_rings;
1184262151Sluigi
1185227614Sluigi/*
1186228845Sluigi * NA returns a pointer to the struct netmap adapter from the ifp,
1187228845Sluigi * WNA is used to write it.
1188227614Sluigi */
1189228845Sluigi#ifndef WNA
1190228845Sluigi#define	WNA(_ifp)	(_ifp)->if_pspare[0]
1191228845Sluigi#endif
1192228845Sluigi#define	NA(_ifp)	((struct netmap_adapter *)WNA(_ifp))
1193227614Sluigi
1194241719Sluigi/*
1195241719Sluigi * Macros to determine if an interface is netmap capable or netmap enabled.
1196241719Sluigi * See the magic field in struct netmap_adapter.
1197241719Sluigi */
1198241719Sluigi#ifdef __FreeBSD__
1199241719Sluigi/*
1200241719Sluigi * on FreeBSD just use if_capabilities and if_capenable.
1201241719Sluigi */
1202241719Sluigi#define NETMAP_CAPABLE(ifp)	(NA(ifp) &&		\
1203241719Sluigi	(ifp)->if_capabilities & IFCAP_NETMAP )
1204227614Sluigi
1205241719Sluigi#define	NETMAP_SET_CAPABLE(ifp)				\
1206241719Sluigi	(ifp)->if_capabilities |= IFCAP_NETMAP
1207241719Sluigi
1208241719Sluigi#else	/* linux */
1209241719Sluigi
1210241719Sluigi/*
1211241719Sluigi * on linux:
1212241719Sluigi * we check if NA(ifp) is set and its first element has a related
1213241719Sluigi * magic value. The capenable is within the struct netmap_adapter.
1214241719Sluigi */
1215241719Sluigi#define	NETMAP_MAGIC	0x52697a7a
1216241719Sluigi
1217241719Sluigi#define NETMAP_CAPABLE(ifp)	(NA(ifp) &&		\
1218241719Sluigi	((uint32_t)(uintptr_t)NA(ifp) ^ NA(ifp)->magic) == NETMAP_MAGIC )
1219241719Sluigi
1220241719Sluigi#define	NETMAP_SET_CAPABLE(ifp)				\
1221241719Sluigi	NA(ifp)->magic = ((uint32_t)(uintptr_t)NA(ifp)) ^ NETMAP_MAGIC
1222241719Sluigi
1223241719Sluigi#endif	/* linux */
1224241719Sluigi
1225238812Sluigi#ifdef __FreeBSD__
1226262151Sluigi
1227270252Sluigi/* Assigns the device IOMMU domain to an allocator.
1228270252Sluigi * Returns -ENOMEM in case the domain is different */
1229270252Sluigi#define nm_iommu_group_id(dev) (0)
1230270252Sluigi
1231262151Sluigi/* Callback invoked by the dma machinery after a successful dmamap_load */
1232230052Sluigistatic void netmap_dmamap_cb(__unused void *arg,
1233230058Sluigi    __unused bus_dma_segment_t * segs, __unused int nseg, __unused int error)
1234230052Sluigi{
1235230052Sluigi}
1236230052Sluigi
1237230052Sluigi/* bus_dmamap_load wrapper: call aforementioned function if map != NULL.
1238230052Sluigi * XXX can we do it without a callback ?
1239230052Sluigi */
1240230052Sluigistatic inline void
1241270252Sluiginetmap_load_map(struct netmap_adapter *na,
1242270252Sluigi	bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
1243230052Sluigi{
1244230052Sluigi	if (map)
1245270252Sluigi		bus_dmamap_load(tag, map, buf, NETMAP_BUF_SIZE(na),
1246230058Sluigi		    netmap_dmamap_cb, NULL, BUS_DMA_NOWAIT);
1247230052Sluigi}
1248230052Sluigi
1249270252Sluigistatic inline void
1250270252Sluiginetmap_unload_map(struct netmap_adapter *na,
1251270252Sluigi        bus_dma_tag_t tag, bus_dmamap_t map)
1252270252Sluigi{
1253270252Sluigi	if (map)
1254270252Sluigi		bus_dmamap_unload(tag, map);
1255270252Sluigi}
1256270252Sluigi
1257230052Sluigi/* update the map when a buffer changes. */
1258230052Sluigistatic inline void
1259270252Sluiginetmap_reload_map(struct netmap_adapter *na,
1260270252Sluigi	bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
1261230052Sluigi{
1262230052Sluigi	if (map) {
1263230052Sluigi		bus_dmamap_unload(tag, map);
1264270252Sluigi		bus_dmamap_load(tag, map, buf, NETMAP_BUF_SIZE(na),
1265230058Sluigi		    netmap_dmamap_cb, NULL, BUS_DMA_NOWAIT);
1266230052Sluigi	}
1267230052Sluigi}
1268262151Sluigi
1269238812Sluigi#else /* linux */
1270230052Sluigi
1271270252Sluigiint nm_iommu_group_id(bus_dma_tag_t dev);
1272270252Sluigiextern size_t     netmap_mem_get_bufsize(struct netmap_mem_d *);
1273270252Sluigi#include <linux/dma-mapping.h>
1274270252Sluigi
1275270252Sluigistatic inline void
1276270252Sluiginetmap_load_map(struct netmap_adapter *na,
1277270252Sluigi	bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
1278270252Sluigi{
1279270252Sluigi	if (map) {
1280270252Sluigi		*map = dma_map_single(na->pdev, buf, netmap_mem_get_bufsize(na->nm_mem),
1281270252Sluigi				DMA_BIDIRECTIONAL);
1282270252Sluigi	}
1283270252Sluigi}
1284270252Sluigi
1285270252Sluigistatic inline void
1286270252Sluiginetmap_unload_map(struct netmap_adapter *na,
1287270252Sluigi	bus_dma_tag_t tag, bus_dmamap_t map)
1288270252Sluigi{
1289270252Sluigi	u_int sz = netmap_mem_get_bufsize(na->nm_mem);
1290270252Sluigi
1291270252Sluigi	if (*map) {
1292270252Sluigi		dma_unmap_single(na->pdev, *map, sz,
1293270252Sluigi				DMA_BIDIRECTIONAL);
1294270252Sluigi	}
1295270252Sluigi}
1296270252Sluigi
1297270252Sluigistatic inline void
1298270252Sluiginetmap_reload_map(struct netmap_adapter *na,
1299270252Sluigi	bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
1300270252Sluigi{
1301270252Sluigi	u_int sz = netmap_mem_get_bufsize(na->nm_mem);
1302270252Sluigi
1303270252Sluigi	if (*map) {
1304270252Sluigi		dma_unmap_single(na->pdev, *map, sz,
1305270252Sluigi				DMA_BIDIRECTIONAL);
1306270252Sluigi	}
1307270252Sluigi
1308270252Sluigi	*map = dma_map_single(na->pdev, buf, sz,
1309270252Sluigi				DMA_BIDIRECTIONAL);
1310270252Sluigi}
1311270252Sluigi
1312231796Sluigi/*
1313238812Sluigi * XXX How do we redefine these functions:
1314238812Sluigi *
1315238812Sluigi * on linux we need
1316238831Sluigi *	dma_map_single(&pdev->dev, virt_addr, len, direction)
1317238831Sluigi *	dma_unmap_single(&adapter->pdev->dev, phys_addr, len, direction
1318238812Sluigi * The len can be implicit (on netmap it is NETMAP_BUF_SIZE)
1319238812Sluigi * unfortunately the direction is not, so we need to change
1320238812Sluigi * something to have a cross API
1321238812Sluigi */
1322270252Sluigi
1323238812Sluigi#if 0
1324238812Sluigi	struct e1000_buffer *buffer_info =  &tx_ring->buffer_info[l];
1325238812Sluigi	/* set time_stamp *before* dma to help avoid a possible race */
1326238812Sluigi	buffer_info->time_stamp = jiffies;
1327238812Sluigi	buffer_info->mapped_as_page = false;
1328238812Sluigi	buffer_info->length = len;
1329238812Sluigi	//buffer_info->next_to_watch = l;
1330238812Sluigi	/* reload dma map */
1331238812Sluigi	dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
1332238831Sluigi			NETMAP_BUF_SIZE, DMA_TO_DEVICE);
1333238812Sluigi	buffer_info->dma = dma_map_single(&adapter->pdev->dev,
1334238831Sluigi			addr, NETMAP_BUF_SIZE, DMA_TO_DEVICE);
1335238812Sluigi
1336238812Sluigi	if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) {
1337238812Sluigi		D("dma mapping error");
1338238812Sluigi		/* goto dma_error; See e1000_put_txbuf() */
1339238812Sluigi		/* XXX reset */
1340238812Sluigi	}
1341238812Sluigi	tx_desc->buffer_addr = htole64(buffer_info->dma); //XXX
1342238812Sluigi
1343238812Sluigi#endif
1344238812Sluigi
1345238812Sluigi/*
1346238812Sluigi * The bus_dmamap_sync() can be one of wmb() or rmb() depending on direction.
1347238812Sluigi */
1348238812Sluigi#define bus_dmamap_sync(_a, _b, _c)
1349238812Sluigi
1350238812Sluigi#endif /* linux */
1351238812Sluigi
1352262151Sluigi
1353238812Sluigi/*
1354231796Sluigi * functions to map NIC to KRING indexes (n2k) and vice versa (k2n)
1355231796Sluigi */
1356231796Sluigistatic inline int
1357232238Sluiginetmap_idx_n2k(struct netmap_kring *kr, int idx)
1358231796Sluigi{
1359232238Sluigi	int n = kr->nkr_num_slots;
1360232238Sluigi	idx += kr->nkr_hwofs;
1361232238Sluigi	if (idx < 0)
1362232238Sluigi		return idx + n;
1363232238Sluigi	else if (idx < n)
1364232238Sluigi		return idx;
1365231796Sluigi	else
1366232238Sluigi		return idx - n;
1367231796Sluigi}
1368230052Sluigi
1369231796Sluigi
1370231796Sluigistatic inline int
1371232238Sluiginetmap_idx_k2n(struct netmap_kring *kr, int idx)
1372231796Sluigi{
1373232238Sluigi	int n = kr->nkr_num_slots;
1374232238Sluigi	idx -= kr->nkr_hwofs;
1375232238Sluigi	if (idx < 0)
1376232238Sluigi		return idx + n;
1377232238Sluigi	else if (idx < n)
1378232238Sluigi		return idx;
1379231796Sluigi	else
1380232238Sluigi		return idx - n;
1381231796Sluigi}
1382231796Sluigi
1383231796Sluigi
1384234227Sluigi/* Entries of the look-up table. */
1385234227Sluigistruct lut_entry {
1386234227Sluigi	void *vaddr;		/* virtual address. */
1387250107Sluigi	vm_paddr_t paddr;	/* physical address. */
1388234227Sluigi};
1389234227Sluigi
1390234227Sluigistruct netmap_obj_pool;
1391234227Sluigi
1392227614Sluigi/*
1393229939Sluigi * NMB return the virtual address of a buffer (buffer 0 on bad index)
1394229939Sluigi * PNMB also fills the physical address
1395227614Sluigi */
1396229939Sluigistatic inline void *
1397270252SluigiNMB(struct netmap_adapter *na, struct netmap_slot *slot)
1398227614Sluigi{
1399270252Sluigi	struct lut_entry *lut = na->na_lut;
1400227614Sluigi	uint32_t i = slot->buf_idx;
1401270252Sluigi	return (unlikely(i >= na->na_lut_objtotal)) ?
1402270252Sluigi		lut[0].vaddr : lut[i].vaddr;
1403227614Sluigi}
1404227614Sluigi
1405229939Sluigistatic inline void *
1406270252SluigiPNMB(struct netmap_adapter *na, struct netmap_slot *slot, uint64_t *pp)
1407229939Sluigi{
1408229939Sluigi	uint32_t i = slot->buf_idx;
1409270252Sluigi	struct lut_entry *lut = na->na_lut;
1410270252Sluigi	void *ret = (i >= na->na_lut_objtotal) ? lut[0].vaddr : lut[i].vaddr;
1411249659Sluigi
1412270252Sluigi	*pp = (i >= na->na_lut_objtotal) ? lut[0].paddr : lut[i].paddr;
1413229939Sluigi	return ret;
1414229939Sluigi}
1415229939Sluigi
1416262151Sluigi/* Generic version of NMB, which uses device-specific memory. */
1417238812Sluigi
1418262151Sluigi
1419262151Sluigi
1420262151Sluigivoid netmap_txsync_to_host(struct netmap_adapter *na);
1421262151Sluigi
1422262151Sluigi
1423262151Sluigi/*
1424262151Sluigi * Structure associated to each thread which registered an interface.
1425262151Sluigi *
1426262151Sluigi * The first 4 fields of this structure are written by NIOCREGIF and
1427262151Sluigi * read by poll() and NIOC?XSYNC.
1428262151Sluigi *
1429262151Sluigi * There is low contention among writers (a correct user program
1430262151Sluigi * should have none) and among writers and readers, so we use a
1431262151Sluigi * single global lock to protect the structure initialization;
1432262151Sluigi * since initialization involves the allocation of memory,
1433262151Sluigi * we reuse the memory allocator lock.
1434262151Sluigi *
1435262151Sluigi * Read access to the structure is lock free. Readers must check that
1436262151Sluigi * np_nifp is not NULL before using the other fields.
1437262151Sluigi * If np_nifp is NULL initialization has not been performed,
1438262151Sluigi * so they should return an error to userspace.
1439262151Sluigi *
1440262151Sluigi * The ref_done field is used to regulate access to the refcount in the
1441262151Sluigi * memory allocator. The refcount must be incremented at most once for
1442262151Sluigi * each open("/dev/netmap"). The increment is performed by the first
1443262151Sluigi * function that calls netmap_get_memory() (currently called by
1444262151Sluigi * mmap(), NIOCGINFO and NIOCREGIF).
1445262151Sluigi * If the refcount is incremented, it is then decremented when the
1446262151Sluigi * private structure is destroyed.
1447262151Sluigi */
1448262151Sluigistruct netmap_priv_d {
1449262151Sluigi	struct netmap_if * volatile np_nifp;	/* netmap if descriptor. */
1450262151Sluigi
1451262151Sluigi	struct netmap_adapter	*np_na;
1452262151Sluigi	uint32_t	np_flags;	/* from the ioctl */
1453262151Sluigi	u_int		np_txqfirst, np_txqlast; /* range of tx rings to scan */
1454262151Sluigi	u_int		np_rxqfirst, np_rxqlast; /* range of rx rings to scan */
1455262151Sluigi	uint16_t	np_txpoll;	/* XXX and also np_rxpoll ? */
1456262151Sluigi
1457262151Sluigi	struct netmap_mem_d     *np_mref;	/* use with NMG_LOCK held */
1458262151Sluigi	/* np_refcount is only used on FreeBSD */
1459262151Sluigi	int		np_refcount;	/* use with NMG_LOCK held */
1460262151Sluigi
1461262151Sluigi	/* pointers to the selinfo to be used for selrecord.
1462262151Sluigi	 * Either the local or the global one depending on the
1463262151Sluigi	 * number of rings.
1464262151Sluigi	 */
1465262151Sluigi	NM_SELINFO_T *np_rxsi, *np_txsi;
1466262151Sluigi	struct thread	*np_td;		/* kqueue, just debugging */
1467262151Sluigi};
1468262151Sluigi
1469270252Sluigi#ifdef WITH_MONITOR
1470262151Sluigi
1471270252Sluigistruct netmap_monitor_adapter {
1472270252Sluigi	struct netmap_adapter up;
1473270252Sluigi
1474270252Sluigi	struct netmap_priv_d priv;
1475270252Sluigi	uint32_t flags;
1476270252Sluigi};
1477270252Sluigi
1478270252Sluigi#endif /* WITH_MONITOR */
1479270252Sluigi
1480270252Sluigi
1481262151Sluigi/*
1482262151Sluigi * generic netmap emulation for devices that do not have
1483262151Sluigi * native netmap support.
1484262151Sluigi */
1485262151Sluigiint generic_netmap_attach(struct ifnet *ifp);
1486262151Sluigi
1487262151Sluigiint netmap_catch_rx(struct netmap_adapter *na, int intercept);
1488262151Sluigivoid generic_rx_handler(struct ifnet *ifp, struct mbuf *m);;
1489262151Sluigivoid netmap_catch_tx(struct netmap_generic_adapter *na, int enable);
1490262151Sluigiint generic_xmit_frame(struct ifnet *ifp, struct mbuf *m, void *addr, u_int len, u_int ring_nr);
1491262151Sluigiint generic_find_num_desc(struct ifnet *ifp, u_int *tx, u_int *rx);
1492262151Sluigivoid generic_find_num_queues(struct ifnet *ifp, u_int *txq, u_int *rxq);
1493262151Sluigi
1494270252Sluigi//#define RATE_GENERIC  /* Enables communication statistics for generic. */
1495270252Sluigi#ifdef RATE_GENERIC
1496270252Sluigivoid generic_rate(int txp, int txs, int txi, int rxp, int rxs, int rxi);
1497270252Sluigi#else
1498270252Sluigi#define generic_rate(txp, txs, txi, rxp, rxs, rxi)
1499270252Sluigi#endif
1500270252Sluigi
1501262151Sluigi/*
1502262151Sluigi * netmap_mitigation API. This is used by the generic adapter
1503262151Sluigi * to reduce the number of interrupt requests/selwakeup
1504262151Sluigi * to clients on incoming packets.
1505262151Sluigi */
1506270252Sluigivoid netmap_mitigation_init(struct nm_generic_mit *mit, int idx,
1507270252Sluigi                                struct netmap_adapter *na);
1508262151Sluigivoid netmap_mitigation_start(struct nm_generic_mit *mit);
1509262151Sluigivoid netmap_mitigation_restart(struct nm_generic_mit *mit);
1510262151Sluigiint netmap_mitigation_active(struct nm_generic_mit *mit);
1511262151Sluigivoid netmap_mitigation_cleanup(struct nm_generic_mit *mit);
1512262151Sluigi
1513262151Sluigi
1514262151Sluigi
1515262151Sluigi/* Shared declarations for the VALE switch. */
1516262151Sluigi
1517262151Sluigi/*
1518262151Sluigi * Each transmit queue accumulates a batch of packets into
1519262151Sluigi * a structure before forwarding. Packets to the same
1520262151Sluigi * destination are put in a list using ft_next as a link field.
1521262151Sluigi * ft_frags and ft_next are valid only on the first fragment.
1522262151Sluigi */
1523262151Sluigistruct nm_bdg_fwd {	/* forwarding entry for a bridge */
1524262151Sluigi	void *ft_buf;		/* netmap or indirect buffer */
1525262151Sluigi	uint8_t ft_frags;	/* how many fragments (only on 1st frag) */
1526262151Sluigi	uint8_t _ft_port;	/* dst port (unused) */
1527262151Sluigi	uint16_t ft_flags;	/* flags, e.g. indirect */
1528262151Sluigi	uint16_t ft_len;	/* src fragment len */
1529262151Sluigi	uint16_t ft_next;	/* next packet to same destination */
1530262151Sluigi};
1531262151Sluigi
1532262151Sluigi/* struct 'virtio_net_hdr' from linux. */
1533262151Sluigistruct nm_vnet_hdr {
1534262151Sluigi#define VIRTIO_NET_HDR_F_NEEDS_CSUM     1	/* Use csum_start, csum_offset */
1535262151Sluigi#define VIRTIO_NET_HDR_F_DATA_VALID    2	/* Csum is valid */
1536262151Sluigi    uint8_t flags;
1537262151Sluigi#define VIRTIO_NET_HDR_GSO_NONE         0       /* Not a GSO frame */
1538262151Sluigi#define VIRTIO_NET_HDR_GSO_TCPV4        1       /* GSO frame, IPv4 TCP (TSO) */
1539262151Sluigi#define VIRTIO_NET_HDR_GSO_UDP          3       /* GSO frame, IPv4 UDP (UFO) */
1540262151Sluigi#define VIRTIO_NET_HDR_GSO_TCPV6        4       /* GSO frame, IPv6 TCP */
1541262151Sluigi#define VIRTIO_NET_HDR_GSO_ECN          0x80    /* TCP has ECN set */
1542262151Sluigi    uint8_t gso_type;
1543262151Sluigi    uint16_t hdr_len;
1544262151Sluigi    uint16_t gso_size;
1545262151Sluigi    uint16_t csum_start;
1546262151Sluigi    uint16_t csum_offset;
1547262151Sluigi};
1548262151Sluigi
1549262151Sluigi#define WORST_CASE_GSO_HEADER	(14+40+60)  /* IPv6 + TCP */
1550262151Sluigi
1551262151Sluigi/* Private definitions for IPv4, IPv6, UDP and TCP headers. */
1552262151Sluigi
1553262151Sluigistruct nm_iphdr {
1554262151Sluigi	uint8_t		version_ihl;
1555262151Sluigi	uint8_t		tos;
1556262151Sluigi	uint16_t	tot_len;
1557262151Sluigi	uint16_t	id;
1558262151Sluigi	uint16_t	frag_off;
1559262151Sluigi	uint8_t		ttl;
1560262151Sluigi	uint8_t		protocol;
1561262151Sluigi	uint16_t	check;
1562262151Sluigi	uint32_t	saddr;
1563262151Sluigi	uint32_t	daddr;
1564262151Sluigi	/*The options start here. */
1565262151Sluigi};
1566262151Sluigi
1567262151Sluigistruct nm_tcphdr {
1568262151Sluigi	uint16_t	source;
1569262151Sluigi	uint16_t	dest;
1570262151Sluigi	uint32_t	seq;
1571262151Sluigi	uint32_t	ack_seq;
1572262151Sluigi	uint8_t		doff;  /* Data offset + Reserved */
1573262151Sluigi	uint8_t		flags;
1574262151Sluigi	uint16_t	window;
1575262151Sluigi	uint16_t	check;
1576262151Sluigi	uint16_t	urg_ptr;
1577262151Sluigi};
1578262151Sluigi
1579262151Sluigistruct nm_udphdr {
1580262151Sluigi	uint16_t	source;
1581262151Sluigi	uint16_t	dest;
1582262151Sluigi	uint16_t	len;
1583262151Sluigi	uint16_t	check;
1584262151Sluigi};
1585262151Sluigi
1586262151Sluigistruct nm_ipv6hdr {
1587262151Sluigi	uint8_t		priority_version;
1588262151Sluigi	uint8_t		flow_lbl[3];
1589262151Sluigi
1590262151Sluigi	uint16_t	payload_len;
1591262151Sluigi	uint8_t		nexthdr;
1592262151Sluigi	uint8_t		hop_limit;
1593262151Sluigi
1594262151Sluigi	uint8_t		saddr[16];
1595262151Sluigi	uint8_t		daddr[16];
1596262151Sluigi};
1597262151Sluigi
1598262151Sluigi/* Type used to store a checksum (in host byte order) that hasn't been
1599262151Sluigi * folded yet.
1600262151Sluigi */
1601262151Sluigi#define rawsum_t uint32_t
1602262151Sluigi
1603262151Sluigirawsum_t nm_csum_raw(uint8_t *data, size_t len, rawsum_t cur_sum);
1604262151Sluigiuint16_t nm_csum_ipv4(struct nm_iphdr *iph);
1605262151Sluigivoid nm_csum_tcpudp_ipv4(struct nm_iphdr *iph, void *data,
1606262151Sluigi		      size_t datalen, uint16_t *check);
1607262151Sluigivoid nm_csum_tcpudp_ipv6(struct nm_ipv6hdr *ip6h, void *data,
1608262151Sluigi		      size_t datalen, uint16_t *check);
1609262151Sluigiuint16_t nm_csum_fold(rawsum_t cur_sum);
1610262151Sluigi
1611262151Sluigivoid bdg_mismatch_datapath(struct netmap_vp_adapter *na,
1612262151Sluigi			   struct netmap_vp_adapter *dst_na,
1613262151Sluigi			   struct nm_bdg_fwd *ft_p, struct netmap_ring *ring,
1614262151Sluigi			   u_int *j, u_int lim, u_int *howmany);
1615270252Sluigi
1616270252Sluigi/* persistent virtual port routines */
1617270252Sluigiint nm_vi_persist(const char *, struct ifnet **);
1618270252Sluigivoid nm_vi_detach(struct ifnet *);
1619270252Sluigivoid nm_vi_init_index(void);
1620270252Sluigi
1621227614Sluigi#endif /* _NET_NETMAP_KERN_H_ */
1622