diff options
Diffstat (limited to 'sys/dev/enic/vnic_wq.c')
-rw-r--r-- | sys/dev/enic/vnic_wq.c | 106 |
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); } |