Changeset View
Changeset View
Standalone View
Standalone View
head/usr.sbin/bhyve/pci_virtio_net.c
Show First 20 Lines • Show All 375 Lines • ▼ Show 20 Lines | do { | ||||
*/ | */ | ||||
vq_relchain(vq, idx, len + sc->rx_vhdrlen); | vq_relchain(vq, idx, len + sc->rx_vhdrlen); | ||||
} while (vq_has_descs(vq)); | } while (vq_has_descs(vq)); | ||||
/* Interrupt if needed, including for NOTIFY_ON_EMPTY. */ | /* Interrupt if needed, including for NOTIFY_ON_EMPTY. */ | ||||
vq_endchains(vq, 1); | vq_endchains(vq, 1); | ||||
} | } | ||||
static int | static __inline int | ||||
pci_vtnet_netmap_writev(struct nm_desc *nmd, struct iovec *iov, int iovcnt) | pci_vtnet_netmap_writev(struct nm_desc *nmd, struct iovec *iov, int iovcnt) | ||||
{ | { | ||||
int r, i; | int r, i; | ||||
int len = 0; | int len = 0; | ||||
for (r = nmd->cur_tx_ring; ; ) { | for (r = nmd->cur_tx_ring; ; ) { | ||||
struct netmap_ring *ring = NETMAP_TXRING(nmd->nifp, r); | struct netmap_ring *ring = NETMAP_TXRING(nmd->nifp, r); | ||||
uint32_t cur, idx; | uint32_t cur, idx; | ||||
char *buf; | char *buf; | ||||
if (nm_ring_empty(ring)) { | if (nm_ring_empty(ring)) { | ||||
r++; | r++; | ||||
if (r > nmd->last_tx_ring) | if (r > nmd->last_tx_ring) | ||||
r = nmd->first_tx_ring; | r = nmd->first_tx_ring; | ||||
if (r == nmd->cur_rx_ring) | if (r == nmd->cur_tx_ring) | ||||
break; | break; | ||||
continue; | continue; | ||||
} | } | ||||
cur = ring->cur; | cur = ring->cur; | ||||
idx = ring->slot[cur].buf_idx; | idx = ring->slot[cur].buf_idx; | ||||
buf = NETMAP_BUF(ring, idx); | buf = NETMAP_BUF(ring, idx); | ||||
for (i = 0; i < iovcnt; i++) { | for (i = 0; i < iovcnt; i++) { | ||||
if (len + iov[i].iov_len > 2048) | |||||
break; | |||||
memcpy(&buf[len], iov[i].iov_base, iov[i].iov_len); | memcpy(&buf[len], iov[i].iov_base, iov[i].iov_len); | ||||
len += iov[i].iov_len; | len += iov[i].iov_len; | ||||
} | } | ||||
ring->slot[cur].len = len; | ring->slot[cur].len = len; | ||||
ring->head = ring->cur = nm_ring_next(ring, cur); | ring->head = ring->cur = nm_ring_next(ring, cur); | ||||
nmd->cur_tx_ring = r; | nmd->cur_tx_ring = r; | ||||
ioctl(nmd->fd, NIOCTXSYNC, NULL); | ioctl(nmd->fd, NIOCTXSYNC, NULL); | ||||
break; | break; | ||||
} | } | ||||
return (len); | return (len); | ||||
} | } | ||||
static inline int | static __inline int | ||||
pci_vtnet_netmap_readv(struct nm_desc *nmd, struct iovec *iov, int iovcnt) | pci_vtnet_netmap_readv(struct nm_desc *nmd, struct iovec *iov, int iovcnt) | ||||
{ | { | ||||
int len = 0; | int len = 0; | ||||
int i = 0; | int i = 0; | ||||
int r; | int r; | ||||
for (r = nmd->cur_rx_ring; ; ) { | for (r = nmd->cur_rx_ring; ; ) { | ||||
struct netmap_ring *ring = NETMAP_RXRING(nmd->nifp, r); | struct netmap_ring *ring = NETMAP_RXRING(nmd->nifp, r); | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | do { | ||||
len = pci_vtnet_netmap_readv(sc->vsc_nmd, riov, n); | len = pci_vtnet_netmap_readv(sc->vsc_nmd, riov, n); | ||||
if (len == 0) { | if (len == 0) { | ||||
/* | /* | ||||
* No more packets, but still some avail ring | * No more packets, but still some avail ring | ||||
* entries. Interrupt if needed/appropriate. | * entries. Interrupt if needed/appropriate. | ||||
*/ | */ | ||||
vq_retchain(vq); | |||||
vq_endchains(vq, 0); | vq_endchains(vq, 0); | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* The only valid field in the rx packet header is the | * The only valid field in the rx packet header is the | ||||
* number of buffers if merged rx bufs were negotiated. | * number of buffers if merged rx bufs were negotiated. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 320 Lines • ▼ Show 20 Lines | #endif | ||||
/* initialize config space */ | /* initialize config space */ | ||||
pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_NET); | pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_NET); | ||||
pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); | pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); | ||||
pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); | pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); | ||||
pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_NET); | pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_NET); | ||||
pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); | pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); | ||||
/* Link is up if we managed to open tap device. */ | /* Link is up if we managed to open tap device or vale port. */ | ||||
sc->vsc_config.status = (opts == NULL || sc->vsc_tapfd >= 0); | sc->vsc_config.status = (opts == NULL || sc->vsc_tapfd >= 0 || | ||||
sc->vsc_nmd != NULL); | |||||
/* use BAR 1 to map MSI-X table and PBA, if we're using MSI-X */ | /* use BAR 1 to map MSI-X table and PBA, if we're using MSI-X */ | ||||
if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix())) | if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix())) | ||||
return (1); | return (1); | ||||
/* use BAR 0 to map config regs in IO space */ | /* use BAR 0 to map config regs in IO space */ | ||||
vi_set_io_bar(&sc->vsc_vs, 0); | vi_set_io_bar(&sc->vsc_vs, 0); | ||||
▲ Show 20 Lines • Show All 76 Lines • Show Last 20 Lines |