1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2008-2017 Cisco Systems, Inc. All rights reserved. 3 * Copyright 2007 Nuova Systems, Inc. All rights reserved. 4 */ 5 6 #include <rte_memzone.h> 7 #include "vnic_dev.h" 8 #include "vnic_rq.h" 9 10 void vnic_rq_free(struct vnic_rq *rq) 11 { 12 struct vnic_dev *vdev; 13 14 vdev = rq->vdev; 15 16 vnic_dev_free_desc_ring(vdev, &rq->ring); 17 18 rq->ctrl = NULL; 19 } 20 21 int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index, 22 unsigned int desc_count, unsigned int desc_size) 23 { 24 int rc; 25 char res_name[RTE_MEMZONE_NAMESIZE]; 26 static int instance; 27 28 rq->index = index; 29 rq->vdev = vdev; 30 rq->admin_chan = false; 31 32 rq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_RQ, index); 33 if (!rq->ctrl) { 34 pr_err("Failed to hook RQ[%u] resource\n", index); 35 return -EINVAL; 36 } 37 38 vnic_rq_disable(rq); 39 40 snprintf(res_name, sizeof(res_name), "%d-rq-%u", instance++, index); 41 rc = vnic_dev_alloc_desc_ring(vdev, &rq->ring, desc_count, desc_size, 42 rq->socket_id, res_name); 43 return rc; 44 } 45 46 int vnic_admin_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, 47 unsigned int desc_count, unsigned int desc_size) 48 { 49 int rc; 50 char res_name[RTE_MEMZONE_NAMESIZE]; 51 static int instance; 52 53 rq->index = 0; 54 rq->vdev = vdev; 55 rq->admin_chan = true; 56 rq->socket_id = SOCKET_ID_ANY; 57 58 rq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_ADMIN_RQ, 0); 59 if (!rq->ctrl) { 60 pr_err("Failed to get admin RQ resource\n"); 61 return -EINVAL; 62 } 63 64 vnic_rq_disable(rq); 65 66 snprintf(res_name, sizeof(res_name), "%d-admin-rq", instance++); 67 rc = vnic_dev_alloc_desc_ring(vdev, &rq->ring, desc_count, desc_size, 68 rq->socket_id, res_name); 69 return rc; 70 } 71 72 void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index, 73 unsigned int fetch_index, unsigned int posted_index, 74 unsigned int error_interrupt_enable, 75 unsigned int error_interrupt_offset) 76 { 77 uint64_t paddr; 78 unsigned int count = rq->ring.desc_count; 79 80 paddr = (uint64_t)rq->ring.base_addr | VNIC_PADDR_TARGET; 81 writeq(paddr, &rq->ctrl->ring_base); 82 iowrite32(count, &rq->ctrl->ring_size); 83 iowrite32(cq_index, &rq->ctrl->cq_index); 84 iowrite32(error_interrupt_enable, &rq->ctrl->error_interrupt_enable); 85 iowrite32(error_interrupt_offset, &rq->ctrl->error_interrupt_offset); 86 iowrite32(0, &rq->ctrl->error_status); 87 iowrite32(fetch_index, &rq->ctrl->fetch_index); 88 iowrite32(posted_index, &rq->ctrl->posted_index); 89 if (rq->data_queue_enable) 90 iowrite32(((1 << 10) | rq->data_queue_idx), 91 &rq->ctrl->data_ring); 92 else 93 iowrite32(0, &rq->ctrl->data_ring); 94 } 95 96 void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index, 97 unsigned int error_interrupt_enable, 98 unsigned int error_interrupt_offset) 99 { 100 uint32_t fetch_index = 0; 101 102 /* Use current fetch_index as the ring starting point */ 103 fetch_index = ioread32(&rq->ctrl->fetch_index); 104 105 if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */ 106 /* Hardware surprise removal: reset fetch_index */ 107 fetch_index = 0; 108 } 109 110 vnic_rq_init_start(rq, cq_index, 111 fetch_index, fetch_index, 112 error_interrupt_enable, 113 error_interrupt_offset); 114 rq->rxst_idx = 0; 115 rq->tot_pkts = 0; 116 rq->pkt_first_seg = NULL; 117 rq->pkt_last_seg = NULL; 118 } 119 120 unsigned int vnic_rq_error_status(struct vnic_rq *rq) 121 { 122 return ioread32(&rq->ctrl->error_status); 123 } 124 125 void vnic_rq_enable(struct vnic_rq *rq) 126 { 127 iowrite32(1, &rq->ctrl->enable); 128 } 129 130 int vnic_rq_disable(struct vnic_rq *rq) 131 { 132 unsigned int wait; 133 134 iowrite32(0, &rq->ctrl->enable); 135 136 /* Wait for HW to ACK disable request */ 137 for (wait = 0; wait < 1000; wait++) { 138 if (!(ioread32(&rq->ctrl->running))) 139 return 0; 140 usleep(10); 141 } 142 143 pr_err("Failed to disable RQ[%d]\n", rq->index); 144 145 return -ETIMEDOUT; 146 } 147 148 void vnic_rq_clean(struct vnic_rq *rq, 149 void (*buf_clean)(struct rte_mbuf **buf)) 150 { 151 struct rte_mbuf **buf; 152 uint32_t fetch_index, i; 153 unsigned int count = rq->ring.desc_count; 154 155 buf = &rq->mbuf_ring[0]; 156 157 for (i = 0; i < count; i++) { 158 (*buf_clean)(buf); 159 buf++; 160 } 161 rq->ring.desc_avail = count - 1; 162 rq->rx_nb_hold = 0; 163 164 /* Use current fetch_index as the ring starting point */ 165 fetch_index = ioread32(&rq->ctrl->fetch_index); 166 167 if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */ 168 /* Hardware surprise removal: reset fetch_index */ 169 fetch_index = 0; 170 } 171 172 iowrite32(fetch_index, &rq->ctrl->posted_index); 173 174 vnic_dev_clear_desc_ring(&rq->ring); 175 } 176