Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/netmap/if_vtnet_netmap.h
Show All 31 Lines | |||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/pmap.h> /* vtophys ? */ | #include <vm/pmap.h> /* vtophys ? */ | ||||
#include <dev/netmap/netmap_kern.h> | #include <dev/netmap/netmap_kern.h> | ||||
/* Register and unregister. */ | /* Register and unregister. */ | ||||
static int | static int | ||||
vtnet_netmap_reg(struct netmap_adapter *na, int state) | vtnet_netmap_reg(struct netmap_adapter *na, int state) | ||||
{ | { | ||||
struct ifnet *ifp = na->ifp; | if_t ifp = na->ifp; | ||||
struct vtnet_softc *sc = ifp->if_softc; | struct vtnet_softc *sc = if_getsoftc(ifp); | ||||
/* | /* | ||||
* Trigger a device reinit, asking vtnet_init_locked() to | * Trigger a device reinit, asking vtnet_init_locked() to | ||||
* also enter or exit netmap mode. | * also enter or exit netmap mode. | ||||
*/ | */ | ||||
VTNET_CORE_LOCK(sc); | VTNET_CORE_LOCK(sc); | ||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING; | if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING); | ||||
vtnet_init_locked(sc, state ? VTNET_INIT_NETMAP_ENTER | vtnet_init_locked(sc, state ? VTNET_INIT_NETMAP_ENTER | ||||
: VTNET_INIT_NETMAP_EXIT); | : VTNET_INIT_NETMAP_EXIT); | ||||
VTNET_CORE_UNLOCK(sc); | VTNET_CORE_UNLOCK(sc); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* Reconcile kernel and user view of the transmit ring. */ | /* Reconcile kernel and user view of the transmit ring. */ | ||||
static int | static int | ||||
vtnet_netmap_txsync(struct netmap_kring *kring, int flags) | vtnet_netmap_txsync(struct netmap_kring *kring, int flags) | ||||
{ | { | ||||
struct netmap_adapter *na = kring->na; | struct netmap_adapter *na = kring->na; | ||||
struct ifnet *ifp = na->ifp; | if_t ifp = na->ifp; | ||||
struct netmap_ring *ring = kring->ring; | struct netmap_ring *ring = kring->ring; | ||||
u_int ring_nr = kring->ring_id; | u_int ring_nr = kring->ring_id; | ||||
u_int nm_i; /* index into the netmap ring */ | u_int nm_i; /* index into the netmap ring */ | ||||
u_int const lim = kring->nkr_num_slots - 1; | u_int const lim = kring->nkr_num_slots - 1; | ||||
u_int const head = kring->rhead; | u_int const head = kring->rhead; | ||||
/* device-specific */ | /* device-specific */ | ||||
struct vtnet_softc *sc = ifp->if_softc; | struct vtnet_softc *sc = if_getsoftc(ifp); | ||||
struct vtnet_txq *txq = &sc->vtnet_txqs[ring_nr]; | struct vtnet_txq *txq = &sc->vtnet_txqs[ring_nr]; | ||||
struct virtqueue *vq = txq->vtntx_vq; | struct virtqueue *vq = txq->vtntx_vq; | ||||
int interrupts = !(kring->nr_kflags & NKR_NOINTR); | int interrupts = !(kring->nr_kflags & NKR_NOINTR); | ||||
u_int n; | u_int n; | ||||
/* | /* | ||||
* First part: process new packets to send. | * First part: process new packets to send. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
* Return a positive error code on error, and 0 on success. | * Return a positive error code on error, and 0 on success. | ||||
* If we could not publish all of the buffers that's an error, | * If we could not publish all of the buffers that's an error, | ||||
* since the netmap ring and the virtqueue would go out of sync. | * since the netmap ring and the virtqueue would go out of sync. | ||||
*/ | */ | ||||
static int | static int | ||||
vtnet_netmap_kring_refill(struct netmap_kring *kring, u_int num) | vtnet_netmap_kring_refill(struct netmap_kring *kring, u_int num) | ||||
{ | { | ||||
struct netmap_adapter *na = kring->na; | struct netmap_adapter *na = kring->na; | ||||
struct ifnet *ifp = na->ifp; | if_t ifp = na->ifp; | ||||
struct netmap_ring *ring = kring->ring; | struct netmap_ring *ring = kring->ring; | ||||
u_int ring_nr = kring->ring_id; | u_int ring_nr = kring->ring_id; | ||||
u_int const lim = kring->nkr_num_slots - 1; | u_int const lim = kring->nkr_num_slots - 1; | ||||
u_int nm_i; | u_int nm_i; | ||||
/* device-specific */ | /* device-specific */ | ||||
struct vtnet_softc *sc = ifp->if_softc; | struct vtnet_softc *sc = if_getsoftc(ifp); | ||||
struct vtnet_rxq *rxq = &sc->vtnet_rxqs[ring_nr]; | struct vtnet_rxq *rxq = &sc->vtnet_rxqs[ring_nr]; | ||||
struct virtqueue *vq = rxq->vtnrx_vq; | struct virtqueue *vq = rxq->vtnrx_vq; | ||||
/* use a local sglist, default might be short */ | /* use a local sglist, default might be short */ | ||||
struct sglist_seg ss[2]; | struct sglist_seg ss[2]; | ||||
struct sglist sg = { ss, 0, 0, 2 }; | struct sglist sg = { ss, 0, 0, 2 }; | ||||
for (nm_i = rxq->vtnrx_nm_refill; num > 0; | for (nm_i = rxq->vtnrx_nm_refill; num > 0; | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | vtnet_netmap_rxq_populate(struct vtnet_rxq *rxq) | ||||
return error; | return error; | ||||
} | } | ||||
/* Reconcile kernel and user view of the receive ring. */ | /* Reconcile kernel and user view of the receive ring. */ | ||||
static int | static int | ||||
vtnet_netmap_rxsync(struct netmap_kring *kring, int flags) | vtnet_netmap_rxsync(struct netmap_kring *kring, int flags) | ||||
{ | { | ||||
struct netmap_adapter *na = kring->na; | struct netmap_adapter *na = kring->na; | ||||
struct ifnet *ifp = na->ifp; | if_t ifp = na->ifp; | ||||
struct netmap_ring *ring = kring->ring; | struct netmap_ring *ring = kring->ring; | ||||
u_int ring_nr = kring->ring_id; | u_int ring_nr = kring->ring_id; | ||||
u_int nm_i; /* index into the netmap ring */ | u_int nm_i; /* index into the netmap ring */ | ||||
u_int const lim = kring->nkr_num_slots - 1; | u_int const lim = kring->nkr_num_slots - 1; | ||||
u_int const head = kring->rhead; | u_int const head = kring->rhead; | ||||
int force_update = (flags & NAF_FORCE_READ) || | int force_update = (flags & NAF_FORCE_READ) || | ||||
(kring->nr_kflags & NKR_PENDINTR); | (kring->nr_kflags & NKR_PENDINTR); | ||||
int interrupts = !(kring->nr_kflags & NKR_NOINTR); | int interrupts = !(kring->nr_kflags & NKR_NOINTR); | ||||
/* device-specific */ | /* device-specific */ | ||||
struct vtnet_softc *sc = ifp->if_softc; | struct vtnet_softc *sc = if_getsoftc(ifp); | ||||
struct vtnet_rxq *rxq = &sc->vtnet_rxqs[ring_nr]; | struct vtnet_rxq *rxq = &sc->vtnet_rxqs[ring_nr]; | ||||
struct virtqueue *vq = rxq->vtnrx_vq; | struct virtqueue *vq = rxq->vtnrx_vq; | ||||
/* | /* | ||||
* First part: import newly received packets. | * First part: import newly received packets. | ||||
* Only accept our own buffers (matching the token). We should only get | * Only accept our own buffers (matching the token). We should only get | ||||
* matching buffers. The hwtail should never overrun hwcur, because | * matching buffers. The hwtail should never overrun hwcur, because | ||||
* we publish only N-1 receive buffers (and not N). | * we publish only N-1 receive buffers (and not N). | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | vtnet_netmap_rxsync(struct netmap_kring *kring, int flags) | ||||
return 0; | return 0; | ||||
} | } | ||||
/* Enable/disable interrupts on all virtqueues. */ | /* Enable/disable interrupts on all virtqueues. */ | ||||
static void | static void | ||||
vtnet_netmap_intr(struct netmap_adapter *na, int state) | vtnet_netmap_intr(struct netmap_adapter *na, int state) | ||||
{ | { | ||||
struct vtnet_softc *sc = na->ifp->if_softc; | struct vtnet_softc *sc = if_getsoftc(na->ifp); | ||||
int i; | int i; | ||||
for (i = 0; i < sc->vtnet_max_vq_pairs; i++) { | for (i = 0; i < sc->vtnet_max_vq_pairs; i++) { | ||||
struct vtnet_rxq *rxq = &sc->vtnet_rxqs[i]; | struct vtnet_rxq *rxq = &sc->vtnet_rxqs[i]; | ||||
struct vtnet_txq *txq = &sc->vtnet_txqs[i]; | struct vtnet_txq *txq = &sc->vtnet_txqs[i]; | ||||
struct virtqueue *txvq = txq->vtntx_vq; | struct virtqueue *txvq = txq->vtntx_vq; | ||||
if (state) { | if (state) { | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | else | ||||
div = 2; | div = 2; | ||||
return virtqueue_size(sc->vtnet_rxqs[0].vtnrx_vq) / div; | return virtqueue_size(sc->vtnet_rxqs[0].vtnrx_vq) / div; | ||||
} | } | ||||
static int | static int | ||||
vtnet_netmap_config(struct netmap_adapter *na, struct nm_config_info *info) | vtnet_netmap_config(struct netmap_adapter *na, struct nm_config_info *info) | ||||
{ | { | ||||
struct vtnet_softc *sc = na->ifp->if_softc; | struct vtnet_softc *sc = if_getsoftc(na->ifp); | ||||
info->num_tx_rings = sc->vtnet_act_vq_pairs; | info->num_tx_rings = sc->vtnet_act_vq_pairs; | ||||
info->num_rx_rings = sc->vtnet_act_vq_pairs; | info->num_rx_rings = sc->vtnet_act_vq_pairs; | ||||
info->num_tx_descs = vtnet_netmap_tx_slots(sc); | info->num_tx_descs = vtnet_netmap_tx_slots(sc); | ||||
info->num_rx_descs = vtnet_netmap_rx_slots(sc); | info->num_rx_descs = vtnet_netmap_rx_slots(sc); | ||||
info->rx_buf_maxsize = NETMAP_BUF_SIZE(na); | info->rx_buf_maxsize = NETMAP_BUF_SIZE(na); | ||||
return 0; | return 0; | ||||
Show All 28 Lines |