aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/enic/vnic_wq.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/enic/vnic_wq.c')
-rw-r--r--sys/dev/enic/vnic_wq.c106
1 files changed, 100 insertions, 6 deletions
diff --git a/sys/dev/enic/vnic_wq.c b/sys/dev/enic/vnic_wq.c
index b032df3392b2..1d3120798798 100644
--- a/sys/dev/enic/vnic_wq.c
+++ b/sys/dev/enic/vnic_wq.c
@@ -7,7 +7,103 @@
#include "vnic_dev.h"
#include "vnic_wq.h"
-void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
+int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev,
+ struct vnic_dev_ring *ring, unsigned int desc_count, unsigned int desc_size)
+{
+ iflib_dma_info_t ifdip;
+ int err;
+
+ if ((ifdip = malloc(sizeof(struct iflib_dma_info),
+ M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
+ device_printf(dev_from_vnic_dev(vdev),
+ "Unable to allocate DMA info memory\n");
+ return (ENOMEM);
+ }
+
+ err = iflib_dma_alloc(vdev->softc->ctx, desc_count * desc_size,
+ ifdip, 0);
+ if (err) {
+ device_printf(dev_from_vnic_dev(vdev),
+ "Unable to allocate DEVCMD2 descriptors\n");
+ err = ENOMEM;
+ goto err_out_alloc;
+ }
+
+ ring->base_addr = ifdip->idi_paddr;
+ ring->descs = ifdip->idi_vaddr;
+ ring->ifdip = ifdip;
+ ring->desc_size = desc_size;
+ ring->desc_count = desc_count;
+ ring->last_count = 0;
+ ring->desc_avail = ring->desc_count - 1;
+
+ ring->base_align = 512;
+ ring->size_unaligned = ring->desc_count * ring->desc_size \
+ + ring->base_align;
+
+ return (err);
+
+ iflib_dma_free(ifdip);
+
+err_out_alloc:
+ free(ifdip, M_DEVBUF);
+ return (err);
+}
+
+void vnic_dev_free_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring)
+{
+ if (ring && ring->descs) {
+ iflib_dma_free(ring->ifdip);
+ free(ring->ifdip, M_DEVBUF);
+ ring->descs = NULL;
+ }
+}
+
+void vnic_wq_free(struct vnic_wq *wq) {
+ vnic_dev_free_desc_ring(wq->vdev, &wq->ring);
+ wq->ctrl = NULL;
+}
+
+int enic_wq_devcmd2_alloc(struct vnic_dev *vdev, struct vnic_wq *wq,
+ unsigned int desc_count, unsigned int desc_size)
+{
+ int err;
+
+ wq->index = 0;
+ wq->vdev = vdev;
+
+
+ wq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_DEVCMD2, 0);
+ if (!wq->ctrl)
+ return (EINVAL);
+ vnic_wq_disable(wq);
+ err = vnic_dev_alloc_desc_ring(vdev, &wq->ring, desc_count, desc_size);
+
+ return (err);
+}
+
+void vnic_dev_deinit_devcmd2(struct vnic_dev *vdev)
+{
+ if (vdev->devcmd2) {
+ vnic_wq_disable(&vdev->devcmd2->wq);
+ if (vdev->devcmd2->wq_ctrl)
+ vnic_wq_free(&vdev->devcmd2->wq);
+ if (vdev->devcmd2->result)
+ vnic_dev_free_desc_ring(vdev, &vdev->devcmd2->results_ring);
+ free(vdev->devcmd2, M_DEVBUF);
+ vdev->devcmd2 = NULL;
+ }
+}
+
+int vnic_dev_deinit(struct vnic_dev *vdev) {
+ u64 a0 = 0, a1 = 0;
+ int wait = 1000;
+
+ return (vnic_dev_cmd(vdev, CMD_DEINIT, &a0, &a1, wait));
+ return (0);
+}
+
+void enic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
unsigned int fetch_index, unsigned int posted_index,
unsigned int error_interrupt_enable,
unsigned int error_interrupt_offset)
@@ -33,7 +129,7 @@ void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
unsigned int error_interrupt_enable,
unsigned int error_interrupt_offset)
{
- vnic_wq_init_start(wq, cq_index, 0, 0,
+ enic_wq_init_start(wq, cq_index, 0, 0,
error_interrupt_enable,
error_interrupt_offset);
wq->cq_pend = 0;
@@ -42,7 +138,7 @@ void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
unsigned int vnic_wq_error_status(struct vnic_wq *wq)
{
- return ENIC_BUS_READ_4(wq->ctrl, TX_ERROR_STATUS);
+ return (ENIC_BUS_READ_4(wq->ctrl, TX_ERROR_STATUS));
}
void vnic_wq_enable(struct vnic_wq *wq)
@@ -65,7 +161,7 @@ int vnic_wq_disable(struct vnic_wq *wq)
pr_err("Failed to disable WQ[%d]\n", wq->index);
- return -ETIMEDOUT;
+ return (ETIMEDOUT);
}
void vnic_wq_clean(struct vnic_wq *wq)
@@ -84,6 +180,4 @@ void vnic_wq_clean(struct vnic_wq *wq)
ENIC_BUS_WRITE_4(wq->ctrl, TX_FETCH_INDEX, 0);
ENIC_BUS_WRITE_4(wq->ctrl, TX_POSTED_INDEX, 0);
ENIC_BUS_WRITE_4(wq->ctrl, TX_ERROR_STATUS, 0);
-
- vnic_dev_clear_desc_ring(&wq->ring);
}