summaryrefslogtreecommitdiff
path: root/sys/dev/netmap/netmap_freebsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/netmap/netmap_freebsd.c')
-rw-r--r--sys/dev/netmap/netmap_freebsd.c110
1 files changed, 40 insertions, 70 deletions
diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c
index d83f21e255ec..2aecb53b47e4 100644
--- a/sys/dev/netmap/netmap_freebsd.c
+++ b/sys/dev/netmap/netmap_freebsd.c
@@ -626,38 +626,26 @@ DRIVER_MODULE_ORDERED(ptn_memdev, pci, ptn_memdev_driver, ptnetmap_devclass,
NULL, NULL, SI_ORDER_MIDDLE + 1);
/*
- * I/O port read/write wrappers.
- * Some are not used, so we keep them commented out until needed
- */
-#define ptn_ioread16(ptn_dev, reg) bus_read_2((ptn_dev)->pci_io, (reg))
-#define ptn_ioread32(ptn_dev, reg) bus_read_4((ptn_dev)->pci_io, (reg))
-#if 0
-#define ptn_ioread8(ptn_dev, reg) bus_read_1((ptn_dev)->pci_io, (reg))
-#define ptn_iowrite8(ptn_dev, reg, val) bus_write_1((ptn_dev)->pci_io, (reg), (val))
-#define ptn_iowrite16(ptn_dev, reg, val) bus_write_2((ptn_dev)->pci_io, (reg), (val))
-#define ptn_iowrite32(ptn_dev, reg, val) bus_write_4((ptn_dev)->pci_io, (reg), (val))
-#endif /* unused */
-
-/*
* Map host netmap memory through PCI-BAR in the guest OS,
* returning physical (nm_paddr) and virtual (nm_addr) addresses
* of the netmap memory mapped in the guest.
*/
int
nm_os_pt_memdev_iomap(struct ptnetmap_memdev *ptn_dev, vm_paddr_t *nm_paddr,
- void **nm_addr)
+ void **nm_addr, uint64_t *mem_size)
{
- uint32_t mem_size;
int rid;
D("ptn_memdev_driver iomap");
rid = PCIR_BAR(PTNETMAP_MEM_PCI_BAR);
- mem_size = ptn_ioread32(ptn_dev, PTNETMAP_IO_PCI_MEMSIZE);
+ *mem_size = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMSIZE_HI);
+ *mem_size = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMSIZE_LO) |
+ (*mem_size << 32);
/* map memory allocator */
ptn_dev->pci_mem = bus_alloc_resource(ptn_dev->dev, SYS_RES_MEMORY,
- &rid, 0, ~0, mem_size, RF_ACTIVE);
+ &rid, 0, ~0, *mem_size, RF_ACTIVE);
if (ptn_dev->pci_mem == NULL) {
*nm_paddr = 0;
*nm_addr = 0;
@@ -667,14 +655,20 @@ nm_os_pt_memdev_iomap(struct ptnetmap_memdev *ptn_dev, vm_paddr_t *nm_paddr,
*nm_paddr = rman_get_start(ptn_dev->pci_mem);
*nm_addr = rman_get_virtual(ptn_dev->pci_mem);
- D("=== BAR %d start %lx len %lx mem_size %x ===",
+ D("=== BAR %d start %lx len %lx mem_size %lx ===",
PTNETMAP_MEM_PCI_BAR,
(unsigned long)(*nm_paddr),
(unsigned long)rman_get_size(ptn_dev->pci_mem),
- mem_size);
+ (unsigned long)*mem_size);
return (0);
}
+uint32_t
+nm_os_pt_memdev_ioread(struct ptnetmap_memdev *ptn_dev, unsigned int reg)
+{
+ return bus_read_4(ptn_dev->pci_io, reg);
+}
+
/* Unmap host netmap memory. */
void
nm_os_pt_memdev_iounmap(struct ptnetmap_memdev *ptn_dev)
@@ -730,7 +724,7 @@ ptn_memdev_attach(device_t dev)
return (ENXIO);
}
- mem_id = ptn_ioread16(ptn_dev, PTNETMAP_IO_PCI_HOSTID);
+ mem_id = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMID);
/* create guest allocator */
ptn_dev->nm_mem = netmap_mem_pt_guest_attach(ptn_dev, mem_id);
@@ -740,7 +734,7 @@ ptn_memdev_attach(device_t dev)
}
netmap_mem_get(ptn_dev->nm_mem);
- D("ptn_memdev_driver probe OK - host_id: %d", mem_id);
+ D("ptn_memdev_driver probe OK - host_mem_id: %d", mem_id);
return (0);
}
@@ -993,12 +987,7 @@ nm_os_ncpus(void)
struct nm_kthread_ctx {
struct thread *user_td; /* thread user-space (kthread creator) to send ioctl */
- /* notification to guest (interrupt) */
- int irq_fd; /* ioctl fd */
- struct nm_kth_ioctl irq_ioctl; /* ioctl arguments */
-
- /* notification from guest */
- void *ioevent_file; /* tsleep() argument */
+ struct ptnetmap_cfgentry_bhyve cfg;
/* worker function and parameter */
nm_kthread_worker_fn_t worker_fn;
@@ -1034,8 +1023,8 @@ nm_os_kthread_wakeup_worker(struct nm_kthread *nmk)
*/
mtx_lock(&nmk->worker_lock);
nmk->scheduled++;
- if (nmk->worker_ctx.ioevent_file) {
- wakeup(nmk->worker_ctx.ioevent_file);
+ if (nmk->worker_ctx.cfg.wchan) {
+ wakeup((void *)nmk->worker_ctx.cfg.wchan);
}
mtx_unlock(&nmk->worker_lock);
}
@@ -1046,11 +1035,13 @@ nm_os_kthread_send_irq(struct nm_kthread *nmk)
struct nm_kthread_ctx *ctx = &nmk->worker_ctx;
int err;
- if (ctx->user_td && ctx->irq_fd > 0) {
- err = kern_ioctl(ctx->user_td, ctx->irq_fd, ctx->irq_ioctl.com, (caddr_t)&ctx->irq_ioctl.data.msix);
+ if (ctx->user_td && ctx->cfg.ioctl_fd > 0) {
+ err = kern_ioctl(ctx->user_td, ctx->cfg.ioctl_fd, ctx->cfg.ioctl_cmd,
+ (caddr_t)&ctx->cfg.ioctl_data);
if (err) {
- D("kern_ioctl error: %d ioctl parameters: fd %d com %ju data %p",
- err, ctx->irq_fd, (uintmax_t)ctx->irq_ioctl.com, &ctx->irq_ioctl.data);
+ D("kern_ioctl error: %d ioctl parameters: fd %d com %lu data %p",
+ err, ctx->cfg.ioctl_fd, (unsigned long)ctx->cfg.ioctl_cmd,
+ &ctx->cfg.ioctl_data);
}
}
}
@@ -1082,10 +1073,10 @@ nm_kthread_worker(void *data)
}
/*
- * if ioevent_file is not defined, we don't have notification
+ * if wchan is not defined, we don't have notification
* mechanism and we continually execute worker_fn()
*/
- if (!ctx->ioevent_file) {
+ if (!ctx->cfg.wchan) {
ctx->worker_fn(ctx->worker_private); /* worker body */
} else {
/* checks if there is a pending notification */
@@ -1099,7 +1090,7 @@ nm_kthread_worker(void *data)
continue;
} else if (nmk->run) {
/* wait on event with one second timeout */
- msleep_spin(ctx->ioevent_file, &nmk->worker_lock,
+ msleep_spin((void *)ctx->cfg.wchan, &nmk->worker_lock,
"nmk_ev", hz);
nmk->scheduled++;
}
@@ -1110,29 +1101,6 @@ nm_kthread_worker(void *data)
kthread_exit();
}
-static int
-nm_kthread_open_files(struct nm_kthread *nmk, struct nm_kthread_cfg *cfg)
-{
- /* send irq through ioctl to bhyve (vmm.ko) */
- if (cfg->event.irqfd) {
- nmk->worker_ctx.irq_fd = cfg->event.irqfd;
- nmk->worker_ctx.irq_ioctl = cfg->event.ioctl;
- }
- /* ring.ioeventfd contains the chan where do tsleep to wait events */
- if (cfg->event.ioeventfd) {
- nmk->worker_ctx.ioevent_file = (void *)cfg->event.ioeventfd;
- }
-
- return 0;
-}
-
-static void
-nm_kthread_close_files(struct nm_kthread *nmk)
-{
- nmk->worker_ctx.irq_fd = 0;
- nmk->worker_ctx.ioevent_file = NULL;
-}
-
void
nm_os_kthread_set_affinity(struct nm_kthread *nmk, int affinity)
{
@@ -1140,10 +1108,15 @@ nm_os_kthread_set_affinity(struct nm_kthread *nmk, int affinity)
}
struct nm_kthread *
-nm_os_kthread_create(struct nm_kthread_cfg *cfg)
+nm_os_kthread_create(struct nm_kthread_cfg *cfg, unsigned int cfgtype,
+ void *opaque)
{
struct nm_kthread *nmk = NULL;
- int error;
+
+ if (cfgtype != PTNETMAP_CFGTYPE_BHYVE) {
+ D("Unsupported cfgtype %u", cfgtype);
+ return NULL;
+ }
nmk = malloc(sizeof(*nmk), M_DEVBUF, M_NOWAIT | M_ZERO);
if (!nmk)
@@ -1158,15 +1131,12 @@ nm_os_kthread_create(struct nm_kthread_cfg *cfg)
/* attach kthread to user process (ptnetmap) */
nmk->attach_user = cfg->attach_user;
- /* open event fd */
- error = nm_kthread_open_files(nmk, cfg);
- if (error)
- goto err;
+ /* store kick/interrupt configuration */
+ if (opaque) {
+ nmk->worker_ctx.cfg = *((struct ptnetmap_cfgentry_bhyve *)opaque);
+ }
return nmk;
-err:
- free(nmk, M_DEVBUF);
- return NULL;
}
int
@@ -1194,7 +1164,7 @@ nm_os_kthread_start(struct nm_kthread *nmk)
goto err;
}
- D("nm_kthread started td 0x%p", nmk->worker);
+ D("nm_kthread started td %p", nmk->worker);
return 0;
err:
@@ -1228,7 +1198,7 @@ nm_os_kthread_delete(struct nm_kthread *nmk)
nm_os_kthread_stop(nmk);
}
- nm_kthread_close_files(nmk);
+ memset(&nmk->worker_ctx.cfg, 0, sizeof(nmk->worker_ctx.cfg));
free(nmk, M_DEVBUF);
}