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 31 rq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_RQ, index); 32 if (!rq->ctrl) { 33 pr_err("Failed to hook RQ[%u] resource\n", index); 34 return -EINVAL; 35 } 36 37 vnic_rq_disable(rq); 38 39 snprintf(res_name, sizeof(res_name), "%d-rq-%u", instance++, index); 40 rc = vnic_dev_alloc_desc_ring(vdev, &rq->ring, desc_count, desc_size, 41 rq->socket_id, res_name); 42 return rc; 43 } 44 45 void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index, 46 unsigned int fetch_index, unsigned int posted_index, 47 unsigned int error_interrupt_enable, 48 unsigned int error_interrupt_offset) 49 { 50 uint64_t paddr; 51 unsigned int count = rq->ring.desc_count; 52 53 paddr = (uint64_t)rq->ring.base_addr | VNIC_PADDR_TARGET; 54 writeq(paddr, &rq->ctrl->ring_base); 55 iowrite32(count, &rq->ctrl->ring_size); 56 iowrite32(cq_index, &rq->ctrl->cq_index); 57 iowrite32(error_interrupt_enable, &rq->ctrl->error_interrupt_enable); 58 iowrite32(error_interrupt_offset, &rq->ctrl->error_interrupt_offset); 59 iowrite32(0, &rq->ctrl->error_status); 60 iowrite32(fetch_index, &rq->ctrl->fetch_index); 61 iowrite32(posted_index, &rq->ctrl->posted_index); 62 if (rq->data_queue_enable) 63 iowrite32(((1 << 10) | rq->data_queue_idx), 64 &rq->ctrl->data_ring); 65 else 66 iowrite32(0, &rq->ctrl->data_ring); 67 } 68 69 void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index, 70 unsigned int error_interrupt_enable, 71 unsigned int error_interrupt_offset) 72 { 73 uint32_t fetch_index = 0; 74 75 /* Use current fetch_index as the ring starting point */ 76 fetch_index = ioread32(&rq->ctrl->fetch_index); 77 78 if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */ 79 /* Hardware surprise removal: reset fetch_index */ 80 fetch_index = 0; 81 } 82 83 vnic_rq_init_start(rq, cq_index, 84 fetch_index, fetch_index, 85 error_interrupt_enable, 86 error_interrupt_offset); 87 rq->rxst_idx = 0; 88 rq->tot_pkts = 0; 89 rq->pkt_first_seg = NULL; 90 rq->pkt_last_seg = NULL; 91 } 92 93 unsigned int vnic_rq_error_status(struct vnic_rq *rq) 94 { 95 return ioread32(&rq->ctrl->error_status); 96 } 97 98 void vnic_rq_enable(struct vnic_rq *rq) 99 { 100 iowrite32(1, &rq->ctrl->enable); 101 } 102 103 int vnic_rq_disable(struct vnic_rq *rq) 104 { 105 unsigned int wait; 106 107 iowrite32(0, &rq->ctrl->enable); 108 109 /* Wait for HW to ACK disable request */ 110 for (wait = 0; wait < 1000; wait++) { 111 if (!(ioread32(&rq->ctrl->running))) 112 return 0; 113 usleep(10); 114 } 115 116 pr_err("Failed to disable RQ[%d]\n", rq->index); 117 118 return -ETIMEDOUT; 119 } 120 121 void vnic_rq_clean(struct vnic_rq *rq, 122 void (*buf_clean)(struct rte_mbuf **buf)) 123 { 124 struct rte_mbuf **buf; 125 uint32_t fetch_index, i; 126 unsigned int count = rq->ring.desc_count; 127 128 buf = &rq->mbuf_ring[0]; 129 130 for (i = 0; i < count; i++) { 131 (*buf_clean)(buf); 132 buf++; 133 } 134 rq->ring.desc_avail = count - 1; 135 rq->rx_nb_hold = 0; 136 137 /* Use current fetch_index as the ring starting point */ 138 fetch_index = ioread32(&rq->ctrl->fetch_index); 139 140 if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */ 141 /* Hardware surprise removal: reset fetch_index */ 142 fetch_index = 0; 143 } 144 145 iowrite32(fetch_index, &rq->ctrl->posted_index); 146 147 vnic_dev_clear_desc_ring(&rq->ring); 148 } 149