diff options
Diffstat (limited to 'sys/dev/netmap/netmap_kern.h')
| -rw-r--r-- | sys/dev/netmap/netmap_kern.h | 119 |
1 files changed, 116 insertions, 3 deletions
diff --git a/sys/dev/netmap/netmap_kern.h b/sys/dev/netmap/netmap_kern.h index fd9db5842df3..d9ae6a4f2054 100644 --- a/sys/dev/netmap/netmap_kern.h +++ b/sys/dev/netmap/netmap_kern.h @@ -459,8 +459,16 @@ struct netmap_kring { * On a NIC reset, the NIC ring indexes may be reset but the * indexes in the netmap rings remain the same. nkr_hwofs * keeps track of the offset between the two. + * + * Moreover, during reset, we can restore only the subset of + * the NIC ring that corresponds to the kernel-owned part of + * the netmap ring. The rest of the slots must be restored + * by the *sync routines when the user releases more slots. + * The nkr_to_refill field keeps track of the number of slots + * that still need to be restored. */ int32_t nkr_hwofs; + int32_t nkr_to_refill; /* last_reclaim is opaque marker to help reduce the frequency * of operations such as reclaiming tx buffers. A possible use @@ -535,6 +543,36 @@ struct netmap_kring { uint32_t pipe_tail; /* hwtail updated by the other end */ #endif /* WITH_PIPES */ + /* mask for the offset-related part of the ptr field in the slots */ + uint64_t offset_mask; + /* maximum user-specified offset, as stipulated at bind time. + * Larger offset requests will be silently capped to offset_max. + */ + uint64_t offset_max; + /* minimum gap between two consecutive offsets into the same + * buffer, as stipulated at bind time. This is used to choose + * the hwbuf_len, but is not otherwise checked for compliance + * at runtime. + */ + uint64_t offset_gap; + + /* size of hardware buffer. This may be less than the size of + * the netmap buffers because of non-zero offsets, or because + * the netmap buffer size exceeds the capability of the hardware. + */ + uint64_t hwbuf_len; + + /* required aligment (in bytes) for the buffers used by this ring. + * Netmap buffers are aligned to cachelines, which should suffice + * for most NICs. If the user is passing offsets, though, we need + * to check that the resulting buf address complies with any + * alignment restriction. + */ + uint64_t buf_align; + + /* harware specific logic for the selection of the hwbuf_len */ + int (*nm_bufcfg)(struct netmap_kring *kring, uint64_t target); + int (*save_notify)(struct netmap_kring *kring, int flags); #ifdef WITH_MONITOR @@ -719,6 +757,8 @@ struct netmap_adapter { #define NAF_FORCE_NATIVE 128 /* the adapter is always NATIVE */ /* free */ #define NAF_MOREFRAG 512 /* the adapter supports NS_MOREFRAG */ +#define NAF_OFFSETS 1024 /* the adapter supports the slot offsets */ +#define NAF_HOST_ALL 2048 /* the adapter wants as many host rings as hw */ #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 @@ -782,6 +822,22 @@ struct netmap_adapter { * nm_config() returns configuration information from the OS * Called with NMG_LOCK held. * + * nm_bufcfg() + * the purpose of this callback is to fill the kring->hwbuf_len + * (l) and kring->buf_align fields. The l value is most important + * for RX rings, where we want to disallow writes outside of the + * netmap buffer. The l value must be computed taking into account + * the stipulated max_offset (o), possibily increased if there are + * alignment constraints, the maxframe (m), if known, and the + * current NETMAP_BUF_SIZE (b) of the memory region used by the + * adapter. We want the largest supported l such that o + l <= b. + * If m is known to be <= b - o, the callback may also choose the + * largest l <= b, ignoring the offset. The buf_align field is + * most important for TX rings when there are offsets. The user + * will see this value in the ring->buf_align field. Misaligned + * offsets will cause the corresponding packets to be silently + * dropped. + * * nm_krings_create() create and init the tx_rings and * rx_rings arrays of kring structures. In particular, * set the nm_sync callbacks for each ring. @@ -811,6 +867,7 @@ struct netmap_adapter { int (*nm_txsync)(struct netmap_kring *kring, int flags); int (*nm_rxsync)(struct netmap_kring *kring, int flags); int (*nm_notify)(struct netmap_kring *kring, int flags); + int (*nm_bufcfg)(struct netmap_kring *kring, uint64_t target); #define NAF_FORCE_READ 1 #define NAF_FORCE_RECLAIM 2 #define NAF_CAN_FORWARD_DOWN 4 @@ -1096,12 +1153,13 @@ struct netmap_bwrap_adapter { * here its original value, to be restored at detach */ struct netmap_vp_adapter *saved_na_vp; + int (*nm_intr_notify)(struct netmap_kring *kring, int flags); }; int nm_bdg_polling(struct nmreq_header *hdr); +int netmap_bdg_attach(struct nmreq_header *hdr, void *auth_token); +int netmap_bdg_detach(struct nmreq_header *hdr, void *auth_token); #ifdef WITH_VALE -int netmap_vale_attach(struct nmreq_header *hdr, void *auth_token); -int netmap_vale_detach(struct nmreq_header *hdr, void *auth_token); int netmap_vale_list(struct nmreq_header *hdr); int netmap_vi_create(struct nmreq_header *hdr, int); int nm_vi_create(struct nmreq_header *); @@ -1431,6 +1489,12 @@ uint32_t nm_rxsync_prologue(struct netmap_kring *, struct netmap_ring *); } while (0) #endif +#define NM_CHECK_ADDR_LEN_OFF(na_, l_, o_) do { \ + if ((l_) + (o_) < (l_) || \ + (l_) + (o_) > NETMAP_BUF_SIZE(na_)) { \ + (l_) = NETMAP_BUF_SIZE(na_) - (o_); \ + } } while (0) + /*---------------------------------------------------------------*/ /* @@ -1493,6 +1557,7 @@ int netmap_get_na(struct nmreq_header *hdr, struct netmap_adapter **na, void netmap_unget_na(struct netmap_adapter *na, struct ifnet *ifp); int netmap_get_hw_na(struct ifnet *ifp, struct netmap_mem_d *nmd, struct netmap_adapter **na); +void netmap_mem_restore(struct netmap_adapter *na); #ifdef WITH_VALE uint32_t netmap_vale_learning(struct nm_bdg_fwd *ft, uint8_t *dst_ring, @@ -1680,7 +1745,7 @@ extern int netmap_generic_txqdisc; /* Assigns the device IOMMU domain to an allocator. * Returns -ENOMEM in case the domain is different */ -#define nm_iommu_group_id(dev) (0) +#define nm_iommu_group_id(dev) (-1) /* Callback invoked by the dma machinery after a successful dmamap_load */ static void netmap_dmamap_cb(__unused void *arg, @@ -1890,6 +1955,9 @@ struct plut_entry { struct netmap_obj_pool; +/* alignment for netmap buffers */ +#define NM_BUF_ALIGN 64 + /* * NMB return the virtual address of a buffer (buffer 0 on bad index) * PNMB also fills the physical address @@ -1919,6 +1987,40 @@ PNMB(struct netmap_adapter *na, struct netmap_slot *slot, uint64_t *pp) return ret; } +static inline void +nm_write_offset(struct netmap_kring *kring, + struct netmap_slot *slot, uint64_t offset) +{ + slot->ptr = (slot->ptr & ~kring->offset_mask) | + (offset & kring->offset_mask); +} + +static inline uint64_t +nm_get_offset(struct netmap_kring *kring, struct netmap_slot *slot) +{ + uint64_t offset = (slot->ptr & kring->offset_mask); + if (unlikely(offset > kring->offset_max)) + offset = kring->offset_max; + return offset; +} + +static inline void * +NMB_O(struct netmap_kring *kring, struct netmap_slot *slot) +{ + void *addr = NMB(kring->na, slot); + return (char *)addr + nm_get_offset(kring, slot); +} + +static inline void * +PNMB_O(struct netmap_kring *kring, struct netmap_slot *slot, uint64_t *pp) +{ + void *addr = PNMB(kring->na, slot, pp); + uint64_t offset = nm_get_offset(kring, slot); + addr = (char *)addr + offset; + *pp += offset; + return addr; +} + /* * Structure associated to each netmap file descriptor. @@ -2418,4 +2520,15 @@ void netmap_uninit_bridges(void); #define CSB_WRITE(csb, field, v) (suword32(&csb->field, v)) #endif /* ! linux */ +/* some macros that may not be defined */ +#ifndef ETH_HLEN +#define ETH_HLEN 6 +#endif +#ifndef ETH_FCS_LEN +#define ETH_FCS_LEN 4 +#endif +#ifndef VLAN_HLEN +#define VLAN_HLEN 4 +#endif + #endif /* _NET_NETMAP_KERN_H_ */ |
