| .. | .. |
|---|
| 24 | 24 | #include "vnic_dev.h" |
|---|
| 25 | 25 | #include "vnic_wq.h" |
|---|
| 26 | 26 | |
|---|
| 27 | + |
|---|
| 28 | +static int vnic_wq_get_ctrl(struct vnic_dev *vdev, struct vnic_wq *wq, |
|---|
| 29 | + unsigned int index, enum vnic_res_type res_type) |
|---|
| 30 | +{ |
|---|
| 31 | + wq->ctrl = vnic_dev_get_res(vdev, res_type, index); |
|---|
| 32 | + |
|---|
| 33 | + if (!wq->ctrl) |
|---|
| 34 | + return -EINVAL; |
|---|
| 35 | + |
|---|
| 36 | + return 0; |
|---|
| 37 | +} |
|---|
| 38 | + |
|---|
| 39 | + |
|---|
| 40 | +static int vnic_wq_alloc_ring(struct vnic_dev *vdev, struct vnic_wq *wq, |
|---|
| 41 | + unsigned int desc_count, unsigned int desc_size) |
|---|
| 42 | +{ |
|---|
| 43 | + return vnic_dev_alloc_desc_ring(vdev, &wq->ring, desc_count, desc_size); |
|---|
| 44 | +} |
|---|
| 45 | + |
|---|
| 46 | + |
|---|
| 27 | 47 | static int vnic_wq_alloc_bufs(struct vnic_wq *wq) |
|---|
| 28 | 48 | { |
|---|
| 29 | 49 | struct vnic_wq_buf *buf; |
|---|
| 30 | | - struct vnic_dev *vdev; |
|---|
| 31 | 50 | unsigned int i, j, count = wq->ring.desc_count; |
|---|
| 32 | 51 | unsigned int blks = VNIC_WQ_BUF_BLKS_NEEDED(count); |
|---|
| 33 | | - |
|---|
| 34 | | - vdev = wq->vdev; |
|---|
| 35 | 52 | |
|---|
| 36 | 53 | for (i = 0; i < blks; i++) { |
|---|
| 37 | 54 | wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ, GFP_ATOMIC); |
|---|
| .. | .. |
|---|
| 111 | 128 | return 0; |
|---|
| 112 | 129 | } |
|---|
| 113 | 130 | |
|---|
| 131 | + |
|---|
| 132 | +int vnic_wq_devcmd2_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, |
|---|
| 133 | + unsigned int desc_count, unsigned int desc_size) |
|---|
| 134 | +{ |
|---|
| 135 | + int err; |
|---|
| 136 | + |
|---|
| 137 | + wq->index = 0; |
|---|
| 138 | + wq->vdev = vdev; |
|---|
| 139 | + |
|---|
| 140 | + err = vnic_wq_get_ctrl(vdev, wq, 0, RES_TYPE_DEVCMD2); |
|---|
| 141 | + if (err) { |
|---|
| 142 | + pr_err("Failed to get devcmd2 resource\n"); |
|---|
| 143 | + return err; |
|---|
| 144 | + } |
|---|
| 145 | + vnic_wq_disable(wq); |
|---|
| 146 | + |
|---|
| 147 | + err = vnic_wq_alloc_ring(vdev, wq, desc_count, desc_size); |
|---|
| 148 | + if (err) |
|---|
| 149 | + return err; |
|---|
| 150 | + return 0; |
|---|
| 151 | +} |
|---|
| 152 | + |
|---|
| 153 | +void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index, |
|---|
| 154 | + unsigned int fetch_index, unsigned int posted_index, |
|---|
| 155 | + unsigned int error_interrupt_enable, |
|---|
| 156 | + unsigned int error_interrupt_offset) |
|---|
| 157 | +{ |
|---|
| 158 | + u64 paddr; |
|---|
| 159 | + unsigned int count = wq->ring.desc_count; |
|---|
| 160 | + |
|---|
| 161 | + paddr = (u64)wq->ring.base_addr | VNIC_PADDR_TARGET; |
|---|
| 162 | + writeq(paddr, &wq->ctrl->ring_base); |
|---|
| 163 | + iowrite32(count, &wq->ctrl->ring_size); |
|---|
| 164 | + iowrite32(fetch_index, &wq->ctrl->fetch_index); |
|---|
| 165 | + iowrite32(posted_index, &wq->ctrl->posted_index); |
|---|
| 166 | + iowrite32(cq_index, &wq->ctrl->cq_index); |
|---|
| 167 | + iowrite32(error_interrupt_enable, &wq->ctrl->error_interrupt_enable); |
|---|
| 168 | + iowrite32(error_interrupt_offset, &wq->ctrl->error_interrupt_offset); |
|---|
| 169 | + iowrite32(0, &wq->ctrl->error_status); |
|---|
| 170 | + |
|---|
| 171 | + wq->to_use = wq->to_clean = |
|---|
| 172 | + &wq->bufs[fetch_index / VNIC_WQ_BUF_BLK_ENTRIES] |
|---|
| 173 | + [fetch_index % VNIC_WQ_BUF_BLK_ENTRIES]; |
|---|
| 174 | +} |
|---|
| 175 | + |
|---|
| 176 | + |
|---|
| 114 | 177 | void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index, |
|---|
| 115 | 178 | unsigned int error_interrupt_enable, |
|---|
| 116 | 179 | unsigned int error_interrupt_offset) |
|---|