aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/netmap/netmap_kern.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/netmap/netmap_kern.h')
-rw-r--r--sys/dev/netmap/netmap_kern.h208
1 files changed, 116 insertions, 92 deletions
diff --git a/sys/dev/netmap/netmap_kern.h b/sys/dev/netmap/netmap_kern.h
index 268c980ff174..3e6451091324 100644
--- a/sys/dev/netmap/netmap_kern.h
+++ b/sys/dev/netmap/netmap_kern.h
@@ -39,6 +39,9 @@
#if defined(linux)
+#if defined(CONFIG_NETMAP_EXTMEM)
+#define WITH_EXTMEM
+#endif
#if defined(CONFIG_NETMAP_VALE)
#define WITH_VALE
#endif
@@ -90,6 +93,7 @@
#define NM_MTX_INIT(m) sx_init(&(m), #m)
#define NM_MTX_DESTROY(m) sx_destroy(&(m))
#define NM_MTX_LOCK(m) sx_xlock(&(m))
+#define NM_MTX_SPINLOCK(m) while (!sx_try_xlock(&(m))) ;
#define NM_MTX_UNLOCK(m) sx_xunlock(&(m))
#define NM_MTX_ASSERT(m) sx_assert(&(m), SA_XLOCKED)
@@ -100,7 +104,7 @@
#define MBUF_TRANSMIT(na, ifp, m) ((na)->if_transmit(ifp, m))
#define GEN_TX_MBUF_IFP(m) ((m)->m_pkthdr.rcvif)
-#define NM_ATOMIC_T volatile int // XXX ?
+#define NM_ATOMIC_T volatile int /* required by atomic/bitops.h */
/* atomic operations */
#include <machine/atomic.h>
#define NM_ATOMIC_TEST_AND_SET(p) (!atomic_cmpset_acq_int((p), 0, 1))
@@ -132,13 +136,10 @@ struct nm_selinfo {
};
-// XXX linux struct, not used in FreeBSD
-struct net_device_ops {
-};
-struct ethtool_ops {
-};
struct hrtimer {
+ /* Not used in FreeBSD. */
};
+
#define NM_BNS_GET(b)
#define NM_BNS_PUT(b)
@@ -202,14 +203,6 @@ struct hrtimer {
#define NETMAP_KERNEL_XCHANGE_POINTERS _IO('i', 180)
#define NETMAP_KERNEL_SEND_SHUTDOWN_SIGNAL _IO_direct('i', 195)
-//Empty data structures are not permitted by MSVC compiler
-//XXX_ale, try to solve this problem
-struct net_device_ops{
- char data[1];
-};
-typedef struct ethtool_ops{
- char data[1];
-};
typedef struct hrtimer{
KTIMER timer;
BOOLEAN active;
@@ -297,6 +290,8 @@ void nm_os_ifnet_fini(void);
void nm_os_ifnet_lock(void);
void nm_os_ifnet_unlock(void);
+unsigned nm_os_ifnet_mtu(struct ifnet *ifp);
+
void nm_os_get_module(void);
void nm_os_put_module(void);
@@ -305,8 +300,10 @@ void netmap_undo_zombie(struct ifnet *);
/* os independent alloc/realloc/free */
void *nm_os_malloc(size_t);
+void *nm_os_vmalloc(size_t);
void *nm_os_realloc(void *, size_t new_size, size_t old_size);
void nm_os_free(void *);
+void nm_os_vfree(void *);
/* passes a packet up to the host stack.
* If the packet is sent (or dropped) immediately it returns NULL,
@@ -371,8 +368,7 @@ struct netmap_zmon_list {
* TX rings: hwcur + hwofs coincides with next_to_send
*
* For received packets, slot->flags is set to nkr_slot_flags
- * so we can provide a proper initial value (e.g. set NS_FORWARD
- * when operating in 'transparent' mode).
+ * so we can provide a proper initial value.
*
* The following fields are used to implement lock-free copy of packets
* from input to output ports in VALE switch:
@@ -427,6 +423,7 @@ struct netmap_kring {
* (used internally by pipes and
* by ptnetmap host ports)
*/
+#define NKR_NOINTR 0x10 /* don't use interrupts on this ring */
uint32_t nr_mode;
uint32_t nr_pending_mode;
@@ -442,8 +439,6 @@ struct netmap_kring {
*/
int32_t nkr_hwofs;
- uint16_t nkr_slot_flags; /* initial value for flags */
-
/* last_reclaim is opaque marker to help reduce the frequency
* of operations such as reclaiming tx buffers. A possible use
* is set it to ticks and do the reclaim only once per tick.
@@ -580,7 +575,7 @@ nm_prev(uint32_t i, uint32_t lim)
+-----------------+ +-----------------+
| | | |
- |XXX free slot XXX| |XXX free slot XXX|
+ | free | | free |
+-----------------+ +-----------------+
head->| owned by user |<-hwcur | not sent to nic |<-hwcur
| | | yet |
@@ -621,9 +616,14 @@ tail->| |<-hwtail | |<-hwlease
* a circular array where completions should be reported.
*/
+struct lut_entry;
+#ifdef __FreeBSD__
+#define plut_entry lut_entry
+#endif
struct netmap_lut {
struct lut_entry *lut;
+ struct plut_entry *plut;
uint32_t objtotal; /* max buffer index */
uint32_t objsize; /* buffer size */
};
@@ -671,6 +671,7 @@ struct netmap_adapter {
#define NAF_HOST_RINGS 64 /* the adapter supports the host rings */
#define NAF_FORCE_NATIVE 128 /* the adapter is always NATIVE */
#define NAF_PTNETMAP_HOST 256 /* the adapter supports ptnetmap in the host */
+#define NAF_MOREFRAG 512 /* the adapter supports NS_MOREFRAG */
#define NAF_ZOMBIE (1U<<30) /* the nic driver has been unloaded */
#define NAF_BUSY (1U<<31) /* the adapter is used internally and
* cannot be registered from userspace
@@ -711,9 +712,8 @@ struct netmap_adapter {
/* copy of if_input for netmap_send_up() */
void (*if_input)(struct ifnet *, struct mbuf *);
- /* references to the ifnet and device routines, used by
- * the generic netmap functions.
- */
+ /* Back reference to the parent ifnet struct. Used for
+ * hardware ports (emulated netmap included). */
struct ifnet *ifp; /* adapter is ifp->if_softc */
/*---- callbacks for this netmap adapter -----*/
@@ -806,6 +806,7 @@ struct netmap_adapter {
* buffer addresses, the total number of buffers and the buffer size.
*/
struct netmap_mem_d *nm_mem;
+ struct netmap_mem_d *nm_mem_prev;
struct netmap_lut na_lut;
/* additional information attached to this adapter
@@ -861,6 +862,8 @@ NMR(struct netmap_adapter *na, enum txrx t)
return (t == NR_TX ? na->tx_rings : na->rx_rings);
}
+int nma_intr_enable(struct netmap_adapter *na, int onoff);
+
/*
* If the NIC is owned by the kernel
* (i.e., bridge), neither another bridge nor user can use it;
@@ -898,8 +901,10 @@ struct netmap_vp_adapter { /* VALE software port */
struct netmap_hw_adapter { /* physical device */
struct netmap_adapter up;
- struct net_device_ops nm_ndo; // XXX linux only
- struct ethtool_ops nm_eto; // XXX linux only
+#ifdef linux
+ struct net_device_ops nm_ndo;
+ struct ethtool_ops nm_eto;
+#endif
const struct ethtool_ops* save_ethtool;
int (*nm_hw_register)(struct netmap_adapter *, int onoff);
@@ -920,12 +925,10 @@ struct netmap_generic_adapter { /* emulated device */
/* Pointer to a previously used netmap adapter. */
struct netmap_adapter *prev;
- /* generic netmap adapters support:
- * a net_device_ops struct overrides ndo_select_queue(),
- * save_if_input saves the if_input hook (FreeBSD),
- * mit implements rx interrupt mitigation,
+ /* Emulated netmap adapters support:
+ * - save_if_input saves the if_input hook (FreeBSD);
+ * - mit implements rx interrupt mitigation;
*/
- struct net_device_ops generic_ndo;
void (*save_if_input)(struct ifnet *, struct mbuf *);
struct nm_generic_mit *mit;
@@ -1186,7 +1189,7 @@ static __inline void nm_kr_start(struct netmap_kring *kr)
* virtual ports (vale, pipes, monitor)
*/
int netmap_attach(struct netmap_adapter *);
-int netmap_attach_ext(struct netmap_adapter *, size_t size);
+int netmap_attach_ext(struct netmap_adapter *, size_t size, int override_reg);
void netmap_detach(struct ifnet *);
int netmap_transmit(struct ifnet *, struct mbuf *);
struct netmap_slot *netmap_reset(struct netmap_adapter *na,
@@ -1279,15 +1282,12 @@ nm_set_native_flags(struct netmap_adapter *na)
ifp->if_transmit = netmap_transmit;
#elif defined (_WIN32)
(void)ifp; /* prevent a warning */
- //XXX_ale can we just comment those?
- //na->if_transmit = ifp->if_transmit;
- //ifp->if_transmit = netmap_transmit;
-#else
+#elif defined (linux)
na->if_transmit = (void *)ifp->netdev_ops;
ifp->netdev_ops = &((struct netmap_hw_adapter *)na)->nm_ndo;
((struct netmap_hw_adapter *)na)->save_ethtool = ifp->ethtool_ops;
ifp->ethtool_ops = &((struct netmap_hw_adapter*)na)->nm_eto;
-#endif
+#endif /* linux */
nm_update_hostrings_mode(na);
}
@@ -1308,8 +1308,6 @@ nm_clear_native_flags(struct netmap_adapter *na)
ifp->if_transmit = na->if_transmit;
#elif defined(_WIN32)
(void)ifp; /* prevent a warning */
- //XXX_ale can we just comment those?
- //ifp->if_transmit = na->if_transmit;
#else
ifp->netdev_ops = (void *)na->if_transmit;
ifp->ethtool_ops = ((struct netmap_hw_adapter*)na)->save_ethtool;
@@ -1374,8 +1372,6 @@ uint32_t nm_rxsync_prologue(struct netmap_kring *, struct netmap_ring *);
* - provide defaults for the setup callbacks and the memory allocator
*/
int netmap_attach_common(struct netmap_adapter *);
-/* common actions to be performed on netmap adapter destruction */
-void netmap_detach_common(struct netmap_adapter *);
/* fill priv->np_[tr]xq{first,last} using the ringid and flags information
* coming from a struct nmreq
*/
@@ -1431,8 +1427,8 @@ int netmap_get_hw_na(struct ifnet *ifp,
*
* VALE only supports unicast or broadcast. The lookup
* function can return 0 .. NM_BDG_MAXPORTS-1 for regular ports,
- * NM_BDG_MAXPORTS for broadcast, NM_BDG_MAXPORTS+1 for unknown.
- * XXX in practice "unknown" might be handled same as broadcast.
+ * NM_BDG_MAXPORTS for broadcast, NM_BDG_MAXPORTS+1 to indicate
+ * drop.
*/
typedef u_int (*bdg_lookup_fn_t)(struct nm_bdg_fwd *ft, uint8_t *ring_nr,
struct netmap_vp_adapter *);
@@ -1471,7 +1467,7 @@ int netmap_bdg_config(struct nmreq *nmr);
#ifdef WITH_PIPES
/* max number of pipes per device */
-#define NM_MAXPIPES 64 /* XXX how many? */
+#define NM_MAXPIPES 64 /* XXX this should probably be a sysctl */
void netmap_pipe_dealloc(struct netmap_adapter *);
int netmap_get_pipe_na(struct nmreq *nmr, struct netmap_adapter **na,
struct netmap_mem_d *nmd, int create);
@@ -1573,7 +1569,9 @@ extern int netmap_flags;
extern int netmap_generic_mit;
extern int netmap_generic_ringsize;
extern int netmap_generic_rings;
+#ifdef linux
extern int netmap_generic_txqdisc;
+#endif
extern int ptnetmap_tx_workers;
/*
@@ -1618,13 +1616,14 @@ static void netmap_dmamap_cb(__unused void *arg,
/* bus_dmamap_load wrapper: call aforementioned function if map != NULL.
* XXX can we do it without a callback ?
*/
-static inline void
+static inline int
netmap_load_map(struct netmap_adapter *na,
bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
{
if (map)
bus_dmamap_load(tag, map, buf, NETMAP_BUF_SIZE(na),
netmap_dmamap_cb, NULL, BUS_DMA_NOWAIT);
+ return 0;
}
static inline void
@@ -1635,6 +1634,8 @@ netmap_unload_map(struct netmap_adapter *na,
bus_dmamap_unload(tag, map);
}
+#define netmap_sync_map(na, tag, map, sz, t)
+
/* update the map when a buffer changes. */
static inline void
netmap_reload_map(struct netmap_adapter *na,
@@ -1654,22 +1655,52 @@ netmap_reload_map(struct netmap_adapter *na,
int nm_iommu_group_id(bus_dma_tag_t dev);
#include <linux/dma-mapping.h>
-static inline void
+/*
+ * on linux we need
+ * dma_map_single(&pdev->dev, virt_addr, len, direction)
+ * dma_unmap_single(&adapter->pdev->dev, phys_addr, len, direction)
+ */
+#if 0
+ struct e1000_buffer *buffer_info = &tx_ring->buffer_info[l];
+ /* set time_stamp *before* dma to help avoid a possible race */
+ buffer_info->time_stamp = jiffies;
+ buffer_info->mapped_as_page = false;
+ buffer_info->length = len;
+ //buffer_info->next_to_watch = l;
+ /* reload dma map */
+ dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
+ NETMAP_BUF_SIZE, DMA_TO_DEVICE);
+ buffer_info->dma = dma_map_single(&adapter->pdev->dev,
+ addr, NETMAP_BUF_SIZE, DMA_TO_DEVICE);
+
+ if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) {
+ D("dma mapping error");
+ /* goto dma_error; See e1000_put_txbuf() */
+ /* XXX reset */
+ }
+ tx_desc->buffer_addr = htole64(buffer_info->dma); //XXX
+
+#endif
+
+static inline int
netmap_load_map(struct netmap_adapter *na,
- bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
+ bus_dma_tag_t tag, bus_dmamap_t map, void *buf, u_int size)
{
- if (0 && map) {
- *map = dma_map_single(na->pdev, buf, NETMAP_BUF_SIZE(na),
+ if (map) {
+ *map = dma_map_single(na->pdev, buf, size,
DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(na->pdev, *map)) {
+ *map = 0;
+ return ENOMEM;
+ }
}
+ return 0;
}
static inline void
netmap_unload_map(struct netmap_adapter *na,
- bus_dma_tag_t tag, bus_dmamap_t map)
+ bus_dma_tag_t tag, bus_dmamap_t map, u_int sz)
{
- u_int sz = NETMAP_BUF_SIZE(na);
-
if (*map) {
dma_unmap_single(na->pdev, *map, sz,
DMA_BIDIRECTIONAL);
@@ -1677,6 +1708,20 @@ netmap_unload_map(struct netmap_adapter *na,
}
static inline void
+netmap_sync_map(struct netmap_adapter *na,
+ bus_dma_tag_t tag, bus_dmamap_t map, u_int sz, enum txrx t)
+{
+ if (*map) {
+ if (t == NR_RX)
+ dma_sync_single_for_cpu(na->pdev, *map, sz,
+ DMA_FROM_DEVICE);
+ else
+ dma_sync_single_for_device(na->pdev, *map, sz,
+ DMA_TO_DEVICE);
+ }
+}
+
+static inline void
netmap_reload_map(struct netmap_adapter *na,
bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
{
@@ -1691,44 +1736,6 @@ netmap_reload_map(struct netmap_adapter *na,
DMA_BIDIRECTIONAL);
}
-/*
- * XXX How do we redefine these functions:
- *
- * on linux we need
- * dma_map_single(&pdev->dev, virt_addr, len, direction)
- * dma_unmap_single(&adapter->pdev->dev, phys_addr, len, direction
- * The len can be implicit (on netmap it is NETMAP_BUF_SIZE)
- * unfortunately the direction is not, so we need to change
- * something to have a cross API
- */
-
-#if 0
- struct e1000_buffer *buffer_info = &tx_ring->buffer_info[l];
- /* set time_stamp *before* dma to help avoid a possible race */
- buffer_info->time_stamp = jiffies;
- buffer_info->mapped_as_page = false;
- buffer_info->length = len;
- //buffer_info->next_to_watch = l;
- /* reload dma map */
- dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
- NETMAP_BUF_SIZE, DMA_TO_DEVICE);
- buffer_info->dma = dma_map_single(&adapter->pdev->dev,
- addr, NETMAP_BUF_SIZE, DMA_TO_DEVICE);
-
- if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) {
- D("dma mapping error");
- /* goto dma_error; See e1000_put_txbuf() */
- /* XXX reset */
- }
- tx_desc->buffer_addr = htole64(buffer_info->dma); //XXX
-
-#endif
-
-/*
- * The bus_dmamap_sync() can be one of wmb() or rmb() depending on direction.
- */
-#define bus_dmamap_sync(_a, _b, _c)
-
#endif /* linux */
@@ -1764,10 +1771,26 @@ netmap_idx_k2n(struct netmap_kring *kr, int idx)
/* Entries of the look-up table. */
+#ifdef __FreeBSD__
+struct lut_entry {
+ void *vaddr; /* virtual address. */
+ vm_paddr_t paddr; /* physical address. */
+};
+#else /* linux & _WIN32 */
+/* dma-mapping in linux can assign a buffer a different address
+ * depending on the device, so we need to have a separate
+ * physical-address look-up table for each na.
+ * We can still share the vaddrs, though, therefore we split
+ * the lut_entry structure.
+ */
struct lut_entry {
void *vaddr; /* virtual address. */
+};
+
+struct plut_entry {
vm_paddr_t paddr; /* physical address. */
};
+#endif /* linux & _WIN32 */
struct netmap_obj_pool;
@@ -1789,12 +1812,13 @@ PNMB(struct netmap_adapter *na, struct netmap_slot *slot, uint64_t *pp)
{
uint32_t i = slot->buf_idx;
struct lut_entry *lut = na->na_lut.lut;
+ struct plut_entry *plut = na->na_lut.plut;
void *ret = (i >= na->na_lut.objtotal) ? lut[0].vaddr : lut[i].vaddr;
-#ifndef _WIN32
- *pp = (i >= na->na_lut.objtotal) ? lut[0].paddr : lut[i].paddr;
+#ifdef _WIN32
+ *pp = (i >= na->na_lut.objtotal) ? (uint64_t)plut[0].paddr.QuadPart : (uint64_t)plut[i].paddr.QuadPart;
#else
- *pp = (i >= na->na_lut.objtotal) ? (uint64_t)lut[0].paddr.QuadPart : (uint64_t)lut[i].paddr.QuadPart;
+ *pp = (i >= na->na_lut.objtotal) ? plut[0].paddr : plut[i].paddr;
#endif
return ret;
}
@@ -1823,7 +1847,7 @@ struct netmap_priv_d {
uint32_t np_flags; /* from the ioctl */
u_int np_qfirst[NR_TXRX],
np_qlast[NR_TXRX]; /* range of tx/rx rings to scan */
- uint16_t np_txpoll; /* XXX and also np_rxpoll ? */
+ uint16_t np_txpoll;
int np_sync_flags; /* to be passed to nm_sync */
int np_refs; /* use with NMG_LOCK held */