3275687927e6a6a354a642d918a6324a3ebb71a5
[dpdk.git] / drivers / net / iavf / iavf_vchnl.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Intel Corporation
3  */
4
5 #include <stdio.h>
6 #include <errno.h>
7 #include <stdint.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <stdarg.h>
11 #include <inttypes.h>
12 #include <rte_byteorder.h>
13 #include <rte_common.h>
14
15 #include <rte_debug.h>
16 #include <rte_alarm.h>
17 #include <rte_atomic.h>
18 #include <rte_eal.h>
19 #include <rte_ether.h>
20 #include <ethdev_driver.h>
21 #include <ethdev_pci.h>
22 #include <rte_dev.h>
23
24 #include "iavf.h"
25 #include "iavf_rxtx.h"
26
27 #define MAX_TRY_TIMES 200
28 #define ASQ_DELAY_MS  10
29
30 static uint32_t
31 iavf_convert_link_speed(enum virtchnl_link_speed virt_link_speed)
32 {
33         uint32_t speed;
34
35         switch (virt_link_speed) {
36         case VIRTCHNL_LINK_SPEED_100MB:
37                 speed = 100;
38                 break;
39         case VIRTCHNL_LINK_SPEED_1GB:
40                 speed = 1000;
41                 break;
42         case VIRTCHNL_LINK_SPEED_10GB:
43                 speed = 10000;
44                 break;
45         case VIRTCHNL_LINK_SPEED_40GB:
46                 speed = 40000;
47                 break;
48         case VIRTCHNL_LINK_SPEED_20GB:
49                 speed = 20000;
50                 break;
51         case VIRTCHNL_LINK_SPEED_25GB:
52                 speed = 25000;
53                 break;
54         case VIRTCHNL_LINK_SPEED_2_5GB:
55                 speed = 2500;
56                 break;
57         case VIRTCHNL_LINK_SPEED_5GB:
58                 speed = 5000;
59                 break;
60         default:
61                 speed = 0;
62                 break;
63         }
64
65         return speed;
66 }
67
68 /* Read data in admin queue to get msg from pf driver */
69 static enum iavf_aq_result
70 iavf_read_msg_from_pf(struct iavf_adapter *adapter, uint16_t buf_len,
71                      uint8_t *buf)
72 {
73         struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
74         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
75         struct rte_eth_dev *dev = adapter->eth_dev;
76         struct iavf_arq_event_info event;
77         enum iavf_aq_result result = IAVF_MSG_NON;
78         enum virtchnl_ops opcode;
79         int ret;
80
81         event.buf_len = buf_len;
82         event.msg_buf = buf;
83         ret = iavf_clean_arq_element(hw, &event, NULL);
84         /* Can't read any msg from adminQ */
85         if (ret) {
86                 PMD_DRV_LOG(DEBUG, "Can't read msg from AQ");
87                 if (ret != IAVF_ERR_ADMIN_QUEUE_NO_WORK)
88                         result = IAVF_MSG_ERR;
89                 return result;
90         }
91
92         opcode = (enum virtchnl_ops)rte_le_to_cpu_32(event.desc.cookie_high);
93         vf->cmd_retval = (enum virtchnl_status_code)rte_le_to_cpu_32(
94                         event.desc.cookie_low);
95
96         PMD_DRV_LOG(DEBUG, "AQ from pf carries opcode %u, retval %d",
97                     opcode, vf->cmd_retval);
98
99         if (opcode == VIRTCHNL_OP_EVENT) {
100                 struct virtchnl_pf_event *vpe =
101                         (struct virtchnl_pf_event *)event.msg_buf;
102
103                 result = IAVF_MSG_SYS;
104                 switch (vpe->event) {
105                 case VIRTCHNL_EVENT_LINK_CHANGE:
106                         vf->link_up =
107                                 vpe->event_data.link_event.link_status;
108                         if (vf->vf_res->vf_cap_flags &
109                                 VIRTCHNL_VF_CAP_ADV_LINK_SPEED) {
110                                 vf->link_speed =
111                                     vpe->event_data.link_event_adv.link_speed;
112                         } else {
113                                 enum virtchnl_link_speed speed;
114                                 speed = vpe->event_data.link_event.link_speed;
115                                 vf->link_speed = iavf_convert_link_speed(speed);
116                         }
117                         iavf_dev_link_update(dev, 0);
118                         PMD_DRV_LOG(INFO, "Link status update:%s",
119                                         vf->link_up ? "up" : "down");
120                         break;
121                 case VIRTCHNL_EVENT_RESET_IMPENDING:
122                         vf->vf_reset = true;
123                         PMD_DRV_LOG(INFO, "VF is resetting");
124                         break;
125                 case VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
126                         vf->dev_closed = true;
127                         PMD_DRV_LOG(INFO, "PF driver closed");
128                         break;
129                 default:
130                         PMD_DRV_LOG(ERR, "%s: Unknown event %d from pf",
131                                         __func__, vpe->event);
132                 }
133         }  else {
134                 /* async reply msg on command issued by vf previously */
135                 result = IAVF_MSG_CMD;
136                 if (opcode != vf->pend_cmd) {
137                         PMD_DRV_LOG(WARNING, "command mismatch, expect %u, get %u",
138                                         vf->pend_cmd, opcode);
139                         result = IAVF_MSG_ERR;
140                 }
141         }
142
143         return result;
144 }
145
146 static int
147 iavf_execute_vf_cmd(struct iavf_adapter *adapter, struct iavf_cmd_info *args)
148 {
149         struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
150         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
151         enum iavf_aq_result result;
152         enum iavf_status ret;
153         int err = 0;
154         int i = 0;
155
156         if (vf->vf_reset)
157                 return -EIO;
158
159         if (_atomic_set_cmd(vf, args->ops))
160                 return -1;
161
162         ret = iavf_aq_send_msg_to_pf(hw, args->ops, IAVF_SUCCESS,
163                                     args->in_args, args->in_args_size, NULL);
164         if (ret) {
165                 PMD_DRV_LOG(ERR, "fail to send cmd %d", args->ops);
166                 _clear_cmd(vf);
167                 return err;
168         }
169
170         switch (args->ops) {
171         case VIRTCHNL_OP_RESET_VF:
172                 /*no need to wait for response */
173                 _clear_cmd(vf);
174                 break;
175         case VIRTCHNL_OP_VERSION:
176         case VIRTCHNL_OP_GET_VF_RESOURCES:
177         case VIRTCHNL_OP_GET_SUPPORTED_RXDIDS:
178         case VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS:
179                 /* for init virtchnl ops, need to poll the response */
180                 do {
181                         result = iavf_read_msg_from_pf(adapter, args->out_size,
182                                                    args->out_buffer);
183                         if (result == IAVF_MSG_CMD)
184                                 break;
185                         iavf_msec_delay(ASQ_DELAY_MS);
186                 } while (i++ < MAX_TRY_TIMES);
187                 if (i >= MAX_TRY_TIMES ||
188                     vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
189                         err = -1;
190                         PMD_DRV_LOG(ERR, "No response or return failure (%d)"
191                                     " for cmd %d", vf->cmd_retval, args->ops);
192                 }
193                 _clear_cmd(vf);
194                 break;
195         case VIRTCHNL_OP_REQUEST_QUEUES:
196                 /*
197                  * ignore async reply, only wait for system message,
198                  * vf_reset = true if get VIRTCHNL_EVENT_RESET_IMPENDING,
199                  * if not, means request queues failed.
200                  */
201                 do {
202                         result = iavf_read_msg_from_pf(adapter, args->out_size,
203                                                    args->out_buffer);
204                         if (result == IAVF_MSG_SYS && vf->vf_reset) {
205                                 break;
206                         } else if (result == IAVF_MSG_CMD ||
207                                 result == IAVF_MSG_ERR) {
208                                 err = -1;
209                                 break;
210                         }
211                         iavf_msec_delay(ASQ_DELAY_MS);
212                         /* If don't read msg or read sys event, continue */
213                 } while (i++ < MAX_TRY_TIMES);
214                 if (i >= MAX_TRY_TIMES ||
215                         vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
216                         err = -1;
217                         PMD_DRV_LOG(ERR, "No response or return failure (%d)"
218                                     " for cmd %d", vf->cmd_retval, args->ops);
219                 }
220                 _clear_cmd(vf);
221                 break;
222         default:
223                 /* For other virtchnl ops in running time,
224                  * wait for the cmd done flag.
225                  */
226                 do {
227                         if (vf->pend_cmd == VIRTCHNL_OP_UNKNOWN)
228                                 break;
229                         iavf_msec_delay(ASQ_DELAY_MS);
230                         /* If don't read msg or read sys event, continue */
231                 } while (i++ < MAX_TRY_TIMES);
232
233                 if (i >= MAX_TRY_TIMES) {
234                         PMD_DRV_LOG(ERR, "No response for cmd %d", args->ops);
235                         _clear_cmd(vf);
236                         err = -EIO;
237                 } else if (vf->cmd_retval ==
238                            VIRTCHNL_STATUS_ERR_NOT_SUPPORTED) {
239                         PMD_DRV_LOG(ERR, "Cmd %d not supported", args->ops);
240                         err = -ENOTSUP;
241                 } else if (vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
242                         PMD_DRV_LOG(ERR, "Return failure %d for cmd %d",
243                                     vf->cmd_retval, args->ops);
244                         err = -EINVAL;
245                 }
246                 break;
247         }
248
249         return err;
250 }
251
252 static void
253 iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg,
254                         uint16_t msglen)
255 {
256         struct virtchnl_pf_event *pf_msg =
257                         (struct virtchnl_pf_event *)msg;
258         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
259
260         if (msglen < sizeof(struct virtchnl_pf_event)) {
261                 PMD_DRV_LOG(DEBUG, "Error event");
262                 return;
263         }
264         switch (pf_msg->event) {
265         case VIRTCHNL_EVENT_RESET_IMPENDING:
266                 PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event");
267                 vf->vf_reset = true;
268                 rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
269                                               NULL);
270                 break;
271         case VIRTCHNL_EVENT_LINK_CHANGE:
272                 PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
273                 vf->link_up = pf_msg->event_data.link_event.link_status;
274                 if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_CAP_ADV_LINK_SPEED) {
275                         vf->link_speed =
276                                 pf_msg->event_data.link_event_adv.link_speed;
277                 } else {
278                         enum virtchnl_link_speed speed;
279                         speed = pf_msg->event_data.link_event.link_speed;
280                         vf->link_speed = iavf_convert_link_speed(speed);
281                 }
282                 iavf_dev_link_update(dev, 0);
283                 rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
284                 break;
285         case VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
286                 PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_PF_DRIVER_CLOSE event");
287                 break;
288         default:
289                 PMD_DRV_LOG(ERR, " unknown event received %u", pf_msg->event);
290                 break;
291         }
292 }
293
294 void
295 iavf_handle_virtchnl_msg(struct rte_eth_dev *dev)
296 {
297         struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
298         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
299         struct iavf_arq_event_info info;
300         uint16_t pending, aq_opc;
301         enum virtchnl_ops msg_opc;
302         enum iavf_status msg_ret;
303         int ret;
304
305         info.buf_len = IAVF_AQ_BUF_SZ;
306         if (!vf->aq_resp) {
307                 PMD_DRV_LOG(ERR, "Buffer for adminq resp should not be NULL");
308                 return;
309         }
310         info.msg_buf = vf->aq_resp;
311
312         pending = 1;
313         while (pending) {
314                 ret = iavf_clean_arq_element(hw, &info, &pending);
315
316                 if (ret != IAVF_SUCCESS) {
317                         PMD_DRV_LOG(INFO, "Failed to read msg from AdminQ,"
318                                     "ret: %d", ret);
319                         break;
320                 }
321                 aq_opc = rte_le_to_cpu_16(info.desc.opcode);
322                 /* For the message sent from pf to vf, opcode is stored in
323                  * cookie_high of struct iavf_aq_desc, while return error code
324                  * are stored in cookie_low, Which is done by PF driver.
325                  */
326                 msg_opc = (enum virtchnl_ops)rte_le_to_cpu_32(
327                                                   info.desc.cookie_high);
328                 msg_ret = (enum iavf_status)rte_le_to_cpu_32(
329                                                   info.desc.cookie_low);
330                 switch (aq_opc) {
331                 case iavf_aqc_opc_send_msg_to_vf:
332                         if (msg_opc == VIRTCHNL_OP_EVENT) {
333                                 iavf_handle_pf_event_msg(dev, info.msg_buf,
334                                                         info.msg_len);
335                         } else {
336                                 /* read message and it's expected one */
337                                 if (msg_opc == vf->pend_cmd)
338                                         _notify_cmd(vf, msg_ret);
339                                 else
340                                         PMD_DRV_LOG(ERR, "command mismatch,"
341                                                     "expect %u, get %u",
342                                                     vf->pend_cmd, msg_opc);
343                                 PMD_DRV_LOG(DEBUG,
344                                             "adminq response is received,"
345                                             " opcode = %d", msg_opc);
346                         }
347                         break;
348                 default:
349                         PMD_DRV_LOG(DEBUG, "Request %u is not supported yet",
350                                     aq_opc);
351                         break;
352                 }
353         }
354 }
355
356 int
357 iavf_enable_vlan_strip(struct iavf_adapter *adapter)
358 {
359         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
360         struct iavf_cmd_info args;
361         int ret;
362
363         memset(&args, 0, sizeof(args));
364         args.ops = VIRTCHNL_OP_ENABLE_VLAN_STRIPPING;
365         args.in_args = NULL;
366         args.in_args_size = 0;
367         args.out_buffer = vf->aq_resp;
368         args.out_size = IAVF_AQ_BUF_SZ;
369         ret = iavf_execute_vf_cmd(adapter, &args);
370         if (ret)
371                 PMD_DRV_LOG(ERR, "Failed to execute command of"
372                             " OP_ENABLE_VLAN_STRIPPING");
373
374         return ret;
375 }
376
377 int
378 iavf_disable_vlan_strip(struct iavf_adapter *adapter)
379 {
380         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
381         struct iavf_cmd_info args;
382         int ret;
383
384         memset(&args, 0, sizeof(args));
385         args.ops = VIRTCHNL_OP_DISABLE_VLAN_STRIPPING;
386         args.in_args = NULL;
387         args.in_args_size = 0;
388         args.out_buffer = vf->aq_resp;
389         args.out_size = IAVF_AQ_BUF_SZ;
390         ret = iavf_execute_vf_cmd(adapter, &args);
391         if (ret)
392                 PMD_DRV_LOG(ERR, "Failed to execute command of"
393                             " OP_DISABLE_VLAN_STRIPPING");
394
395         return ret;
396 }
397
398 #define VIRTCHNL_VERSION_MAJOR_START 1
399 #define VIRTCHNL_VERSION_MINOR_START 1
400
401 /* Check API version with sync wait until version read from admin queue */
402 int
403 iavf_check_api_version(struct iavf_adapter *adapter)
404 {
405         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
406         struct virtchnl_version_info version, *pver;
407         struct iavf_cmd_info args;
408         int err;
409
410         version.major = VIRTCHNL_VERSION_MAJOR;
411         version.minor = VIRTCHNL_VERSION_MINOR;
412
413         args.ops = VIRTCHNL_OP_VERSION;
414         args.in_args = (uint8_t *)&version;
415         args.in_args_size = sizeof(version);
416         args.out_buffer = vf->aq_resp;
417         args.out_size = IAVF_AQ_BUF_SZ;
418
419         err = iavf_execute_vf_cmd(adapter, &args);
420         if (err) {
421                 PMD_INIT_LOG(ERR, "Fail to execute command of OP_VERSION");
422                 return err;
423         }
424
425         pver = (struct virtchnl_version_info *)args.out_buffer;
426         vf->virtchnl_version = *pver;
427
428         if (vf->virtchnl_version.major < VIRTCHNL_VERSION_MAJOR_START ||
429             (vf->virtchnl_version.major == VIRTCHNL_VERSION_MAJOR_START &&
430              vf->virtchnl_version.minor < VIRTCHNL_VERSION_MINOR_START)) {
431                 PMD_INIT_LOG(ERR, "VIRTCHNL API version should not be lower"
432                              " than (%u.%u) to support Adapative VF",
433                              VIRTCHNL_VERSION_MAJOR_START,
434                              VIRTCHNL_VERSION_MAJOR_START);
435                 return -1;
436         } else if (vf->virtchnl_version.major > VIRTCHNL_VERSION_MAJOR ||
437                    (vf->virtchnl_version.major == VIRTCHNL_VERSION_MAJOR &&
438                     vf->virtchnl_version.minor > VIRTCHNL_VERSION_MINOR)) {
439                 PMD_INIT_LOG(ERR, "PF/VF API version mismatch:(%u.%u)-(%u.%u)",
440                              vf->virtchnl_version.major,
441                              vf->virtchnl_version.minor,
442                              VIRTCHNL_VERSION_MAJOR,
443                              VIRTCHNL_VERSION_MINOR);
444                 return -1;
445         }
446
447         PMD_DRV_LOG(DEBUG, "Peer is supported PF host");
448         return 0;
449 }
450
451 int
452 iavf_get_vf_resource(struct iavf_adapter *adapter)
453 {
454         struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
455         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
456         struct iavf_cmd_info args;
457         uint32_t caps, len;
458         int err, i;
459
460         args.ops = VIRTCHNL_OP_GET_VF_RESOURCES;
461         args.out_buffer = vf->aq_resp;
462         args.out_size = IAVF_AQ_BUF_SZ;
463
464         caps = IAVF_BASIC_OFFLOAD_CAPS | VIRTCHNL_VF_CAP_ADV_LINK_SPEED |
465                 VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC |
466                 VIRTCHNL_VF_OFFLOAD_FDIR_PF |
467                 VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF |
468                 VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
469                 VIRTCHNL_VF_OFFLOAD_CRC |
470                 VIRTCHNL_VF_OFFLOAD_VLAN_V2 |
471                 VIRTCHNL_VF_LARGE_NUM_QPAIRS |
472                 VIRTCHNL_VF_OFFLOAD_QOS;
473
474         args.in_args = (uint8_t *)&caps;
475         args.in_args_size = sizeof(caps);
476
477         err = iavf_execute_vf_cmd(adapter, &args);
478
479         if (err) {
480                 PMD_DRV_LOG(ERR,
481                             "Failed to execute command of OP_GET_VF_RESOURCE");
482                 return -1;
483         }
484
485         len =  sizeof(struct virtchnl_vf_resource) +
486                       IAVF_MAX_VF_VSI * sizeof(struct virtchnl_vsi_resource);
487
488         rte_memcpy(vf->vf_res, args.out_buffer,
489                    RTE_MIN(args.out_size, len));
490         /* parse  VF config message back from PF*/
491         iavf_vf_parse_hw_config(hw, vf->vf_res);
492         for (i = 0; i < vf->vf_res->num_vsis; i++) {
493                 if (vf->vf_res->vsi_res[i].vsi_type == VIRTCHNL_VSI_SRIOV)
494                         vf->vsi_res = &vf->vf_res->vsi_res[i];
495         }
496
497         if (!vf->vsi_res) {
498                 PMD_INIT_LOG(ERR, "no LAN VSI found");
499                 return -1;
500         }
501
502         vf->vsi.vsi_id = vf->vsi_res->vsi_id;
503         vf->vsi.nb_qps = vf->vsi_res->num_queue_pairs;
504         vf->vsi.adapter = adapter;
505
506         return 0;
507 }
508
509 int
510 iavf_get_supported_rxdid(struct iavf_adapter *adapter)
511 {
512         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
513         struct iavf_cmd_info args;
514         int ret;
515
516         args.ops = VIRTCHNL_OP_GET_SUPPORTED_RXDIDS;
517         args.in_args = NULL;
518         args.in_args_size = 0;
519         args.out_buffer = vf->aq_resp;
520         args.out_size = IAVF_AQ_BUF_SZ;
521
522         ret = iavf_execute_vf_cmd(adapter, &args);
523         if (ret) {
524                 PMD_DRV_LOG(ERR,
525                             "Failed to execute command of OP_GET_SUPPORTED_RXDIDS");
526                 return ret;
527         }
528
529         vf->supported_rxdid =
530                 ((struct virtchnl_supported_rxdids *)args.out_buffer)->supported_rxdids;
531
532         return 0;
533 }
534
535 int
536 iavf_config_vlan_strip_v2(struct iavf_adapter *adapter, bool enable)
537 {
538         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
539         struct virtchnl_vlan_supported_caps *stripping_caps;
540         struct virtchnl_vlan_setting vlan_strip;
541         struct iavf_cmd_info args;
542         uint32_t *ethertype;
543         int ret;
544
545         stripping_caps = &vf->vlan_v2_caps.offloads.stripping_support;
546
547         if ((stripping_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
548             (stripping_caps->outer & VIRTCHNL_VLAN_TOGGLE))
549                 ethertype = &vlan_strip.outer_ethertype_setting;
550         else if ((stripping_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
551                  (stripping_caps->inner & VIRTCHNL_VLAN_TOGGLE))
552                 ethertype = &vlan_strip.inner_ethertype_setting;
553         else
554                 return -ENOTSUP;
555
556         memset(&vlan_strip, 0, sizeof(vlan_strip));
557         vlan_strip.vport_id = vf->vsi_res->vsi_id;
558         *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
559
560         args.ops = enable ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 :
561                             VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2;
562         args.in_args = (uint8_t *)&vlan_strip;
563         args.in_args_size = sizeof(vlan_strip);
564         args.out_buffer = vf->aq_resp;
565         args.out_size = IAVF_AQ_BUF_SZ;
566         ret = iavf_execute_vf_cmd(adapter, &args);
567         if (ret)
568                 PMD_DRV_LOG(ERR, "fail to execute command %s",
569                             enable ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" :
570                                      "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2");
571
572         return ret;
573 }
574
575 int
576 iavf_config_vlan_insert_v2(struct iavf_adapter *adapter, bool enable)
577 {
578         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
579         struct virtchnl_vlan_supported_caps *insertion_caps;
580         struct virtchnl_vlan_setting vlan_insert;
581         struct iavf_cmd_info args;
582         uint32_t *ethertype;
583         int ret;
584
585         insertion_caps = &vf->vlan_v2_caps.offloads.insertion_support;
586
587         if ((insertion_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
588             (insertion_caps->outer & VIRTCHNL_VLAN_TOGGLE))
589                 ethertype = &vlan_insert.outer_ethertype_setting;
590         else if ((insertion_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
591                  (insertion_caps->inner & VIRTCHNL_VLAN_TOGGLE))
592                 ethertype = &vlan_insert.inner_ethertype_setting;
593         else
594                 return -ENOTSUP;
595
596         memset(&vlan_insert, 0, sizeof(vlan_insert));
597         vlan_insert.vport_id = vf->vsi_res->vsi_id;
598         *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
599
600         args.ops = enable ? VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 :
601                             VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2;
602         args.in_args = (uint8_t *)&vlan_insert;
603         args.in_args_size = sizeof(vlan_insert);
604         args.out_buffer = vf->aq_resp;
605         args.out_size = IAVF_AQ_BUF_SZ;
606         ret = iavf_execute_vf_cmd(adapter, &args);
607         if (ret)
608                 PMD_DRV_LOG(ERR, "fail to execute command %s",
609                             enable ? "VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2" :
610                                      "VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2");
611
612         return ret;
613 }
614
615 int
616 iavf_add_del_vlan_v2(struct iavf_adapter *adapter, uint16_t vlanid, bool add)
617 {
618         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
619         struct virtchnl_vlan_supported_caps *supported_caps;
620         struct virtchnl_vlan_filter_list_v2 vlan_filter;
621         struct virtchnl_vlan *vlan_setting;
622         struct iavf_cmd_info args;
623         uint32_t filtering_caps;
624         int err;
625
626         supported_caps = &vf->vlan_v2_caps.filtering.filtering_support;
627         if (supported_caps->outer) {
628                 filtering_caps = supported_caps->outer;
629                 vlan_setting = &vlan_filter.filters[0].outer;
630         } else {
631                 filtering_caps = supported_caps->inner;
632                 vlan_setting = &vlan_filter.filters[0].inner;
633         }
634
635         if (!(filtering_caps & VIRTCHNL_VLAN_ETHERTYPE_8100))
636                 return -ENOTSUP;
637
638         memset(&vlan_filter, 0, sizeof(vlan_filter));
639         vlan_filter.vport_id = vf->vsi_res->vsi_id;
640         vlan_filter.num_elements = 1;
641         vlan_setting->tpid = RTE_ETHER_TYPE_VLAN;
642         vlan_setting->tci = vlanid;
643
644         args.ops = add ? VIRTCHNL_OP_ADD_VLAN_V2 : VIRTCHNL_OP_DEL_VLAN_V2;
645         args.in_args = (uint8_t *)&vlan_filter;
646         args.in_args_size = sizeof(vlan_filter);
647         args.out_buffer = vf->aq_resp;
648         args.out_size = IAVF_AQ_BUF_SZ;
649         err = iavf_execute_vf_cmd(adapter, &args);
650         if (err)
651                 PMD_DRV_LOG(ERR, "fail to execute command %s",
652                             add ? "OP_ADD_VLAN_V2" :  "OP_DEL_VLAN_V2");
653
654         return err;
655 }
656
657 int
658 iavf_get_vlan_offload_caps_v2(struct iavf_adapter *adapter)
659 {
660         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
661         struct iavf_cmd_info args;
662         int ret;
663
664         args.ops = VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS;
665         args.in_args = NULL;
666         args.in_args_size = 0;
667         args.out_buffer = vf->aq_resp;
668         args.out_size = IAVF_AQ_BUF_SZ;
669
670         ret = iavf_execute_vf_cmd(adapter, &args);
671         if (ret) {
672                 PMD_DRV_LOG(ERR,
673                             "Failed to execute command of VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS");
674                 return ret;
675         }
676
677         rte_memcpy(&vf->vlan_v2_caps, vf->aq_resp, sizeof(vf->vlan_v2_caps));
678
679         return 0;
680 }
681
682 int
683 iavf_enable_queues(struct iavf_adapter *adapter)
684 {
685         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
686         struct virtchnl_queue_select queue_select;
687         struct iavf_cmd_info args;
688         int err;
689
690         memset(&queue_select, 0, sizeof(queue_select));
691         queue_select.vsi_id = vf->vsi_res->vsi_id;
692
693         queue_select.rx_queues = BIT(adapter->eth_dev->data->nb_rx_queues) - 1;
694         queue_select.tx_queues = BIT(adapter->eth_dev->data->nb_tx_queues) - 1;
695
696         args.ops = VIRTCHNL_OP_ENABLE_QUEUES;
697         args.in_args = (u8 *)&queue_select;
698         args.in_args_size = sizeof(queue_select);
699         args.out_buffer = vf->aq_resp;
700         args.out_size = IAVF_AQ_BUF_SZ;
701         err = iavf_execute_vf_cmd(adapter, &args);
702         if (err) {
703                 PMD_DRV_LOG(ERR,
704                             "Failed to execute command of OP_ENABLE_QUEUES");
705                 return err;
706         }
707         return 0;
708 }
709
710 int
711 iavf_disable_queues(struct iavf_adapter *adapter)
712 {
713         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
714         struct virtchnl_queue_select queue_select;
715         struct iavf_cmd_info args;
716         int err;
717
718         memset(&queue_select, 0, sizeof(queue_select));
719         queue_select.vsi_id = vf->vsi_res->vsi_id;
720
721         queue_select.rx_queues = BIT(adapter->eth_dev->data->nb_rx_queues) - 1;
722         queue_select.tx_queues = BIT(adapter->eth_dev->data->nb_tx_queues) - 1;
723
724         args.ops = VIRTCHNL_OP_DISABLE_QUEUES;
725         args.in_args = (u8 *)&queue_select;
726         args.in_args_size = sizeof(queue_select);
727         args.out_buffer = vf->aq_resp;
728         args.out_size = IAVF_AQ_BUF_SZ;
729         err = iavf_execute_vf_cmd(adapter, &args);
730         if (err) {
731                 PMD_DRV_LOG(ERR,
732                             "Failed to execute command of OP_DISABLE_QUEUES");
733                 return err;
734         }
735         return 0;
736 }
737
738 int
739 iavf_switch_queue(struct iavf_adapter *adapter, uint16_t qid,
740                  bool rx, bool on)
741 {
742         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
743         struct virtchnl_queue_select queue_select;
744         struct iavf_cmd_info args;
745         int err;
746
747         memset(&queue_select, 0, sizeof(queue_select));
748         queue_select.vsi_id = vf->vsi_res->vsi_id;
749         if (rx)
750                 queue_select.rx_queues |= 1 << qid;
751         else
752                 queue_select.tx_queues |= 1 << qid;
753
754         if (on)
755                 args.ops = VIRTCHNL_OP_ENABLE_QUEUES;
756         else
757                 args.ops = VIRTCHNL_OP_DISABLE_QUEUES;
758         args.in_args = (u8 *)&queue_select;
759         args.in_args_size = sizeof(queue_select);
760         args.out_buffer = vf->aq_resp;
761         args.out_size = IAVF_AQ_BUF_SZ;
762         err = iavf_execute_vf_cmd(adapter, &args);
763         if (err)
764                 PMD_DRV_LOG(ERR, "Failed to execute command of %s",
765                             on ? "OP_ENABLE_QUEUES" : "OP_DISABLE_QUEUES");
766         return err;
767 }
768
769 int
770 iavf_enable_queues_lv(struct iavf_adapter *adapter)
771 {
772         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
773         struct virtchnl_del_ena_dis_queues *queue_select;
774         struct virtchnl_queue_chunk *queue_chunk;
775         struct iavf_cmd_info args;
776         int err, len;
777
778         len = sizeof(struct virtchnl_del_ena_dis_queues) +
779                   sizeof(struct virtchnl_queue_chunk) *
780                   (IAVF_RXTX_QUEUE_CHUNKS_NUM - 1);
781         queue_select = rte_zmalloc("queue_select", len, 0);
782         if (!queue_select)
783                 return -ENOMEM;
784
785         queue_chunk = queue_select->chunks.chunks;
786         queue_select->chunks.num_chunks = IAVF_RXTX_QUEUE_CHUNKS_NUM;
787         queue_select->vport_id = vf->vsi_res->vsi_id;
788
789         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].type = VIRTCHNL_QUEUE_TYPE_TX;
790         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].start_queue_id = 0;
791         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].num_queues =
792                 adapter->eth_dev->data->nb_tx_queues;
793
794         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].type = VIRTCHNL_QUEUE_TYPE_RX;
795         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].start_queue_id = 0;
796         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].num_queues =
797                 adapter->eth_dev->data->nb_rx_queues;
798
799         args.ops = VIRTCHNL_OP_ENABLE_QUEUES_V2;
800         args.in_args = (u8 *)queue_select;
801         args.in_args_size = len;
802         args.out_buffer = vf->aq_resp;
803         args.out_size = IAVF_AQ_BUF_SZ;
804         err = iavf_execute_vf_cmd(adapter, &args);
805         if (err)
806                 PMD_DRV_LOG(ERR,
807                             "Failed to execute command of OP_ENABLE_QUEUES_V2");
808
809         rte_free(queue_select);
810         return err;
811 }
812
813 int
814 iavf_disable_queues_lv(struct iavf_adapter *adapter)
815 {
816         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
817         struct virtchnl_del_ena_dis_queues *queue_select;
818         struct virtchnl_queue_chunk *queue_chunk;
819         struct iavf_cmd_info args;
820         int err, len;
821
822         len = sizeof(struct virtchnl_del_ena_dis_queues) +
823                   sizeof(struct virtchnl_queue_chunk) *
824                   (IAVF_RXTX_QUEUE_CHUNKS_NUM - 1);
825         queue_select = rte_zmalloc("queue_select", len, 0);
826         if (!queue_select)
827                 return -ENOMEM;
828
829         queue_chunk = queue_select->chunks.chunks;
830         queue_select->chunks.num_chunks = IAVF_RXTX_QUEUE_CHUNKS_NUM;
831         queue_select->vport_id = vf->vsi_res->vsi_id;
832
833         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].type = VIRTCHNL_QUEUE_TYPE_TX;
834         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].start_queue_id = 0;
835         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].num_queues =
836                 adapter->eth_dev->data->nb_tx_queues;
837
838         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].type = VIRTCHNL_QUEUE_TYPE_RX;
839         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].start_queue_id = 0;
840         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].num_queues =
841                 adapter->eth_dev->data->nb_rx_queues;
842
843         args.ops = VIRTCHNL_OP_DISABLE_QUEUES_V2;
844         args.in_args = (u8 *)queue_select;
845         args.in_args_size = len;
846         args.out_buffer = vf->aq_resp;
847         args.out_size = IAVF_AQ_BUF_SZ;
848         err = iavf_execute_vf_cmd(adapter, &args);
849         if (err)
850                 PMD_DRV_LOG(ERR,
851                             "Failed to execute command of OP_DISABLE_QUEUES_V2");
852
853         rte_free(queue_select);
854         return err;
855 }
856
857 int
858 iavf_switch_queue_lv(struct iavf_adapter *adapter, uint16_t qid,
859                  bool rx, bool on)
860 {
861         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
862         struct virtchnl_del_ena_dis_queues *queue_select;
863         struct virtchnl_queue_chunk *queue_chunk;
864         struct iavf_cmd_info args;
865         int err, len;
866
867         len = sizeof(struct virtchnl_del_ena_dis_queues);
868         queue_select = rte_zmalloc("queue_select", len, 0);
869         if (!queue_select)
870                 return -ENOMEM;
871
872         queue_chunk = queue_select->chunks.chunks;
873         queue_select->chunks.num_chunks = 1;
874         queue_select->vport_id = vf->vsi_res->vsi_id;
875
876         if (rx) {
877                 queue_chunk->type = VIRTCHNL_QUEUE_TYPE_RX;
878                 queue_chunk->start_queue_id = qid;
879                 queue_chunk->num_queues = 1;
880         } else {
881                 queue_chunk->type = VIRTCHNL_QUEUE_TYPE_TX;
882                 queue_chunk->start_queue_id = qid;
883                 queue_chunk->num_queues = 1;
884         }
885
886         if (on)
887                 args.ops = VIRTCHNL_OP_ENABLE_QUEUES_V2;
888         else
889                 args.ops = VIRTCHNL_OP_DISABLE_QUEUES_V2;
890         args.in_args = (u8 *)queue_select;
891         args.in_args_size = len;
892         args.out_buffer = vf->aq_resp;
893         args.out_size = IAVF_AQ_BUF_SZ;
894         err = iavf_execute_vf_cmd(adapter, &args);
895         if (err)
896                 PMD_DRV_LOG(ERR, "Failed to execute command of %s",
897                             on ? "OP_ENABLE_QUEUES_V2" : "OP_DISABLE_QUEUES_V2");
898
899         rte_free(queue_select);
900         return err;
901 }
902
903 int
904 iavf_configure_rss_lut(struct iavf_adapter *adapter)
905 {
906         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
907         struct virtchnl_rss_lut *rss_lut;
908         struct iavf_cmd_info args;
909         int len, err = 0;
910
911         len = sizeof(*rss_lut) + vf->vf_res->rss_lut_size - 1;
912         rss_lut = rte_zmalloc("rss_lut", len, 0);
913         if (!rss_lut)
914                 return -ENOMEM;
915
916         rss_lut->vsi_id = vf->vsi_res->vsi_id;
917         rss_lut->lut_entries = vf->vf_res->rss_lut_size;
918         rte_memcpy(rss_lut->lut, vf->rss_lut, vf->vf_res->rss_lut_size);
919
920         args.ops = VIRTCHNL_OP_CONFIG_RSS_LUT;
921         args.in_args = (u8 *)rss_lut;
922         args.in_args_size = len;
923         args.out_buffer = vf->aq_resp;
924         args.out_size = IAVF_AQ_BUF_SZ;
925
926         err = iavf_execute_vf_cmd(adapter, &args);
927         if (err)
928                 PMD_DRV_LOG(ERR,
929                             "Failed to execute command of OP_CONFIG_RSS_LUT");
930
931         rte_free(rss_lut);
932         return err;
933 }
934
935 int
936 iavf_configure_rss_key(struct iavf_adapter *adapter)
937 {
938         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
939         struct virtchnl_rss_key *rss_key;
940         struct iavf_cmd_info args;
941         int len, err = 0;
942
943         len = sizeof(*rss_key) + vf->vf_res->rss_key_size - 1;
944         rss_key = rte_zmalloc("rss_key", len, 0);
945         if (!rss_key)
946                 return -ENOMEM;
947
948         rss_key->vsi_id = vf->vsi_res->vsi_id;
949         rss_key->key_len = vf->vf_res->rss_key_size;
950         rte_memcpy(rss_key->key, vf->rss_key, vf->vf_res->rss_key_size);
951
952         args.ops = VIRTCHNL_OP_CONFIG_RSS_KEY;
953         args.in_args = (u8 *)rss_key;
954         args.in_args_size = len;
955         args.out_buffer = vf->aq_resp;
956         args.out_size = IAVF_AQ_BUF_SZ;
957
958         err = iavf_execute_vf_cmd(adapter, &args);
959         if (err)
960                 PMD_DRV_LOG(ERR,
961                             "Failed to execute command of OP_CONFIG_RSS_KEY");
962
963         rte_free(rss_key);
964         return err;
965 }
966
967 int
968 iavf_configure_queues(struct iavf_adapter *adapter,
969                 uint16_t num_queue_pairs, uint16_t index)
970 {
971         struct iavf_rx_queue **rxq =
972                 (struct iavf_rx_queue **)adapter->eth_dev->data->rx_queues;
973         struct iavf_tx_queue **txq =
974                 (struct iavf_tx_queue **)adapter->eth_dev->data->tx_queues;
975         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
976         struct virtchnl_vsi_queue_config_info *vc_config;
977         struct virtchnl_queue_pair_info *vc_qp;
978         struct iavf_cmd_info args;
979         uint16_t i, size;
980         int err;
981
982         size = sizeof(*vc_config) +
983                sizeof(vc_config->qpair[0]) * num_queue_pairs;
984         vc_config = rte_zmalloc("cfg_queue", size, 0);
985         if (!vc_config)
986                 return -ENOMEM;
987
988         vc_config->vsi_id = vf->vsi_res->vsi_id;
989         vc_config->num_queue_pairs = num_queue_pairs;
990
991         for (i = index, vc_qp = vc_config->qpair;
992                  i < index + num_queue_pairs;
993              i++, vc_qp++) {
994                 vc_qp->txq.vsi_id = vf->vsi_res->vsi_id;
995                 vc_qp->txq.queue_id = i;
996
997                 /* Virtchnnl configure tx queues by pairs */
998                 if (i < adapter->eth_dev->data->nb_tx_queues) {
999                         vc_qp->txq.ring_len = txq[i]->nb_tx_desc;
1000                         vc_qp->txq.dma_ring_addr = txq[i]->tx_ring_phys_addr;
1001                 }
1002
1003                 vc_qp->rxq.vsi_id = vf->vsi_res->vsi_id;
1004                 vc_qp->rxq.queue_id = i;
1005                 vc_qp->rxq.max_pkt_size = vf->max_pkt_len;
1006
1007                 if (i >= adapter->eth_dev->data->nb_rx_queues)
1008                         continue;
1009
1010                 /* Virtchnnl configure rx queues by pairs */
1011                 vc_qp->rxq.ring_len = rxq[i]->nb_rx_desc;
1012                 vc_qp->rxq.dma_ring_addr = rxq[i]->rx_ring_phys_addr;
1013                 vc_qp->rxq.databuffer_size = rxq[i]->rx_buf_len;
1014                 vc_qp->rxq.crc_disable = rxq[i]->crc_len != 0 ? 1 : 0;
1015 #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
1016                 if (vf->vf_res->vf_cap_flags &
1017                     VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC &&
1018                     vf->supported_rxdid & BIT(rxq[i]->rxdid)) {
1019                         vc_qp->rxq.rxdid = rxq[i]->rxdid;
1020                         PMD_DRV_LOG(NOTICE, "request RXDID[%d] in Queue[%d]",
1021                                     vc_qp->rxq.rxdid, i);
1022                 } else {
1023                         PMD_DRV_LOG(NOTICE, "RXDID[%d] is not supported, "
1024                                     "request default RXDID[%d] in Queue[%d]",
1025                                     rxq[i]->rxdid, IAVF_RXDID_LEGACY_1, i);
1026                         vc_qp->rxq.rxdid = IAVF_RXDID_LEGACY_1;
1027                 }
1028 #else
1029                 if (vf->vf_res->vf_cap_flags &
1030                         VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC &&
1031                         vf->supported_rxdid & BIT(IAVF_RXDID_LEGACY_0)) {
1032                         vc_qp->rxq.rxdid = IAVF_RXDID_LEGACY_0;
1033                         PMD_DRV_LOG(NOTICE, "request RXDID[%d] in Queue[%d]",
1034                                     vc_qp->rxq.rxdid, i);
1035                 } else {
1036                         PMD_DRV_LOG(ERR, "RXDID[%d] is not supported",
1037                                     IAVF_RXDID_LEGACY_0);
1038                         return -1;
1039                 }
1040 #endif
1041         }
1042
1043         memset(&args, 0, sizeof(args));
1044         args.ops = VIRTCHNL_OP_CONFIG_VSI_QUEUES;
1045         args.in_args = (uint8_t *)vc_config;
1046         args.in_args_size = size;
1047         args.out_buffer = vf->aq_resp;
1048         args.out_size = IAVF_AQ_BUF_SZ;
1049
1050         err = iavf_execute_vf_cmd(adapter, &args);
1051         if (err)
1052                 PMD_DRV_LOG(ERR, "Failed to execute command of"
1053                             " VIRTCHNL_OP_CONFIG_VSI_QUEUES");
1054
1055         rte_free(vc_config);
1056         return err;
1057 }
1058
1059 int
1060 iavf_config_irq_map(struct iavf_adapter *adapter)
1061 {
1062         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1063         struct virtchnl_irq_map_info *map_info;
1064         struct virtchnl_vector_map *vecmap;
1065         struct iavf_cmd_info args;
1066         int len, i, err;
1067
1068         len = sizeof(struct virtchnl_irq_map_info) +
1069               sizeof(struct virtchnl_vector_map) * vf->nb_msix;
1070
1071         map_info = rte_zmalloc("map_info", len, 0);
1072         if (!map_info)
1073                 return -ENOMEM;
1074
1075         map_info->num_vectors = vf->nb_msix;
1076         for (i = 0; i < adapter->eth_dev->data->nb_rx_queues; i++) {
1077                 vecmap =
1078                     &map_info->vecmap[vf->qv_map[i].vector_id - vf->msix_base];
1079                 vecmap->vsi_id = vf->vsi_res->vsi_id;
1080                 vecmap->rxitr_idx = IAVF_ITR_INDEX_DEFAULT;
1081                 vecmap->vector_id = vf->qv_map[i].vector_id;
1082                 vecmap->txq_map = 0;
1083                 vecmap->rxq_map |= 1 << vf->qv_map[i].queue_id;
1084         }
1085
1086         args.ops = VIRTCHNL_OP_CONFIG_IRQ_MAP;
1087         args.in_args = (u8 *)map_info;
1088         args.in_args_size = len;
1089         args.out_buffer = vf->aq_resp;
1090         args.out_size = IAVF_AQ_BUF_SZ;
1091         err = iavf_execute_vf_cmd(adapter, &args);
1092         if (err)
1093                 PMD_DRV_LOG(ERR, "fail to execute command OP_CONFIG_IRQ_MAP");
1094
1095         rte_free(map_info);
1096         return err;
1097 }
1098
1099 int
1100 iavf_config_irq_map_lv(struct iavf_adapter *adapter, uint16_t num,
1101                 uint16_t index)
1102 {
1103         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1104         struct virtchnl_queue_vector_maps *map_info;
1105         struct virtchnl_queue_vector *qv_maps;
1106         struct iavf_cmd_info args;
1107         int len, i, err;
1108         int count = 0;
1109
1110         len = sizeof(struct virtchnl_queue_vector_maps) +
1111               sizeof(struct virtchnl_queue_vector) * (num - 1);
1112
1113         map_info = rte_zmalloc("map_info", len, 0);
1114         if (!map_info)
1115                 return -ENOMEM;
1116
1117         map_info->vport_id = vf->vsi_res->vsi_id;
1118         map_info->num_qv_maps = num;
1119         for (i = index; i < index + map_info->num_qv_maps; i++) {
1120                 qv_maps = &map_info->qv_maps[count++];
1121                 qv_maps->itr_idx = VIRTCHNL_ITR_IDX_0;
1122                 qv_maps->queue_type = VIRTCHNL_QUEUE_TYPE_RX;
1123                 qv_maps->queue_id = vf->qv_map[i].queue_id;
1124                 qv_maps->vector_id = vf->qv_map[i].vector_id;
1125         }
1126
1127         args.ops = VIRTCHNL_OP_MAP_QUEUE_VECTOR;
1128         args.in_args = (u8 *)map_info;
1129         args.in_args_size = len;
1130         args.out_buffer = vf->aq_resp;
1131         args.out_size = IAVF_AQ_BUF_SZ;
1132         err = iavf_execute_vf_cmd(adapter, &args);
1133         if (err)
1134                 PMD_DRV_LOG(ERR, "fail to execute command OP_MAP_QUEUE_VECTOR");
1135
1136         rte_free(map_info);
1137         return err;
1138 }
1139
1140 void
1141 iavf_add_del_all_mac_addr(struct iavf_adapter *adapter, bool add)
1142 {
1143         struct virtchnl_ether_addr_list *list;
1144         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1145         struct rte_ether_addr *addr;
1146         struct iavf_cmd_info args;
1147         int len, err, i, j;
1148         int next_begin = 0;
1149         int begin = 0;
1150
1151         do {
1152                 j = 0;
1153                 len = sizeof(struct virtchnl_ether_addr_list);
1154                 for (i = begin; i < IAVF_NUM_MACADDR_MAX; i++, next_begin++) {
1155                         addr = &adapter->eth_dev->data->mac_addrs[i];
1156                         if (rte_is_zero_ether_addr(addr))
1157                                 continue;
1158                         len += sizeof(struct virtchnl_ether_addr);
1159                         if (len >= IAVF_AQ_BUF_SZ) {
1160                                 next_begin = i + 1;
1161                                 break;
1162                         }
1163                 }
1164
1165                 list = rte_zmalloc("iavf_del_mac_buffer", len, 0);
1166                 if (!list) {
1167                         PMD_DRV_LOG(ERR, "fail to allocate memory");
1168                         return;
1169                 }
1170
1171                 for (i = begin; i < next_begin; i++) {
1172                         addr = &adapter->eth_dev->data->mac_addrs[i];
1173                         if (rte_is_zero_ether_addr(addr))
1174                                 continue;
1175                         rte_memcpy(list->list[j].addr, addr->addr_bytes,
1176                                    sizeof(addr->addr_bytes));
1177                         list->list[j].type = (j == 0 ?
1178                                               VIRTCHNL_ETHER_ADDR_PRIMARY :
1179                                               VIRTCHNL_ETHER_ADDR_EXTRA);
1180                         PMD_DRV_LOG(DEBUG, "add/rm mac:" RTE_ETHER_ADDR_PRT_FMT,
1181                                     RTE_ETHER_ADDR_BYTES(addr));
1182                         j++;
1183                 }
1184                 list->vsi_id = vf->vsi_res->vsi_id;
1185                 list->num_elements = j;
1186                 args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR :
1187                            VIRTCHNL_OP_DEL_ETH_ADDR;
1188                 args.in_args = (uint8_t *)list;
1189                 args.in_args_size = len;
1190                 args.out_buffer = vf->aq_resp;
1191                 args.out_size = IAVF_AQ_BUF_SZ;
1192                 err = iavf_execute_vf_cmd(adapter, &args);
1193                 if (err)
1194                         PMD_DRV_LOG(ERR, "fail to execute command %s",
1195                                     add ? "OP_ADD_ETHER_ADDRESS" :
1196                                     "OP_DEL_ETHER_ADDRESS");
1197                 rte_free(list);
1198                 begin = next_begin;
1199         } while (begin < IAVF_NUM_MACADDR_MAX);
1200 }
1201
1202 int
1203 iavf_query_stats(struct iavf_adapter *adapter,
1204                 struct virtchnl_eth_stats **pstats)
1205 {
1206         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1207         struct virtchnl_queue_select q_stats;
1208         struct iavf_cmd_info args;
1209         int err;
1210
1211         memset(&q_stats, 0, sizeof(q_stats));
1212         q_stats.vsi_id = vf->vsi_res->vsi_id;
1213         args.ops = VIRTCHNL_OP_GET_STATS;
1214         args.in_args = (uint8_t *)&q_stats;
1215         args.in_args_size = sizeof(q_stats);
1216         args.out_buffer = vf->aq_resp;
1217         args.out_size = IAVF_AQ_BUF_SZ;
1218
1219         err = iavf_execute_vf_cmd(adapter, &args);
1220         if (err) {
1221                 PMD_DRV_LOG(ERR, "fail to execute command OP_GET_STATS");
1222                 *pstats = NULL;
1223                 return err;
1224         }
1225         *pstats = (struct virtchnl_eth_stats *)args.out_buffer;
1226         return 0;
1227 }
1228
1229 int
1230 iavf_config_promisc(struct iavf_adapter *adapter,
1231                    bool enable_unicast,
1232                    bool enable_multicast)
1233 {
1234         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1235         struct virtchnl_promisc_info promisc;
1236         struct iavf_cmd_info args;
1237         int err;
1238
1239         promisc.flags = 0;
1240         promisc.vsi_id = vf->vsi_res->vsi_id;
1241
1242         if (enable_unicast)
1243                 promisc.flags |= FLAG_VF_UNICAST_PROMISC;
1244
1245         if (enable_multicast)
1246                 promisc.flags |= FLAG_VF_MULTICAST_PROMISC;
1247
1248         args.ops = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE;
1249         args.in_args = (uint8_t *)&promisc;
1250         args.in_args_size = sizeof(promisc);
1251         args.out_buffer = vf->aq_resp;
1252         args.out_size = IAVF_AQ_BUF_SZ;
1253
1254         err = iavf_execute_vf_cmd(adapter, &args);
1255
1256         if (err) {
1257                 PMD_DRV_LOG(ERR,
1258                             "fail to execute command CONFIG_PROMISCUOUS_MODE");
1259
1260                 if (err == -ENOTSUP)
1261                         return err;
1262
1263                 return -EAGAIN;
1264         }
1265
1266         vf->promisc_unicast_enabled = enable_unicast;
1267         vf->promisc_multicast_enabled = enable_multicast;
1268         return 0;
1269 }
1270
1271 int
1272 iavf_add_del_eth_addr(struct iavf_adapter *adapter, struct rte_ether_addr *addr,
1273                      bool add, uint8_t type)
1274 {
1275         struct virtchnl_ether_addr_list *list;
1276         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1277         uint8_t cmd_buffer[sizeof(struct virtchnl_ether_addr_list) +
1278                            sizeof(struct virtchnl_ether_addr)];
1279         struct iavf_cmd_info args;
1280         int err;
1281
1282         list = (struct virtchnl_ether_addr_list *)cmd_buffer;
1283         list->vsi_id = vf->vsi_res->vsi_id;
1284         list->num_elements = 1;
1285         list->list[0].type = type;
1286         rte_memcpy(list->list[0].addr, addr->addr_bytes,
1287                    sizeof(addr->addr_bytes));
1288
1289         args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR;
1290         args.in_args = cmd_buffer;
1291         args.in_args_size = sizeof(cmd_buffer);
1292         args.out_buffer = vf->aq_resp;
1293         args.out_size = IAVF_AQ_BUF_SZ;
1294         err = iavf_execute_vf_cmd(adapter, &args);
1295         if (err)
1296                 PMD_DRV_LOG(ERR, "fail to execute command %s",
1297                             add ? "OP_ADD_ETH_ADDR" :  "OP_DEL_ETH_ADDR");
1298         return err;
1299 }
1300
1301 int
1302 iavf_add_del_vlan(struct iavf_adapter *adapter, uint16_t vlanid, bool add)
1303 {
1304         struct virtchnl_vlan_filter_list *vlan_list;
1305         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1306         uint8_t cmd_buffer[sizeof(struct virtchnl_vlan_filter_list) +
1307                                                         sizeof(uint16_t)];
1308         struct iavf_cmd_info args;
1309         int err;
1310
1311         vlan_list = (struct virtchnl_vlan_filter_list *)cmd_buffer;
1312         vlan_list->vsi_id = vf->vsi_res->vsi_id;
1313         vlan_list->num_elements = 1;
1314         vlan_list->vlan_id[0] = vlanid;
1315
1316         args.ops = add ? VIRTCHNL_OP_ADD_VLAN : VIRTCHNL_OP_DEL_VLAN;
1317         args.in_args = cmd_buffer;
1318         args.in_args_size = sizeof(cmd_buffer);
1319         args.out_buffer = vf->aq_resp;
1320         args.out_size = IAVF_AQ_BUF_SZ;
1321         err = iavf_execute_vf_cmd(adapter, &args);
1322         if (err)
1323                 PMD_DRV_LOG(ERR, "fail to execute command %s",
1324                             add ? "OP_ADD_VLAN" :  "OP_DEL_VLAN");
1325
1326         return err;
1327 }
1328
1329 int
1330 iavf_fdir_add(struct iavf_adapter *adapter,
1331         struct iavf_fdir_conf *filter)
1332 {
1333         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1334         struct virtchnl_fdir_add *fdir_ret;
1335
1336         struct iavf_cmd_info args;
1337         int err;
1338
1339         filter->add_fltr.vsi_id = vf->vsi_res->vsi_id;
1340         filter->add_fltr.validate_only = 0;
1341
1342         args.ops = VIRTCHNL_OP_ADD_FDIR_FILTER;
1343         args.in_args = (uint8_t *)(&filter->add_fltr);
1344         args.in_args_size = sizeof(*(&filter->add_fltr));
1345         args.out_buffer = vf->aq_resp;
1346         args.out_size = IAVF_AQ_BUF_SZ;
1347
1348         err = iavf_execute_vf_cmd(adapter, &args);
1349         if (err) {
1350                 PMD_DRV_LOG(ERR, "fail to execute command OP_ADD_FDIR_FILTER");
1351                 return err;
1352         }
1353
1354         fdir_ret = (struct virtchnl_fdir_add *)args.out_buffer;
1355         filter->flow_id = fdir_ret->flow_id;
1356
1357         if (fdir_ret->status == VIRTCHNL_FDIR_SUCCESS) {
1358                 PMD_DRV_LOG(INFO,
1359                         "Succeed in adding rule request by PF");
1360         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE) {
1361                 PMD_DRV_LOG(ERR,
1362                         "Failed to add rule request due to no hw resource");
1363                 return -1;
1364         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_EXIST) {
1365                 PMD_DRV_LOG(ERR,
1366                         "Failed to add rule request due to the rule is already existed");
1367                 return -1;
1368         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT) {
1369                 PMD_DRV_LOG(ERR,
1370                         "Failed to add rule request due to the rule is conflict with existing rule");
1371                 return -1;
1372         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_INVALID) {
1373                 PMD_DRV_LOG(ERR,
1374                         "Failed to add rule request due to the hw doesn't support");
1375                 return -1;
1376         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT) {
1377                 PMD_DRV_LOG(ERR,
1378                         "Failed to add rule request due to time out for programming");
1379                 return -1;
1380         } else {
1381                 PMD_DRV_LOG(ERR,
1382                         "Failed to add rule request due to other reasons");
1383                 return -1;
1384         }
1385
1386         return 0;
1387 };
1388
1389 int
1390 iavf_fdir_del(struct iavf_adapter *adapter,
1391         struct iavf_fdir_conf *filter)
1392 {
1393         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1394         struct virtchnl_fdir_del *fdir_ret;
1395
1396         struct iavf_cmd_info args;
1397         int err;
1398
1399         filter->del_fltr.vsi_id = vf->vsi_res->vsi_id;
1400         filter->del_fltr.flow_id = filter->flow_id;
1401
1402         args.ops = VIRTCHNL_OP_DEL_FDIR_FILTER;
1403         args.in_args = (uint8_t *)(&filter->del_fltr);
1404         args.in_args_size = sizeof(filter->del_fltr);
1405         args.out_buffer = vf->aq_resp;
1406         args.out_size = IAVF_AQ_BUF_SZ;
1407
1408         err = iavf_execute_vf_cmd(adapter, &args);
1409         if (err) {
1410                 PMD_DRV_LOG(ERR, "fail to execute command OP_DEL_FDIR_FILTER");
1411                 return err;
1412         }
1413
1414         fdir_ret = (struct virtchnl_fdir_del *)args.out_buffer;
1415
1416         if (fdir_ret->status == VIRTCHNL_FDIR_SUCCESS) {
1417                 PMD_DRV_LOG(INFO,
1418                         "Succeed in deleting rule request by PF");
1419         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST) {
1420                 PMD_DRV_LOG(ERR,
1421                         "Failed to delete rule request due to this rule doesn't exist");
1422                 return -1;
1423         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT) {
1424                 PMD_DRV_LOG(ERR,
1425                         "Failed to delete rule request due to time out for programming");
1426                 return -1;
1427         } else {
1428                 PMD_DRV_LOG(ERR,
1429                         "Failed to delete rule request due to other reasons");
1430                 return -1;
1431         }
1432
1433         return 0;
1434 };
1435
1436 int
1437 iavf_fdir_check(struct iavf_adapter *adapter,
1438                 struct iavf_fdir_conf *filter)
1439 {
1440         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1441         struct virtchnl_fdir_add *fdir_ret;
1442
1443         struct iavf_cmd_info args;
1444         int err;
1445
1446         filter->add_fltr.vsi_id = vf->vsi_res->vsi_id;
1447         filter->add_fltr.validate_only = 1;
1448
1449         args.ops = VIRTCHNL_OP_ADD_FDIR_FILTER;
1450         args.in_args = (uint8_t *)(&filter->add_fltr);
1451         args.in_args_size = sizeof(*(&filter->add_fltr));
1452         args.out_buffer = vf->aq_resp;
1453         args.out_size = IAVF_AQ_BUF_SZ;
1454
1455         err = iavf_execute_vf_cmd(adapter, &args);
1456         if (err) {
1457                 PMD_DRV_LOG(ERR, "fail to check flow direcotor rule");
1458                 return err;
1459         }
1460
1461         fdir_ret = (struct virtchnl_fdir_add *)args.out_buffer;
1462
1463         if (fdir_ret->status == VIRTCHNL_FDIR_SUCCESS) {
1464                 PMD_DRV_LOG(INFO,
1465                         "Succeed in checking rule request by PF");
1466         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_INVALID) {
1467                 PMD_DRV_LOG(ERR,
1468                         "Failed to check rule request due to parameters validation"
1469                         " or HW doesn't support");
1470                 return -1;
1471         } else {
1472                 PMD_DRV_LOG(ERR,
1473                         "Failed to check rule request due to other reasons");
1474                 return -1;
1475         }
1476
1477         return 0;
1478 }
1479
1480 int
1481 iavf_add_del_rss_cfg(struct iavf_adapter *adapter,
1482                      struct virtchnl_rss_cfg *rss_cfg, bool add)
1483 {
1484         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1485         struct iavf_cmd_info args;
1486         int err;
1487
1488         memset(&args, 0, sizeof(args));
1489         args.ops = add ? VIRTCHNL_OP_ADD_RSS_CFG :
1490                 VIRTCHNL_OP_DEL_RSS_CFG;
1491         args.in_args = (u8 *)rss_cfg;
1492         args.in_args_size = sizeof(*rss_cfg);
1493         args.out_buffer = vf->aq_resp;
1494         args.out_size = IAVF_AQ_BUF_SZ;
1495
1496         err = iavf_execute_vf_cmd(adapter, &args);
1497         if (err)
1498                 PMD_DRV_LOG(ERR,
1499                             "Failed to execute command of %s",
1500                             add ? "OP_ADD_RSS_CFG" :
1501                             "OP_DEL_RSS_INPUT_CFG");
1502
1503         return err;
1504 }
1505
1506 int
1507 iavf_get_hena_caps(struct iavf_adapter *adapter, uint64_t *caps)
1508 {
1509         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1510         struct iavf_cmd_info args;
1511         int err;
1512
1513         args.ops = VIRTCHNL_OP_GET_RSS_HENA_CAPS;
1514         args.in_args = NULL;
1515         args.in_args_size = 0;
1516         args.out_buffer = vf->aq_resp;
1517         args.out_size = IAVF_AQ_BUF_SZ;
1518
1519         err = iavf_execute_vf_cmd(adapter, &args);
1520         if (err) {
1521                 PMD_DRV_LOG(ERR,
1522                             "Failed to execute command of OP_GET_RSS_HENA_CAPS");
1523                 return err;
1524         }
1525
1526         *caps = ((struct virtchnl_rss_hena *)args.out_buffer)->hena;
1527         return 0;
1528 }
1529
1530 int
1531 iavf_set_hena(struct iavf_adapter *adapter, uint64_t hena)
1532 {
1533         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1534         struct virtchnl_rss_hena vrh;
1535         struct iavf_cmd_info args;
1536         int err;
1537
1538         vrh.hena = hena;
1539         args.ops = VIRTCHNL_OP_SET_RSS_HENA;
1540         args.in_args = (u8 *)&vrh;
1541         args.in_args_size = sizeof(vrh);
1542         args.out_buffer = vf->aq_resp;
1543         args.out_size = IAVF_AQ_BUF_SZ;
1544
1545         err = iavf_execute_vf_cmd(adapter, &args);
1546         if (err)
1547                 PMD_DRV_LOG(ERR,
1548                             "Failed to execute command of OP_SET_RSS_HENA");
1549
1550         return err;
1551 }
1552
1553 int
1554 iavf_get_qos_cap(struct iavf_adapter *adapter)
1555 {
1556         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1557         struct iavf_cmd_info args;
1558         uint32_t len;
1559         int err;
1560
1561         args.ops = VIRTCHNL_OP_GET_QOS_CAPS;
1562         args.in_args = NULL;
1563         args.in_args_size = 0;
1564         args.out_buffer = vf->aq_resp;
1565         args.out_size = IAVF_AQ_BUF_SZ;
1566         err = iavf_execute_vf_cmd(adapter, &args);
1567
1568         if (err) {
1569                 PMD_DRV_LOG(ERR,
1570                             "Failed to execute command of OP_GET_VF_RESOURCE");
1571                 return -1;
1572         }
1573
1574         len =  sizeof(struct virtchnl_qos_cap_list) +
1575                 IAVF_MAX_TRAFFIC_CLASS * sizeof(struct virtchnl_qos_cap_elem);
1576
1577         rte_memcpy(vf->qos_cap, args.out_buffer,
1578                    RTE_MIN(args.out_size, len));
1579
1580         return 0;
1581 }
1582
1583 int iavf_set_q_tc_map(struct rte_eth_dev *dev,
1584                 struct virtchnl_queue_tc_mapping *q_tc_mapping, uint16_t size)
1585 {
1586         struct iavf_adapter *adapter =
1587                         IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1588         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
1589         struct iavf_cmd_info args;
1590         int err;
1591
1592         memset(&args, 0, sizeof(args));
1593         args.ops = VIRTCHNL_OP_CONFIG_QUEUE_TC_MAP;
1594         args.in_args = (uint8_t *)q_tc_mapping;
1595         args.in_args_size = size;
1596         args.out_buffer = vf->aq_resp;
1597         args.out_size = IAVF_AQ_BUF_SZ;
1598
1599         err = iavf_execute_vf_cmd(adapter, &args);
1600         if (err)
1601                 PMD_DRV_LOG(ERR, "Failed to execute command of"
1602                             " VIRTCHNL_OP_CONFIG_TC_MAP");
1603         return err;
1604 }
1605
1606 int
1607 iavf_add_del_mc_addr_list(struct iavf_adapter *adapter,
1608                         struct rte_ether_addr *mc_addrs,
1609                         uint32_t mc_addrs_num, bool add)
1610 {
1611         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1612         uint8_t cmd_buffer[sizeof(struct virtchnl_ether_addr_list) +
1613                 (IAVF_NUM_MACADDR_MAX * sizeof(struct virtchnl_ether_addr))];
1614         struct virtchnl_ether_addr_list *list;
1615         struct iavf_cmd_info args;
1616         uint32_t i;
1617         int err;
1618
1619         if (mc_addrs == NULL || mc_addrs_num == 0)
1620                 return 0;
1621
1622         list = (struct virtchnl_ether_addr_list *)cmd_buffer;
1623         list->vsi_id = vf->vsi_res->vsi_id;
1624         list->num_elements = mc_addrs_num;
1625
1626         for (i = 0; i < mc_addrs_num; i++) {
1627                 if (!IAVF_IS_MULTICAST(mc_addrs[i].addr_bytes)) {
1628                         PMD_DRV_LOG(ERR, "Invalid mac:" RTE_ETHER_ADDR_PRT_FMT,
1629                                     RTE_ETHER_ADDR_BYTES(&mc_addrs[i]));
1630                         return -EINVAL;
1631                 }
1632
1633                 memcpy(list->list[i].addr, mc_addrs[i].addr_bytes,
1634                         sizeof(list->list[i].addr));
1635                 list->list[i].type = VIRTCHNL_ETHER_ADDR_EXTRA;
1636         }
1637
1638         args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR;
1639         args.in_args = cmd_buffer;
1640         args.in_args_size = sizeof(struct virtchnl_ether_addr_list) +
1641                 i * sizeof(struct virtchnl_ether_addr);
1642         args.out_buffer = vf->aq_resp;
1643         args.out_size = IAVF_AQ_BUF_SZ;
1644         err = iavf_execute_vf_cmd(adapter, &args);
1645
1646         if (err) {
1647                 PMD_DRV_LOG(ERR, "fail to execute command %s",
1648                         add ? "OP_ADD_ETH_ADDR" : "OP_DEL_ETH_ADDR");
1649                 return err;
1650         }
1651
1652         return 0;
1653 }
1654
1655 int
1656 iavf_request_queues(struct iavf_adapter *adapter, uint16_t num)
1657 {
1658         struct rte_eth_dev *dev = adapter->eth_dev;
1659         struct iavf_info *vf =  IAVF_DEV_PRIVATE_TO_VF(adapter);
1660         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1661         struct virtchnl_vf_res_request vfres;
1662         struct iavf_cmd_info args;
1663         uint16_t num_queue_pairs;
1664         int err;
1665
1666         if (!(vf->vf_res->vf_cap_flags &
1667                 VIRTCHNL_VF_OFFLOAD_REQ_QUEUES)) {
1668                 PMD_DRV_LOG(ERR, "request queues not supported");
1669                 return -1;
1670         }
1671
1672         if (num == 0) {
1673                 PMD_DRV_LOG(ERR, "queue number cannot be zero");
1674                 return -1;
1675         }
1676         vfres.num_queue_pairs = num;
1677
1678         args.ops = VIRTCHNL_OP_REQUEST_QUEUES;
1679         args.in_args = (u8 *)&vfres;
1680         args.in_args_size = sizeof(vfres);
1681         args.out_buffer = vf->aq_resp;
1682         args.out_size = IAVF_AQ_BUF_SZ;
1683
1684         if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) {
1685                 /* disable interrupt to avoid the admin queue message to be read
1686                  * before iavf_read_msg_from_pf.
1687                  */
1688                 rte_intr_disable(&pci_dev->intr_handle);
1689                 err = iavf_execute_vf_cmd(adapter, &args);
1690                 rte_intr_enable(&pci_dev->intr_handle);
1691         } else {
1692                 rte_eal_alarm_cancel(iavf_dev_alarm_handler, dev);
1693                 err = iavf_execute_vf_cmd(adapter, &args);
1694                 rte_eal_alarm_set(IAVF_ALARM_INTERVAL,
1695                                   iavf_dev_alarm_handler, dev);
1696         }
1697
1698         if (err) {
1699                 PMD_DRV_LOG(ERR, "fail to execute command OP_REQUEST_QUEUES");
1700                 return err;
1701         }
1702
1703         /* request queues succeeded, vf is resetting */
1704         if (vf->vf_reset) {
1705                 PMD_DRV_LOG(INFO, "vf is resetting");
1706                 return 0;
1707         }
1708
1709         /* request additional queues failed, return available number */
1710         num_queue_pairs =
1711           ((struct virtchnl_vf_res_request *)args.out_buffer)->num_queue_pairs;
1712         PMD_DRV_LOG(ERR, "request queues failed, only %u queues "
1713                 "available", num_queue_pairs);
1714
1715         return -1;
1716 }
1717
1718 int
1719 iavf_get_max_rss_queue_region(struct iavf_adapter *adapter)
1720 {
1721         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1722         struct iavf_cmd_info args;
1723         uint16_t qregion_width;
1724         int err;
1725
1726         args.ops = VIRTCHNL_OP_GET_MAX_RSS_QREGION;
1727         args.in_args = NULL;
1728         args.in_args_size = 0;
1729         args.out_buffer = vf->aq_resp;
1730         args.out_size = IAVF_AQ_BUF_SZ;
1731
1732         err = iavf_execute_vf_cmd(adapter, &args);
1733         if (err) {
1734                 PMD_DRV_LOG(ERR, "Failed to execute command of VIRTCHNL_OP_GET_MAX_RSS_QREGION");
1735                 return err;
1736         }
1737
1738         qregion_width =
1739         ((struct virtchnl_max_rss_qregion *)args.out_buffer)->qregion_width;
1740
1741         vf->max_rss_qregion = (uint16_t)(1 << qregion_width);
1742
1743         return 0;
1744 }