.. | .. |
---|
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) |
---|