Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Intel Corporation
3 : : */
4 : :
5 : : #include <fcntl.h>
6 : : #include <stdio.h>
7 : : #include <errno.h>
8 : : #include <stdint.h>
9 : : #include <string.h>
10 : : #include <unistd.h>
11 : : #include <stdarg.h>
12 : : #include <inttypes.h>
13 : : #include <rte_byteorder.h>
14 : : #include <rte_common.h>
15 : : #include <rte_os_shim.h>
16 : :
17 : : #include <rte_debug.h>
18 : : #include <rte_alarm.h>
19 : : #include <rte_atomic.h>
20 : : #include <rte_eal.h>
21 : : #include <rte_ether.h>
22 : : #include <ethdev_driver.h>
23 : : #include <ethdev_pci.h>
24 : : #include <dev_driver.h>
25 : :
26 : : #include "iavf.h"
27 : : #include "iavf_rxtx.h"
28 : :
29 : : #define MAX_TRY_TIMES 2000
30 : : #define ASQ_DELAY_MS 1
31 : :
32 : : #define MAX_EVENT_PENDING 16
33 : :
34 : : struct iavf_event_element {
35 : : TAILQ_ENTRY(iavf_event_element) next;
36 : : struct rte_eth_dev *dev;
37 : : enum rte_eth_event_type event;
38 : : void *param;
39 : : size_t param_alloc_size;
40 : : uint8_t param_alloc_data[0];
41 : : };
42 : :
43 : : struct iavf_event_handler {
44 : : uint32_t ndev;
45 : : rte_thread_t tid;
46 : : int fd[2];
47 : : pthread_mutex_t lock;
48 : : TAILQ_HEAD(event_list, iavf_event_element) pending;
49 : : };
50 : :
51 : : static struct iavf_event_handler event_handler = {
52 : : .fd = {-1, -1},
53 : : };
54 : :
55 : : #ifndef TAILQ_FOREACH_SAFE
56 : : #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
57 : : for ((var) = TAILQ_FIRST((head)); \
58 : : (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
59 : : (var) = (tvar))
60 : : #endif
61 : :
62 : : static uint32_t
63 : 0 : iavf_dev_event_handle(void *param __rte_unused)
64 : : {
65 : : struct iavf_event_handler *handler = &event_handler;
66 : : TAILQ_HEAD(event_list, iavf_event_element) pending;
67 : :
68 : 0 : while (true) {
69 : : char unused[MAX_EVENT_PENDING];
70 : 0 : ssize_t nr = read(handler->fd[0], &unused, sizeof(unused));
71 [ # # ]: 0 : if (nr <= 0)
72 : : break;
73 : :
74 : 0 : TAILQ_INIT(&pending);
75 : 0 : pthread_mutex_lock(&handler->lock);
76 [ # # ]: 0 : TAILQ_CONCAT(&pending, &handler->pending, next);
77 : 0 : pthread_mutex_unlock(&handler->lock);
78 : :
79 : : struct iavf_event_element *pos, *save_next;
80 [ # # ]: 0 : TAILQ_FOREACH_SAFE(pos, &pending, next, save_next) {
81 [ # # ]: 0 : TAILQ_REMOVE(&pending, pos, next);
82 : :
83 : 0 : struct iavf_adapter *adapter = pos->dev->data->dev_private;
84 [ # # ]: 0 : if (pos->event == RTE_ETH_EVENT_INTR_RESET &&
85 [ # # ]: 0 : adapter->devargs.auto_reset) {
86 : 0 : iavf_handle_hw_reset(pos->dev);
87 : 0 : rte_free(pos);
88 : 0 : continue;
89 : : }
90 : :
91 : 0 : rte_eth_dev_callback_process(pos->dev, pos->event, pos->param);
92 : 0 : rte_free(pos);
93 : : }
94 : : }
95 : :
96 : 0 : return 0;
97 : : }
98 : :
99 : : void
100 : 0 : iavf_dev_event_post(struct rte_eth_dev *dev,
101 : : enum rte_eth_event_type event,
102 : : void *param, size_t param_alloc_size)
103 : : {
104 : : struct iavf_event_handler *handler = &event_handler;
105 : : char notify_byte;
106 : 0 : struct iavf_event_element *elem = rte_malloc(NULL, sizeof(*elem) + param_alloc_size, 0);
107 [ # # ]: 0 : if (!elem)
108 : 0 : return;
109 : :
110 : 0 : elem->dev = dev;
111 : 0 : elem->event = event;
112 : 0 : elem->param = param;
113 : 0 : elem->param_alloc_size = param_alloc_size;
114 [ # # ]: 0 : if (param && param_alloc_size) {
115 [ # # ]: 0 : rte_memcpy(elem->param_alloc_data, param, param_alloc_size);
116 : 0 : elem->param = elem->param_alloc_data;
117 : : }
118 : :
119 : 0 : pthread_mutex_lock(&handler->lock);
120 : 0 : TAILQ_INSERT_TAIL(&handler->pending, elem, next);
121 : 0 : pthread_mutex_unlock(&handler->lock);
122 : :
123 : 0 : ssize_t nw = write(handler->fd[1], ¬ify_byte, 1);
124 : : RTE_SET_USED(nw);
125 : : }
126 : :
127 : : int
128 : 0 : iavf_dev_event_handler_init(void)
129 : : {
130 : : struct iavf_event_handler *handler = &event_handler;
131 : :
132 [ # # ]: 0 : if (__atomic_fetch_add(&handler->ndev, 1, __ATOMIC_RELAXED) + 1 != 1)
133 : : return 0;
134 : : #if defined(RTE_EXEC_ENV_IS_WINDOWS) && RTE_EXEC_ENV_IS_WINDOWS != 0
135 : : int err = _pipe(handler->fd, MAX_EVENT_PENDING, O_BINARY);
136 : : #else
137 : 0 : int err = pipe(handler->fd);
138 : : #endif
139 [ # # ]: 0 : if (err != 0) {
140 : 0 : __atomic_fetch_sub(&handler->ndev, 1, __ATOMIC_RELAXED);
141 : 0 : return -1;
142 : : }
143 : :
144 : 0 : TAILQ_INIT(&handler->pending);
145 : 0 : pthread_mutex_init(&handler->lock, NULL);
146 : :
147 [ # # ]: 0 : if (rte_thread_create_internal_control(&handler->tid, "iavf-event",
148 : : iavf_dev_event_handle, NULL)) {
149 : 0 : __atomic_fetch_sub(&handler->ndev, 1, __ATOMIC_RELAXED);
150 : 0 : return -1;
151 : : }
152 : :
153 : : return 0;
154 : : }
155 : :
156 : : void
157 : 0 : iavf_dev_event_handler_fini(void)
158 : : {
159 : : struct iavf_event_handler *handler = &event_handler;
160 : :
161 [ # # ]: 0 : if (__atomic_fetch_sub(&handler->ndev, 1, __ATOMIC_RELAXED) - 1 != 0)
162 : : return;
163 : :
164 : 0 : int unused = pthread_cancel((pthread_t)handler->tid.opaque_id);
165 : : RTE_SET_USED(unused);
166 : 0 : close(handler->fd[0]);
167 : 0 : close(handler->fd[1]);
168 : 0 : handler->fd[0] = -1;
169 : 0 : handler->fd[1] = -1;
170 : :
171 : 0 : rte_thread_join(handler->tid, NULL);
172 : 0 : pthread_mutex_destroy(&handler->lock);
173 : :
174 : : struct iavf_event_element *pos, *save_next;
175 [ # # ]: 0 : TAILQ_FOREACH_SAFE(pos, &handler->pending, next, save_next) {
176 [ # # ]: 0 : TAILQ_REMOVE(&handler->pending, pos, next);
177 : 0 : rte_free(pos);
178 : : }
179 : : }
180 : :
181 : : static uint32_t
182 : 0 : iavf_convert_link_speed(enum virtchnl_link_speed virt_link_speed)
183 : : {
184 : : uint32_t speed;
185 : :
186 [ # # # # : 0 : switch (virt_link_speed) {
# # # #
# ]
187 : : case VIRTCHNL_LINK_SPEED_100MB:
188 : : speed = 100;
189 : : break;
190 : 0 : case VIRTCHNL_LINK_SPEED_1GB:
191 : : speed = 1000;
192 : 0 : break;
193 : 0 : case VIRTCHNL_LINK_SPEED_10GB:
194 : : speed = 10000;
195 : 0 : break;
196 : 0 : case VIRTCHNL_LINK_SPEED_40GB:
197 : : speed = 40000;
198 : 0 : break;
199 : 0 : case VIRTCHNL_LINK_SPEED_20GB:
200 : : speed = 20000;
201 : 0 : break;
202 : 0 : case VIRTCHNL_LINK_SPEED_25GB:
203 : : speed = 25000;
204 : 0 : break;
205 : 0 : case VIRTCHNL_LINK_SPEED_2_5GB:
206 : : speed = 2500;
207 : 0 : break;
208 : 0 : case VIRTCHNL_LINK_SPEED_5GB:
209 : : speed = 5000;
210 : 0 : break;
211 : 0 : default:
212 : : speed = 0;
213 : 0 : break;
214 : : }
215 : :
216 : 0 : return speed;
217 : : }
218 : :
219 : : /* Read data in admin queue to get msg from pf driver */
220 : : static enum iavf_aq_result
221 : 0 : iavf_read_msg_from_pf(struct iavf_adapter *adapter, uint16_t buf_len,
222 : : uint8_t *buf)
223 : : {
224 : 0 : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
225 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
226 : : struct iavf_arq_event_info event;
227 : : enum iavf_aq_result result = IAVF_MSG_NON;
228 : : enum virtchnl_ops opcode;
229 : : int ret;
230 : :
231 : 0 : event.buf_len = buf_len;
232 : 0 : event.msg_buf = buf;
233 : 0 : ret = iavf_clean_arq_element(hw, &event, NULL);
234 : : /* Can't read any msg from adminQ */
235 [ # # ]: 0 : if (ret) {
236 : 0 : PMD_DRV_LOG(DEBUG, "Can't read msg from AQ");
237 [ # # ]: 0 : if (ret != IAVF_ERR_ADMIN_QUEUE_NO_WORK)
238 : : result = IAVF_MSG_ERR;
239 : 0 : return result;
240 : : }
241 : :
242 : 0 : opcode = (enum virtchnl_ops)rte_le_to_cpu_32(event.desc.cookie_high);
243 : 0 : vf->cmd_retval = (enum virtchnl_status_code)rte_le_to_cpu_32(
244 : : event.desc.cookie_low);
245 : :
246 : 0 : PMD_DRV_LOG(DEBUG, "AQ from pf carries opcode %u, retval %d",
247 : : opcode, vf->cmd_retval);
248 : :
249 [ # # ]: 0 : if (opcode == VIRTCHNL_OP_EVENT) {
250 : 0 : struct virtchnl_pf_event *vpe =
251 : : (struct virtchnl_pf_event *)event.msg_buf;
252 : :
253 : : result = IAVF_MSG_SYS;
254 [ # # # # ]: 0 : switch (vpe->event) {
255 : 0 : case VIRTCHNL_EVENT_LINK_CHANGE:
256 : 0 : vf->link_up =
257 : 0 : vpe->event_data.link_event.link_status;
258 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags &
259 : : VIRTCHNL_VF_CAP_ADV_LINK_SPEED) {
260 : 0 : vf->link_speed =
261 : 0 : vpe->event_data.link_event_adv.link_speed;
262 : : } else {
263 : : enum virtchnl_link_speed speed;
264 : 0 : speed = vpe->event_data.link_event.link_speed;
265 : 0 : vf->link_speed = iavf_convert_link_speed(speed);
266 : : }
267 : 0 : iavf_dev_link_update(vf->eth_dev, 0);
268 : 0 : iavf_dev_event_post(vf->eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL, 0);
269 [ # # # # ]: 0 : if (vf->link_up && !vf->vf_reset) {
270 : 0 : iavf_dev_watchdog_disable(adapter);
271 : : } else {
272 [ # # ]: 0 : if (!vf->link_up)
273 : 0 : iavf_dev_watchdog_enable(adapter);
274 : : }
275 [ # # ]: 0 : if (adapter->devargs.no_poll_on_link_down) {
276 [ # # # # ]: 0 : if (vf->link_up && adapter->no_poll) {
277 : 0 : adapter->no_poll = false;
278 : 0 : PMD_DRV_LOG(DEBUG, "VF no poll turned off");
279 : : }
280 [ # # ]: 0 : if (!vf->link_up) {
281 : 0 : adapter->no_poll = true;
282 : 0 : PMD_DRV_LOG(DEBUG, "VF no poll turned on");
283 : : }
284 : : }
285 [ # # ]: 0 : PMD_DRV_LOG(INFO, "Link status update:%s",
286 : : vf->link_up ? "up" : "down");
287 : 0 : break;
288 : 0 : case VIRTCHNL_EVENT_RESET_IMPENDING:
289 : 0 : vf->vf_reset = true;
290 : 0 : PMD_DRV_LOG(INFO, "VF is resetting");
291 : 0 : break;
292 : 0 : case VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
293 : 0 : vf->dev_closed = true;
294 : 0 : PMD_DRV_LOG(INFO, "PF driver closed");
295 : 0 : break;
296 : 0 : default:
297 : 0 : PMD_DRV_LOG(ERR, "%s: Unknown event %d from pf",
298 : : __func__, vpe->event);
299 : : }
300 : : } else {
301 : : /* async reply msg on command issued by vf previously */
302 : : result = IAVF_MSG_CMD;
303 [ # # ]: 0 : if (opcode != vf->pend_cmd) {
304 : 0 : PMD_DRV_LOG(WARNING, "command mismatch, expect %u, get %u",
305 : : vf->pend_cmd, opcode);
306 : : result = IAVF_MSG_ERR;
307 : : }
308 : : }
309 : :
310 : : return result;
311 : : }
312 : :
313 : : static int
314 : 0 : iavf_execute_vf_cmd(struct iavf_adapter *adapter, struct iavf_cmd_info *args,
315 : : int async)
316 : : {
317 : 0 : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
318 : 0 : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
319 : : enum iavf_aq_result result;
320 : : enum iavf_status ret;
321 : : int err = 0;
322 : : int i = 0;
323 : :
324 [ # # ]: 0 : if (vf->vf_reset)
325 : : return -EIO;
326 : :
327 : :
328 [ # # ]: 0 : if (async) {
329 [ # # ]: 0 : if (_atomic_set_async_response_cmd(vf, args->ops))
330 : : return -1;
331 : : } else {
332 [ # # ]: 0 : if (_atomic_set_cmd(vf, args->ops))
333 : : return -1;
334 : : }
335 : :
336 : 0 : ret = iavf_aq_send_msg_to_pf(hw, args->ops, IAVF_SUCCESS,
337 : 0 : args->in_args, args->in_args_size, NULL);
338 [ # # ]: 0 : if (ret) {
339 : 0 : PMD_DRV_LOG(ERR, "fail to send cmd %d", args->ops);
340 : : _clear_cmd(vf);
341 : 0 : return err;
342 : : }
343 : :
344 [ # # # ]: 0 : switch (args->ops) {
345 : : case VIRTCHNL_OP_RESET_VF:
346 : : case VIRTCHNL_OP_REQUEST_QUEUES:
347 : : /*no need to wait for response */
348 : : _clear_cmd(vf);
349 : : break;
350 : 0 : case VIRTCHNL_OP_VERSION:
351 : : case VIRTCHNL_OP_GET_VF_RESOURCES:
352 : : case VIRTCHNL_OP_GET_SUPPORTED_RXDIDS:
353 : : case VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS:
354 : : /* for init virtchnl ops, need to poll the response */
355 : : do {
356 : 0 : result = iavf_read_msg_from_pf(adapter, args->out_size,
357 : : args->out_buffer);
358 [ # # ]: 0 : if (result == IAVF_MSG_CMD)
359 : : break;
360 : 0 : iavf_msec_delay(ASQ_DELAY_MS);
361 [ # # ]: 0 : } while (i++ < MAX_TRY_TIMES);
362 [ # # ]: 0 : if (i >= MAX_TRY_TIMES ||
363 [ # # ]: 0 : vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
364 : : err = -1;
365 : 0 : PMD_DRV_LOG(ERR, "No response or return failure (%d)"
366 : : " for cmd %d", vf->cmd_retval, args->ops);
367 : : }
368 : : _clear_cmd(vf);
369 : : break;
370 : 0 : default:
371 [ # # ]: 0 : if (rte_thread_is_intr()) {
372 : : /* For virtchnl ops were executed in eal_intr_thread,
373 : : * need to poll the response.
374 : : */
375 : : do {
376 : 0 : result = iavf_read_msg_from_pf(adapter, args->out_size,
377 : : args->out_buffer);
378 [ # # ]: 0 : if (result == IAVF_MSG_CMD)
379 : : break;
380 : 0 : iavf_msec_delay(ASQ_DELAY_MS);
381 [ # # ]: 0 : } while (i++ < MAX_TRY_TIMES);
382 [ # # ]: 0 : if (i >= MAX_TRY_TIMES ||
383 [ # # ]: 0 : vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
384 : : err = -1;
385 : 0 : PMD_DRV_LOG(ERR, "No response or return failure (%d)"
386 : : " for cmd %d", vf->cmd_retval, args->ops);
387 : : }
388 : : _clear_cmd(vf);
389 : : } else {
390 : : /* For other virtchnl ops in running time,
391 : : * wait for the cmd done flag.
392 : : */
393 : : do {
394 [ # # ]: 0 : if (vf->pend_cmd == VIRTCHNL_OP_UNKNOWN)
395 : : break;
396 : 0 : iavf_msec_delay(ASQ_DELAY_MS);
397 : : /* If don't read msg or read sys event, continue */
398 [ # # ]: 0 : } while (i++ < MAX_TRY_TIMES);
399 : :
400 [ # # ]: 0 : if (i >= MAX_TRY_TIMES) {
401 : 0 : PMD_DRV_LOG(ERR, "No response for cmd %d", args->ops);
402 : : _clear_cmd(vf);
403 : : err = -EIO;
404 [ # # ]: 0 : } else if (vf->cmd_retval ==
405 : : VIRTCHNL_STATUS_ERR_NOT_SUPPORTED) {
406 : 0 : PMD_DRV_LOG(ERR, "Cmd %d not supported", args->ops);
407 : : err = -ENOTSUP;
408 [ # # ]: 0 : } else if (vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
409 : 0 : PMD_DRV_LOG(ERR, "Return failure %d for cmd %d",
410 : : vf->cmd_retval, args->ops);
411 : : err = -EINVAL;
412 : : }
413 : : }
414 : : break;
415 : : }
416 : :
417 : : return err;
418 : : }
419 : :
420 : : static int
421 : 0 : iavf_execute_vf_cmd_safe(struct iavf_adapter *adapter,
422 : : struct iavf_cmd_info *args, int async)
423 : : {
424 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
425 : : int ret;
426 : 0 : int is_intr_thread = rte_thread_is_intr();
427 : :
428 [ # # ]: 0 : if (is_intr_thread) {
429 [ # # ]: 0 : if (!rte_spinlock_trylock(&vf->aq_lock))
430 : : return -EIO;
431 : : } else {
432 : 0 : rte_spinlock_lock(&vf->aq_lock);
433 : : }
434 : 0 : ret = iavf_execute_vf_cmd(adapter, args, async);
435 : 0 : rte_spinlock_unlock(&vf->aq_lock);
436 : :
437 : 0 : return ret;
438 : : }
439 : :
440 : : static void
441 : 0 : iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg,
442 : : uint16_t msglen)
443 : : {
444 : 0 : struct iavf_adapter *adapter =
445 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
446 : : struct iavf_info *vf = &adapter->vf;
447 : : struct virtchnl_pf_event *pf_msg =
448 : : (struct virtchnl_pf_event *)msg;
449 : :
450 [ # # ]: 0 : if (adapter->closed) {
451 : 0 : PMD_DRV_LOG(DEBUG, "Port closed");
452 : 0 : return;
453 : : }
454 : :
455 [ # # ]: 0 : if (msglen < sizeof(struct virtchnl_pf_event)) {
456 : 0 : PMD_DRV_LOG(DEBUG, "Error event");
457 : 0 : return;
458 : : }
459 [ # # # # ]: 0 : switch (pf_msg->event) {
460 : 0 : case VIRTCHNL_EVENT_RESET_IMPENDING:
461 : 0 : PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event");
462 : 0 : vf->link_up = false;
463 [ # # ]: 0 : if (!vf->vf_reset) {
464 : 0 : vf->vf_reset = true;
465 : 0 : iavf_dev_event_post(dev, RTE_ETH_EVENT_INTR_RESET,
466 : : NULL, 0);
467 : : }
468 : : break;
469 : 0 : case VIRTCHNL_EVENT_LINK_CHANGE:
470 : 0 : PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
471 : 0 : vf->link_up = pf_msg->event_data.link_event.link_status;
472 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_CAP_ADV_LINK_SPEED) {
473 : 0 : vf->link_speed =
474 : 0 : pf_msg->event_data.link_event_adv.link_speed;
475 : : } else {
476 : : enum virtchnl_link_speed speed;
477 : 0 : speed = pf_msg->event_data.link_event.link_speed;
478 : 0 : vf->link_speed = iavf_convert_link_speed(speed);
479 : : }
480 : 0 : iavf_dev_link_update(dev, 0);
481 [ # # # # ]: 0 : if (vf->link_up && !vf->vf_reset) {
482 : 0 : iavf_dev_watchdog_disable(adapter);
483 : : } else {
484 [ # # ]: 0 : if (!vf->link_up)
485 : 0 : iavf_dev_watchdog_enable(adapter);
486 : : }
487 [ # # ]: 0 : if (adapter->devargs.no_poll_on_link_down) {
488 [ # # # # ]: 0 : if (vf->link_up && adapter->no_poll) {
489 : 0 : adapter->no_poll = false;
490 : 0 : PMD_DRV_LOG(DEBUG, "VF no poll turned off");
491 : : }
492 [ # # ]: 0 : if (!vf->link_up) {
493 : 0 : adapter->no_poll = true;
494 : 0 : PMD_DRV_LOG(DEBUG, "VF no poll turned on");
495 : : }
496 : : }
497 : 0 : iavf_dev_event_post(dev, RTE_ETH_EVENT_INTR_LSC, NULL, 0);
498 : 0 : break;
499 : 0 : case VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
500 : 0 : PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_PF_DRIVER_CLOSE event");
501 : 0 : break;
502 : 0 : default:
503 : 0 : PMD_DRV_LOG(ERR, " unknown event received %u", pf_msg->event);
504 : 0 : break;
505 : : }
506 : : }
507 : :
508 : : void
509 : 0 : iavf_handle_virtchnl_msg(struct rte_eth_dev *dev)
510 : : {
511 : 0 : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
512 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
513 : : struct iavf_arq_event_info info;
514 : : uint16_t pending, aq_opc;
515 : : enum virtchnl_ops msg_opc;
516 : : enum iavf_status msg_ret;
517 : : int ret;
518 : :
519 : 0 : info.buf_len = IAVF_AQ_BUF_SZ;
520 [ # # ]: 0 : if (!vf->aq_resp) {
521 : 0 : PMD_DRV_LOG(ERR, "Buffer for adminq resp should not be NULL");
522 : 0 : return;
523 : : }
524 : 0 : info.msg_buf = vf->aq_resp;
525 : :
526 : 0 : pending = 1;
527 [ # # ]: 0 : while (pending) {
528 : 0 : ret = iavf_clean_arq_element(hw, &info, &pending);
529 : :
530 [ # # ]: 0 : if (ret != IAVF_SUCCESS) {
531 : 0 : PMD_DRV_LOG(INFO, "Failed to read msg from AdminQ,"
532 : : "ret: %d", ret);
533 : 0 : break;
534 : : }
535 : 0 : aq_opc = rte_le_to_cpu_16(info.desc.opcode);
536 : : /* For the message sent from pf to vf, opcode is stored in
537 : : * cookie_high of struct iavf_aq_desc, while return error code
538 : : * are stored in cookie_low, Which is done by PF driver.
539 : : */
540 : 0 : msg_opc = (enum virtchnl_ops)rte_le_to_cpu_32(
541 : : info.desc.cookie_high);
542 : 0 : msg_ret = (enum iavf_status)rte_le_to_cpu_32(
543 : : info.desc.cookie_low);
544 [ # # ]: 0 : switch (aq_opc) {
545 : 0 : case iavf_aqc_opc_send_msg_to_vf:
546 [ # # ]: 0 : if (msg_opc == VIRTCHNL_OP_EVENT) {
547 : 0 : iavf_handle_pf_event_msg(dev, info.msg_buf,
548 : 0 : info.msg_len);
549 : : } else {
550 : : /* check for unsolicited messages i.e. events */
551 [ # # ]: 0 : if (info.msg_len > 0) {
552 : : switch (msg_opc) {
553 : 0 : case VIRTCHNL_OP_INLINE_IPSEC_CRYPTO: {
554 : 0 : struct inline_ipsec_msg *imsg =
555 : : (struct inline_ipsec_msg *)info.msg_buf;
556 [ # # ]: 0 : if (imsg->ipsec_opcode
557 : 0 : == INLINE_IPSEC_OP_EVENT) {
558 : : struct rte_eth_event_ipsec_desc desc;
559 : : struct virtchnl_ipsec_event *ev =
560 : : imsg->ipsec_data.event;
561 : 0 : desc.subtype =
562 : : RTE_ETH_EVENT_IPSEC_UNKNOWN;
563 : 0 : desc.metadata =
564 : 0 : ev->ipsec_event_data;
565 : 0 : iavf_dev_event_post(dev,
566 : : RTE_ETH_EVENT_IPSEC,
567 : : &desc, sizeof(desc));
568 : : continue;
569 : : }
570 : : }
571 : : break;
572 : : default:
573 : : break;
574 : : }
575 : :
576 : : }
577 : :
578 : : /* read message and it's expected one */
579 [ # # ]: 0 : if (msg_opc == vf->pend_cmd) {
580 : : uint32_t cmd_count =
581 : 0 : __atomic_fetch_sub(&vf->pend_cmd_count,
582 : : 1, __ATOMIC_RELAXED) - 1;
583 [ # # ]: 0 : if (cmd_count == 0)
584 : : _notify_cmd(vf, msg_ret);
585 : : } else {
586 : 0 : PMD_DRV_LOG(ERR,
587 : : "command mismatch, expect %u, get %u",
588 : : vf->pend_cmd, msg_opc);
589 : : }
590 : 0 : PMD_DRV_LOG(DEBUG,
591 : : "adminq response is received, opcode = %d",
592 : : msg_opc);
593 : : }
594 : : break;
595 : 0 : default:
596 : 0 : PMD_DRV_LOG(DEBUG, "Request %u is not supported yet",
597 : : aq_opc);
598 : 0 : break;
599 : : }
600 : : }
601 : : }
602 : :
603 : : int
604 : 0 : iavf_enable_vlan_strip(struct iavf_adapter *adapter)
605 : : {
606 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
607 : : struct iavf_cmd_info args;
608 : : int ret;
609 : :
610 : : memset(&args, 0, sizeof(args));
611 : 0 : args.ops = VIRTCHNL_OP_ENABLE_VLAN_STRIPPING;
612 : : args.in_args = NULL;
613 : : args.in_args_size = 0;
614 : 0 : args.out_buffer = vf->aq_resp;
615 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
616 : 0 : ret = iavf_execute_vf_cmd_safe(adapter, &args, 0);
617 [ # # ]: 0 : if (ret)
618 : 0 : PMD_DRV_LOG(ERR, "Failed to execute command of"
619 : : " OP_ENABLE_VLAN_STRIPPING");
620 : :
621 : 0 : return ret;
622 : : }
623 : :
624 : : int
625 : 0 : iavf_disable_vlan_strip(struct iavf_adapter *adapter)
626 : : {
627 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
628 : : struct iavf_cmd_info args;
629 : : int ret;
630 : :
631 : : memset(&args, 0, sizeof(args));
632 : 0 : args.ops = VIRTCHNL_OP_DISABLE_VLAN_STRIPPING;
633 : : args.in_args = NULL;
634 : : args.in_args_size = 0;
635 : 0 : args.out_buffer = vf->aq_resp;
636 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
637 : 0 : ret = iavf_execute_vf_cmd_safe(adapter, &args, 0);
638 [ # # ]: 0 : if (ret)
639 : 0 : PMD_DRV_LOG(ERR, "Failed to execute command of"
640 : : " OP_DISABLE_VLAN_STRIPPING");
641 : :
642 : 0 : return ret;
643 : : }
644 : :
645 : : #define VIRTCHNL_VERSION_MAJOR_START 1
646 : : #define VIRTCHNL_VERSION_MINOR_START 1
647 : :
648 : : /* Check API version with sync wait until version read from admin queue */
649 : : int
650 : 0 : iavf_check_api_version(struct iavf_adapter *adapter)
651 : : {
652 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
653 : : struct virtchnl_version_info version, *pver;
654 : : struct iavf_cmd_info args;
655 : : int err;
656 : :
657 : 0 : version.major = VIRTCHNL_VERSION_MAJOR;
658 : 0 : version.minor = VIRTCHNL_VERSION_MINOR;
659 : :
660 : 0 : args.ops = VIRTCHNL_OP_VERSION;
661 : 0 : args.in_args = (uint8_t *)&version;
662 : 0 : args.in_args_size = sizeof(version);
663 : 0 : args.out_buffer = vf->aq_resp;
664 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
665 : :
666 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
667 [ # # ]: 0 : if (err) {
668 : 0 : PMD_INIT_LOG(ERR, "Fail to execute command of OP_VERSION");
669 : 0 : return err;
670 : : }
671 : :
672 : 0 : pver = (struct virtchnl_version_info *)args.out_buffer;
673 : 0 : vf->virtchnl_version = *pver;
674 : :
675 [ # # ]: 0 : if (vf->virtchnl_version.major < VIRTCHNL_VERSION_MAJOR_START ||
676 [ # # ]: 0 : (vf->virtchnl_version.major == VIRTCHNL_VERSION_MAJOR_START &&
677 : : vf->virtchnl_version.minor < VIRTCHNL_VERSION_MINOR_START)) {
678 : 0 : PMD_INIT_LOG(ERR, "VIRTCHNL API version should not be lower"
679 : : " than (%u.%u) to support Adaptive VF",
680 : : VIRTCHNL_VERSION_MAJOR_START,
681 : : VIRTCHNL_VERSION_MAJOR_START);
682 : 0 : return -1;
683 [ # # ]: 0 : } else if (vf->virtchnl_version.major > VIRTCHNL_VERSION_MAJOR ||
684 : 0 : (vf->virtchnl_version.major == VIRTCHNL_VERSION_MAJOR &&
685 [ # # ]: 0 : vf->virtchnl_version.minor > VIRTCHNL_VERSION_MINOR)) {
686 : 0 : PMD_INIT_LOG(ERR, "PF/VF API version mismatch:(%u.%u)-(%u.%u)",
687 : : vf->virtchnl_version.major,
688 : : vf->virtchnl_version.minor,
689 : : VIRTCHNL_VERSION_MAJOR,
690 : : VIRTCHNL_VERSION_MINOR);
691 : 0 : return -1;
692 : : }
693 : :
694 : 0 : PMD_DRV_LOG(DEBUG, "Peer is supported PF host");
695 : 0 : return 0;
696 : : }
697 : :
698 : : int
699 : 0 : iavf_get_vf_resource(struct iavf_adapter *adapter)
700 : : {
701 : 0 : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
702 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
703 : : struct iavf_cmd_info args;
704 : : uint32_t caps, len;
705 : : int err, i;
706 : :
707 : 0 : args.ops = VIRTCHNL_OP_GET_VF_RESOURCES;
708 : 0 : args.out_buffer = vf->aq_resp;
709 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
710 : :
711 : 0 : caps = IAVF_BASIC_OFFLOAD_CAPS | VIRTCHNL_VF_CAP_ADV_LINK_SPEED |
712 : : VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC |
713 : : VIRTCHNL_VF_OFFLOAD_FDIR_PF |
714 : : VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF |
715 : : VIRTCHNL_VF_OFFLOAD_FSUB_PF |
716 : : VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
717 : : VIRTCHNL_VF_OFFLOAD_CRC |
718 : : VIRTCHNL_VF_OFFLOAD_VLAN_V2 |
719 : : VIRTCHNL_VF_LARGE_NUM_QPAIRS |
720 : : VIRTCHNL_VF_OFFLOAD_QOS |
721 : : VIRTCHNL_VF_OFFLOAD_INLINE_IPSEC_CRYPTO |
722 : : VIRTCHNL_VF_CAP_PTP;
723 : :
724 : 0 : args.in_args = (uint8_t *)∩︀
725 : 0 : args.in_args_size = sizeof(caps);
726 : :
727 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
728 : :
729 [ # # ]: 0 : if (err) {
730 : 0 : PMD_DRV_LOG(ERR,
731 : : "Failed to execute command of OP_GET_VF_RESOURCE");
732 : 0 : return -1;
733 : : }
734 : :
735 : : len = sizeof(struct virtchnl_vf_resource) +
736 : : IAVF_MAX_VF_VSI * sizeof(struct virtchnl_vsi_resource);
737 : :
738 : 0 : rte_memcpy(vf->vf_res, args.out_buffer,
739 [ # # ]: 0 : RTE_MIN(args.out_size, len));
740 : : /* parse VF config message back from PF*/
741 : 0 : iavf_vf_parse_hw_config(hw, vf->vf_res);
742 [ # # ]: 0 : for (i = 0; i < vf->vf_res->num_vsis; i++) {
743 [ # # ]: 0 : if (vf->vf_res->vsi_res[i].vsi_type == VIRTCHNL_VSI_SRIOV)
744 : 0 : vf->vsi_res = &vf->vf_res->vsi_res[i];
745 : : }
746 : :
747 [ # # ]: 0 : if (!vf->vsi_res) {
748 : 0 : PMD_INIT_LOG(ERR, "no LAN VSI found");
749 : 0 : return -1;
750 : : }
751 : :
752 : 0 : vf->vsi.vsi_id = vf->vsi_res->vsi_id;
753 : 0 : vf->vsi.nb_qps = vf->vsi_res->num_queue_pairs;
754 : 0 : vf->vsi.adapter = adapter;
755 : :
756 : 0 : return 0;
757 : : }
758 : :
759 : : int
760 : 0 : iavf_get_supported_rxdid(struct iavf_adapter *adapter)
761 : : {
762 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
763 : : struct iavf_cmd_info args;
764 : : int ret;
765 : :
766 : 0 : args.ops = VIRTCHNL_OP_GET_SUPPORTED_RXDIDS;
767 : 0 : args.in_args = NULL;
768 : 0 : args.in_args_size = 0;
769 : 0 : args.out_buffer = vf->aq_resp;
770 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
771 : :
772 : 0 : ret = iavf_execute_vf_cmd_safe(adapter, &args, 0);
773 [ # # ]: 0 : if (ret) {
774 : 0 : PMD_DRV_LOG(ERR,
775 : : "Failed to execute command of OP_GET_SUPPORTED_RXDIDS");
776 : 0 : return ret;
777 : : }
778 : :
779 : 0 : vf->supported_rxdid =
780 : 0 : ((struct virtchnl_supported_rxdids *)args.out_buffer)->supported_rxdids;
781 : :
782 : 0 : return 0;
783 : : }
784 : :
785 : : int
786 : 0 : iavf_config_vlan_strip_v2(struct iavf_adapter *adapter, bool enable)
787 : : {
788 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
789 : : struct virtchnl_vlan_supported_caps *stripping_caps;
790 : : struct virtchnl_vlan_setting vlan_strip;
791 : : struct iavf_cmd_info args;
792 : : uint32_t *ethertype;
793 : : int ret;
794 : :
795 : : stripping_caps = &vf->vlan_v2_caps.offloads.stripping_support;
796 : :
797 [ # # # # ]: 0 : if ((stripping_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
798 : : (stripping_caps->outer & VIRTCHNL_VLAN_TOGGLE))
799 : : ethertype = &vlan_strip.outer_ethertype_setting;
800 [ # # # # ]: 0 : else if ((stripping_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
801 : : (stripping_caps->inner & VIRTCHNL_VLAN_TOGGLE))
802 : : ethertype = &vlan_strip.inner_ethertype_setting;
803 : : else
804 : : return -ENOTSUP;
805 : :
806 : : memset(&vlan_strip, 0, sizeof(vlan_strip));
807 : 0 : vlan_strip.vport_id = vf->vsi_res->vsi_id;
808 : 0 : *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
809 : :
810 [ # # ]: 0 : args.ops = enable ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 :
811 : : VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2;
812 : 0 : args.in_args = (uint8_t *)&vlan_strip;
813 : 0 : args.in_args_size = sizeof(vlan_strip);
814 : 0 : args.out_buffer = vf->aq_resp;
815 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
816 : 0 : ret = iavf_execute_vf_cmd_safe(adapter, &args, 0);
817 [ # # ]: 0 : if (ret)
818 [ # # ]: 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
819 : : enable ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" :
820 : : "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2");
821 : :
822 : : return ret;
823 : : }
824 : :
825 : : int
826 : 0 : iavf_config_vlan_insert_v2(struct iavf_adapter *adapter, bool enable)
827 : : {
828 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
829 : : struct virtchnl_vlan_supported_caps *insertion_caps;
830 : : struct virtchnl_vlan_setting vlan_insert;
831 : : struct iavf_cmd_info args;
832 : : uint32_t *ethertype;
833 : : int ret;
834 : :
835 : : insertion_caps = &vf->vlan_v2_caps.offloads.insertion_support;
836 : :
837 [ # # # # ]: 0 : if ((insertion_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
838 : : (insertion_caps->outer & VIRTCHNL_VLAN_TOGGLE))
839 : : ethertype = &vlan_insert.outer_ethertype_setting;
840 [ # # # # ]: 0 : else if ((insertion_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
841 : : (insertion_caps->inner & VIRTCHNL_VLAN_TOGGLE))
842 : : ethertype = &vlan_insert.inner_ethertype_setting;
843 : : else
844 : : return -ENOTSUP;
845 : :
846 : : memset(&vlan_insert, 0, sizeof(vlan_insert));
847 : 0 : vlan_insert.vport_id = vf->vsi_res->vsi_id;
848 : 0 : *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
849 : :
850 [ # # ]: 0 : args.ops = enable ? VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 :
851 : : VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2;
852 : 0 : args.in_args = (uint8_t *)&vlan_insert;
853 : 0 : args.in_args_size = sizeof(vlan_insert);
854 : 0 : args.out_buffer = vf->aq_resp;
855 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
856 : 0 : ret = iavf_execute_vf_cmd_safe(adapter, &args, 0);
857 [ # # ]: 0 : if (ret)
858 [ # # ]: 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
859 : : enable ? "VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2" :
860 : : "VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2");
861 : :
862 : : return ret;
863 : : }
864 : :
865 : : int
866 : 0 : iavf_add_del_vlan_v2(struct iavf_adapter *adapter, uint16_t vlanid, bool add)
867 : : {
868 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
869 : : struct virtchnl_vlan_supported_caps *supported_caps;
870 : : struct virtchnl_vlan_filter_list_v2 vlan_filter;
871 : : struct virtchnl_vlan *vlan_setting;
872 : : struct iavf_cmd_info args;
873 : : uint32_t filtering_caps;
874 : : int err;
875 : :
876 : : supported_caps = &vf->vlan_v2_caps.filtering.filtering_support;
877 [ # # ]: 0 : if (supported_caps->outer) {
878 : : filtering_caps = supported_caps->outer;
879 : : vlan_setting = &vlan_filter.filters[0].outer;
880 : : } else {
881 : 0 : filtering_caps = supported_caps->inner;
882 : : vlan_setting = &vlan_filter.filters[0].inner;
883 : : }
884 : :
885 [ # # ]: 0 : if (!(filtering_caps & VIRTCHNL_VLAN_ETHERTYPE_8100))
886 : : return -ENOTSUP;
887 : :
888 : : memset(&vlan_filter, 0, sizeof(vlan_filter));
889 : 0 : vlan_filter.vport_id = vf->vsi_res->vsi_id;
890 : 0 : vlan_filter.num_elements = 1;
891 : 0 : vlan_setting->tpid = RTE_ETHER_TYPE_VLAN;
892 : 0 : vlan_setting->tci = vlanid;
893 : :
894 [ # # ]: 0 : args.ops = add ? VIRTCHNL_OP_ADD_VLAN_V2 : VIRTCHNL_OP_DEL_VLAN_V2;
895 : 0 : args.in_args = (uint8_t *)&vlan_filter;
896 : 0 : args.in_args_size = sizeof(vlan_filter);
897 : 0 : args.out_buffer = vf->aq_resp;
898 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
899 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
900 [ # # ]: 0 : if (err)
901 [ # # ]: 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
902 : : add ? "OP_ADD_VLAN_V2" : "OP_DEL_VLAN_V2");
903 : :
904 : : return err;
905 : : }
906 : :
907 : : int
908 : 0 : iavf_get_vlan_offload_caps_v2(struct iavf_adapter *adapter)
909 : : {
910 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
911 : : struct iavf_cmd_info args;
912 : : int ret;
913 : :
914 : 0 : args.ops = VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS;
915 : 0 : args.in_args = NULL;
916 : 0 : args.in_args_size = 0;
917 : 0 : args.out_buffer = vf->aq_resp;
918 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
919 : :
920 : 0 : ret = iavf_execute_vf_cmd_safe(adapter, &args, 0);
921 [ # # ]: 0 : if (ret) {
922 : 0 : PMD_DRV_LOG(ERR,
923 : : "Failed to execute command of VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS");
924 : 0 : return ret;
925 : : }
926 : :
927 [ # # ]: 0 : rte_memcpy(&vf->vlan_v2_caps, vf->aq_resp, sizeof(vf->vlan_v2_caps));
928 : :
929 : : return 0;
930 : : }
931 : :
932 : : int
933 : 0 : iavf_enable_queues(struct iavf_adapter *adapter)
934 : : {
935 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
936 : : struct virtchnl_queue_select queue_select;
937 : : struct iavf_cmd_info args;
938 : : int err;
939 : :
940 : : memset(&queue_select, 0, sizeof(queue_select));
941 : 0 : queue_select.vsi_id = vf->vsi_res->vsi_id;
942 : :
943 : 0 : queue_select.rx_queues = BIT(adapter->dev_data->nb_rx_queues) - 1;
944 : 0 : queue_select.tx_queues = BIT(adapter->dev_data->nb_tx_queues) - 1;
945 : :
946 : 0 : args.ops = VIRTCHNL_OP_ENABLE_QUEUES;
947 : 0 : args.in_args = (u8 *)&queue_select;
948 : 0 : args.in_args_size = sizeof(queue_select);
949 : 0 : args.out_buffer = vf->aq_resp;
950 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
951 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
952 [ # # ]: 0 : if (err) {
953 : 0 : PMD_DRV_LOG(ERR,
954 : : "Failed to execute command of OP_ENABLE_QUEUES");
955 : 0 : return err;
956 : : }
957 : : return 0;
958 : : }
959 : :
960 : : int
961 : 0 : iavf_disable_queues(struct iavf_adapter *adapter)
962 : : {
963 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
964 : : struct virtchnl_queue_select queue_select;
965 : : struct iavf_cmd_info args;
966 : : int err;
967 : :
968 : : memset(&queue_select, 0, sizeof(queue_select));
969 : 0 : queue_select.vsi_id = vf->vsi_res->vsi_id;
970 : :
971 : 0 : queue_select.rx_queues = BIT(adapter->dev_data->nb_rx_queues) - 1;
972 : 0 : queue_select.tx_queues = BIT(adapter->dev_data->nb_tx_queues) - 1;
973 : :
974 : 0 : args.ops = VIRTCHNL_OP_DISABLE_QUEUES;
975 : 0 : args.in_args = (u8 *)&queue_select;
976 : 0 : args.in_args_size = sizeof(queue_select);
977 : 0 : args.out_buffer = vf->aq_resp;
978 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
979 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
980 [ # # ]: 0 : if (err) {
981 : 0 : PMD_DRV_LOG(ERR,
982 : : "Failed to execute command of OP_DISABLE_QUEUES");
983 : 0 : return err;
984 : : }
985 : : return 0;
986 : : }
987 : :
988 : : int
989 : 0 : iavf_switch_queue(struct iavf_adapter *adapter, uint16_t qid,
990 : : bool rx, bool on)
991 : : {
992 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
993 : : struct virtchnl_queue_select queue_select;
994 : : struct iavf_cmd_info args;
995 : : int err;
996 : :
997 [ # # ]: 0 : if (adapter->closed)
998 : : return -EIO;
999 : :
1000 : : memset(&queue_select, 0, sizeof(queue_select));
1001 : 0 : queue_select.vsi_id = vf->vsi_res->vsi_id;
1002 [ # # ]: 0 : if (rx)
1003 : 0 : queue_select.rx_queues |= 1 << qid;
1004 : : else
1005 : 0 : queue_select.tx_queues |= 1 << qid;
1006 : :
1007 [ # # ]: 0 : if (on)
1008 : 0 : args.ops = VIRTCHNL_OP_ENABLE_QUEUES;
1009 : : else
1010 : 0 : args.ops = VIRTCHNL_OP_DISABLE_QUEUES;
1011 : 0 : args.in_args = (u8 *)&queue_select;
1012 : 0 : args.in_args_size = sizeof(queue_select);
1013 : 0 : args.out_buffer = vf->aq_resp;
1014 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1015 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1016 [ # # ]: 0 : if (err)
1017 [ # # ]: 0 : PMD_DRV_LOG(ERR, "Failed to execute command of %s",
1018 : : on ? "OP_ENABLE_QUEUES" : "OP_DISABLE_QUEUES");
1019 : : return err;
1020 : : }
1021 : :
1022 : : int
1023 : 0 : iavf_enable_queues_lv(struct iavf_adapter *adapter)
1024 : : {
1025 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1026 : : struct virtchnl_del_ena_dis_queues *queue_select;
1027 : : struct virtchnl_queue_chunk *queue_chunk;
1028 : : struct iavf_cmd_info args;
1029 : : int err, len;
1030 : :
1031 : : len = sizeof(struct virtchnl_del_ena_dis_queues) +
1032 : : sizeof(struct virtchnl_queue_chunk) *
1033 : : (IAVF_RXTX_QUEUE_CHUNKS_NUM - 1);
1034 : 0 : queue_select = rte_zmalloc("queue_select", len, 0);
1035 [ # # ]: 0 : if (!queue_select)
1036 : : return -ENOMEM;
1037 : :
1038 : : queue_chunk = queue_select->chunks.chunks;
1039 : 0 : queue_select->chunks.num_chunks = IAVF_RXTX_QUEUE_CHUNKS_NUM;
1040 : 0 : queue_select->vport_id = vf->vsi_res->vsi_id;
1041 : :
1042 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].type = VIRTCHNL_QUEUE_TYPE_TX;
1043 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].start_queue_id = 0;
1044 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].num_queues =
1045 : 0 : adapter->dev_data->nb_tx_queues;
1046 : :
1047 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].type = VIRTCHNL_QUEUE_TYPE_RX;
1048 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].start_queue_id = 0;
1049 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].num_queues =
1050 : 0 : adapter->dev_data->nb_rx_queues;
1051 : :
1052 : 0 : args.ops = VIRTCHNL_OP_ENABLE_QUEUES_V2;
1053 : 0 : args.in_args = (u8 *)queue_select;
1054 : 0 : args.in_args_size = len;
1055 : 0 : args.out_buffer = vf->aq_resp;
1056 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1057 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1058 [ # # ]: 0 : if (err)
1059 : 0 : PMD_DRV_LOG(ERR,
1060 : : "Failed to execute command of OP_ENABLE_QUEUES_V2");
1061 : :
1062 : 0 : rte_free(queue_select);
1063 : 0 : return err;
1064 : : }
1065 : :
1066 : : int
1067 : 0 : iavf_disable_queues_lv(struct iavf_adapter *adapter)
1068 : : {
1069 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1070 : : struct virtchnl_del_ena_dis_queues *queue_select;
1071 : : struct virtchnl_queue_chunk *queue_chunk;
1072 : : struct iavf_cmd_info args;
1073 : : int err, len;
1074 : :
1075 : : len = sizeof(struct virtchnl_del_ena_dis_queues) +
1076 : : sizeof(struct virtchnl_queue_chunk) *
1077 : : (IAVF_RXTX_QUEUE_CHUNKS_NUM - 1);
1078 : 0 : queue_select = rte_zmalloc("queue_select", len, 0);
1079 [ # # ]: 0 : if (!queue_select)
1080 : : return -ENOMEM;
1081 : :
1082 : : queue_chunk = queue_select->chunks.chunks;
1083 : 0 : queue_select->chunks.num_chunks = IAVF_RXTX_QUEUE_CHUNKS_NUM;
1084 : 0 : queue_select->vport_id = vf->vsi_res->vsi_id;
1085 : :
1086 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].type = VIRTCHNL_QUEUE_TYPE_TX;
1087 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].start_queue_id = 0;
1088 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].num_queues =
1089 : 0 : adapter->dev_data->nb_tx_queues;
1090 : :
1091 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].type = VIRTCHNL_QUEUE_TYPE_RX;
1092 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].start_queue_id = 0;
1093 : 0 : queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].num_queues =
1094 : 0 : adapter->dev_data->nb_rx_queues;
1095 : :
1096 : 0 : args.ops = VIRTCHNL_OP_DISABLE_QUEUES_V2;
1097 : 0 : args.in_args = (u8 *)queue_select;
1098 : 0 : args.in_args_size = len;
1099 : 0 : args.out_buffer = vf->aq_resp;
1100 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1101 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1102 [ # # ]: 0 : if (err)
1103 : 0 : PMD_DRV_LOG(ERR,
1104 : : "Failed to execute command of OP_DISABLE_QUEUES_V2");
1105 : :
1106 : 0 : rte_free(queue_select);
1107 : 0 : return err;
1108 : : }
1109 : :
1110 : : int
1111 : 0 : iavf_switch_queue_lv(struct iavf_adapter *adapter, uint16_t qid,
1112 : : bool rx, bool on)
1113 : : {
1114 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1115 : : struct virtchnl_del_ena_dis_queues *queue_select;
1116 : : struct virtchnl_queue_chunk *queue_chunk;
1117 : : struct iavf_cmd_info args;
1118 : : int err, len;
1119 : :
1120 : : len = sizeof(struct virtchnl_del_ena_dis_queues);
1121 : 0 : queue_select = rte_zmalloc("queue_select", len, 0);
1122 [ # # ]: 0 : if (!queue_select)
1123 : : return -ENOMEM;
1124 : :
1125 : : queue_chunk = queue_select->chunks.chunks;
1126 : 0 : queue_select->chunks.num_chunks = 1;
1127 : 0 : queue_select->vport_id = vf->vsi_res->vsi_id;
1128 : :
1129 [ # # ]: 0 : if (rx) {
1130 : 0 : queue_chunk->type = VIRTCHNL_QUEUE_TYPE_RX;
1131 : 0 : queue_chunk->start_queue_id = qid;
1132 : 0 : queue_chunk->num_queues = 1;
1133 : : } else {
1134 : 0 : queue_chunk->type = VIRTCHNL_QUEUE_TYPE_TX;
1135 : 0 : queue_chunk->start_queue_id = qid;
1136 : 0 : queue_chunk->num_queues = 1;
1137 : : }
1138 : :
1139 [ # # ]: 0 : if (on)
1140 : 0 : args.ops = VIRTCHNL_OP_ENABLE_QUEUES_V2;
1141 : : else
1142 : 0 : args.ops = VIRTCHNL_OP_DISABLE_QUEUES_V2;
1143 : 0 : args.in_args = (u8 *)queue_select;
1144 : 0 : args.in_args_size = len;
1145 : 0 : args.out_buffer = vf->aq_resp;
1146 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1147 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1148 [ # # ]: 0 : if (err)
1149 [ # # ]: 0 : PMD_DRV_LOG(ERR, "Failed to execute command of %s",
1150 : : on ? "OP_ENABLE_QUEUES_V2" : "OP_DISABLE_QUEUES_V2");
1151 : :
1152 : 0 : rte_free(queue_select);
1153 : 0 : return err;
1154 : : }
1155 : :
1156 : : int
1157 : 0 : iavf_configure_rss_lut(struct iavf_adapter *adapter)
1158 : : {
1159 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1160 : : struct virtchnl_rss_lut *rss_lut;
1161 : : struct iavf_cmd_info args;
1162 : : int len, err = 0;
1163 : :
1164 : 0 : len = sizeof(*rss_lut) + vf->vf_res->rss_lut_size - 1;
1165 : 0 : rss_lut = rte_zmalloc("rss_lut", len, 0);
1166 [ # # ]: 0 : if (!rss_lut)
1167 : : return -ENOMEM;
1168 : :
1169 : 0 : rss_lut->vsi_id = vf->vsi_res->vsi_id;
1170 : 0 : rss_lut->lut_entries = vf->vf_res->rss_lut_size;
1171 [ # # ]: 0 : rte_memcpy(rss_lut->lut, vf->rss_lut, vf->vf_res->rss_lut_size);
1172 : :
1173 : 0 : args.ops = VIRTCHNL_OP_CONFIG_RSS_LUT;
1174 : 0 : args.in_args = (u8 *)rss_lut;
1175 : 0 : args.in_args_size = len;
1176 : 0 : args.out_buffer = vf->aq_resp;
1177 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1178 : :
1179 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1180 [ # # ]: 0 : if (err)
1181 : 0 : PMD_DRV_LOG(ERR,
1182 : : "Failed to execute command of OP_CONFIG_RSS_LUT");
1183 : :
1184 : 0 : rte_free(rss_lut);
1185 : 0 : return err;
1186 : : }
1187 : :
1188 : : int
1189 : 0 : iavf_configure_rss_key(struct iavf_adapter *adapter)
1190 : : {
1191 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1192 : : struct virtchnl_rss_key *rss_key;
1193 : : struct iavf_cmd_info args;
1194 : : int len, err = 0;
1195 : :
1196 : 0 : len = sizeof(*rss_key) + vf->vf_res->rss_key_size - 1;
1197 : 0 : rss_key = rte_zmalloc("rss_key", len, 0);
1198 [ # # ]: 0 : if (!rss_key)
1199 : : return -ENOMEM;
1200 : :
1201 : 0 : rss_key->vsi_id = vf->vsi_res->vsi_id;
1202 : 0 : rss_key->key_len = vf->vf_res->rss_key_size;
1203 [ # # ]: 0 : rte_memcpy(rss_key->key, vf->rss_key, vf->vf_res->rss_key_size);
1204 : :
1205 : 0 : args.ops = VIRTCHNL_OP_CONFIG_RSS_KEY;
1206 : 0 : args.in_args = (u8 *)rss_key;
1207 : 0 : args.in_args_size = len;
1208 : 0 : args.out_buffer = vf->aq_resp;
1209 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1210 : :
1211 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1212 [ # # ]: 0 : if (err)
1213 : 0 : PMD_DRV_LOG(ERR,
1214 : : "Failed to execute command of OP_CONFIG_RSS_KEY");
1215 : :
1216 : 0 : rte_free(rss_key);
1217 : 0 : return err;
1218 : : }
1219 : :
1220 : : int
1221 : 0 : iavf_configure_queues(struct iavf_adapter *adapter,
1222 : : uint16_t num_queue_pairs, uint16_t index)
1223 : : {
1224 : 0 : struct iavf_rx_queue **rxq =
1225 : 0 : (struct iavf_rx_queue **)adapter->dev_data->rx_queues;
1226 : 0 : struct iavf_tx_queue **txq =
1227 : : (struct iavf_tx_queue **)adapter->dev_data->tx_queues;
1228 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1229 : : struct virtchnl_vsi_queue_config_info *vc_config;
1230 : : struct virtchnl_queue_pair_info *vc_qp;
1231 : : struct iavf_cmd_info args;
1232 : : uint16_t i, size;
1233 : : int err;
1234 : :
1235 : 0 : size = sizeof(*vc_config) +
1236 : 0 : sizeof(vc_config->qpair[0]) * num_queue_pairs;
1237 : 0 : vc_config = rte_zmalloc("cfg_queue", size, 0);
1238 [ # # ]: 0 : if (!vc_config)
1239 : : return -ENOMEM;
1240 : :
1241 : 0 : vc_config->vsi_id = vf->vsi_res->vsi_id;
1242 : 0 : vc_config->num_queue_pairs = num_queue_pairs;
1243 : :
1244 : 0 : for (i = index, vc_qp = vc_config->qpair;
1245 [ # # ]: 0 : i < index + num_queue_pairs;
1246 : 0 : i++, vc_qp++) {
1247 : 0 : vc_qp->txq.vsi_id = vf->vsi_res->vsi_id;
1248 : 0 : vc_qp->txq.queue_id = i;
1249 : :
1250 : : /* Virtchnnl configure tx queues by pairs */
1251 [ # # ]: 0 : if (i < adapter->dev_data->nb_tx_queues) {
1252 : 0 : vc_qp->txq.ring_len = txq[i]->nb_tx_desc;
1253 : 0 : vc_qp->txq.dma_ring_addr = txq[i]->tx_ring_phys_addr;
1254 : : }
1255 : :
1256 : 0 : vc_qp->rxq.vsi_id = vf->vsi_res->vsi_id;
1257 : 0 : vc_qp->rxq.queue_id = i;
1258 : 0 : vc_qp->rxq.max_pkt_size = vf->max_pkt_len;
1259 : :
1260 [ # # ]: 0 : if (i >= adapter->dev_data->nb_rx_queues)
1261 : 0 : continue;
1262 : :
1263 : : /* Virtchnnl configure rx queues by pairs */
1264 : 0 : vc_qp->rxq.ring_len = rxq[i]->nb_rx_desc;
1265 : 0 : vc_qp->rxq.dma_ring_addr = rxq[i]->rx_ring_phys_addr;
1266 : 0 : vc_qp->rxq.databuffer_size = rxq[i]->rx_buf_len;
1267 : 0 : vc_qp->rxq.crc_disable = rxq[i]->crc_len != 0 ? 1 : 0;
1268 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
1269 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags &
1270 : : VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC) {
1271 [ # # ]: 0 : if (vf->supported_rxdid & BIT(rxq[i]->rxdid)) {
1272 : 0 : vc_qp->rxq.rxdid = rxq[i]->rxdid;
1273 : 0 : PMD_DRV_LOG(NOTICE, "request RXDID[%d] in Queue[%d]",
1274 : : vc_qp->rxq.rxdid, i);
1275 : : } else {
1276 : 0 : PMD_DRV_LOG(NOTICE, "RXDID[%d] is not supported, "
1277 : : "request default RXDID[%d] in Queue[%d]",
1278 : : rxq[i]->rxdid, IAVF_RXDID_LEGACY_1, i);
1279 : 0 : vc_qp->rxq.rxdid = IAVF_RXDID_LEGACY_1;
1280 : : }
1281 : :
1282 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_CAP_PTP &&
1283 [ # # ]: 0 : vf->ptp_caps & VIRTCHNL_1588_PTP_CAP_RX_TSTAMP &&
1284 [ # # ]: 0 : rxq[i]->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP)
1285 : 0 : vc_qp->rxq.flags |= VIRTCHNL_PTP_RX_TSTAMP;
1286 : : }
1287 : : #else
1288 : : if (vf->vf_res->vf_cap_flags &
1289 : : VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC &&
1290 : : vf->supported_rxdid & BIT(IAVF_RXDID_LEGACY_0)) {
1291 : : vc_qp->rxq.rxdid = IAVF_RXDID_LEGACY_0;
1292 : : PMD_DRV_LOG(NOTICE, "request RXDID[%d] in Queue[%d]",
1293 : : vc_qp->rxq.rxdid, i);
1294 : : } else {
1295 : : PMD_DRV_LOG(ERR, "RXDID[%d] is not supported",
1296 : : IAVF_RXDID_LEGACY_0);
1297 : : return -1;
1298 : : }
1299 : : #endif
1300 : : }
1301 : :
1302 : : memset(&args, 0, sizeof(args));
1303 : 0 : args.ops = VIRTCHNL_OP_CONFIG_VSI_QUEUES;
1304 : 0 : args.in_args = (uint8_t *)vc_config;
1305 : 0 : args.in_args_size = size;
1306 : 0 : args.out_buffer = vf->aq_resp;
1307 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1308 : :
1309 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1310 [ # # ]: 0 : if (err)
1311 : 0 : PMD_DRV_LOG(ERR, "Failed to execute command of"
1312 : : " VIRTCHNL_OP_CONFIG_VSI_QUEUES");
1313 : :
1314 : 0 : rte_free(vc_config);
1315 : 0 : return err;
1316 : : }
1317 : :
1318 : : int
1319 : 0 : iavf_config_irq_map(struct iavf_adapter *adapter)
1320 : : {
1321 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1322 : : struct virtchnl_irq_map_info *map_info;
1323 : : struct virtchnl_vector_map *vecmap;
1324 : : struct iavf_cmd_info args;
1325 : : int len, i, err;
1326 : :
1327 : 0 : len = sizeof(struct virtchnl_irq_map_info) +
1328 : 0 : sizeof(struct virtchnl_vector_map) * vf->nb_msix;
1329 : :
1330 : 0 : map_info = rte_zmalloc("map_info", len, 0);
1331 [ # # ]: 0 : if (!map_info)
1332 : : return -ENOMEM;
1333 : :
1334 : 0 : map_info->num_vectors = vf->nb_msix;
1335 [ # # ]: 0 : for (i = 0; i < adapter->dev_data->nb_rx_queues; i++) {
1336 : : vecmap =
1337 : 0 : &map_info->vecmap[vf->qv_map[i].vector_id - vf->msix_base];
1338 : 0 : vecmap->vsi_id = vf->vsi_res->vsi_id;
1339 : 0 : vecmap->rxitr_idx = IAVF_ITR_INDEX_DEFAULT;
1340 : 0 : vecmap->vector_id = vf->qv_map[i].vector_id;
1341 : 0 : vecmap->txq_map = 0;
1342 : 0 : vecmap->rxq_map |= 1 << vf->qv_map[i].queue_id;
1343 : : }
1344 : :
1345 : 0 : args.ops = VIRTCHNL_OP_CONFIG_IRQ_MAP;
1346 : 0 : args.in_args = (u8 *)map_info;
1347 : 0 : args.in_args_size = len;
1348 : 0 : args.out_buffer = vf->aq_resp;
1349 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1350 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1351 [ # # ]: 0 : if (err)
1352 : 0 : PMD_DRV_LOG(ERR, "fail to execute command OP_CONFIG_IRQ_MAP");
1353 : :
1354 : 0 : rte_free(map_info);
1355 : 0 : return err;
1356 : : }
1357 : :
1358 : : int
1359 : 0 : iavf_config_irq_map_lv(struct iavf_adapter *adapter, uint16_t num,
1360 : : uint16_t index)
1361 : : {
1362 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1363 : : struct virtchnl_queue_vector_maps *map_info;
1364 : : struct virtchnl_queue_vector *qv_maps;
1365 : : struct iavf_cmd_info args;
1366 : : int len, i, err;
1367 : : int count = 0;
1368 : :
1369 : 0 : len = sizeof(struct virtchnl_queue_vector_maps) +
1370 : 0 : sizeof(struct virtchnl_queue_vector) * (num - 1);
1371 : :
1372 : 0 : map_info = rte_zmalloc("map_info", len, 0);
1373 [ # # ]: 0 : if (!map_info)
1374 : : return -ENOMEM;
1375 : :
1376 : 0 : map_info->vport_id = vf->vsi_res->vsi_id;
1377 : 0 : map_info->num_qv_maps = num;
1378 [ # # ]: 0 : for (i = index; i < index + map_info->num_qv_maps; i++) {
1379 : 0 : qv_maps = &map_info->qv_maps[count++];
1380 : 0 : qv_maps->itr_idx = VIRTCHNL_ITR_IDX_0;
1381 : 0 : qv_maps->queue_type = VIRTCHNL_QUEUE_TYPE_RX;
1382 : 0 : qv_maps->queue_id = vf->qv_map[i].queue_id;
1383 : 0 : qv_maps->vector_id = vf->qv_map[i].vector_id;
1384 : : }
1385 : :
1386 : 0 : args.ops = VIRTCHNL_OP_MAP_QUEUE_VECTOR;
1387 : 0 : args.in_args = (u8 *)map_info;
1388 : 0 : args.in_args_size = len;
1389 : 0 : args.out_buffer = vf->aq_resp;
1390 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1391 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1392 [ # # ]: 0 : if (err)
1393 : 0 : PMD_DRV_LOG(ERR, "fail to execute command OP_MAP_QUEUE_VECTOR");
1394 : :
1395 : 0 : rte_free(map_info);
1396 : 0 : return err;
1397 : : }
1398 : :
1399 : : void
1400 : 0 : iavf_add_del_all_mac_addr(struct iavf_adapter *adapter, bool add)
1401 : : {
1402 : : struct virtchnl_ether_addr_list *list;
1403 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1404 : : struct rte_ether_addr *addr;
1405 : : struct iavf_cmd_info args;
1406 : : int len, err, i, j;
1407 : : int next_begin = 0;
1408 : : int begin = 0;
1409 : :
1410 : : do {
1411 : : j = 0;
1412 : : len = sizeof(struct virtchnl_ether_addr_list);
1413 [ # # ]: 0 : for (i = begin; i < IAVF_NUM_MACADDR_MAX; i++, next_begin++) {
1414 [ # # ]: 0 : addr = &adapter->dev_data->mac_addrs[i];
1415 [ # # ]: 0 : if (rte_is_zero_ether_addr(addr))
1416 : 0 : continue;
1417 : 0 : len += sizeof(struct virtchnl_ether_addr);
1418 [ # # ]: 0 : if (len >= IAVF_AQ_BUF_SZ) {
1419 : 0 : next_begin = i + 1;
1420 : 0 : break;
1421 : : }
1422 : : }
1423 : :
1424 : 0 : list = rte_zmalloc("iavf_del_mac_buffer", len, 0);
1425 [ # # ]: 0 : if (!list) {
1426 : 0 : PMD_DRV_LOG(ERR, "fail to allocate memory");
1427 : 0 : return;
1428 : : }
1429 : :
1430 [ # # ]: 0 : for (i = begin; i < next_begin; i++) {
1431 [ # # ]: 0 : addr = &adapter->dev_data->mac_addrs[i];
1432 [ # # ]: 0 : if (rte_is_zero_ether_addr(addr))
1433 : 0 : continue;
1434 [ # # ]: 0 : rte_memcpy(list->list[j].addr, addr->addr_bytes,
1435 : : sizeof(addr->addr_bytes));
1436 [ # # ]: 0 : list->list[j].type = (j == 0 ?
1437 : : VIRTCHNL_ETHER_ADDR_PRIMARY :
1438 : : VIRTCHNL_ETHER_ADDR_EXTRA);
1439 : 0 : PMD_DRV_LOG(DEBUG, "add/rm mac:" RTE_ETHER_ADDR_PRT_FMT,
1440 : : RTE_ETHER_ADDR_BYTES(addr));
1441 : 0 : j++;
1442 : : }
1443 : 0 : list->vsi_id = vf->vsi_res->vsi_id;
1444 : 0 : list->num_elements = j;
1445 [ # # ]: 0 : args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR :
1446 : : VIRTCHNL_OP_DEL_ETH_ADDR;
1447 : 0 : args.in_args = (uint8_t *)list;
1448 : 0 : args.in_args_size = len;
1449 : 0 : args.out_buffer = vf->aq_resp;
1450 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1451 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1452 [ # # ]: 0 : if (err)
1453 [ # # ]: 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
1454 : : add ? "OP_ADD_ETHER_ADDRESS" :
1455 : : "OP_DEL_ETHER_ADDRESS");
1456 : 0 : rte_free(list);
1457 : : begin = next_begin;
1458 [ # # ]: 0 : } while (begin < IAVF_NUM_MACADDR_MAX);
1459 : : }
1460 : :
1461 : : int
1462 : 0 : iavf_query_stats(struct iavf_adapter *adapter,
1463 : : struct virtchnl_eth_stats **pstats)
1464 : : {
1465 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1466 : : struct virtchnl_queue_select q_stats;
1467 : : struct iavf_cmd_info args;
1468 : : int err;
1469 : :
1470 [ # # ]: 0 : if (adapter->closed)
1471 : : return -EIO;
1472 : :
1473 : : memset(&q_stats, 0, sizeof(q_stats));
1474 : 0 : q_stats.vsi_id = vf->vsi_res->vsi_id;
1475 : 0 : args.ops = VIRTCHNL_OP_GET_STATS;
1476 : 0 : args.in_args = (uint8_t *)&q_stats;
1477 : 0 : args.in_args_size = sizeof(q_stats);
1478 : 0 : args.out_buffer = vf->aq_resp;
1479 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1480 : :
1481 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1482 [ # # ]: 0 : if (err) {
1483 : 0 : PMD_DRV_LOG(ERR, "fail to execute command OP_GET_STATS");
1484 : 0 : *pstats = NULL;
1485 : 0 : return err;
1486 : : }
1487 : 0 : *pstats = (struct virtchnl_eth_stats *)args.out_buffer;
1488 : 0 : return 0;
1489 : : }
1490 : :
1491 : : int
1492 : 0 : iavf_config_promisc(struct iavf_adapter *adapter,
1493 : : bool enable_unicast,
1494 : : bool enable_multicast)
1495 : : {
1496 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1497 : : struct virtchnl_promisc_info promisc;
1498 : : struct iavf_cmd_info args;
1499 : : int err;
1500 : :
1501 [ # # ]: 0 : if (adapter->closed)
1502 : : return -EIO;
1503 : :
1504 : 0 : promisc.flags = 0;
1505 : 0 : promisc.vsi_id = vf->vsi_res->vsi_id;
1506 : :
1507 [ # # ]: 0 : if (enable_unicast)
1508 : 0 : promisc.flags |= FLAG_VF_UNICAST_PROMISC;
1509 : :
1510 [ # # ]: 0 : if (enable_multicast)
1511 : 0 : promisc.flags |= FLAG_VF_MULTICAST_PROMISC;
1512 : :
1513 : 0 : args.ops = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE;
1514 : 0 : args.in_args = (uint8_t *)&promisc;
1515 : 0 : args.in_args_size = sizeof(promisc);
1516 : 0 : args.out_buffer = vf->aq_resp;
1517 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1518 : :
1519 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1520 : :
1521 [ # # ]: 0 : if (err) {
1522 : 0 : PMD_DRV_LOG(ERR,
1523 : : "fail to execute command CONFIG_PROMISCUOUS_MODE");
1524 : :
1525 [ # # ]: 0 : if (err == -ENOTSUP)
1526 : : return err;
1527 : :
1528 : 0 : return -EAGAIN;
1529 : : }
1530 : :
1531 : 0 : vf->promisc_unicast_enabled = enable_unicast;
1532 : 0 : vf->promisc_multicast_enabled = enable_multicast;
1533 : 0 : return 0;
1534 : : }
1535 : :
1536 : : int
1537 : 0 : iavf_add_del_eth_addr(struct iavf_adapter *adapter, struct rte_ether_addr *addr,
1538 : : bool add, uint8_t type)
1539 : : {
1540 : : struct virtchnl_ether_addr_list *list;
1541 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1542 : : uint8_t cmd_buffer[sizeof(struct virtchnl_ether_addr_list) +
1543 : : sizeof(struct virtchnl_ether_addr)];
1544 : : struct iavf_cmd_info args;
1545 : : int err;
1546 : :
1547 [ # # ]: 0 : if (adapter->closed)
1548 : : return -EIO;
1549 : :
1550 : : list = (struct virtchnl_ether_addr_list *)cmd_buffer;
1551 : 0 : list->vsi_id = vf->vsi_res->vsi_id;
1552 : 0 : list->num_elements = 1;
1553 : 0 : list->list[0].type = type;
1554 [ # # ]: 0 : rte_memcpy(list->list[0].addr, addr->addr_bytes,
1555 : : sizeof(addr->addr_bytes));
1556 : :
1557 [ # # ]: 0 : args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR;
1558 : 0 : args.in_args = cmd_buffer;
1559 : 0 : args.in_args_size = sizeof(cmd_buffer);
1560 : 0 : args.out_buffer = vf->aq_resp;
1561 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1562 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1563 [ # # ]: 0 : if (err)
1564 [ # # ]: 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
1565 : : add ? "OP_ADD_ETH_ADDR" : "OP_DEL_ETH_ADDR");
1566 : : return err;
1567 : : }
1568 : :
1569 : : int
1570 : 0 : iavf_add_del_vlan(struct iavf_adapter *adapter, uint16_t vlanid, bool add)
1571 : : {
1572 : : struct virtchnl_vlan_filter_list *vlan_list;
1573 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1574 : : uint8_t cmd_buffer[sizeof(struct virtchnl_vlan_filter_list) +
1575 : : sizeof(uint16_t)];
1576 : : struct iavf_cmd_info args;
1577 : : int err;
1578 : :
1579 : : vlan_list = (struct virtchnl_vlan_filter_list *)cmd_buffer;
1580 : 0 : vlan_list->vsi_id = vf->vsi_res->vsi_id;
1581 : 0 : vlan_list->num_elements = 1;
1582 : 0 : vlan_list->vlan_id[0] = vlanid;
1583 : :
1584 [ # # ]: 0 : args.ops = add ? VIRTCHNL_OP_ADD_VLAN : VIRTCHNL_OP_DEL_VLAN;
1585 : 0 : args.in_args = cmd_buffer;
1586 : 0 : args.in_args_size = sizeof(cmd_buffer);
1587 : 0 : args.out_buffer = vf->aq_resp;
1588 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1589 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1590 [ # # ]: 0 : if (err)
1591 [ # # ]: 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
1592 : : add ? "OP_ADD_VLAN" : "OP_DEL_VLAN");
1593 : :
1594 : 0 : return err;
1595 : : }
1596 : :
1597 : : int
1598 : 0 : iavf_fdir_add(struct iavf_adapter *adapter,
1599 : : struct iavf_fdir_conf *filter)
1600 : : {
1601 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1602 : : struct virtchnl_fdir_add *fdir_ret;
1603 : :
1604 : : struct iavf_cmd_info args;
1605 : : int err;
1606 : :
1607 : 0 : filter->add_fltr.vsi_id = vf->vsi_res->vsi_id;
1608 : 0 : filter->add_fltr.validate_only = 0;
1609 : :
1610 : 0 : args.ops = VIRTCHNL_OP_ADD_FDIR_FILTER;
1611 : 0 : args.in_args = (uint8_t *)(&filter->add_fltr);
1612 : 0 : args.in_args_size = sizeof(*(&filter->add_fltr));
1613 : 0 : args.out_buffer = vf->aq_resp;
1614 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1615 : :
1616 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1617 [ # # ]: 0 : if (err) {
1618 : 0 : PMD_DRV_LOG(ERR, "fail to execute command OP_ADD_FDIR_FILTER");
1619 : 0 : return err;
1620 : : }
1621 : :
1622 : 0 : fdir_ret = (struct virtchnl_fdir_add *)args.out_buffer;
1623 : 0 : filter->flow_id = fdir_ret->flow_id;
1624 : :
1625 [ # # ]: 0 : if (fdir_ret->status == VIRTCHNL_FDIR_SUCCESS) {
1626 : 0 : PMD_DRV_LOG(INFO,
1627 : : "Succeed in adding rule request by PF");
1628 : : } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE) {
1629 : 0 : PMD_DRV_LOG(ERR,
1630 : : "Failed to add rule request due to no hw resource");
1631 : 0 : return -1;
1632 : : } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_EXIST) {
1633 : 0 : PMD_DRV_LOG(ERR,
1634 : : "Failed to add rule request due to the rule is already existed");
1635 : 0 : return -1;
1636 : : } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT) {
1637 : 0 : PMD_DRV_LOG(ERR,
1638 : : "Failed to add rule request due to the rule is conflict with existing rule");
1639 : 0 : return -1;
1640 : : } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_INVALID) {
1641 : 0 : PMD_DRV_LOG(ERR,
1642 : : "Failed to add rule request due to the hw doesn't support");
1643 : 0 : return -1;
1644 : : } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT) {
1645 : 0 : PMD_DRV_LOG(ERR,
1646 : : "Failed to add rule request due to time out for programming");
1647 : 0 : return -1;
1648 : : } else {
1649 : 0 : PMD_DRV_LOG(ERR,
1650 : : "Failed to add rule request due to other reasons");
1651 : 0 : return -1;
1652 : : }
1653 : :
1654 : 0 : return 0;
1655 : : };
1656 : :
1657 : : int
1658 : 0 : iavf_fdir_del(struct iavf_adapter *adapter,
1659 : : struct iavf_fdir_conf *filter)
1660 : : {
1661 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1662 : : struct virtchnl_fdir_del *fdir_ret;
1663 : :
1664 : : struct iavf_cmd_info args;
1665 : : int err;
1666 : :
1667 : 0 : filter->del_fltr.vsi_id = vf->vsi_res->vsi_id;
1668 : 0 : filter->del_fltr.flow_id = filter->flow_id;
1669 : :
1670 : 0 : args.ops = VIRTCHNL_OP_DEL_FDIR_FILTER;
1671 : 0 : args.in_args = (uint8_t *)(&filter->del_fltr);
1672 : 0 : args.in_args_size = sizeof(filter->del_fltr);
1673 : 0 : args.out_buffer = vf->aq_resp;
1674 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1675 : :
1676 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1677 [ # # ]: 0 : if (err) {
1678 : 0 : PMD_DRV_LOG(ERR, "fail to execute command OP_DEL_FDIR_FILTER");
1679 : 0 : return err;
1680 : : }
1681 : :
1682 : 0 : fdir_ret = (struct virtchnl_fdir_del *)args.out_buffer;
1683 : :
1684 [ # # ]: 0 : if (fdir_ret->status == VIRTCHNL_FDIR_SUCCESS) {
1685 : 0 : PMD_DRV_LOG(INFO,
1686 : : "Succeed in deleting rule request by PF");
1687 [ # # ]: 0 : } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST) {
1688 : 0 : PMD_DRV_LOG(ERR,
1689 : : "Failed to delete rule request due to this rule doesn't exist");
1690 : 0 : return -1;
1691 [ # # ]: 0 : } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT) {
1692 : 0 : PMD_DRV_LOG(ERR,
1693 : : "Failed to delete rule request due to time out for programming");
1694 : 0 : return -1;
1695 : : } else {
1696 : 0 : PMD_DRV_LOG(ERR,
1697 : : "Failed to delete rule request due to other reasons");
1698 : 0 : return -1;
1699 : : }
1700 : :
1701 : 0 : return 0;
1702 : : };
1703 : :
1704 : : int
1705 : 0 : iavf_fdir_check(struct iavf_adapter *adapter,
1706 : : struct iavf_fdir_conf *filter)
1707 : : {
1708 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1709 : : struct virtchnl_fdir_add *fdir_ret;
1710 : :
1711 : : struct iavf_cmd_info args;
1712 : : int err;
1713 : :
1714 : 0 : filter->add_fltr.vsi_id = vf->vsi_res->vsi_id;
1715 : 0 : filter->add_fltr.validate_only = 1;
1716 : :
1717 : 0 : args.ops = VIRTCHNL_OP_ADD_FDIR_FILTER;
1718 : 0 : args.in_args = (uint8_t *)(&filter->add_fltr);
1719 : 0 : args.in_args_size = sizeof(*(&filter->add_fltr));
1720 : 0 : args.out_buffer = vf->aq_resp;
1721 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1722 : :
1723 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1724 [ # # ]: 0 : if (err) {
1725 : 0 : PMD_DRV_LOG(ERR, "fail to check flow director rule");
1726 : 0 : return err;
1727 : : }
1728 : :
1729 : 0 : fdir_ret = (struct virtchnl_fdir_add *)args.out_buffer;
1730 : :
1731 [ # # ]: 0 : if (fdir_ret->status == VIRTCHNL_FDIR_SUCCESS) {
1732 : 0 : PMD_DRV_LOG(INFO,
1733 : : "Succeed in checking rule request by PF");
1734 [ # # ]: 0 : } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_INVALID) {
1735 : 0 : PMD_DRV_LOG(ERR,
1736 : : "Failed to check rule request due to parameters validation"
1737 : : " or HW doesn't support");
1738 : : err = -1;
1739 : : } else {
1740 : 0 : PMD_DRV_LOG(ERR,
1741 : : "Failed to check rule request due to other reasons");
1742 : : err = -1;
1743 : : }
1744 : :
1745 : : return err;
1746 : : }
1747 : :
1748 : : int
1749 : 0 : iavf_flow_sub(struct iavf_adapter *adapter, struct iavf_fsub_conf *filter)
1750 : : {
1751 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1752 : : struct virtchnl_flow_sub *fsub_cfg;
1753 : : struct iavf_cmd_info args;
1754 : : int err;
1755 : :
1756 : 0 : filter->sub_fltr.vsi_id = vf->vsi_res->vsi_id;
1757 : 0 : filter->sub_fltr.validate_only = 0;
1758 : :
1759 : : memset(&args, 0, sizeof(args));
1760 : 0 : args.ops = VIRTCHNL_OP_FLOW_SUBSCRIBE;
1761 : 0 : args.in_args = (uint8_t *)(&filter->sub_fltr);
1762 : 0 : args.in_args_size = sizeof(*(&filter->sub_fltr));
1763 : 0 : args.out_buffer = vf->aq_resp;
1764 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1765 : :
1766 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1767 [ # # ]: 0 : if (err) {
1768 : 0 : PMD_DRV_LOG(ERR, "Failed to execute command of "
1769 : : "OP_FLOW_SUBSCRIBE");
1770 : 0 : return err;
1771 : : }
1772 : :
1773 : 0 : fsub_cfg = (struct virtchnl_flow_sub *)args.out_buffer;
1774 : 0 : filter->flow_id = fsub_cfg->flow_id;
1775 : :
1776 [ # # ]: 0 : if (fsub_cfg->status == VIRTCHNL_FSUB_SUCCESS) {
1777 : 0 : PMD_DRV_LOG(INFO, "Succeed in adding rule request by PF");
1778 [ # # ]: 0 : } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_NORESOURCE) {
1779 : 0 : PMD_DRV_LOG(ERR, "Failed to add rule request due to no hw "
1780 : : "resource");
1781 : : err = -1;
1782 [ # # ]: 0 : } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_EXIST) {
1783 : 0 : PMD_DRV_LOG(ERR, "Failed to add rule request due to the rule "
1784 : : "is already existed");
1785 : : err = -1;
1786 [ # # ]: 0 : } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_INVALID) {
1787 : 0 : PMD_DRV_LOG(ERR, "Failed to add rule request due to the hw "
1788 : : "doesn't support");
1789 : : err = -1;
1790 : : } else {
1791 : 0 : PMD_DRV_LOG(ERR, "Failed to add rule request due to other "
1792 : : "reasons");
1793 : : err = -1;
1794 : : }
1795 : :
1796 : : return err;
1797 : : }
1798 : :
1799 : : int
1800 : 0 : iavf_flow_unsub(struct iavf_adapter *adapter, struct iavf_fsub_conf *filter)
1801 : : {
1802 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1803 : : struct virtchnl_flow_unsub *unsub_cfg;
1804 : : struct iavf_cmd_info args;
1805 : : int err;
1806 : :
1807 : 0 : filter->unsub_fltr.vsi_id = vf->vsi_res->vsi_id;
1808 : 0 : filter->unsub_fltr.flow_id = filter->flow_id;
1809 : :
1810 : : memset(&args, 0, sizeof(args));
1811 : 0 : args.ops = VIRTCHNL_OP_FLOW_UNSUBSCRIBE;
1812 : 0 : args.in_args = (uint8_t *)(&filter->unsub_fltr);
1813 : 0 : args.in_args_size = sizeof(filter->unsub_fltr);
1814 : 0 : args.out_buffer = vf->aq_resp;
1815 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1816 : :
1817 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1818 [ # # ]: 0 : if (err) {
1819 : 0 : PMD_DRV_LOG(ERR, "Failed to execute command of "
1820 : : "OP_FLOW_UNSUBSCRIBE");
1821 : 0 : return err;
1822 : : }
1823 : :
1824 : 0 : unsub_cfg = (struct virtchnl_flow_unsub *)args.out_buffer;
1825 : :
1826 [ # # ]: 0 : if (unsub_cfg->status == VIRTCHNL_FSUB_SUCCESS) {
1827 : 0 : PMD_DRV_LOG(INFO, "Succeed in deleting rule request by PF");
1828 [ # # ]: 0 : } else if (unsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_NONEXIST) {
1829 : 0 : PMD_DRV_LOG(ERR, "Failed to delete rule request due to this "
1830 : : "rule doesn't exist");
1831 : : err = -1;
1832 : : } else {
1833 : 0 : PMD_DRV_LOG(ERR, "Failed to delete rule request due to other "
1834 : : "reasons");
1835 : : err = -1;
1836 : : }
1837 : :
1838 : : return err;
1839 : : }
1840 : :
1841 : : int
1842 : 0 : iavf_flow_sub_check(struct iavf_adapter *adapter,
1843 : : struct iavf_fsub_conf *filter)
1844 : : {
1845 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1846 : : struct virtchnl_flow_sub *fsub_cfg;
1847 : :
1848 : : struct iavf_cmd_info args;
1849 : : int err;
1850 : :
1851 : 0 : filter->sub_fltr.vsi_id = vf->vsi_res->vsi_id;
1852 : 0 : filter->sub_fltr.validate_only = 1;
1853 : :
1854 : 0 : args.ops = VIRTCHNL_OP_FLOW_SUBSCRIBE;
1855 : 0 : args.in_args = (uint8_t *)(&filter->sub_fltr);
1856 : 0 : args.in_args_size = sizeof(*(&filter->sub_fltr));
1857 : 0 : args.out_buffer = vf->aq_resp;
1858 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1859 : :
1860 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1861 [ # # ]: 0 : if (err) {
1862 : 0 : PMD_DRV_LOG(ERR, "Failed to check flow subscription rule");
1863 : 0 : return err;
1864 : : }
1865 : :
1866 : 0 : fsub_cfg = (struct virtchnl_flow_sub *)args.out_buffer;
1867 : :
1868 [ # # ]: 0 : if (fsub_cfg->status == VIRTCHNL_FSUB_SUCCESS) {
1869 : 0 : PMD_DRV_LOG(INFO, "Succeed in checking rule request by PF");
1870 [ # # ]: 0 : } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_INVALID) {
1871 : 0 : PMD_DRV_LOG(ERR, "Failed to check rule request due to "
1872 : : "parameters validation or HW doesn't "
1873 : : "support");
1874 : : err = -1;
1875 : : } else {
1876 : 0 : PMD_DRV_LOG(ERR, "Failed to check rule request due to other "
1877 : : "reasons");
1878 : : err = -1;
1879 : : }
1880 : :
1881 : : return err;
1882 : : }
1883 : :
1884 : : int
1885 [ # # ]: 0 : iavf_add_del_rss_cfg(struct iavf_adapter *adapter,
1886 : : struct virtchnl_rss_cfg *rss_cfg, bool add)
1887 : : {
1888 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1889 : : struct iavf_cmd_info args;
1890 : : int err;
1891 : :
1892 : : memset(&args, 0, sizeof(args));
1893 [ # # ]: 0 : args.ops = add ? VIRTCHNL_OP_ADD_RSS_CFG :
1894 : : VIRTCHNL_OP_DEL_RSS_CFG;
1895 : 0 : args.in_args = (u8 *)rss_cfg;
1896 : 0 : args.in_args_size = sizeof(*rss_cfg);
1897 : 0 : args.out_buffer = vf->aq_resp;
1898 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1899 : :
1900 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1901 [ # # ]: 0 : if (err)
1902 [ # # ]: 0 : PMD_DRV_LOG(ERR,
1903 : : "Failed to execute command of %s",
1904 : : add ? "OP_ADD_RSS_CFG" :
1905 : : "OP_DEL_RSS_INPUT_CFG");
1906 : :
1907 : 0 : return err;
1908 : : }
1909 : :
1910 : : int
1911 : 0 : iavf_get_hena_caps(struct iavf_adapter *adapter, uint64_t *caps)
1912 : : {
1913 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1914 : : struct iavf_cmd_info args;
1915 : : int err;
1916 : :
1917 : 0 : args.ops = VIRTCHNL_OP_GET_RSS_HENA_CAPS;
1918 : 0 : args.in_args = NULL;
1919 : 0 : args.in_args_size = 0;
1920 : 0 : args.out_buffer = vf->aq_resp;
1921 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1922 : :
1923 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1924 [ # # ]: 0 : if (err) {
1925 : 0 : PMD_DRV_LOG(ERR,
1926 : : "Failed to execute command of OP_GET_RSS_HENA_CAPS");
1927 : 0 : return err;
1928 : : }
1929 : :
1930 : 0 : *caps = ((struct virtchnl_rss_hena *)args.out_buffer)->hena;
1931 : 0 : return 0;
1932 : : }
1933 : :
1934 : : int
1935 : 0 : iavf_set_hena(struct iavf_adapter *adapter, uint64_t hena)
1936 : : {
1937 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1938 : : struct virtchnl_rss_hena vrh;
1939 : : struct iavf_cmd_info args;
1940 : : int err;
1941 : :
1942 : 0 : vrh.hena = hena;
1943 : 0 : args.ops = VIRTCHNL_OP_SET_RSS_HENA;
1944 : 0 : args.in_args = (u8 *)&vrh;
1945 : 0 : args.in_args_size = sizeof(vrh);
1946 : 0 : args.out_buffer = vf->aq_resp;
1947 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1948 : :
1949 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1950 [ # # ]: 0 : if (err)
1951 : 0 : PMD_DRV_LOG(ERR,
1952 : : "Failed to execute command of OP_SET_RSS_HENA");
1953 : :
1954 : 0 : return err;
1955 : : }
1956 : :
1957 : : int
1958 : 0 : iavf_get_qos_cap(struct iavf_adapter *adapter)
1959 : : {
1960 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1961 : : struct iavf_cmd_info args;
1962 : : uint32_t len;
1963 : : int err;
1964 : :
1965 : 0 : args.ops = VIRTCHNL_OP_GET_QOS_CAPS;
1966 : 0 : args.in_args = NULL;
1967 : 0 : args.in_args_size = 0;
1968 : 0 : args.out_buffer = vf->aq_resp;
1969 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
1970 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
1971 : :
1972 [ # # ]: 0 : if (err) {
1973 : 0 : PMD_DRV_LOG(ERR,
1974 : : "Failed to execute command of OP_GET_VF_RESOURCE");
1975 : 0 : return -1;
1976 : : }
1977 : :
1978 : : len = sizeof(struct virtchnl_qos_cap_list) +
1979 : : IAVF_MAX_TRAFFIC_CLASS * sizeof(struct virtchnl_qos_cap_elem);
1980 : :
1981 : 0 : rte_memcpy(vf->qos_cap, args.out_buffer,
1982 [ # # ]: 0 : RTE_MIN(args.out_size, len));
1983 : :
1984 : : return 0;
1985 : : }
1986 : :
1987 : 0 : int iavf_set_q_tc_map(struct rte_eth_dev *dev,
1988 : : struct virtchnl_queue_tc_mapping *q_tc_mapping, uint16_t size)
1989 : : {
1990 : 0 : struct iavf_adapter *adapter =
1991 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1992 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
1993 : : struct iavf_cmd_info args;
1994 : : int err;
1995 : :
1996 : : memset(&args, 0, sizeof(args));
1997 : 0 : args.ops = VIRTCHNL_OP_CONFIG_QUEUE_TC_MAP;
1998 : 0 : args.in_args = (uint8_t *)q_tc_mapping;
1999 : 0 : args.in_args_size = size;
2000 : 0 : args.out_buffer = vf->aq_resp;
2001 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
2002 : :
2003 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
2004 [ # # ]: 0 : if (err)
2005 : 0 : PMD_DRV_LOG(ERR, "Failed to execute command of"
2006 : : " VIRTCHNL_OP_CONFIG_TC_MAP");
2007 : 0 : return err;
2008 : : }
2009 : :
2010 : 0 : int iavf_set_q_bw(struct rte_eth_dev *dev,
2011 : : struct virtchnl_queues_bw_cfg *q_bw, uint16_t size)
2012 : : {
2013 : 0 : struct iavf_adapter *adapter =
2014 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2015 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
2016 : : struct iavf_cmd_info args;
2017 : : int err;
2018 : :
2019 : : memset(&args, 0, sizeof(args));
2020 : 0 : args.ops = VIRTCHNL_OP_CONFIG_QUEUE_BW;
2021 : 0 : args.in_args = (uint8_t *)q_bw;
2022 : 0 : args.in_args_size = size;
2023 : 0 : args.out_buffer = vf->aq_resp;
2024 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
2025 : :
2026 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
2027 [ # # ]: 0 : if (err)
2028 : 0 : PMD_DRV_LOG(ERR, "Failed to execute command of"
2029 : : " VIRTCHNL_OP_CONFIG_QUEUE_BW");
2030 : 0 : return err;
2031 : : }
2032 : :
2033 : : int
2034 : 0 : iavf_add_del_mc_addr_list(struct iavf_adapter *adapter,
2035 : : struct rte_ether_addr *mc_addrs,
2036 : : uint32_t mc_addrs_num, bool add)
2037 : : {
2038 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
2039 : : uint8_t cmd_buffer[sizeof(struct virtchnl_ether_addr_list) +
2040 : : (IAVF_NUM_MACADDR_MAX * sizeof(struct virtchnl_ether_addr))];
2041 : : struct virtchnl_ether_addr_list *list;
2042 : : struct iavf_cmd_info args;
2043 : : uint32_t i;
2044 : : int err;
2045 : :
2046 [ # # ]: 0 : if (mc_addrs == NULL || mc_addrs_num == 0)
2047 : : return 0;
2048 : :
2049 : : list = (struct virtchnl_ether_addr_list *)cmd_buffer;
2050 : 0 : list->vsi_id = vf->vsi_res->vsi_id;
2051 : 0 : list->num_elements = mc_addrs_num;
2052 : :
2053 [ # # ]: 0 : for (i = 0; i < mc_addrs_num; i++) {
2054 [ # # ]: 0 : if (!IAVF_IS_MULTICAST(mc_addrs[i].addr_bytes)) {
2055 : 0 : PMD_DRV_LOG(ERR, "Invalid mac:" RTE_ETHER_ADDR_PRT_FMT,
2056 : : RTE_ETHER_ADDR_BYTES(&mc_addrs[i]));
2057 : 0 : return -EINVAL;
2058 : : }
2059 : :
2060 : 0 : memcpy(list->list[i].addr, mc_addrs[i].addr_bytes,
2061 : : sizeof(list->list[i].addr));
2062 : 0 : list->list[i].type = VIRTCHNL_ETHER_ADDR_EXTRA;
2063 : : }
2064 : :
2065 [ # # ]: 0 : args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR;
2066 : 0 : args.in_args = cmd_buffer;
2067 : 0 : args.in_args_size = sizeof(struct virtchnl_ether_addr_list) +
2068 : 0 : i * sizeof(struct virtchnl_ether_addr);
2069 : 0 : args.out_buffer = vf->aq_resp;
2070 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
2071 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
2072 : :
2073 [ # # ]: 0 : if (err) {
2074 [ # # ]: 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
2075 : : add ? "OP_ADD_ETH_ADDR" : "OP_DEL_ETH_ADDR");
2076 : 0 : return err;
2077 : : }
2078 : :
2079 : : return 0;
2080 : : }
2081 : :
2082 : : int
2083 : 0 : iavf_request_queues(struct rte_eth_dev *dev, uint16_t num)
2084 : : {
2085 : 0 : struct iavf_adapter *adapter =
2086 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2087 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
2088 : : struct virtchnl_vf_res_request vfres;
2089 : : struct iavf_cmd_info args;
2090 : : uint16_t num_queue_pairs;
2091 : : int err;
2092 : : int i = 0;
2093 : :
2094 [ # # ]: 0 : if (!(vf->vf_res->vf_cap_flags &
2095 : : VIRTCHNL_VF_OFFLOAD_REQ_QUEUES)) {
2096 : 0 : PMD_DRV_LOG(ERR, "request queues not supported");
2097 : 0 : return -1;
2098 : : }
2099 : :
2100 [ # # ]: 0 : if (num == 0) {
2101 : 0 : PMD_DRV_LOG(ERR, "queue number cannot be zero");
2102 : 0 : return -1;
2103 : : }
2104 : 0 : vfres.num_queue_pairs = num;
2105 : :
2106 : 0 : args.ops = VIRTCHNL_OP_REQUEST_QUEUES;
2107 : 0 : args.in_args = (u8 *)&vfres;
2108 : 0 : args.in_args_size = sizeof(vfres);
2109 : 0 : args.out_buffer = vf->aq_resp;
2110 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
2111 : :
2112 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) {
2113 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
2114 : : } else {
2115 : 0 : rte_eal_alarm_cancel(iavf_dev_alarm_handler, dev);
2116 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
2117 : 0 : rte_eal_alarm_set(IAVF_ALARM_INTERVAL,
2118 : : iavf_dev_alarm_handler, dev);
2119 : : }
2120 : :
2121 [ # # ]: 0 : if (err) {
2122 : 0 : PMD_DRV_LOG(ERR, "fail to execute command OP_REQUEST_QUEUES");
2123 : 0 : return err;
2124 : : }
2125 : :
2126 : : /* wait for interrupt notification vf is resetting */
2127 [ # # ]: 0 : while (i++ < MAX_TRY_TIMES) {
2128 [ # # ]: 0 : if (vf->vf_reset)
2129 : : break;
2130 : 0 : iavf_msec_delay(ASQ_DELAY_MS);
2131 : : }
2132 : :
2133 : : /* request queues succeeded, vf is resetting */
2134 [ # # ]: 0 : if (vf->vf_reset) {
2135 : 0 : PMD_DRV_LOG(INFO, "vf is resetting");
2136 : 0 : return 0;
2137 : : }
2138 : :
2139 : : /* request additional queues failed, return available number */
2140 : 0 : num_queue_pairs =
2141 : 0 : ((struct virtchnl_vf_res_request *)args.out_buffer)->num_queue_pairs;
2142 : 0 : PMD_DRV_LOG(ERR, "request queues failed, only %u queues "
2143 : : "available", num_queue_pairs);
2144 : :
2145 : 0 : return -1;
2146 : : }
2147 : :
2148 : : int
2149 : 0 : iavf_get_max_rss_queue_region(struct iavf_adapter *adapter)
2150 : : {
2151 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
2152 : : struct iavf_cmd_info args;
2153 : : uint16_t qregion_width;
2154 : : int err;
2155 : :
2156 : 0 : args.ops = VIRTCHNL_OP_GET_MAX_RSS_QREGION;
2157 : 0 : args.in_args = NULL;
2158 : 0 : args.in_args_size = 0;
2159 : 0 : args.out_buffer = vf->aq_resp;
2160 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
2161 : :
2162 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
2163 [ # # ]: 0 : if (err) {
2164 : 0 : PMD_DRV_LOG(ERR, "Failed to execute command of VIRTCHNL_OP_GET_MAX_RSS_QREGION");
2165 : 0 : return err;
2166 : : }
2167 : :
2168 : 0 : qregion_width =
2169 : 0 : ((struct virtchnl_max_rss_qregion *)args.out_buffer)->qregion_width;
2170 : :
2171 : 0 : vf->max_rss_qregion = (uint16_t)(1 << qregion_width);
2172 : :
2173 : 0 : return 0;
2174 : : }
2175 : :
2176 : :
2177 : :
2178 : : int
2179 : 0 : iavf_ipsec_crypto_request(struct iavf_adapter *adapter,
2180 : : uint8_t *msg, size_t msg_len,
2181 : : uint8_t *resp_msg, size_t resp_msg_len)
2182 : : {
2183 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
2184 : : struct iavf_cmd_info args;
2185 : : int err;
2186 : :
2187 : 0 : args.ops = VIRTCHNL_OP_INLINE_IPSEC_CRYPTO;
2188 : 0 : args.in_args = msg;
2189 : 0 : args.in_args_size = msg_len;
2190 : 0 : args.out_buffer = vf->aq_resp;
2191 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
2192 : :
2193 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 1);
2194 [ # # ]: 0 : if (err) {
2195 : 0 : PMD_DRV_LOG(ERR, "fail to execute command %s",
2196 : : "OP_INLINE_IPSEC_CRYPTO");
2197 : 0 : return err;
2198 : : }
2199 : :
2200 : 0 : memcpy(resp_msg, args.out_buffer, resp_msg_len);
2201 : :
2202 : 0 : return 0;
2203 : : }
2204 : :
2205 : : int
2206 : 0 : iavf_set_vf_quanta_size(struct iavf_adapter *adapter, u16 start_queue_id, u16 num_queues)
2207 : : {
2208 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
2209 : : struct iavf_cmd_info args;
2210 : : struct virtchnl_quanta_cfg q_quanta;
2211 : : int err;
2212 : :
2213 [ # # ]: 0 : if (adapter->devargs.quanta_size == 0)
2214 : : return 0;
2215 : :
2216 : 0 : q_quanta.quanta_size = adapter->devargs.quanta_size;
2217 : 0 : q_quanta.queue_select.type = VIRTCHNL_QUEUE_TYPE_TX;
2218 : 0 : q_quanta.queue_select.start_queue_id = start_queue_id;
2219 : 0 : q_quanta.queue_select.num_queues = num_queues;
2220 : :
2221 : 0 : args.ops = VIRTCHNL_OP_CONFIG_QUANTA;
2222 : 0 : args.in_args = (uint8_t *)&q_quanta;
2223 : 0 : args.in_args_size = sizeof(q_quanta);
2224 : 0 : args.out_buffer = vf->aq_resp;
2225 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
2226 : :
2227 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
2228 [ # # ]: 0 : if (err) {
2229 : 0 : PMD_DRV_LOG(ERR, "Failed to execute command VIRTCHNL_OP_CONFIG_QUANTA");
2230 : 0 : return err;
2231 : : }
2232 : :
2233 : : return 0;
2234 : : }
2235 : :
2236 : : int
2237 : 0 : iavf_get_ptp_cap(struct iavf_adapter *adapter)
2238 : : {
2239 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
2240 : : struct virtchnl_ptp_caps ptp_caps;
2241 : : struct iavf_cmd_info args;
2242 : : int err;
2243 : :
2244 : 0 : ptp_caps.caps = VIRTCHNL_1588_PTP_CAP_RX_TSTAMP |
2245 : : VIRTCHNL_1588_PTP_CAP_READ_PHC;
2246 : :
2247 : 0 : args.ops = VIRTCHNL_OP_1588_PTP_GET_CAPS;
2248 : 0 : args.in_args = (uint8_t *)&ptp_caps;
2249 : 0 : args.in_args_size = sizeof(ptp_caps);
2250 : 0 : args.out_buffer = vf->aq_resp;
2251 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
2252 : :
2253 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
2254 [ # # ]: 0 : if (err) {
2255 : 0 : PMD_DRV_LOG(ERR,
2256 : : "Failed to execute command of OP_1588_PTP_GET_CAPS");
2257 : 0 : return err;
2258 : : }
2259 : :
2260 : 0 : vf->ptp_caps = ((struct virtchnl_ptp_caps *)args.out_buffer)->caps;
2261 : :
2262 : 0 : return 0;
2263 : : }
2264 : :
2265 : : int
2266 : 0 : iavf_get_phc_time(struct iavf_rx_queue *rxq)
2267 : : {
2268 : 0 : struct iavf_adapter *adapter = rxq->vsi->adapter;
2269 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
2270 : : struct virtchnl_phc_time phc_time;
2271 : : struct iavf_cmd_info args;
2272 : : int err = 0;
2273 : :
2274 : 0 : args.ops = VIRTCHNL_OP_1588_PTP_GET_TIME;
2275 : 0 : args.in_args = (uint8_t *)&phc_time;
2276 : 0 : args.in_args_size = sizeof(phc_time);
2277 : 0 : args.out_buffer = vf->aq_resp;
2278 : 0 : args.out_size = IAVF_AQ_BUF_SZ;
2279 : :
2280 : 0 : rte_spinlock_lock(&vf->phc_time_aq_lock);
2281 : 0 : err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
2282 [ # # ]: 0 : if (err) {
2283 : 0 : PMD_DRV_LOG(ERR,
2284 : : "Failed to execute command of VIRTCHNL_OP_1588_PTP_GET_TIME");
2285 : 0 : goto out;
2286 : : }
2287 : 0 : rxq->phc_time = ((struct virtchnl_phc_time *)args.out_buffer)->time;
2288 : :
2289 : 0 : out:
2290 : : rte_spinlock_unlock(&vf->phc_time_aq_lock);
2291 : 0 : return err;
2292 : : }
|