xref: /dpdk/drivers/net/enic/base/vnic_wq.c (revision 00ce43111dc5b364722c882cdd37d3664d87b6cc)
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 "vnic_dev.h"
7 #include "vnic_wq.h"
8 
9 static inline
10 int vnic_wq_get_ctrl(struct vnic_dev *vdev, struct vnic_wq *wq,
11 				unsigned int index, enum vnic_res_type res_type)
12 {
13 	wq->ctrl = vnic_dev_get_res(vdev, res_type, index);
14 	if (!wq->ctrl)
15 		return -EINVAL;
16 	return 0;
17 }
18 
19 static inline
20 int vnic_wq_alloc_ring(struct vnic_dev *vdev, struct vnic_wq *wq,
21 				unsigned int desc_count, unsigned int desc_size)
22 {
23 	char res_name[RTE_MEMZONE_NAMESIZE];
24 	static int instance;
25 
26 	snprintf(res_name, sizeof(res_name), "%d-%swq-%u",
27 		 instance++, wq->admin_chan ? "admin-" : "", wq->index);
28 	return vnic_dev_alloc_desc_ring(vdev, &wq->ring, desc_count, desc_size,
29 		wq->socket_id, res_name);
30 }
31 
32 static int vnic_wq_alloc_bufs(struct vnic_wq *wq)
33 {
34 	unsigned int count = wq->ring.desc_count;
35        /* Allocate the mbuf ring */
36 	wq->bufs = (struct rte_mbuf **)rte_zmalloc_socket(wq->admin_chan ? "admin-wq-bufs" : "wq-bufs",
37 		    sizeof(struct rte_mbuf *) * count,
38 		    RTE_CACHE_LINE_SIZE, wq->socket_id);
39 	wq->head_idx = 0;
40 	wq->tail_idx = 0;
41 	if (wq->bufs == NULL)
42 		return -ENOMEM;
43 	return 0;
44 }
45 
46 void vnic_wq_free(struct vnic_wq *wq)
47 {
48 	struct vnic_dev *vdev;
49 
50 	vdev = wq->vdev;
51 
52 	vnic_dev_free_desc_ring(vdev, &wq->ring);
53 
54 	rte_free(wq->bufs);
55 	wq->ctrl = NULL;
56 }
57 
58 
59 int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
60 	unsigned int desc_count, unsigned int desc_size)
61 {
62 	int err;
63 
64 	wq->index = index;
65 	wq->vdev = vdev;
66 	wq->admin_chan = false;
67 
68 	err = vnic_wq_get_ctrl(vdev, wq, index, RES_TYPE_WQ);
69 	if (err) {
70 		pr_err("Failed to hook WQ[%d] resource, err %d\n", index, err);
71 		return err;
72 	}
73 
74 	vnic_wq_disable(wq);
75 
76 	err = vnic_wq_alloc_ring(vdev, wq, desc_count, desc_size);
77 	if (err)
78 		return err;
79 
80 	err = vnic_wq_alloc_bufs(wq);
81 	if (err) {
82 		vnic_wq_free(wq);
83 		return err;
84 	}
85 
86 	return 0;
87 }
88 
89 int vnic_admin_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq,
90 	unsigned int desc_count, unsigned int desc_size)
91 {
92 	int err;
93 
94 	wq->index = 0;
95 	wq->vdev = vdev;
96 	wq->admin_chan = true;
97 	wq->socket_id = SOCKET_ID_ANY;
98 
99 	err = vnic_wq_get_ctrl(vdev, wq, 0, RES_TYPE_ADMIN_WQ);
100 	if (err) {
101 		pr_err("Failed to get admin WQ resource err %d\n", err);
102 		return err;
103 	}
104 
105 	vnic_wq_disable(wq);
106 
107 	err = vnic_wq_alloc_ring(vdev, wq, desc_count, desc_size);
108 	if (err)
109 		return err;
110 
111 	err = vnic_wq_alloc_bufs(wq);
112 	if (err) {
113 		vnic_wq_free(wq);
114 		return err;
115 	}
116 
117 	return 0;
118 }
119 
120 void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
121 	unsigned int fetch_index, unsigned int posted_index,
122 	unsigned int error_interrupt_enable,
123 	unsigned int error_interrupt_offset)
124 {
125 	uint64_t paddr;
126 	unsigned int count = wq->ring.desc_count;
127 
128 	paddr = (uint64_t)wq->ring.base_addr | VNIC_PADDR_TARGET;
129 	writeq(paddr, &wq->ctrl->ring_base);
130 	iowrite32(count, &wq->ctrl->ring_size);
131 	iowrite32(fetch_index, &wq->ctrl->fetch_index);
132 	iowrite32(posted_index, &wq->ctrl->posted_index);
133 	iowrite32(cq_index, &wq->ctrl->cq_index);
134 	iowrite32(error_interrupt_enable, &wq->ctrl->error_interrupt_enable);
135 	iowrite32(error_interrupt_offset, &wq->ctrl->error_interrupt_offset);
136 	iowrite32(0, &wq->ctrl->error_status);
137 
138 	wq->head_idx = fetch_index;
139 	wq->tail_idx = wq->head_idx;
140 }
141 
142 void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
143 	unsigned int error_interrupt_enable,
144 	unsigned int error_interrupt_offset)
145 {
146 	vnic_wq_init_start(wq, cq_index, 0, 0,
147 		error_interrupt_enable,
148 		error_interrupt_offset);
149 	wq->cq_pend = 0;
150 	wq->last_completed_index = 0;
151 }
152 
153 unsigned int vnic_wq_error_status(struct vnic_wq *wq)
154 {
155 	return ioread32(&wq->ctrl->error_status);
156 }
157 
158 void vnic_wq_enable(struct vnic_wq *wq)
159 {
160 	iowrite32(1, &wq->ctrl->enable);
161 }
162 
163 int vnic_wq_disable(struct vnic_wq *wq)
164 {
165 	unsigned int wait;
166 
167 	iowrite32(0, &wq->ctrl->enable);
168 
169 	/* Wait for HW to ACK disable request */
170 	for (wait = 0; wait < 1000; wait++) {
171 		if (!(ioread32(&wq->ctrl->running)))
172 			return 0;
173 		usleep(10);
174 	}
175 
176 	pr_err("Failed to disable WQ[%d]\n", wq->index);
177 
178 	return -ETIMEDOUT;
179 }
180 
181 void vnic_wq_clean(struct vnic_wq *wq,
182 		   void (*buf_clean)(struct rte_mbuf **buf))
183 {
184 	struct rte_mbuf **buf;
185 	unsigned int  to_clean = wq->tail_idx;
186 
187 	buf = &wq->bufs[to_clean];
188 
189 	while (vnic_wq_desc_used(wq) > 0) {
190 
191 		(*buf_clean)(buf);
192 		to_clean = buf_idx_incr(wq->ring.desc_count, to_clean);
193 
194 		buf = &wq->bufs[to_clean];
195 		wq->ring.desc_avail++;
196 	}
197 
198 	wq->head_idx = 0;
199 	wq->tail_idx = 0;
200 	wq->last_completed_index = 0;
201 	*((uint32_t *)wq->cqmsg_rz->addr) = 0;
202 
203 	iowrite32(0, &wq->ctrl->fetch_index);
204 	iowrite32(0, &wq->ctrl->posted_index);
205 	iowrite32(0, &wq->ctrl->error_status);
206 
207 	vnic_dev_clear_desc_ring(&wq->ring);
208 }
209