LCOV - code coverage report
Current view: top level - drivers/net/intel/iavf - iavf_vchnl.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 1145 0.0 %
Date: 2026-07-01 18:02:41 Functions: 0 61 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 482 0.0 %

           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                 :            :         RTE_ATOMIC(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, false);
      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                 :          0 :         char notify_byte = 0;
     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 :                 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], &notify_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 (rte_atomic_fetch_add_explicit(&handler->ndev, 1, rte_memory_order_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 :                 rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_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 :                 rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_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 (rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_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 != NULL &&
     259         [ #  # ]:          0 :                             vf->vf_res->vf_cap_flags & 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 :                                 iavf_set_no_poll(adapter, true);
     277         [ #  # ]:          0 :                                 if (adapter->no_poll)
     278                 :          0 :                                         PMD_DRV_LOG(DEBUG, "VF no poll turned on");
     279                 :            :                                 else
     280                 :          0 :                                         PMD_DRV_LOG(DEBUG, "VF no poll turned off");
     281                 :            :                         }
     282         [ #  # ]:          0 :                         PMD_DRV_LOG(INFO, "Link status update:%s",
     283                 :            :                                         vf->link_up ? "up" : "down");
     284                 :          0 :                         break;
     285                 :          0 :                 case VIRTCHNL_EVENT_RESET_IMPENDING:
     286                 :          0 :                         vf->vf_reset = true;
     287                 :          0 :                         iavf_set_no_poll(adapter, false);
     288                 :          0 :                         PMD_DRV_LOG(INFO, "VF is resetting");
     289                 :          0 :                         break;
     290                 :          0 :                 case VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
     291                 :          0 :                         vf->dev_closed = true;
     292                 :          0 :                         PMD_DRV_LOG(INFO, "PF driver closed");
     293                 :          0 :                         break;
     294                 :          0 :                 default:
     295                 :          0 :                         PMD_DRV_LOG(ERR, "%s: Unknown event %d from pf",
     296                 :            :                                         __func__, vpe->event);
     297                 :            :                 }
     298                 :            :         }  else {
     299                 :            :                 /* async reply msg on command issued by vf previously */
     300                 :            :                 result = IAVF_MSG_CMD;
     301         [ #  # ]:          0 :                 if (opcode != vf->pend_cmd) {
     302         [ #  # ]:          0 :                         if (opcode == VIRTCHNL_OP_UNKNOWN)
     303                 :          0 :                                 PMD_DRV_LOG(DEBUG,
     304                 :            :                                             "Spurious msg with opcode 0, pending cmd %u",
     305                 :            :                                             vf->pend_cmd);
     306                 :            :                         else
     307                 :          0 :                                 PMD_DRV_LOG(WARNING,
     308                 :            :                                             "command mismatch, expect %u, get %u",
     309                 :            :                                             vf->pend_cmd, opcode);
     310                 :            : 
     311                 :            :                         result = IAVF_MSG_ERR;
     312                 :            :                 }
     313                 :            :         }
     314                 :            : 
     315                 :            :         return result;
     316                 :            : }
     317                 :            : 
     318                 :            : static int
     319                 :          0 : iavf_set_pending_cmd(struct iavf_info *vf, enum virtchnl_ops ops,
     320                 :            :                     uint32_t resp_count)
     321                 :            : {
     322                 :            :         enum virtchnl_ops op_unk = VIRTCHNL_OP_UNKNOWN;
     323                 :          0 :         int ret = rte_atomic_compare_exchange_strong_explicit(&vf->pend_cmd,
     324                 :            :                         &op_unk, ops, rte_memory_order_acquire,
     325                 :            :                         rte_memory_order_acquire);
     326                 :            : 
     327         [ #  # ]:          0 :         if (ret == 0) {
     328                 :          0 :                 PMD_DRV_LOG(ERR, "There is incomplete cmd %d", vf->pend_cmd);
     329                 :          0 :                 return -1;
     330                 :            :         }
     331                 :            : 
     332                 :          0 :         rte_atomic_store_explicit(&vf->pend_cmd_count, resp_count,
     333                 :            :                         rte_memory_order_relaxed);
     334                 :            : 
     335                 :          0 :         return 0;
     336                 :            : }
     337                 :            : 
     338                 :            : static inline void
     339                 :            : iavf_clear_pending_cmd(struct iavf_info *vf)
     340                 :            : {
     341                 :            :         rte_wmb();
     342                 :          0 :         vf->pend_cmd = VIRTCHNL_OP_UNKNOWN;
     343                 :          0 :         vf->cmd_retval = VIRTCHNL_STATUS_SUCCESS;
     344                 :            : }
     345                 :            : 
     346                 :            : static inline void
     347                 :            : iavf_notify_pending_cmd(struct iavf_info *vf, int msg_ret)
     348                 :            : {
     349                 :          0 :         vf->cmd_retval = msg_ret;
     350                 :            :         rte_wmb();
     351                 :          0 :         vf->pend_cmd = VIRTCHNL_OP_UNKNOWN;
     352                 :          0 : }
     353                 :            : 
     354                 :            : static int
     355                 :            : iavf_get_cmd_resp_count(enum virtchnl_ops op)
     356                 :            : {
     357                 :          0 :         switch (op) {
     358                 :            :         case VIRTCHNL_OP_RESET_VF:
     359                 :            :         case VIRTCHNL_OP_REQUEST_QUEUES:
     360                 :            :                 /* These commands trigger reset and are not waited for */
     361                 :            :                 return 0;
     362                 :          0 :         case VIRTCHNL_OP_INLINE_IPSEC_CRYPTO:
     363                 :            :                 /* IPsec crypto commands generate two responses */
     364                 :          0 :                 return 2;
     365                 :          0 :         default:
     366                 :            :                 /* All other commands generate one response */
     367                 :          0 :                 return 1;
     368                 :            :         }
     369                 :            : }
     370                 :            : 
     371                 :            : static int
     372                 :            : iavf_op_needs_poll(struct iavf_info *vf)
     373                 :            : {
     374                 :            :         /* Poll if interrupts disabled or we are in interrupt thread */
     375         [ #  # ]:          0 :         return !vf->aq_intr_enabled || rte_thread_is_intr();
     376                 :            : }
     377                 :            : 
     378                 :            : static int
     379                 :          0 : iavf_wait_for_msg(struct iavf_adapter *adapter, struct iavf_cmd_info *args,
     380                 :            :                 bool poll)
     381                 :            : {
     382                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
     383                 :            :         int err = 0;
     384                 :            :         int i = 0;
     385                 :            : 
     386         [ #  # ]:          0 :         if (args->out_buffer == NULL) {
     387                 :          0 :                 PMD_DRV_LOG(ERR, "Invalid buffer for cmd %d response", args->ops);
     388                 :          0 :                 return -EINVAL;
     389                 :            :         }
     390                 :            : 
     391                 :            :         /* Wait for command completion */
     392                 :            :         do {
     393         [ #  # ]:          0 :                 if (poll) {
     394                 :            :                         enum iavf_aq_result result;
     395                 :          0 :                         result = iavf_read_msg_from_pf(adapter, args->out_size,
     396                 :            :                                         args->out_buffer);
     397         [ #  # ]:          0 :                         if (result == IAVF_MSG_CMD)
     398                 :            :                                 break;
     399                 :            :                 } else {
     400                 :            :                         /* check if interrupt thread has erased pending cmd */
     401         [ #  # ]:          0 :                         if (vf->pend_cmd == VIRTCHNL_OP_UNKNOWN)
     402                 :            :                                 break;
     403                 :            :                 }
     404                 :          0 :                 iavf_msec_delay(ASQ_DELAY_MS);
     405         [ #  # ]:          0 :         } while (i++ < MAX_TRY_TIMES);
     406                 :            : 
     407         [ #  # ]:          0 :         if (i >= MAX_TRY_TIMES) {
     408                 :          0 :                 PMD_DRV_LOG(ERR, "No response for cmd %d", args->ops);
     409                 :            :                 err = -EIO;
     410         [ #  # ]:          0 :         } else if (vf->cmd_retval == VIRTCHNL_STATUS_ERR_NOT_SUPPORTED) {
     411                 :          0 :                 PMD_DRV_LOG(ERR, "Cmd %d not supported", args->ops);
     412                 :            :                 err = -ENOTSUP;
     413         [ #  # ]:          0 :         } else if (vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
     414                 :          0 :                 PMD_DRV_LOG(ERR, "Return failure %d for cmd %d",
     415                 :            :                                 vf->cmd_retval, args->ops);
     416                 :            :                 err = -EINVAL;
     417                 :            :         }
     418                 :            : 
     419                 :            :         return err;
     420                 :            : }
     421                 :            : 
     422                 :            : static int
     423                 :          0 : iavf_execute_vf_cmd(struct iavf_adapter *adapter, struct iavf_cmd_info *args)
     424                 :            : {
     425                 :          0 :         struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
     426         [ #  # ]:          0 :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
     427                 :            :         enum iavf_status status;
     428                 :            :         uint32_t resp_count;
     429                 :            :         bool poll = iavf_op_needs_poll(vf);
     430                 :            :         int err;
     431                 :            : 
     432         [ #  # ]:          0 :         if (vf->vf_reset)
     433                 :            :                 return -EIO;
     434                 :            : 
     435      [ #  #  # ]:          0 :         resp_count = iavf_get_cmd_resp_count(args->ops);
     436                 :            : 
     437                 :            :         /*
     438                 :            :          * For some commands, we are not waiting for responses because they
     439                 :            :          * produce a reset event. However, we still need to set pending command
     440                 :            :          * to avoid sending commands while another one is already in progress.
     441                 :            :          */
     442         [ #  # ]:          0 :         if (iavf_set_pending_cmd(vf, args->ops, RTE_MAX(1U, resp_count)) != 0)
     443                 :            :                 return -1;
     444                 :            : 
     445                 :          0 :         status = iavf_aq_send_msg_to_pf(hw, args->ops, IAVF_SUCCESS,
     446                 :          0 :                         args->in_args, args->in_args_size, NULL);
     447         [ #  # ]:          0 :         if (status != IAVF_SUCCESS) {
     448                 :          0 :                 PMD_DRV_LOG(ERR, "fail to send cmd %d", args->ops);
     449                 :            :                 err = (int)status;
     450                 :          0 :                 goto clear_cmd;
     451         [ #  # ]:          0 :         } else if (resp_count == 0) {
     452                 :            :                 /* we're not waiting on responses */
     453                 :            :                 err = 0;
     454                 :          0 :                 goto clear_cmd;
     455                 :            :         }
     456                 :            : 
     457                 :          0 :         err = iavf_wait_for_msg(adapter, args, poll);
     458                 :            : 
     459                 :            :         /*
     460                 :            :          * messages received through interrupts store their response in global
     461                 :            :          * buffer, so we need to copy it if we received the message.
     462                 :            :          */
     463         [ #  # ]:          0 :         if (!poll && err == 0)
     464                 :          0 :                 memcpy(args->out_buffer, vf->aq_resp, args->out_size);
     465                 :            : 
     466                 :            :         /* in interrupt success case, pending cmd is cleared by intr thread */
     467         [ #  # ]:          0 :         if (err != 0 || poll)
     468                 :          0 :                 goto clear_cmd;
     469                 :            : 
     470                 :            :         return err;
     471                 :          0 : clear_cmd:
     472                 :            :         iavf_clear_pending_cmd(vf);
     473                 :          0 :         return err;
     474                 :            : }
     475                 :            : 
     476                 :            : static int
     477                 :          0 : iavf_execute_vf_cmd_safe(struct iavf_adapter *adapter,
     478                 :            :         struct iavf_cmd_info *args)
     479                 :            : {
     480                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
     481                 :            :         int ret;
     482                 :          0 :         int is_intr_thread = rte_thread_is_intr();
     483                 :            : 
     484         [ #  # ]:          0 :         if (is_intr_thread) {
     485         [ #  # ]:          0 :                 if (!rte_spinlock_trylock(&vf->aq_lock))
     486                 :            :                         return -EIO;
     487                 :            :         } else {
     488                 :          0 :                 rte_spinlock_lock(&vf->aq_lock);
     489                 :            :         }
     490                 :          0 :         ret = iavf_execute_vf_cmd(adapter, args);
     491                 :          0 :         rte_spinlock_unlock(&vf->aq_lock);
     492                 :            : 
     493                 :          0 :         return ret;
     494                 :            : }
     495                 :            : 
     496                 :            : static void
     497                 :          0 : iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg,
     498                 :            :                         uint16_t msglen)
     499                 :            : {
     500                 :          0 :         struct iavf_adapter *adapter =
     501                 :          0 :                 IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
     502                 :            :         struct iavf_info *vf = &adapter->vf;
     503                 :            :         struct virtchnl_pf_event *pf_msg =
     504                 :            :                         (struct virtchnl_pf_event *)msg;
     505                 :            : 
     506         [ #  # ]:          0 :         if (adapter->closed) {
     507                 :          0 :                 PMD_DRV_LOG(DEBUG, "Port closed");
     508                 :          0 :                 return;
     509                 :            :         }
     510                 :            : 
     511         [ #  # ]:          0 :         if (msglen < sizeof(struct virtchnl_pf_event)) {
     512                 :          0 :                 PMD_DRV_LOG(DEBUG, "Error event");
     513                 :          0 :                 return;
     514                 :            :         }
     515   [ #  #  #  # ]:          0 :         switch (pf_msg->event) {
     516                 :          0 :         case VIRTCHNL_EVENT_RESET_IMPENDING:
     517                 :          0 :                 PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event");
     518                 :          0 :                 vf->link_up = false;
     519         [ #  # ]:          0 :                 if (!vf->vf_reset) {
     520                 :          0 :                         vf->vf_reset = true;
     521                 :          0 :                         iavf_set_no_poll(adapter, false);
     522                 :          0 :                         iavf_dev_event_post(dev, RTE_ETH_EVENT_INTR_RESET,
     523                 :            :                                 NULL, 0);
     524                 :            :                 }
     525                 :            :                 break;
     526                 :          0 :         case VIRTCHNL_EVENT_LINK_CHANGE:
     527                 :          0 :                 PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
     528                 :          0 :                 vf->link_up = pf_msg->event_data.link_event.link_status;
     529         [ #  # ]:          0 :                 if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_CAP_ADV_LINK_SPEED) {
     530                 :          0 :                         vf->link_speed =
     531                 :          0 :                                 pf_msg->event_data.link_event_adv.link_speed;
     532                 :            :                 } else {
     533                 :            :                         enum virtchnl_link_speed speed;
     534                 :          0 :                         speed = pf_msg->event_data.link_event.link_speed;
     535                 :          0 :                         vf->link_speed = iavf_convert_link_speed(speed);
     536                 :            :                 }
     537                 :          0 :                 iavf_dev_link_update(dev, 0);
     538   [ #  #  #  # ]:          0 :                 if (vf->link_up && !vf->vf_reset) {
     539                 :          0 :                         iavf_dev_watchdog_disable(adapter);
     540                 :            :                 } else {
     541         [ #  # ]:          0 :                         if (!vf->link_up)
     542                 :          0 :                                 iavf_dev_watchdog_enable(adapter);
     543                 :            :                 }
     544         [ #  # ]:          0 :                 if (adapter->devargs.no_poll_on_link_down) {
     545                 :          0 :                         iavf_set_no_poll(adapter, true);
     546         [ #  # ]:          0 :                         if (adapter->no_poll)
     547                 :          0 :                                 PMD_DRV_LOG(DEBUG, "VF no poll turned on");
     548                 :            :                         else
     549                 :          0 :                                 PMD_DRV_LOG(DEBUG, "VF no poll turned off");
     550                 :            :                 }
     551                 :          0 :                 iavf_dev_event_post(dev, RTE_ETH_EVENT_INTR_LSC, NULL, 0);
     552                 :          0 :                 break;
     553                 :          0 :         case VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
     554                 :          0 :                 PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_PF_DRIVER_CLOSE event");
     555                 :          0 :                 break;
     556                 :          0 :         default:
     557                 :          0 :                 PMD_DRV_LOG(ERR, " unknown event received %u", pf_msg->event);
     558                 :          0 :                 break;
     559                 :            :         }
     560                 :            : }
     561                 :            : 
     562                 :            : void
     563                 :          0 : iavf_handle_virtchnl_msg(struct rte_eth_dev *dev)
     564                 :            : {
     565                 :          0 :         struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     566                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
     567                 :            :         struct iavf_arq_event_info info;
     568                 :            :         uint16_t pending, aq_opc;
     569                 :            :         enum virtchnl_ops msg_opc;
     570                 :            :         enum iavf_status msg_ret;
     571                 :            :         int ret;
     572                 :            : 
     573                 :          0 :         info.buf_len = IAVF_AQ_BUF_SZ;
     574                 :          0 :         info.msg_buf = vf->aq_resp;
     575                 :            : 
     576                 :          0 :         pending = 1;
     577         [ #  # ]:          0 :         while (pending) {
     578                 :          0 :                 ret = iavf_clean_arq_element(hw, &info, &pending);
     579                 :            : 
     580         [ #  # ]:          0 :                 if (ret != IAVF_SUCCESS) {
     581                 :            :                         /*
     582                 :            :                          * IAVF_ERR_ADMIN_QUEUE_NO_WORK (-57) means AQ is empty
     583                 :            :                          * and is a normal way to terminate the drain loop.
     584                 :            :                          * Log error only for genuine other failure codes.
     585                 :            :                          * Incorrect logging like this during VF resets might
     586                 :            :                          * mislead into chasing a non-existent AQ failure.
     587                 :            :                          */
     588         [ #  # ]:          0 :                         if (ret != IAVF_ERR_ADMIN_QUEUE_NO_WORK)
     589                 :          0 :                                 PMD_DRV_LOG(INFO, "Failed to read msg from AdminQ,"
     590                 :            :                                             "ret: %d", ret);
     591                 :            :                         break;
     592                 :            :                 }
     593                 :          0 :                 aq_opc = rte_le_to_cpu_16(info.desc.opcode);
     594                 :            :                 /* For the message sent from pf to vf, opcode is stored in
     595                 :            :                  * cookie_high of struct iavf_aq_desc, while return error code
     596                 :            :                  * are stored in cookie_low, Which is done by PF driver.
     597                 :            :                  */
     598                 :          0 :                 msg_opc = (enum virtchnl_ops)rte_le_to_cpu_32(
     599                 :            :                                                   info.desc.cookie_high);
     600                 :          0 :                 msg_ret = (enum iavf_status)rte_le_to_cpu_32(
     601                 :            :                                                   info.desc.cookie_low);
     602         [ #  # ]:          0 :                 switch (aq_opc) {
     603                 :          0 :                 case iavf_aqc_opc_send_msg_to_vf:
     604         [ #  # ]:          0 :                         if (msg_opc == VIRTCHNL_OP_EVENT) {
     605                 :          0 :                                 iavf_handle_pf_event_msg(dev, info.msg_buf,
     606                 :          0 :                                                 info.msg_len);
     607                 :            :                         } else {
     608                 :            :                                 /* check for unsolicited messages i.e. events */
     609         [ #  # ]:          0 :                                 if (info.msg_len > 0) {
     610                 :            :                                         switch (msg_opc) {
     611                 :          0 :                                         case VIRTCHNL_OP_INLINE_IPSEC_CRYPTO: {
     612                 :          0 :                                                 struct inline_ipsec_msg *imsg =
     613                 :            :                                                         (struct inline_ipsec_msg *)info.msg_buf;
     614         [ #  # ]:          0 :                                                 if (imsg->ipsec_opcode
     615                 :          0 :                                                                 == INLINE_IPSEC_OP_EVENT) {
     616                 :            :                                                         struct rte_eth_event_ipsec_desc desc;
     617                 :            :                                                         struct virtchnl_ipsec_event *ev =
     618                 :            :                                                                         imsg->ipsec_data.event;
     619                 :          0 :                                                         desc.subtype =
     620                 :            :                                                                         RTE_ETH_EVENT_IPSEC_UNKNOWN;
     621                 :          0 :                                                         desc.metadata =
     622                 :          0 :                                                                         ev->ipsec_event_data;
     623                 :          0 :                                                         iavf_dev_event_post(dev,
     624                 :            :                                                                 RTE_ETH_EVENT_IPSEC,
     625                 :            :                                                                 &desc, sizeof(desc));
     626                 :            :                                                         continue;
     627                 :            :                                         }
     628                 :            :                                 }
     629                 :            :                                                 break;
     630                 :            :                                         default:
     631                 :            :                                                 break;
     632                 :            :                                         }
     633                 :            : 
     634                 :            :                                 }
     635                 :            : 
     636                 :            :                                 /* read message and it's expected one */
     637         [ #  # ]:          0 :                                 if (msg_opc == vf->pend_cmd) {
     638                 :            :                                         uint32_t cmd_count =
     639                 :          0 :                                         rte_atomic_fetch_sub_explicit(&vf->pend_cmd_count,
     640                 :            :                                                         1, rte_memory_order_relaxed) - 1;
     641         [ #  # ]:          0 :                                         if (cmd_count == 0)
     642                 :            :                                                 iavf_notify_pending_cmd(vf, msg_ret);
     643                 :            :                                 } else {
     644                 :          0 :                                         PMD_DRV_LOG(ERR,
     645                 :            :                                         "command mismatch, expect %u, get %u",
     646                 :            :                                                 vf->pend_cmd, msg_opc);
     647                 :            :                                 }
     648                 :          0 :                                 PMD_DRV_LOG(DEBUG,
     649                 :            :                                 "adminq response is received, opcode = %d",
     650                 :            :                                                 msg_opc);
     651                 :            :                         }
     652                 :            :                         break;
     653                 :          0 :                 default:
     654                 :          0 :                         PMD_DRV_LOG(DEBUG, "Request %u is not supported yet",
     655                 :            :                                     aq_opc);
     656                 :          0 :                         break;
     657                 :            :                 }
     658                 :            :         }
     659                 :          0 : }
     660                 :            : 
     661                 :            : int
     662                 :          0 : iavf_enable_vlan_strip(struct iavf_adapter *adapter)
     663                 :            : {
     664                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
     665                 :            :         struct iavf_cmd_info args;
     666                 :            :         int ret;
     667                 :            : 
     668                 :            :         memset(&args, 0, sizeof(args));
     669                 :          0 :         args.ops = VIRTCHNL_OP_ENABLE_VLAN_STRIPPING;
     670                 :            :         args.in_args = NULL;
     671                 :            :         args.in_args_size = 0;
     672                 :          0 :         args.out_buffer = msg_buf;
     673                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
     674                 :          0 :         ret = iavf_execute_vf_cmd_safe(adapter, &args);
     675         [ #  # ]:          0 :         if (ret)
     676                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to execute command of"
     677                 :            :                             " OP_ENABLE_VLAN_STRIPPING");
     678                 :            : 
     679                 :          0 :         return ret;
     680                 :            : }
     681                 :            : 
     682                 :            : int
     683                 :          0 : iavf_disable_vlan_strip(struct iavf_adapter *adapter)
     684                 :            : {
     685                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
     686                 :            :         struct iavf_cmd_info args;
     687                 :            :         int ret;
     688                 :            : 
     689                 :            :         memset(&args, 0, sizeof(args));
     690                 :          0 :         args.ops = VIRTCHNL_OP_DISABLE_VLAN_STRIPPING;
     691                 :            :         args.in_args = NULL;
     692                 :            :         args.in_args_size = 0;
     693                 :          0 :         args.out_buffer = msg_buf;
     694                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
     695                 :          0 :         ret = iavf_execute_vf_cmd_safe(adapter, &args);
     696         [ #  # ]:          0 :         if (ret)
     697                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to execute command of"
     698                 :            :                             " OP_DISABLE_VLAN_STRIPPING");
     699                 :            : 
     700                 :          0 :         return ret;
     701                 :            : }
     702                 :            : 
     703                 :            : #define VIRTCHNL_VERSION_MAJOR_START 1
     704                 :            : #define VIRTCHNL_VERSION_MINOR_START 1
     705                 :            : 
     706                 :            : /* Check API version with sync wait until version read from admin queue */
     707                 :            : int
     708                 :          0 : iavf_check_api_version(struct iavf_adapter *adapter)
     709                 :            : {
     710                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
     711                 :            :         struct virtchnl_version_info version, *pver;
     712                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
     713                 :            :         struct iavf_cmd_info args;
     714                 :            :         int err;
     715                 :            : 
     716                 :          0 :         version.major = VIRTCHNL_VERSION_MAJOR;
     717                 :          0 :         version.minor = VIRTCHNL_VERSION_MINOR;
     718                 :            : 
     719                 :          0 :         args.ops = VIRTCHNL_OP_VERSION;
     720                 :          0 :         args.in_args = (uint8_t *)&version;
     721                 :          0 :         args.in_args_size = sizeof(version);
     722                 :          0 :         args.out_buffer = msg_buf;
     723                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
     724                 :            : 
     725                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
     726         [ #  # ]:          0 :         if (err) {
     727                 :          0 :                 PMD_INIT_LOG(ERR, "Fail to execute command of OP_VERSION");
     728                 :          0 :                 return err;
     729                 :            :         }
     730                 :            : 
     731                 :          0 :         pver = (struct virtchnl_version_info *)args.out_buffer;
     732                 :          0 :         vf->virtchnl_version = *pver;
     733                 :            : 
     734         [ #  # ]:          0 :         if (vf->virtchnl_version.major < VIRTCHNL_VERSION_MAJOR_START ||
     735         [ #  # ]:          0 :             (vf->virtchnl_version.major == VIRTCHNL_VERSION_MAJOR_START &&
     736                 :            :              vf->virtchnl_version.minor < VIRTCHNL_VERSION_MINOR_START)) {
     737                 :          0 :                 PMD_INIT_LOG(ERR, "VIRTCHNL API version should not be lower"
     738                 :            :                              " than (%u.%u) to support Adaptive VF",
     739                 :            :                              VIRTCHNL_VERSION_MAJOR_START,
     740                 :            :                              VIRTCHNL_VERSION_MAJOR_START);
     741                 :          0 :                 return -1;
     742         [ #  # ]:          0 :         } else if (vf->virtchnl_version.major > VIRTCHNL_VERSION_MAJOR ||
     743                 :          0 :                    (vf->virtchnl_version.major == VIRTCHNL_VERSION_MAJOR &&
     744         [ #  # ]:          0 :                     vf->virtchnl_version.minor > VIRTCHNL_VERSION_MINOR)) {
     745                 :          0 :                 PMD_INIT_LOG(ERR, "PF/VF API version mismatch:(%u.%u)-(%u.%u)",
     746                 :            :                              vf->virtchnl_version.major,
     747                 :            :                              vf->virtchnl_version.minor,
     748                 :            :                              VIRTCHNL_VERSION_MAJOR,
     749                 :            :                              VIRTCHNL_VERSION_MINOR);
     750                 :          0 :                 return -1;
     751                 :            :         }
     752                 :            : 
     753                 :          0 :         PMD_DRV_LOG(DEBUG, "Peer is supported PF host");
     754                 :          0 :         return 0;
     755                 :            : }
     756                 :            : 
     757                 :            : int
     758                 :          0 : iavf_get_vf_resource(struct iavf_adapter *adapter)
     759                 :            : {
     760                 :          0 :         struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
     761                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
     762                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
     763                 :            :         struct iavf_cmd_info args;
     764                 :            :         uint32_t caps, len;
     765                 :            :         int err, i;
     766                 :            : 
     767                 :          0 :         args.ops = VIRTCHNL_OP_GET_VF_RESOURCES;
     768                 :          0 :         args.out_buffer = msg_buf;
     769                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
     770                 :            : 
     771                 :          0 :         caps = IAVF_BASIC_OFFLOAD_CAPS | VIRTCHNL_VF_CAP_ADV_LINK_SPEED |
     772                 :            :                 VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC |
     773                 :            :                 VIRTCHNL_VF_OFFLOAD_FDIR_PF |
     774                 :            :                 VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF |
     775                 :            :                 VIRTCHNL_VF_OFFLOAD_FSUB_PF |
     776                 :            :                 VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
     777                 :            :                 VIRTCHNL_VF_OFFLOAD_USO |
     778                 :            :                 VIRTCHNL_VF_OFFLOAD_CRC |
     779                 :            :                 VIRTCHNL_VF_OFFLOAD_VLAN_V2 |
     780                 :            :                 VIRTCHNL_VF_LARGE_NUM_QPAIRS |
     781                 :            :                 VIRTCHNL_VF_OFFLOAD_QOS |
     782                 :            :                 VIRTCHNL_VF_OFFLOAD_INLINE_IPSEC_CRYPTO |
     783                 :            :                 VIRTCHNL_VF_CAP_PTP;
     784                 :            : 
     785                 :          0 :         args.in_args = (uint8_t *)&caps;
     786                 :          0 :         args.in_args_size = sizeof(caps);
     787                 :            : 
     788                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
     789                 :            : 
     790         [ #  # ]:          0 :         if (err) {
     791                 :          0 :                 PMD_DRV_LOG(ERR,
     792                 :            :                             "Failed to execute command of OP_GET_VF_RESOURCE");
     793                 :          0 :                 return -1;
     794                 :            :         }
     795                 :            : 
     796                 :            :         len =  sizeof(struct virtchnl_vf_resource) +
     797                 :            :                       IAVF_MAX_VF_VSI * sizeof(struct virtchnl_vsi_resource);
     798                 :            : 
     799                 :          0 :         memcpy(vf->vf_res, args.out_buffer,
     800                 :          0 :                    RTE_MIN(args.out_size, len));
     801                 :            :         /* parse  VF config message back from PF*/
     802                 :          0 :         iavf_vf_parse_hw_config(hw, vf->vf_res);
     803         [ #  # ]:          0 :         for (i = 0; i < vf->vf_res->num_vsis; i++) {
     804         [ #  # ]:          0 :                 if (vf->vf_res->vsi_res[i].vsi_type == VIRTCHNL_VSI_SRIOV)
     805                 :          0 :                         vf->vsi_res = &vf->vf_res->vsi_res[i];
     806                 :            :         }
     807                 :            : 
     808         [ #  # ]:          0 :         if (!vf->vsi_res) {
     809                 :          0 :                 PMD_INIT_LOG(ERR, "no LAN VSI found");
     810                 :          0 :                 return -1;
     811                 :            :         }
     812                 :            : 
     813                 :          0 :         vf->vsi.vsi_id = vf->vsi_res->vsi_id;
     814                 :          0 :         vf->vsi.nb_qps = vf->vsi_res->num_queue_pairs;
     815                 :          0 :         vf->vsi.adapter = adapter;
     816                 :            : 
     817                 :          0 :         return 0;
     818                 :            : }
     819                 :            : 
     820                 :            : int
     821                 :          0 : iavf_get_supported_rxdid(struct iavf_adapter *adapter)
     822                 :            : {
     823                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
     824                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
     825                 :            :         struct iavf_cmd_info args;
     826                 :            :         int ret;
     827                 :            : 
     828                 :          0 :         args.ops = VIRTCHNL_OP_GET_SUPPORTED_RXDIDS;
     829                 :          0 :         args.in_args = NULL;
     830                 :          0 :         args.in_args_size = 0;
     831                 :          0 :         args.out_buffer = msg_buf;
     832                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
     833                 :            : 
     834                 :          0 :         ret = iavf_execute_vf_cmd_safe(adapter, &args);
     835         [ #  # ]:          0 :         if (ret) {
     836                 :          0 :                 PMD_DRV_LOG(ERR,
     837                 :            :                             "Failed to execute command of OP_GET_SUPPORTED_RXDIDS");
     838                 :          0 :                 return ret;
     839                 :            :         }
     840                 :            : 
     841                 :          0 :         vf->supported_rxdid =
     842                 :          0 :                 ((struct virtchnl_supported_rxdids *)args.out_buffer)->supported_rxdids;
     843                 :            : 
     844                 :          0 :         return 0;
     845                 :            : }
     846                 :            : 
     847                 :            : int
     848                 :          0 : iavf_config_outer_vlan_strip_v2(struct iavf_adapter *adapter, bool enable)
     849                 :            : {
     850                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
     851                 :            :         struct virtchnl_vlan_supported_caps *stripping_caps;
     852                 :            :         struct virtchnl_vlan_setting vlan_strip;
     853         [ #  # ]:          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
     854                 :            :         struct iavf_cmd_info args;
     855                 :            :         uint32_t *ethertype;
     856                 :            :         int ret;
     857                 :            : 
     858                 :            :         memset(&vlan_strip, 0, sizeof(vlan_strip));
     859                 :            :         stripping_caps = &vf->vlan_v2_caps.offloads.stripping_support;
     860   [ #  #  #  # ]:          0 :         if ((stripping_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_88A8) &&
     861                 :          0 :             (stripping_caps->outer & VIRTCHNL_VLAN_TOGGLE) &&
     862         [ #  # ]:          0 :             adapter->tpid == RTE_ETHER_TYPE_QINQ) {
     863                 :            :                 ethertype = &vlan_strip.outer_ethertype_setting;
     864                 :          0 :                 *ethertype = VIRTCHNL_VLAN_ETHERTYPE_88A8;
     865   [ #  #  #  # ]:          0 :         } else if ((stripping_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
     866                 :          0 :                    (stripping_caps->outer & VIRTCHNL_VLAN_TOGGLE) &&
     867         [ #  # ]:          0 :                    adapter->tpid == RTE_ETHER_TYPE_VLAN) {
     868                 :            :                 ethertype = &vlan_strip.outer_ethertype_setting;
     869                 :          0 :                 *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
     870                 :            :         } else {
     871                 :            :                 return -ENOTSUP;
     872                 :            :         }
     873                 :            : 
     874                 :          0 :         vlan_strip.vport_id = vf->vsi_res->vsi_id;
     875                 :            : 
     876         [ #  # ]:          0 :         args.ops = enable ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 :
     877                 :            :                             VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2;
     878                 :          0 :         args.in_args = (uint8_t *)&vlan_strip;
     879                 :          0 :         args.in_args_size = sizeof(vlan_strip);
     880                 :          0 :         args.out_buffer = msg_buf;
     881                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
     882                 :          0 :         ret = iavf_execute_vf_cmd_safe(adapter, &args);
     883         [ #  # ]:          0 :         if (ret)
     884         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR, "fail to execute command %s",
     885                 :            :                             enable ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" :
     886                 :            :                                      "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2");
     887                 :            : 
     888                 :            :         return ret;
     889                 :            : }
     890                 :            : 
     891                 :            : int
     892                 :          0 : iavf_config_vlan_strip_v2(struct iavf_adapter *adapter, bool enable)
     893                 :            : {
     894                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
     895                 :            :         struct virtchnl_vlan_supported_caps *stripping_caps;
     896                 :            :         struct virtchnl_vlan_setting vlan_strip;
     897                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
     898                 :            :         struct iavf_cmd_info args;
     899                 :            :         uint32_t *ethertype;
     900                 :          0 :         int qinq = adapter->dev_data->dev_conf.rxmode.offloads &
     901                 :            :                    RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
     902                 :            :         int ret;
     903                 :            : 
     904                 :            :         stripping_caps = &vf->vlan_v2_caps.offloads.stripping_support;
     905                 :            : 
     906                 :            :         /* When VLAN extend is disabled, Single VLAN mode which is Outer VLAN
     907                 :            :          * When VLAN extend is enabled, QinQ mode, this API works only on
     908                 :            :          * Inner VLAN strip which is always 0x8100.
     909                 :            :          */
     910   [ #  #  #  #  :          0 :         if (!qinq && (stripping_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
                   #  # ]
     911                 :            :             (stripping_caps->outer & VIRTCHNL_VLAN_TOGGLE))
     912                 :            :                 ethertype = &vlan_strip.outer_ethertype_setting;
     913   [ #  #  #  #  :          0 :         else if (qinq && (stripping_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
                   #  # ]
     914                 :            :                  (stripping_caps->inner & VIRTCHNL_VLAN_TOGGLE))
     915                 :            :                 ethertype = &vlan_strip.inner_ethertype_setting;
     916                 :            :         else
     917                 :            :                 return -ENOTSUP;
     918                 :            : 
     919                 :            :         memset(&vlan_strip, 0, sizeof(vlan_strip));
     920                 :          0 :         vlan_strip.vport_id = vf->vsi_res->vsi_id;
     921                 :          0 :         *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
     922                 :            : 
     923         [ #  # ]:          0 :         args.ops = enable ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 :
     924                 :            :                             VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2;
     925                 :          0 :         args.in_args = (uint8_t *)&vlan_strip;
     926                 :          0 :         args.in_args_size = sizeof(vlan_strip);
     927                 :          0 :         args.out_buffer = msg_buf;
     928                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
     929                 :          0 :         ret = iavf_execute_vf_cmd_safe(adapter, &args);
     930         [ #  # ]:          0 :         if (ret)
     931         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR, "fail to execute command %s",
     932                 :            :                             enable ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" :
     933                 :            :                                      "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2");
     934                 :            : 
     935                 :            :         return ret;
     936                 :            : }
     937                 :            : 
     938                 :            : int
     939                 :          0 : iavf_config_outer_vlan_insert_v2(struct iavf_adapter *adapter, bool enable)
     940                 :            : {
     941                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
     942                 :            :         struct virtchnl_vlan_supported_caps *insertion_caps;
     943                 :            :         struct virtchnl_vlan_setting vlan_insert;
     944         [ #  # ]:          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
     945                 :            :         struct iavf_cmd_info args;
     946                 :            :         uint32_t *ethertype;
     947                 :            :         int ret;
     948                 :            : 
     949                 :            :         memset(&vlan_insert, 0, sizeof(vlan_insert));
     950                 :            :         insertion_caps = &vf->vlan_v2_caps.offloads.insertion_support;
     951                 :            : 
     952   [ #  #  #  # ]:          0 :         if ((insertion_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_88A8) &&
     953                 :          0 :             (insertion_caps->outer & VIRTCHNL_VLAN_TOGGLE) &&
     954         [ #  # ]:          0 :             adapter->tpid == RTE_ETHER_TYPE_QINQ) {
     955                 :            :                 ethertype = &vlan_insert.outer_ethertype_setting;
     956                 :          0 :                 *ethertype = VIRTCHNL_VLAN_ETHERTYPE_88A8;
     957   [ #  #  #  # ]:          0 :         } else if ((insertion_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
     958                 :          0 :                    (insertion_caps->outer & VIRTCHNL_VLAN_TOGGLE) &&
     959         [ #  # ]:          0 :                    adapter->tpid == RTE_ETHER_TYPE_VLAN) {
     960                 :            :                 ethertype = &vlan_insert.outer_ethertype_setting;
     961                 :          0 :                 *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
     962                 :            :         } else {
     963                 :            :                 return -ENOTSUP;
     964                 :            :         }
     965                 :            : 
     966                 :          0 :         vlan_insert.vport_id = vf->vsi_res->vsi_id;
     967                 :            : 
     968         [ #  # ]:          0 :         args.ops = enable ? VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 :
     969                 :            :                             VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2;
     970                 :          0 :         args.in_args = (uint8_t *)&vlan_insert;
     971                 :          0 :         args.in_args_size = sizeof(vlan_insert);
     972                 :          0 :         args.out_buffer = msg_buf;
     973                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
     974                 :          0 :         ret = iavf_execute_vf_cmd_safe(adapter, &args);
     975         [ #  # ]:          0 :         if (ret)
     976         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR, "fail to execute command %s",
     977                 :            :                             enable ? "VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2" :
     978                 :            :                                      "VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2");
     979                 :            : 
     980                 :            :         return ret;
     981                 :            : }
     982                 :            : 
     983                 :            : int
     984                 :          0 : iavf_config_vlan_insert_v2(struct iavf_adapter *adapter, bool enable)
     985                 :            : {
     986                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
     987                 :            :         struct virtchnl_vlan_supported_caps *insertion_caps;
     988                 :            :         struct virtchnl_vlan_setting vlan_insert;
     989                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
     990                 :            :         struct iavf_cmd_info args;
     991                 :            :         uint32_t *ethertype;
     992                 :          0 :         bool qinq = adapter->dev_data->dev_conf.rxmode.offloads &
     993                 :            :                     RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
     994                 :          0 :         bool insert_qinq = adapter->dev_data->dev_conf.txmode.offloads &
     995                 :            :                            RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
     996                 :            :         int ret;
     997                 :            : 
     998         [ #  # ]:          0 :         if (qinq && insert_qinq)
     999                 :          0 :                 iavf_config_outer_vlan_insert_v2(adapter, enable);
    1000                 :            : 
    1001                 :            :         insertion_caps = &vf->vlan_v2_caps.offloads.insertion_support;
    1002                 :            : 
    1003   [ #  #  #  #  :          0 :         if (!qinq && (insertion_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
                   #  # ]
    1004                 :            :             (insertion_caps->outer & VIRTCHNL_VLAN_TOGGLE))
    1005                 :            :                 ethertype = &vlan_insert.outer_ethertype_setting;
    1006   [ #  #  #  #  :          0 :         else if (qinq && (insertion_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
                   #  # ]
    1007                 :            :                  (insertion_caps->inner & VIRTCHNL_VLAN_TOGGLE))
    1008                 :            :                 ethertype = &vlan_insert.inner_ethertype_setting;
    1009                 :            :         else
    1010                 :            :                 return -ENOTSUP;
    1011                 :            : 
    1012                 :            :         memset(&vlan_insert, 0, sizeof(vlan_insert));
    1013                 :          0 :         vlan_insert.vport_id = vf->vsi_res->vsi_id;
    1014                 :          0 :         *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
    1015                 :            : 
    1016         [ #  # ]:          0 :         args.ops = enable ? VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 :
    1017                 :            :                             VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2;
    1018                 :          0 :         args.in_args = (uint8_t *)&vlan_insert;
    1019                 :          0 :         args.in_args_size = sizeof(vlan_insert);
    1020                 :          0 :         args.out_buffer = msg_buf;
    1021                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1022                 :          0 :         ret = iavf_execute_vf_cmd_safe(adapter, &args);
    1023         [ #  # ]:          0 :         if (ret)
    1024         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR, "fail to execute command %s",
    1025                 :            :                             enable ? "VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2" :
    1026                 :            :                                      "VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2");
    1027                 :            : 
    1028                 :            :         return ret;
    1029                 :            : }
    1030                 :            : 
    1031                 :            : int
    1032                 :          0 : iavf_add_del_vlan_v2(struct iavf_adapter *adapter, uint16_t vlanid, bool add)
    1033                 :            : {
    1034                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1035                 :            :         struct virtchnl_vlan_supported_caps *supported_caps;
    1036                 :            :         struct virtchnl_vlan_filter_list_v2 vlan_filter;
    1037                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1038                 :            :         struct virtchnl_vlan *vlan_setting;
    1039                 :            :         struct iavf_cmd_info args;
    1040                 :            :         uint32_t filtering_caps;
    1041                 :          0 :         int qinq = adapter->dev_data->dev_conf.rxmode.offloads &
    1042                 :            :                    RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
    1043                 :            :         int err;
    1044                 :            : 
    1045                 :            :         supported_caps = &vf->vlan_v2_caps.filtering.filtering_support;
    1046         [ #  # ]:          0 :         if (supported_caps->outer) {
    1047                 :            :                 filtering_caps = supported_caps->outer;
    1048                 :            :                 vlan_setting = &vlan_filter.filters[0].outer;
    1049                 :            :         } else {
    1050                 :          0 :                 filtering_caps = supported_caps->inner;
    1051                 :            :                 vlan_setting = &vlan_filter.filters[0].inner;
    1052                 :            :         }
    1053                 :            : 
    1054         [ #  # ]:          0 :         if (!(filtering_caps & VIRTCHNL_VLAN_ETHERTYPE_8100))
    1055                 :            :                 return -ENOTSUP;
    1056                 :            : 
    1057                 :            :         memset(&vlan_filter, 0, sizeof(vlan_filter));
    1058                 :          0 :         vlan_filter.vport_id = vf->vsi_res->vsi_id;
    1059                 :          0 :         vlan_filter.num_elements = 1;
    1060   [ #  #  #  # ]:          0 :         if (qinq && adapter->tpid == RTE_ETHER_TYPE_QINQ)
    1061                 :          0 :                 vlan_setting->tpid = RTE_ETHER_TYPE_QINQ;
    1062                 :            :         else
    1063                 :          0 :                 vlan_setting->tpid = RTE_ETHER_TYPE_VLAN;
    1064                 :          0 :         vlan_setting->tci = vlanid;
    1065                 :            : 
    1066         [ #  # ]:          0 :         args.ops = add ? VIRTCHNL_OP_ADD_VLAN_V2 : VIRTCHNL_OP_DEL_VLAN_V2;
    1067                 :          0 :         args.in_args = (uint8_t *)&vlan_filter;
    1068                 :          0 :         args.in_args_size = sizeof(vlan_filter);
    1069                 :          0 :         args.out_buffer = msg_buf;
    1070                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1071                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1072         [ #  # ]:          0 :         if (err)
    1073         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR, "fail to execute command %s",
    1074                 :            :                             add ? "OP_ADD_VLAN_V2" :  "OP_DEL_VLAN_V2");
    1075                 :            : 
    1076                 :            :         return err;
    1077                 :            : }
    1078                 :            : 
    1079                 :            : int
    1080                 :          0 : iavf_get_vlan_offload_caps_v2(struct iavf_adapter *adapter)
    1081                 :            : {
    1082                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1083                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1084                 :            :         struct iavf_cmd_info args;
    1085                 :            :         int ret;
    1086                 :            : 
    1087                 :          0 :         args.ops = VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS;
    1088                 :          0 :         args.in_args = NULL;
    1089                 :          0 :         args.in_args_size = 0;
    1090                 :          0 :         args.out_buffer = msg_buf;
    1091                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1092                 :            : 
    1093                 :          0 :         ret = iavf_execute_vf_cmd_safe(adapter, &args);
    1094         [ #  # ]:          0 :         if (ret) {
    1095                 :          0 :                 PMD_DRV_LOG(ERR,
    1096                 :            :                             "Failed to execute command of VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS");
    1097                 :          0 :                 return ret;
    1098                 :            :         }
    1099                 :            : 
    1100                 :          0 :         memcpy(&vf->vlan_v2_caps, args.out_buffer, sizeof(vf->vlan_v2_caps));
    1101                 :            : 
    1102                 :          0 :         return 0;
    1103                 :            : }
    1104                 :            : 
    1105                 :            : int
    1106                 :          0 : iavf_enable_queues(struct iavf_adapter *adapter)
    1107                 :            : {
    1108                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1109                 :            :         struct virtchnl_queue_select queue_select;
    1110                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1111                 :            :         struct iavf_cmd_info args;
    1112                 :            :         int err;
    1113                 :            : 
    1114                 :            :         memset(&queue_select, 0, sizeof(queue_select));
    1115                 :          0 :         queue_select.vsi_id = vf->vsi_res->vsi_id;
    1116                 :            : 
    1117                 :          0 :         queue_select.rx_queues = BIT(adapter->dev_data->nb_rx_queues) - 1;
    1118                 :          0 :         queue_select.tx_queues = BIT(adapter->dev_data->nb_tx_queues) - 1;
    1119                 :            : 
    1120                 :          0 :         args.ops = VIRTCHNL_OP_ENABLE_QUEUES;
    1121                 :          0 :         args.in_args = (u8 *)&queue_select;
    1122                 :          0 :         args.in_args_size = sizeof(queue_select);
    1123                 :          0 :         args.out_buffer = msg_buf;
    1124                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1125                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1126         [ #  # ]:          0 :         if (err) {
    1127                 :          0 :                 PMD_DRV_LOG(ERR,
    1128                 :            :                             "Failed to execute command of OP_ENABLE_QUEUES");
    1129                 :          0 :                 return err;
    1130                 :            :         }
    1131                 :            :         return 0;
    1132                 :            : }
    1133                 :            : 
    1134                 :            : int
    1135                 :          0 : iavf_disable_queues(struct iavf_adapter *adapter)
    1136                 :            : {
    1137                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1138                 :            :         struct virtchnl_queue_select queue_select;
    1139                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1140                 :            :         struct iavf_cmd_info args;
    1141                 :            :         int err;
    1142                 :            : 
    1143                 :            :         memset(&queue_select, 0, sizeof(queue_select));
    1144                 :          0 :         queue_select.vsi_id = vf->vsi_res->vsi_id;
    1145                 :            : 
    1146                 :          0 :         queue_select.rx_queues = BIT(adapter->dev_data->nb_rx_queues) - 1;
    1147                 :          0 :         queue_select.tx_queues = BIT(adapter->dev_data->nb_tx_queues) - 1;
    1148                 :            : 
    1149                 :          0 :         args.ops = VIRTCHNL_OP_DISABLE_QUEUES;
    1150                 :          0 :         args.in_args = (u8 *)&queue_select;
    1151                 :          0 :         args.in_args_size = sizeof(queue_select);
    1152                 :          0 :         args.out_buffer = msg_buf;
    1153                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1154                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1155         [ #  # ]:          0 :         if (err) {
    1156                 :          0 :                 PMD_DRV_LOG(ERR,
    1157                 :            :                             "Failed to execute command of OP_DISABLE_QUEUES");
    1158                 :          0 :                 return err;
    1159                 :            :         }
    1160                 :            :         return 0;
    1161                 :            : }
    1162                 :            : 
    1163                 :            : int
    1164                 :          0 : iavf_switch_queue(struct iavf_adapter *adapter, uint16_t qid,
    1165                 :            :                  bool rx, bool on)
    1166                 :            : {
    1167                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1168                 :            :         struct virtchnl_queue_select queue_select;
    1169                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1170                 :            :         struct iavf_cmd_info args;
    1171                 :            :         int err;
    1172                 :            : 
    1173         [ #  # ]:          0 :         if (adapter->closed)
    1174                 :            :                 return -EIO;
    1175                 :            : 
    1176                 :            :         memset(&queue_select, 0, sizeof(queue_select));
    1177                 :          0 :         queue_select.vsi_id = vf->vsi_res->vsi_id;
    1178         [ #  # ]:          0 :         if (rx)
    1179                 :          0 :                 queue_select.rx_queues |= 1 << qid;
    1180                 :            :         else
    1181                 :          0 :                 queue_select.tx_queues |= 1 << qid;
    1182                 :            : 
    1183         [ #  # ]:          0 :         if (on)
    1184                 :          0 :                 args.ops = VIRTCHNL_OP_ENABLE_QUEUES;
    1185                 :            :         else
    1186                 :          0 :                 args.ops = VIRTCHNL_OP_DISABLE_QUEUES;
    1187                 :          0 :         args.in_args = (u8 *)&queue_select;
    1188                 :          0 :         args.in_args_size = sizeof(queue_select);
    1189                 :          0 :         args.out_buffer = msg_buf;
    1190                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1191                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1192         [ #  # ]:          0 :         if (err)
    1193         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR, "Failed to execute command of %s",
    1194                 :            :                             on ? "OP_ENABLE_QUEUES" : "OP_DISABLE_QUEUES");
    1195                 :            :         return err;
    1196                 :            : }
    1197                 :            : 
    1198                 :            : int
    1199                 :          0 : iavf_enable_queues_lv(struct iavf_adapter *adapter)
    1200                 :            : {
    1201                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1202                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1203                 :            :         struct {
    1204                 :            :                 struct virtchnl_del_ena_dis_queues msg;
    1205                 :            :                 struct virtchnl_queue_chunk chunks[IAVF_RXTX_QUEUE_CHUNKS_NUM - 1];
    1206                 :          0 :         } queue_req = {0};
    1207                 :            :         struct virtchnl_del_ena_dis_queues *queue_select = &queue_req.msg;
    1208                 :            :         struct virtchnl_queue_chunk *queue_chunk = queue_select->chunks.chunks;
    1209                 :            :         struct iavf_cmd_info args;
    1210                 :            :         int err;
    1211                 :            : 
    1212                 :          0 :         queue_select->chunks.num_chunks = IAVF_RXTX_QUEUE_CHUNKS_NUM;
    1213                 :          0 :         queue_select->vport_id = vf->vsi_res->vsi_id;
    1214                 :            : 
    1215                 :            :         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].type = VIRTCHNL_QUEUE_TYPE_TX;
    1216                 :            :         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].start_queue_id = 0;
    1217                 :          0 :         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].num_queues =
    1218                 :          0 :                 adapter->dev_data->nb_tx_queues;
    1219                 :            : 
    1220                 :          0 :         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].type = VIRTCHNL_QUEUE_TYPE_RX;
    1221                 :            :         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].start_queue_id = 0;
    1222                 :          0 :         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].num_queues =
    1223                 :          0 :                 adapter->dev_data->nb_rx_queues;
    1224                 :            : 
    1225                 :          0 :         args.ops = VIRTCHNL_OP_ENABLE_QUEUES_V2;
    1226                 :          0 :         args.in_args = (u8 *)queue_select;
    1227                 :          0 :         args.in_args_size = sizeof(queue_req);
    1228                 :          0 :         args.out_buffer = msg_buf;
    1229                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1230                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1231         [ #  # ]:          0 :         if (err)
    1232                 :          0 :                 PMD_DRV_LOG(ERR,
    1233                 :            :                             "Failed to execute command of OP_ENABLE_QUEUES_V2");
    1234                 :            : 
    1235                 :          0 :         return err;
    1236                 :            : }
    1237                 :            : 
    1238                 :            : int
    1239                 :          0 : iavf_disable_queues_lv(struct iavf_adapter *adapter)
    1240                 :            : {
    1241                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1242                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1243                 :            :         struct {
    1244                 :            :                 struct virtchnl_del_ena_dis_queues msg;
    1245                 :            :                 struct virtchnl_queue_chunk chunks[IAVF_RXTX_QUEUE_CHUNKS_NUM - 1];
    1246                 :          0 :         } queue_req = {0};
    1247                 :            :         struct virtchnl_del_ena_dis_queues *queue_select = &queue_req.msg;
    1248                 :            :         struct virtchnl_queue_chunk *queue_chunk = queue_select->chunks.chunks;
    1249                 :            :         struct iavf_cmd_info args;
    1250                 :            :         int err;
    1251                 :            : 
    1252                 :          0 :         queue_select->chunks.num_chunks = IAVF_RXTX_QUEUE_CHUNKS_NUM;
    1253                 :          0 :         queue_select->vport_id = vf->vsi_res->vsi_id;
    1254                 :            : 
    1255                 :            :         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].type = VIRTCHNL_QUEUE_TYPE_TX;
    1256                 :            :         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].start_queue_id = 0;
    1257                 :          0 :         queue_chunk[VIRTCHNL_QUEUE_TYPE_TX].num_queues =
    1258                 :          0 :                 adapter->dev_data->nb_tx_queues;
    1259                 :            : 
    1260                 :          0 :         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].type = VIRTCHNL_QUEUE_TYPE_RX;
    1261                 :            :         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].start_queue_id = 0;
    1262                 :          0 :         queue_chunk[VIRTCHNL_QUEUE_TYPE_RX].num_queues =
    1263                 :          0 :                 adapter->dev_data->nb_rx_queues;
    1264                 :            : 
    1265                 :          0 :         args.ops = VIRTCHNL_OP_DISABLE_QUEUES_V2;
    1266                 :          0 :         args.in_args = (u8 *)queue_select;
    1267                 :          0 :         args.in_args_size = sizeof(queue_req);
    1268                 :          0 :         args.out_buffer = msg_buf;
    1269                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1270                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1271         [ #  # ]:          0 :         if (err)
    1272                 :          0 :                 PMD_DRV_LOG(ERR,
    1273                 :            :                             "Failed to execute command of OP_DISABLE_QUEUES_V2");
    1274                 :            : 
    1275                 :          0 :         return err;
    1276                 :            : }
    1277                 :            : 
    1278                 :            : int
    1279                 :          0 : iavf_switch_queue_lv(struct iavf_adapter *adapter, uint16_t qid,
    1280                 :            :                  bool rx, bool on)
    1281                 :            : {
    1282                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1283                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1284                 :            :         struct {
    1285                 :            :                 struct virtchnl_del_ena_dis_queues msg;
    1286                 :          0 :         } queue_req = {0};
    1287                 :            :         struct virtchnl_del_ena_dis_queues *queue_select = &queue_req.msg;
    1288                 :            :         struct virtchnl_queue_chunk *queue_chunk = queue_select->chunks.chunks;
    1289                 :            :         struct iavf_cmd_info args;
    1290                 :            :         int err;
    1291                 :            : 
    1292                 :          0 :         queue_select->chunks.num_chunks = 1;
    1293                 :          0 :         queue_select->vport_id = vf->vsi_res->vsi_id;
    1294                 :            : 
    1295         [ #  # ]:          0 :         if (rx) {
    1296                 :          0 :                 queue_chunk->type = VIRTCHNL_QUEUE_TYPE_RX;
    1297                 :          0 :                 queue_chunk->start_queue_id = qid;
    1298                 :          0 :                 queue_chunk->num_queues = 1;
    1299                 :            :         } else {
    1300                 :            :                 queue_chunk->type = VIRTCHNL_QUEUE_TYPE_TX;
    1301                 :          0 :                 queue_chunk->start_queue_id = qid;
    1302                 :          0 :                 queue_chunk->num_queues = 1;
    1303                 :            :         }
    1304                 :            : 
    1305         [ #  # ]:          0 :         if (on)
    1306                 :          0 :                 args.ops = VIRTCHNL_OP_ENABLE_QUEUES_V2;
    1307                 :            :         else
    1308                 :          0 :                 args.ops = VIRTCHNL_OP_DISABLE_QUEUES_V2;
    1309                 :          0 :         args.in_args = (u8 *)queue_select;
    1310                 :          0 :         args.in_args_size = sizeof(queue_req);
    1311                 :          0 :         args.out_buffer = msg_buf;
    1312                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1313                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1314         [ #  # ]:          0 :         if (err)
    1315         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR, "Failed to execute command of %s",
    1316                 :            :                             on ? "OP_ENABLE_QUEUES_V2" : "OP_DISABLE_QUEUES_V2");
    1317                 :            : 
    1318                 :          0 :         return err;
    1319                 :            : }
    1320                 :            : 
    1321                 :            : int
    1322                 :          0 : iavf_configure_rss_lut(struct iavf_adapter *adapter)
    1323                 :            : {
    1324                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1325                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1326                 :            :         struct virtchnl_rss_lut *rss_lut;
    1327                 :            :         struct iavf_cmd_info args;
    1328                 :            :         int len, err = 0;
    1329                 :            : 
    1330                 :          0 :         len = sizeof(*rss_lut) + vf->vf_res->rss_lut_size - 1;
    1331                 :          0 :         rss_lut = calloc(1, len);
    1332         [ #  # ]:          0 :         if (!rss_lut)
    1333                 :            :                 return -ENOMEM;
    1334                 :            : 
    1335                 :          0 :         rss_lut->vsi_id = vf->vsi_res->vsi_id;
    1336                 :          0 :         rss_lut->lut_entries = vf->vf_res->rss_lut_size;
    1337                 :          0 :         memcpy(rss_lut->lut, vf->rss_lut, vf->vf_res->rss_lut_size);
    1338                 :            : 
    1339                 :          0 :         args.ops = VIRTCHNL_OP_CONFIG_RSS_LUT;
    1340                 :          0 :         args.in_args = (u8 *)rss_lut;
    1341                 :          0 :         args.in_args_size = len;
    1342                 :          0 :         args.out_buffer = msg_buf;
    1343                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1344                 :            : 
    1345                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1346         [ #  # ]:          0 :         if (err)
    1347                 :          0 :                 PMD_DRV_LOG(ERR,
    1348                 :            :                             "Failed to execute command of OP_CONFIG_RSS_LUT");
    1349                 :            : 
    1350                 :          0 :         free(rss_lut);
    1351                 :          0 :         return err;
    1352                 :            : }
    1353                 :            : 
    1354                 :            : int
    1355                 :          0 : iavf_configure_rss_key(struct iavf_adapter *adapter)
    1356                 :            : {
    1357                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1358                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1359                 :            :         struct virtchnl_rss_key *rss_key;
    1360                 :            :         struct iavf_cmd_info args;
    1361                 :            :         int len, err = 0;
    1362                 :            : 
    1363                 :          0 :         len = sizeof(*rss_key) + vf->vf_res->rss_key_size - 1;
    1364                 :          0 :         rss_key = calloc(1, len);
    1365         [ #  # ]:          0 :         if (!rss_key)
    1366                 :            :                 return -ENOMEM;
    1367                 :            : 
    1368                 :          0 :         rss_key->vsi_id = vf->vsi_res->vsi_id;
    1369                 :          0 :         rss_key->key_len = vf->vf_res->rss_key_size;
    1370                 :          0 :         memcpy(rss_key->key, vf->rss_key, vf->vf_res->rss_key_size);
    1371                 :            : 
    1372                 :          0 :         args.ops = VIRTCHNL_OP_CONFIG_RSS_KEY;
    1373                 :          0 :         args.in_args = (u8 *)rss_key;
    1374                 :          0 :         args.in_args_size = len;
    1375                 :          0 :         args.out_buffer = msg_buf;
    1376                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1377                 :            : 
    1378                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1379         [ #  # ]:          0 :         if (err)
    1380                 :          0 :                 PMD_DRV_LOG(ERR,
    1381                 :            :                             "Failed to execute command of OP_CONFIG_RSS_KEY");
    1382                 :            : 
    1383                 :          0 :         free(rss_key);
    1384                 :          0 :         return err;
    1385                 :            : }
    1386                 :            : 
    1387                 :            : static void
    1388                 :          0 : iavf_configure_queue_pair(struct iavf_adapter *adapter,
    1389                 :            :                 struct virtchnl_queue_pair_info *vc_qp,
    1390                 :            :                 uint16_t q_idx)
    1391                 :            : {
    1392                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1393                 :          0 :         struct ci_rx_queue **rxq = (struct ci_rx_queue **)adapter->dev_data->rx_queues;
    1394                 :          0 :         struct ci_tx_queue **txq = (struct ci_tx_queue **)adapter->dev_data->tx_queues;
    1395                 :            : 
    1396                 :            :         /* common parts */
    1397                 :          0 :         vc_qp->txq.vsi_id = vf->vsi_res->vsi_id;
    1398                 :          0 :         vc_qp->txq.queue_id = q_idx;
    1399                 :            : 
    1400                 :          0 :         vc_qp->rxq.vsi_id = vf->vsi_res->vsi_id;
    1401                 :          0 :         vc_qp->rxq.queue_id = q_idx;
    1402                 :          0 :         vc_qp->rxq.max_pkt_size = vf->max_pkt_len;
    1403                 :            : 
    1404                 :            :         /* is this txq active? */
    1405         [ #  # ]:          0 :         if (q_idx < adapter->dev_data->nb_tx_queues) {
    1406                 :          0 :                 vc_qp->txq.ring_len = txq[q_idx]->nb_tx_desc;
    1407                 :          0 :                 vc_qp->txq.dma_ring_addr = txq[q_idx]->tx_ring_dma;
    1408                 :            :         }
    1409                 :            : 
    1410                 :            :         /* is this rxq active? */
    1411         [ #  # ]:          0 :         if (q_idx >= adapter->dev_data->nb_rx_queues)
    1412                 :            :                 return;
    1413                 :            : 
    1414                 :          0 :         vc_qp->rxq.ring_len = rxq[q_idx]->nb_rx_desc;
    1415                 :          0 :         vc_qp->rxq.dma_ring_addr = rxq[q_idx]->rx_ring_phys_addr;
    1416                 :          0 :         vc_qp->rxq.databuffer_size = rxq[q_idx]->rx_buf_len;
    1417                 :          0 :         vc_qp->rxq.crc_disable = rxq[q_idx]->crc_len != 0 ? 1 : 0;
    1418         [ #  # ]:          0 :         if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC) {
    1419         [ #  # ]:          0 :                 if (vf->supported_rxdid & RTE_BIT64(rxq[q_idx]->rxdid)) {
    1420                 :          0 :                         vc_qp->rxq.rxdid = rxq[q_idx]->rxdid;
    1421                 :          0 :                         PMD_DRV_LOG(NOTICE, "request RXDID[%d] in Queue[%d]",
    1422                 :            :                                         vc_qp->rxq.rxdid, q_idx);
    1423                 :            :                 } else {
    1424                 :          0 :                         PMD_DRV_LOG(NOTICE, "RXDID[%d] is not supported, "
    1425                 :            :                                         "request default RXDID[%d] in Queue[%d]",
    1426                 :            :                                         rxq[q_idx]->rxdid, IAVF_RXDID_LEGACY_1, q_idx);
    1427                 :          0 :                         vc_qp->rxq.rxdid = IAVF_RXDID_LEGACY_1;
    1428                 :            :                 }
    1429                 :            : 
    1430         [ #  # ]:          0 :                 if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_CAP_PTP &&
    1431         [ #  # ]:          0 :                         vf->ptp_caps & VIRTCHNL_1588_PTP_CAP_RX_TSTAMP &&
    1432         [ #  # ]:          0 :                         rxq[q_idx]->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP)
    1433                 :          0 :                         vc_qp->rxq.flags |= VIRTCHNL_PTP_RX_TSTAMP;
    1434                 :            :         }
    1435                 :            : }
    1436                 :            : 
    1437                 :            : static int
    1438                 :          0 : iavf_configure_queue_chunk(struct iavf_adapter *adapter,
    1439                 :            :                 uint16_t chunk_sz,
    1440                 :            :                 uint16_t chunk_start)
    1441                 :            : {
    1442                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1443                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1444                 :            :         struct {
    1445                 :            :                 struct virtchnl_vsi_queue_config_info config;
    1446                 :            :                 struct virtchnl_queue_pair_info qp[IAVF_CFG_Q_NUM_PER_BUF];
    1447                 :          0 :         } queue_req = {0};
    1448                 :          0 :         struct iavf_cmd_info args = {0};
    1449                 :            :         struct virtchnl_vsi_queue_config_info *vc_config = &queue_req.config;
    1450                 :            :         struct virtchnl_queue_pair_info *vc_qp = vc_config->qpair;
    1451                 :          0 :         uint16_t chunk_end = chunk_start + chunk_sz;
    1452                 :            :         uint16_t i;
    1453                 :            :         size_t buf_len;
    1454                 :            :         int err;
    1455                 :            : 
    1456         [ #  # ]:          0 :         if (chunk_sz > IAVF_CFG_Q_NUM_PER_BUF)
    1457                 :            :                 return -EINVAL;
    1458                 :            : 
    1459                 :          0 :         vc_config->vsi_id = vf->vsi_res->vsi_id;
    1460                 :          0 :         vc_config->num_queue_pairs = chunk_sz;
    1461                 :            : 
    1462         [ #  # ]:          0 :         for (i = chunk_start; i < chunk_end; i++, vc_qp++)
    1463                 :          0 :                 iavf_configure_queue_pair(adapter, vc_qp, i);
    1464                 :            : 
    1465                 :            :         /* for some reason PF side checks for buffer being too big, so adjust it down */
    1466                 :          0 :         buf_len = sizeof(struct virtchnl_vsi_queue_config_info) +
    1467                 :          0 :                         sizeof(struct virtchnl_queue_pair_info) * chunk_sz;
    1468                 :            : 
    1469                 :          0 :         args.ops = VIRTCHNL_OP_CONFIG_VSI_QUEUES;
    1470                 :          0 :         args.in_args = (uint8_t *)vc_config;
    1471                 :          0 :         args.in_args_size = buf_len;
    1472                 :          0 :         args.out_buffer = msg_buf;
    1473                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1474                 :            : 
    1475                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1476         [ #  # ]:          0 :         if (err)
    1477                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to execute command VIRTCHNL_OP_CONFIG_VSI_QUEUES");
    1478                 :            :         return err;
    1479                 :            : }
    1480                 :            : 
    1481                 :            : int
    1482                 :          0 : iavf_configure_queues(struct iavf_adapter *adapter, uint16_t num_queue_pairs)
    1483                 :            : {
    1484                 :            :         uint16_t c;
    1485                 :            :         int err;
    1486                 :            : 
    1487                 :            :         /*
    1488                 :            :          * we cannot configure all queues in one go because they won't fit into
    1489                 :            :          * adminq buffer, so we're going to chunk them instead
    1490                 :            :          */
    1491         [ #  # ]:          0 :         for (c = 0; c < num_queue_pairs; c += IAVF_CFG_Q_NUM_PER_BUF) {
    1492                 :          0 :                 uint16_t chunk_sz = RTE_MIN(num_queue_pairs - c, IAVF_CFG_Q_NUM_PER_BUF);
    1493                 :          0 :                 err = iavf_configure_queue_chunk(adapter, chunk_sz, c);
    1494         [ #  # ]:          0 :                 if (err) {
    1495                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to configure queues chunk [%u, %u)",
    1496                 :            :                                         c, c + chunk_sz);
    1497                 :          0 :                         return err;
    1498                 :            :                 }
    1499                 :            :         }
    1500                 :            :         return 0;
    1501                 :            : }
    1502                 :            : 
    1503                 :            : int
    1504                 :          0 : iavf_config_irq_map(struct iavf_adapter *adapter)
    1505                 :            : {
    1506                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1507                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1508                 :            :         struct {
    1509                 :            :                 struct virtchnl_irq_map_info map_info;
    1510                 :            :                 struct virtchnl_vector_map vecmap[IAVF_MAX_NUM_QUEUES_DFLT];
    1511                 :          0 :         } map_req = {0};
    1512                 :            :         struct virtchnl_irq_map_info *map_info = &map_req.map_info;
    1513                 :          0 :         struct iavf_cmd_info args = {0};
    1514                 :            :         int i, err, max_vmi = -1;
    1515                 :            :         size_t buf_len;
    1516                 :            : 
    1517         [ #  # ]:          0 :         if (adapter->dev_data->nb_rx_queues > IAVF_MAX_NUM_QUEUES_DFLT) {
    1518                 :          0 :                 PMD_DRV_LOG(ERR, "number of queues (%u) exceeds the max supported (%u)",
    1519                 :            :                             adapter->dev_data->nb_rx_queues, IAVF_MAX_NUM_QUEUES_DFLT);
    1520                 :          0 :                 return -EINVAL;
    1521                 :            :         }
    1522                 :            : 
    1523         [ #  # ]:          0 :         for (i = 0; i < adapter->dev_data->nb_rx_queues; i++) {
    1524                 :            :                 struct virtchnl_vector_map *vecmap;
    1525                 :            :                 /* always 0 for 1 MSIX, never bigger than rxq for multi MSIX */
    1526                 :          0 :                 uint16_t vmi = vf->qv_map[i].vector_id - vf->msix_base;
    1527                 :            : 
    1528                 :            :                 /* can't happen but avoid static analysis warnings */
    1529         [ #  # ]:          0 :                 if (vmi >= IAVF_MAX_NUM_QUEUES_DFLT) {
    1530                 :          0 :                         PMD_DRV_LOG(ERR, "vector id (%u) exceeds the max supported (%u)",
    1531                 :            :                                         vf->qv_map[i].vector_id,
    1532                 :            :                                         vf->msix_base + IAVF_MAX_NUM_QUEUES_DFLT - 1);
    1533                 :          0 :                         return -EINVAL;
    1534                 :            :                 }
    1535                 :            : 
    1536                 :          0 :                 vecmap = &map_info->vecmap[vmi];
    1537                 :          0 :                 vecmap->vsi_id = vf->vsi_res->vsi_id;
    1538                 :          0 :                 vecmap->rxitr_idx = IAVF_ITR_INDEX_DEFAULT;
    1539                 :          0 :                 vecmap->vector_id = vf->qv_map[i].vector_id;
    1540                 :          0 :                 vecmap->txq_map = 0;
    1541                 :          0 :                 vecmap->rxq_map |= 1 << vf->qv_map[i].queue_id;
    1542                 :            : 
    1543                 :            :                 /* MSIX vectors round robin so look for max */
    1544         [ #  # ]:          0 :                 if (vmi > max_vmi) {
    1545                 :          0 :                         map_info->num_vectors++;
    1546                 :            :                         max_vmi = vmi;
    1547                 :            :                 }
    1548                 :            :         }
    1549                 :            : 
    1550                 :            :         /* for some reason PF side checks for buffer being too big, so adjust it down */
    1551                 :          0 :         buf_len = sizeof(struct virtchnl_irq_map_info) +
    1552                 :          0 :                   sizeof(struct virtchnl_vector_map) * map_info->num_vectors;
    1553                 :            : 
    1554                 :          0 :         args.ops = VIRTCHNL_OP_CONFIG_IRQ_MAP;
    1555                 :          0 :         args.in_args = (u8 *)map_info;
    1556                 :          0 :         args.in_args_size = buf_len;
    1557                 :          0 :         args.out_buffer = msg_buf;
    1558                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1559                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1560         [ #  # ]:          0 :         if (err)
    1561                 :          0 :                 PMD_DRV_LOG(ERR, "fail to execute command OP_CONFIG_IRQ_MAP");
    1562                 :            : 
    1563                 :            :         return err;
    1564                 :            : }
    1565                 :            : 
    1566                 :            : static int
    1567                 :          0 : iavf_config_irq_map_lv_chunk(struct iavf_adapter *adapter,
    1568                 :            :                 uint16_t chunk_sz,
    1569                 :            :                 uint16_t chunk_start)
    1570                 :            : {
    1571                 :            :         struct {
    1572                 :            :                 struct virtchnl_queue_vector_maps map_info;
    1573                 :            :                 struct virtchnl_queue_vector qv_maps[IAVF_CFG_Q_NUM_PER_BUF];
    1574                 :          0 :         } chunk_req = {0};
    1575                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1576                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1577                 :          0 :         struct iavf_cmd_info args = {0};
    1578                 :            :         struct virtchnl_queue_vector_maps *map_info = &chunk_req.map_info;
    1579                 :            :         struct virtchnl_queue_vector *qv_maps = chunk_req.qv_maps;
    1580                 :            :         size_t buf_len;
    1581                 :            :         uint16_t i;
    1582                 :            : 
    1583         [ #  # ]:          0 :         if (chunk_sz > IAVF_CFG_Q_NUM_PER_BUF)
    1584                 :            :                 return -EINVAL;
    1585                 :            : 
    1586                 :          0 :         map_info->vport_id = vf->vsi_res->vsi_id;
    1587                 :          0 :         map_info->num_qv_maps = chunk_sz;
    1588         [ #  # ]:          0 :         for (i = 0; i < chunk_sz; i++) {
    1589                 :          0 :                 qv_maps = &map_info->qv_maps[i];
    1590                 :          0 :                 qv_maps->itr_idx = VIRTCHNL_ITR_IDX_0;
    1591                 :          0 :                 qv_maps->queue_type = VIRTCHNL_QUEUE_TYPE_RX;
    1592                 :          0 :                 qv_maps->queue_id = vf->qv_map[chunk_start + i].queue_id;
    1593                 :          0 :                 qv_maps->vector_id = vf->qv_map[chunk_start + i].vector_id;
    1594                 :            :         }
    1595                 :            : 
    1596                 :            :         /* for some reason PF side checks for buffer being too big, so adjust it down */
    1597                 :          0 :         buf_len = sizeof(struct virtchnl_queue_vector_maps) +
    1598                 :          0 :                   sizeof(struct virtchnl_queue_vector) * (chunk_sz - 1);
    1599                 :            : 
    1600                 :          0 :         args.ops = VIRTCHNL_OP_MAP_QUEUE_VECTOR;
    1601                 :          0 :         args.in_args = (u8 *)map_info;
    1602                 :          0 :         args.in_args_size = buf_len;
    1603                 :          0 :         args.out_buffer = msg_buf;
    1604                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1605                 :            : 
    1606                 :          0 :         return iavf_execute_vf_cmd_safe(adapter, &args);
    1607                 :            : }
    1608                 :            : 
    1609                 :            : int
    1610                 :          0 : iavf_config_irq_map_lv(struct iavf_adapter *adapter, uint16_t num)
    1611                 :            : {
    1612                 :            :         uint16_t c;
    1613                 :            :         int err;
    1614                 :            : 
    1615         [ #  # ]:          0 :         for (c = 0; c < num; c += IAVF_CFG_Q_NUM_PER_BUF) {
    1616                 :          0 :                 uint16_t chunk_sz = RTE_MIN(num - c, IAVF_CFG_Q_NUM_PER_BUF);
    1617                 :          0 :                 err = iavf_config_irq_map_lv_chunk(adapter, chunk_sz, c);
    1618         [ #  # ]:          0 :                 if (err) {
    1619                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to configure irq map chunk [%u, %u)",
    1620                 :            :                                         c, c + chunk_sz);
    1621                 :          0 :                         return err;
    1622                 :            :                 }
    1623                 :            :         }
    1624                 :            :         return 0;
    1625                 :            : }
    1626                 :            : 
    1627                 :            : void
    1628                 :          0 : iavf_add_del_all_mac_addr(struct iavf_adapter *adapter, bool add)
    1629                 :            : {
    1630                 :            :         struct {
    1631                 :            :                 struct virtchnl_ether_addr_list list;
    1632                 :            :                 struct virtchnl_ether_addr addr[IAVF_NUM_MACADDR_MAX];
    1633                 :          0 :         } list_req = {0};
    1634                 :            :         struct virtchnl_ether_addr_list *list = &list_req.list;
    1635                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1636                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1637                 :          0 :         struct iavf_cmd_info args = {0};
    1638                 :            :         int err, i;
    1639                 :            :         size_t buf_len;
    1640                 :            : 
    1641         [ #  # ]:          0 :         for (i = 0; i < IAVF_NUM_MACADDR_MAX; i++) {
    1642                 :          0 :                 struct rte_ether_addr *addr = &adapter->dev_data->mac_addrs[i];
    1643         [ #  # ]:          0 :                 struct virtchnl_ether_addr *vc_addr = &list->list[list->num_elements];
    1644                 :            : 
    1645                 :            :                 /* ignore empty addresses */
    1646         [ #  # ]:          0 :                 if (rte_is_zero_ether_addr(addr))
    1647                 :          0 :                         continue;
    1648                 :          0 :                 list->num_elements++;
    1649                 :            : 
    1650         [ #  # ]:          0 :                 memcpy(vc_addr->addr, addr->addr_bytes, sizeof(addr->addr_bytes));
    1651         [ #  # ]:          0 :                 vc_addr->type = (list->num_elements == 1) ?
    1652                 :            :                                 VIRTCHNL_ETHER_ADDR_PRIMARY :
    1653                 :            :                                 VIRTCHNL_ETHER_ADDR_EXTRA;
    1654                 :            :         }
    1655                 :            : 
    1656                 :            :         /* for some reason PF side checks for buffer being too big, so adjust it down */
    1657                 :          0 :         buf_len = sizeof(struct virtchnl_ether_addr_list) +
    1658                 :          0 :                   sizeof(struct virtchnl_ether_addr) * list->num_elements;
    1659                 :            : 
    1660                 :          0 :         list->vsi_id = vf->vsi_res->vsi_id;
    1661         [ #  # ]:          0 :         args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR;
    1662                 :          0 :         args.in_args = (uint8_t *)list;
    1663                 :          0 :         args.in_args_size = buf_len;
    1664                 :          0 :         args.out_buffer = msg_buf;
    1665                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1666                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1667         [ #  # ]:          0 :         if (err)
    1668         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR, "fail to execute command %s",
    1669                 :            :                                 add ? "OP_ADD_ETHER_ADDRESS" : "OP_DEL_ETHER_ADDRESS");
    1670                 :          0 : }
    1671                 :            : 
    1672                 :            : int
    1673                 :          0 : iavf_query_stats(struct iavf_adapter *adapter,
    1674                 :            :                 struct virtchnl_eth_stats *pstats)
    1675                 :            : {
    1676                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1677                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1678                 :            :         struct virtchnl_queue_select q_stats;
    1679                 :            :         struct iavf_cmd_info args;
    1680                 :            :         int err;
    1681                 :            : 
    1682         [ #  # ]:          0 :         if (adapter->closed)
    1683                 :            :                 return -EIO;
    1684                 :            : 
    1685                 :            :         memset(&q_stats, 0, sizeof(q_stats));
    1686                 :          0 :         q_stats.vsi_id = vf->vsi_res->vsi_id;
    1687                 :          0 :         args.ops = VIRTCHNL_OP_GET_STATS;
    1688                 :          0 :         args.in_args = (uint8_t *)&q_stats;
    1689                 :          0 :         args.in_args_size = sizeof(q_stats);
    1690                 :          0 :         args.out_buffer = msg_buf;
    1691                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1692                 :            : 
    1693                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1694         [ #  # ]:          0 :         if (err) {
    1695                 :          0 :                 PMD_DRV_LOG(ERR, "fail to execute command OP_GET_STATS");
    1696                 :          0 :                 return err;
    1697                 :            :         }
    1698                 :          0 :         *pstats = *(struct virtchnl_eth_stats *)args.out_buffer;
    1699                 :          0 :         return 0;
    1700                 :            : }
    1701                 :            : 
    1702                 :            : int
    1703                 :          0 : iavf_config_promisc(struct iavf_adapter *adapter,
    1704                 :            :                    bool enable_unicast,
    1705                 :            :                    bool enable_multicast)
    1706                 :            : {
    1707                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1708                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1709                 :            :         struct virtchnl_promisc_info promisc;
    1710                 :            :         struct iavf_cmd_info args;
    1711                 :            :         int err;
    1712                 :            : 
    1713         [ #  # ]:          0 :         if (adapter->closed)
    1714                 :            :                 return -EIO;
    1715                 :            : 
    1716                 :          0 :         promisc.flags = 0;
    1717                 :          0 :         promisc.vsi_id = vf->vsi_res->vsi_id;
    1718                 :            : 
    1719         [ #  # ]:          0 :         if (enable_unicast)
    1720                 :          0 :                 promisc.flags |= FLAG_VF_UNICAST_PROMISC;
    1721                 :            : 
    1722         [ #  # ]:          0 :         if (enable_multicast)
    1723                 :          0 :                 promisc.flags |= FLAG_VF_MULTICAST_PROMISC;
    1724                 :            : 
    1725                 :          0 :         args.ops = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE;
    1726                 :          0 :         args.in_args = (uint8_t *)&promisc;
    1727                 :          0 :         args.in_args_size = sizeof(promisc);
    1728                 :          0 :         args.out_buffer = msg_buf;
    1729                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1730                 :            : 
    1731                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1732                 :            : 
    1733         [ #  # ]:          0 :         if (err) {
    1734                 :          0 :                 PMD_DRV_LOG(ERR,
    1735                 :            :                             "fail to execute command CONFIG_PROMISCUOUS_MODE");
    1736                 :            : 
    1737         [ #  # ]:          0 :                 if (err == -ENOTSUP)
    1738                 :            :                         return err;
    1739                 :            : 
    1740                 :          0 :                 return -EAGAIN;
    1741                 :            :         }
    1742                 :            : 
    1743                 :          0 :         vf->promisc_unicast_enabled = enable_unicast;
    1744                 :          0 :         vf->promisc_multicast_enabled = enable_multicast;
    1745                 :          0 :         return 0;
    1746                 :            : }
    1747                 :            : 
    1748                 :            : int
    1749                 :          0 : iavf_add_del_eth_addr(struct iavf_adapter *adapter, struct rte_ether_addr *addr,
    1750                 :            :                      bool add, uint8_t type)
    1751                 :            : {
    1752                 :            :         struct virtchnl_ether_addr_list *list;
    1753                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1754                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1755                 :            :         uint8_t cmd_buffer[sizeof(struct virtchnl_ether_addr_list) +
    1756                 :            :                            sizeof(struct virtchnl_ether_addr)];
    1757                 :            :         struct iavf_cmd_info args;
    1758                 :            :         int err;
    1759                 :            : 
    1760         [ #  # ]:          0 :         if (adapter->closed)
    1761                 :            :                 return -EIO;
    1762                 :            : 
    1763                 :            :         list = (struct virtchnl_ether_addr_list *)cmd_buffer;
    1764                 :          0 :         list->vsi_id = vf->vsi_res->vsi_id;
    1765                 :          0 :         list->num_elements = 1;
    1766                 :          0 :         list->list[0].type = type;
    1767                 :            :         memcpy(list->list[0].addr, addr->addr_bytes,
    1768                 :            :                    sizeof(addr->addr_bytes));
    1769                 :            : 
    1770         [ #  # ]:          0 :         args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR;
    1771                 :          0 :         args.in_args = cmd_buffer;
    1772                 :          0 :         args.in_args_size = sizeof(cmd_buffer);
    1773                 :          0 :         args.out_buffer = msg_buf;
    1774                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1775                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1776         [ #  # ]:          0 :         if (err)
    1777         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR, "fail to execute command %s",
    1778                 :            :                             add ? "OP_ADD_ETH_ADDR" :  "OP_DEL_ETH_ADDR");
    1779                 :            :         return err;
    1780                 :            : }
    1781                 :            : 
    1782                 :            : int
    1783                 :          0 : iavf_add_del_vlan(struct iavf_adapter *adapter, uint16_t vlanid, bool add)
    1784                 :            : {
    1785                 :            :         struct virtchnl_vlan_filter_list *vlan_list;
    1786                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1787                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1788                 :            :         uint8_t cmd_buffer[sizeof(struct virtchnl_vlan_filter_list) +
    1789                 :            :                                                         sizeof(uint16_t)];
    1790                 :            :         struct iavf_cmd_info args;
    1791                 :            :         int err;
    1792                 :            : 
    1793                 :            :         vlan_list = (struct virtchnl_vlan_filter_list *)cmd_buffer;
    1794                 :          0 :         vlan_list->vsi_id = vf->vsi_res->vsi_id;
    1795                 :          0 :         vlan_list->num_elements = 1;
    1796                 :          0 :         vlan_list->vlan_id[0] = vlanid;
    1797                 :            : 
    1798         [ #  # ]:          0 :         args.ops = add ? VIRTCHNL_OP_ADD_VLAN : VIRTCHNL_OP_DEL_VLAN;
    1799                 :          0 :         args.in_args = cmd_buffer;
    1800                 :          0 :         args.in_args_size = sizeof(cmd_buffer);
    1801                 :          0 :         args.out_buffer = msg_buf;
    1802                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1803                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1804         [ #  # ]:          0 :         if (err)
    1805         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR, "fail to execute command %s",
    1806                 :            :                             add ? "OP_ADD_VLAN" :  "OP_DEL_VLAN");
    1807                 :            : 
    1808                 :          0 :         return err;
    1809                 :            : }
    1810                 :            : 
    1811                 :            : int
    1812                 :          0 : iavf_fdir_add(struct iavf_adapter *adapter,
    1813                 :            :         struct iavf_fdir_conf *filter)
    1814                 :            : {
    1815                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1816                 :            :         struct virtchnl_fdir_add *fdir_ret;
    1817                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1818                 :            :         struct iavf_cmd_info args;
    1819                 :            :         int err;
    1820                 :            : 
    1821                 :          0 :         filter->add_fltr.vsi_id = vf->vsi_res->vsi_id;
    1822                 :          0 :         filter->add_fltr.validate_only = 0;
    1823                 :            : 
    1824                 :          0 :         args.ops = VIRTCHNL_OP_ADD_FDIR_FILTER;
    1825                 :          0 :         args.in_args = (uint8_t *)(&filter->add_fltr);
    1826                 :          0 :         args.in_args_size = sizeof(*(&filter->add_fltr));
    1827                 :          0 :         args.out_buffer = msg_buf;
    1828                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1829                 :            : 
    1830                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1831         [ #  # ]:          0 :         if (err) {
    1832                 :          0 :                 PMD_DRV_LOG(ERR, "fail to execute command OP_ADD_FDIR_FILTER");
    1833                 :          0 :                 return err;
    1834                 :            :         }
    1835                 :            : 
    1836                 :          0 :         fdir_ret = (struct virtchnl_fdir_add *)args.out_buffer;
    1837                 :          0 :         filter->flow_id = fdir_ret->flow_id;
    1838                 :            : 
    1839         [ #  # ]:          0 :         if (fdir_ret->status == VIRTCHNL_FDIR_SUCCESS) {
    1840                 :          0 :                 PMD_DRV_LOG(INFO,
    1841                 :            :                         "Succeed in adding rule request by PF");
    1842                 :            :         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_NORESOURCE) {
    1843                 :          0 :                 PMD_DRV_LOG(ERR,
    1844                 :            :                         "Failed to add rule request due to no hw resource");
    1845                 :          0 :                 return -1;
    1846                 :            :         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_EXIST) {
    1847                 :          0 :                 PMD_DRV_LOG(ERR,
    1848                 :            :                         "Failed to add rule request due to the rule is already existed");
    1849                 :          0 :                 return -1;
    1850                 :            :         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_CONFLICT) {
    1851                 :          0 :                 PMD_DRV_LOG(ERR,
    1852                 :            :                         "Failed to add rule request due to the rule is conflict with existing rule");
    1853                 :          0 :                 return -1;
    1854                 :            :         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_INVALID) {
    1855                 :          0 :                 PMD_DRV_LOG(ERR,
    1856                 :            :                         "Failed to add rule request due to the hw doesn't support");
    1857                 :          0 :                 return -1;
    1858                 :            :         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT) {
    1859                 :          0 :                 PMD_DRV_LOG(ERR,
    1860                 :            :                         "Failed to add rule request due to time out for programming");
    1861                 :          0 :                 return -1;
    1862                 :            :         } else {
    1863                 :          0 :                 PMD_DRV_LOG(ERR,
    1864                 :            :                         "Failed to add rule request due to other reasons");
    1865                 :          0 :                 return -1;
    1866                 :            :         }
    1867                 :            : 
    1868                 :          0 :         return 0;
    1869                 :            : };
    1870                 :            : 
    1871                 :            : int
    1872                 :          0 : iavf_fdir_del(struct iavf_adapter *adapter,
    1873                 :            :         struct iavf_fdir_conf *filter)
    1874                 :            : {
    1875                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1876                 :            :         struct virtchnl_fdir_del *fdir_ret;
    1877                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1878                 :            :         struct iavf_cmd_info args;
    1879                 :            :         int err;
    1880                 :            : 
    1881                 :          0 :         filter->del_fltr.vsi_id = vf->vsi_res->vsi_id;
    1882                 :          0 :         filter->del_fltr.flow_id = filter->flow_id;
    1883                 :            : 
    1884                 :          0 :         args.ops = VIRTCHNL_OP_DEL_FDIR_FILTER;
    1885                 :          0 :         args.in_args = (uint8_t *)(&filter->del_fltr);
    1886                 :          0 :         args.in_args_size = sizeof(filter->del_fltr);
    1887                 :          0 :         args.out_buffer = msg_buf;
    1888                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1889                 :            : 
    1890                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1891         [ #  # ]:          0 :         if (err) {
    1892                 :          0 :                 PMD_DRV_LOG(ERR, "fail to execute command OP_DEL_FDIR_FILTER");
    1893                 :          0 :                 return err;
    1894                 :            :         }
    1895                 :            : 
    1896                 :          0 :         fdir_ret = (struct virtchnl_fdir_del *)args.out_buffer;
    1897                 :            : 
    1898         [ #  # ]:          0 :         if (fdir_ret->status == VIRTCHNL_FDIR_SUCCESS) {
    1899                 :          0 :                 PMD_DRV_LOG(INFO,
    1900                 :            :                         "Succeed in deleting rule request by PF");
    1901         [ #  # ]:          0 :         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST) {
    1902                 :          0 :                 PMD_DRV_LOG(ERR,
    1903                 :            :                         "Failed to delete rule request due to this rule doesn't exist");
    1904                 :          0 :                 return -1;
    1905         [ #  # ]:          0 :         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_TIMEOUT) {
    1906                 :          0 :                 PMD_DRV_LOG(ERR,
    1907                 :            :                         "Failed to delete rule request due to time out for programming");
    1908                 :          0 :                 return -1;
    1909                 :            :         } else {
    1910                 :          0 :                 PMD_DRV_LOG(ERR,
    1911                 :            :                         "Failed to delete rule request due to other reasons");
    1912                 :          0 :                 return -1;
    1913                 :            :         }
    1914                 :            : 
    1915                 :          0 :         return 0;
    1916                 :            : };
    1917                 :            : 
    1918                 :            : int
    1919                 :          0 : iavf_fdir_check(struct iavf_adapter *adapter,
    1920                 :            :                 struct iavf_fdir_conf *filter)
    1921                 :            : {
    1922                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1923                 :            :         struct virtchnl_fdir_add *fdir_ret;
    1924                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1925                 :            :         struct iavf_cmd_info args;
    1926                 :            :         int err;
    1927                 :            : 
    1928                 :          0 :         filter->add_fltr.vsi_id = vf->vsi_res->vsi_id;
    1929                 :          0 :         filter->add_fltr.validate_only = 1;
    1930                 :            : 
    1931                 :          0 :         args.ops = VIRTCHNL_OP_ADD_FDIR_FILTER;
    1932                 :          0 :         args.in_args = (uint8_t *)(&filter->add_fltr);
    1933                 :          0 :         args.in_args_size = sizeof(*(&filter->add_fltr));
    1934                 :          0 :         args.out_buffer = msg_buf;
    1935                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1936                 :            : 
    1937                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1938         [ #  # ]:          0 :         if (err) {
    1939                 :          0 :                 PMD_DRV_LOG(ERR, "fail to check flow director rule");
    1940                 :          0 :                 return err;
    1941                 :            :         }
    1942                 :            : 
    1943                 :          0 :         fdir_ret = (struct virtchnl_fdir_add *)args.out_buffer;
    1944                 :            : 
    1945         [ #  # ]:          0 :         if (fdir_ret->status == VIRTCHNL_FDIR_SUCCESS) {
    1946                 :          0 :                 PMD_DRV_LOG(INFO,
    1947                 :            :                         "Succeed in checking rule request by PF");
    1948         [ #  # ]:          0 :         } else if (fdir_ret->status == VIRTCHNL_FDIR_FAILURE_RULE_INVALID) {
    1949                 :          0 :                 PMD_DRV_LOG(ERR,
    1950                 :            :                         "Failed to check rule request due to parameters validation"
    1951                 :            :                         " or HW doesn't support");
    1952                 :            :                 err = -1;
    1953                 :            :         } else {
    1954                 :          0 :                 PMD_DRV_LOG(ERR,
    1955                 :            :                         "Failed to check rule request due to other reasons");
    1956                 :            :                 err =  -1;
    1957                 :            :         }
    1958                 :            : 
    1959                 :            :         return err;
    1960                 :            : }
    1961                 :            : 
    1962                 :            : int
    1963                 :          0 : iavf_flow_sub(struct iavf_adapter *adapter, struct iavf_fsub_conf *filter)
    1964                 :            : {
    1965                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    1966                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    1967                 :            :         struct virtchnl_flow_sub *fsub_cfg;
    1968                 :            :         struct iavf_cmd_info args;
    1969                 :            :         int err;
    1970                 :            : 
    1971                 :          0 :         filter->sub_fltr.vsi_id = vf->vsi_res->vsi_id;
    1972                 :          0 :         filter->sub_fltr.validate_only = 0;
    1973                 :            : 
    1974                 :            :         memset(&args, 0, sizeof(args));
    1975                 :          0 :         args.ops = VIRTCHNL_OP_FLOW_SUBSCRIBE;
    1976                 :          0 :         args.in_args = (uint8_t *)(&filter->sub_fltr);
    1977                 :          0 :         args.in_args_size = sizeof(*(&filter->sub_fltr));
    1978                 :          0 :         args.out_buffer = msg_buf;
    1979                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    1980                 :            : 
    1981                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    1982         [ #  # ]:          0 :         if (err) {
    1983                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to execute command of "
    1984                 :            :                                  "OP_FLOW_SUBSCRIBE");
    1985                 :          0 :                 return err;
    1986                 :            :         }
    1987                 :            : 
    1988                 :          0 :         fsub_cfg = (struct virtchnl_flow_sub *)args.out_buffer;
    1989                 :          0 :         filter->flow_id = fsub_cfg->flow_id;
    1990                 :            : 
    1991         [ #  # ]:          0 :         if (fsub_cfg->status == VIRTCHNL_FSUB_SUCCESS) {
    1992                 :          0 :                 PMD_DRV_LOG(INFO, "Succeed in adding rule request by PF");
    1993         [ #  # ]:          0 :         } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_NORESOURCE) {
    1994                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to add rule request due to no hw "
    1995                 :            :                                  "resource");
    1996                 :            :                 err = -1;
    1997         [ #  # ]:          0 :         } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_EXIST) {
    1998                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to add rule request due to the rule "
    1999                 :            :                                  "is already existed");
    2000                 :            :                 err = -1;
    2001         [ #  # ]:          0 :         } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_INVALID) {
    2002                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to add rule request due to the hw "
    2003                 :            :                                  "doesn't support");
    2004                 :            :                 err = -1;
    2005                 :            :         } else {
    2006                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to add rule request due to other "
    2007                 :            :                                  "reasons");
    2008                 :            :                 err = -1;
    2009                 :            :         }
    2010                 :            : 
    2011                 :            :         return err;
    2012                 :            : }
    2013                 :            : 
    2014                 :            : int
    2015                 :          0 : iavf_flow_unsub(struct iavf_adapter *adapter, struct iavf_fsub_conf *filter)
    2016                 :            : {
    2017                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    2018                 :            :         struct virtchnl_flow_unsub *unsub_cfg;
    2019                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2020                 :            :         struct iavf_cmd_info args;
    2021                 :            :         int err;
    2022                 :            : 
    2023                 :          0 :         filter->unsub_fltr.vsi_id = vf->vsi_res->vsi_id;
    2024                 :          0 :         filter->unsub_fltr.flow_id = filter->flow_id;
    2025                 :            : 
    2026                 :            :         memset(&args, 0, sizeof(args));
    2027                 :          0 :         args.ops = VIRTCHNL_OP_FLOW_UNSUBSCRIBE;
    2028                 :          0 :         args.in_args = (uint8_t *)(&filter->unsub_fltr);
    2029                 :          0 :         args.in_args_size = sizeof(filter->unsub_fltr);
    2030                 :          0 :         args.out_buffer = msg_buf;
    2031                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2032                 :            : 
    2033                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2034         [ #  # ]:          0 :         if (err) {
    2035                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to execute command of "
    2036                 :            :                                  "OP_FLOW_UNSUBSCRIBE");
    2037                 :          0 :                 return err;
    2038                 :            :         }
    2039                 :            : 
    2040                 :          0 :         unsub_cfg = (struct virtchnl_flow_unsub *)args.out_buffer;
    2041                 :            : 
    2042         [ #  # ]:          0 :         if (unsub_cfg->status == VIRTCHNL_FSUB_SUCCESS) {
    2043                 :          0 :                 PMD_DRV_LOG(INFO, "Succeed in deleting rule request by PF");
    2044         [ #  # ]:          0 :         } else if (unsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_NONEXIST) {
    2045                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to delete rule request due to this "
    2046                 :            :                                  "rule doesn't exist");
    2047                 :            :                 err = -1;
    2048                 :            :         } else {
    2049                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to delete rule request due to other "
    2050                 :            :                                  "reasons");
    2051                 :            :                 err = -1;
    2052                 :            :         }
    2053                 :            : 
    2054                 :            :         return err;
    2055                 :            : }
    2056                 :            : 
    2057                 :            : int
    2058                 :          0 : iavf_flow_sub_check(struct iavf_adapter *adapter,
    2059                 :            :                     struct iavf_fsub_conf *filter)
    2060                 :            : {
    2061                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    2062                 :            :         struct virtchnl_flow_sub *fsub_cfg;
    2063                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2064                 :            :         struct iavf_cmd_info args;
    2065                 :            :         int err;
    2066                 :            : 
    2067                 :          0 :         filter->sub_fltr.vsi_id = vf->vsi_res->vsi_id;
    2068                 :          0 :         filter->sub_fltr.validate_only = 1;
    2069                 :            : 
    2070                 :          0 :         args.ops = VIRTCHNL_OP_FLOW_SUBSCRIBE;
    2071                 :          0 :         args.in_args = (uint8_t *)(&filter->sub_fltr);
    2072                 :          0 :         args.in_args_size = sizeof(*(&filter->sub_fltr));
    2073                 :          0 :         args.out_buffer = msg_buf;
    2074                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2075                 :            : 
    2076                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2077         [ #  # ]:          0 :         if (err) {
    2078                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to check flow subscription rule");
    2079                 :          0 :                 return err;
    2080                 :            :         }
    2081                 :            : 
    2082                 :          0 :         fsub_cfg = (struct virtchnl_flow_sub *)args.out_buffer;
    2083                 :            : 
    2084         [ #  # ]:          0 :         if (fsub_cfg->status == VIRTCHNL_FSUB_SUCCESS) {
    2085                 :          0 :                 PMD_DRV_LOG(INFO, "Succeed in checking rule request by PF");
    2086         [ #  # ]:          0 :         } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_INVALID) {
    2087                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to check rule request due to "
    2088                 :            :                                  "parameters validation or HW doesn't "
    2089                 :            :                                  "support");
    2090                 :            :                 err = -1;
    2091                 :            :         } else {
    2092                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to check rule request due to other "
    2093                 :            :                                  "reasons");
    2094                 :            :                 err = -1;
    2095                 :            :         }
    2096                 :            : 
    2097                 :            :         return err;
    2098                 :            : }
    2099                 :            : 
    2100                 :            : int
    2101                 :          0 : iavf_add_del_rss_cfg(struct iavf_adapter *adapter,
    2102                 :            :                      struct virtchnl_rss_cfg *rss_cfg, bool add)
    2103                 :            : {
    2104         [ #  # ]:          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2105                 :            :         struct iavf_cmd_info args;
    2106                 :            :         int err;
    2107                 :            : 
    2108                 :            :         memset(&args, 0, sizeof(args));
    2109         [ #  # ]:          0 :         args.ops = add ? VIRTCHNL_OP_ADD_RSS_CFG :
    2110                 :            :                 VIRTCHNL_OP_DEL_RSS_CFG;
    2111                 :          0 :         args.in_args = (u8 *)rss_cfg;
    2112                 :          0 :         args.in_args_size = sizeof(*rss_cfg);
    2113                 :          0 :         args.out_buffer = msg_buf;
    2114                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2115                 :            : 
    2116                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2117         [ #  # ]:          0 :         if (err)
    2118         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR,
    2119                 :            :                             "Failed to execute command of %s",
    2120                 :            :                             add ? "OP_ADD_RSS_CFG" :
    2121                 :            :                             "OP_DEL_RSS_INPUT_CFG");
    2122                 :            : 
    2123                 :          0 :         return err;
    2124                 :            : }
    2125                 :            : 
    2126                 :            : int
    2127                 :          0 : iavf_get_hena_caps(struct iavf_adapter *adapter, uint64_t *caps)
    2128                 :            : {
    2129                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2130                 :            :         struct virtchnl_rss_hena *hena;
    2131                 :            :         struct iavf_cmd_info args;
    2132                 :            :         int err;
    2133                 :            : 
    2134                 :          0 :         args.ops = VIRTCHNL_OP_GET_RSS_HENA_CAPS;
    2135                 :          0 :         args.in_args = NULL;
    2136                 :          0 :         args.in_args_size = 0;
    2137                 :          0 :         args.out_buffer = msg_buf;
    2138                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2139                 :            : 
    2140                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2141         [ #  # ]:          0 :         if (err) {
    2142                 :          0 :                 PMD_DRV_LOG(ERR,
    2143                 :            :                             "Failed to execute command of OP_GET_RSS_HENA_CAPS");
    2144                 :          0 :                 return err;
    2145                 :            :         }
    2146                 :            : 
    2147                 :          0 :         hena = (struct virtchnl_rss_hena *)args.out_buffer;
    2148                 :          0 :         *caps = hena->hena;
    2149                 :          0 :         return 0;
    2150                 :            : }
    2151                 :            : 
    2152                 :            : int
    2153                 :          0 : iavf_set_hena(struct iavf_adapter *adapter, uint64_t hena)
    2154                 :            : {
    2155                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2156                 :            :         struct virtchnl_rss_hena vrh;
    2157                 :            :         struct iavf_cmd_info args;
    2158                 :            :         int err;
    2159                 :            : 
    2160                 :          0 :         vrh.hena = hena;
    2161                 :          0 :         args.ops = VIRTCHNL_OP_SET_RSS_HENA;
    2162                 :          0 :         args.in_args = (u8 *)&vrh;
    2163                 :          0 :         args.in_args_size = sizeof(vrh);
    2164                 :          0 :         args.out_buffer = msg_buf;
    2165                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2166                 :            : 
    2167                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2168         [ #  # ]:          0 :         if (err)
    2169                 :          0 :                 PMD_DRV_LOG(ERR,
    2170                 :            :                             "Failed to execute command of OP_SET_RSS_HENA");
    2171                 :            : 
    2172                 :          0 :         return err;
    2173                 :            : }
    2174                 :            : 
    2175                 :            : int
    2176                 :          0 : iavf_get_qos_cap(struct iavf_adapter *adapter)
    2177                 :            : {
    2178                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    2179                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2180                 :            :         struct iavf_cmd_info args;
    2181                 :            :         uint32_t len;
    2182                 :            :         int err;
    2183                 :            : 
    2184                 :          0 :         args.ops = VIRTCHNL_OP_GET_QOS_CAPS;
    2185                 :          0 :         args.in_args = NULL;
    2186                 :          0 :         args.in_args_size = 0;
    2187                 :          0 :         args.out_buffer = msg_buf;
    2188                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2189                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2190                 :            : 
    2191         [ #  # ]:          0 :         if (err) {
    2192                 :          0 :                 PMD_DRV_LOG(ERR,
    2193                 :            :                             "Failed to execute command of OP_GET_VF_RESOURCE");
    2194                 :          0 :                 return -1;
    2195                 :            :         }
    2196                 :            : 
    2197                 :            :         len =  sizeof(struct virtchnl_qos_cap_list) +
    2198                 :            :                 IAVF_MAX_TRAFFIC_CLASS * sizeof(struct virtchnl_qos_cap_elem);
    2199                 :            : 
    2200                 :          0 :         memcpy(vf->qos_cap, args.out_buffer,
    2201                 :          0 :                    RTE_MIN(args.out_size, len));
    2202                 :            : 
    2203                 :          0 :         return 0;
    2204                 :            : }
    2205                 :            : 
    2206                 :          0 : int iavf_set_q_tc_map(struct rte_eth_dev *dev,
    2207                 :            :                 struct virtchnl_queue_tc_mapping *q_tc_mapping, uint16_t size)
    2208                 :            : {
    2209                 :          0 :         struct iavf_adapter *adapter =
    2210                 :          0 :                         IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
    2211                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2212                 :            :         struct iavf_cmd_info args;
    2213                 :            :         int err;
    2214                 :            : 
    2215                 :            :         memset(&args, 0, sizeof(args));
    2216                 :          0 :         args.ops = VIRTCHNL_OP_CONFIG_QUEUE_TC_MAP;
    2217                 :          0 :         args.in_args = (uint8_t *)q_tc_mapping;
    2218                 :          0 :         args.in_args_size = size;
    2219                 :          0 :         args.out_buffer = msg_buf;
    2220                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2221                 :            : 
    2222                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2223         [ #  # ]:          0 :         if (err)
    2224                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to execute command of"
    2225                 :            :                             " VIRTCHNL_OP_CONFIG_TC_MAP");
    2226                 :          0 :         return err;
    2227                 :            : }
    2228                 :            : 
    2229                 :          0 : int iavf_set_q_bw(struct rte_eth_dev *dev,
    2230                 :            :                 struct virtchnl_queues_bw_cfg *q_bw, uint16_t size)
    2231                 :            : {
    2232                 :          0 :         struct iavf_adapter *adapter =
    2233                 :          0 :                         IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
    2234                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2235                 :            :         struct iavf_cmd_info args;
    2236                 :            :         int err;
    2237                 :            : 
    2238                 :            :         memset(&args, 0, sizeof(args));
    2239                 :          0 :         args.ops = VIRTCHNL_OP_CONFIG_QUEUE_BW;
    2240                 :          0 :         args.in_args = (uint8_t *)q_bw;
    2241                 :          0 :         args.in_args_size = size;
    2242                 :          0 :         args.out_buffer = msg_buf;
    2243                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2244                 :            : 
    2245                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2246         [ #  # ]:          0 :         if (err)
    2247                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to execute command of"
    2248                 :            :                             " VIRTCHNL_OP_CONFIG_QUEUE_BW");
    2249                 :          0 :         return err;
    2250                 :            : }
    2251                 :            : 
    2252                 :            : int
    2253                 :          0 : iavf_add_del_mc_addr_list(struct iavf_adapter *adapter,
    2254                 :            :                         struct rte_ether_addr *mc_addrs,
    2255                 :            :                         uint32_t mc_addrs_num, bool add)
    2256                 :            : {
    2257                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    2258                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2259                 :            :         uint8_t cmd_buffer[sizeof(struct virtchnl_ether_addr_list) +
    2260                 :            :                 (IAVF_NUM_MACADDR_MAX * sizeof(struct virtchnl_ether_addr))];
    2261                 :            :         struct virtchnl_ether_addr_list *list;
    2262                 :            :         struct iavf_cmd_info args;
    2263                 :            :         uint32_t i;
    2264                 :            :         int err;
    2265                 :            : 
    2266         [ #  # ]:          0 :         if (mc_addrs == NULL || mc_addrs_num == 0)
    2267                 :            :                 return 0;
    2268                 :            : 
    2269                 :            :         list = (struct virtchnl_ether_addr_list *)cmd_buffer;
    2270                 :          0 :         list->vsi_id = vf->vsi_res->vsi_id;
    2271                 :          0 :         list->num_elements = mc_addrs_num;
    2272                 :            : 
    2273         [ #  # ]:          0 :         for (i = 0; i < mc_addrs_num; i++) {
    2274         [ #  # ]:          0 :                 if (!IAVF_IS_MULTICAST(mc_addrs[i].addr_bytes)) {
    2275                 :          0 :                         PMD_DRV_LOG(ERR, "Invalid mac:" RTE_ETHER_ADDR_PRT_FMT,
    2276                 :            :                                     RTE_ETHER_ADDR_BYTES(&mc_addrs[i]));
    2277                 :          0 :                         return -EINVAL;
    2278                 :            :                 }
    2279                 :            : 
    2280                 :          0 :                 memcpy(list->list[i].addr, mc_addrs[i].addr_bytes,
    2281                 :            :                         sizeof(list->list[i].addr));
    2282                 :          0 :                 list->list[i].type = VIRTCHNL_ETHER_ADDR_EXTRA;
    2283                 :            :         }
    2284                 :            : 
    2285         [ #  # ]:          0 :         args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR;
    2286                 :          0 :         args.in_args = cmd_buffer;
    2287                 :          0 :         args.in_args_size = sizeof(struct virtchnl_ether_addr_list) +
    2288                 :          0 :                 i * sizeof(struct virtchnl_ether_addr);
    2289                 :          0 :         args.out_buffer = msg_buf;
    2290                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2291                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2292                 :            : 
    2293         [ #  # ]:          0 :         if (err) {
    2294         [ #  # ]:          0 :                 PMD_DRV_LOG(ERR, "fail to execute command %s",
    2295                 :            :                         add ? "OP_ADD_ETH_ADDR" : "OP_DEL_ETH_ADDR");
    2296                 :          0 :                 return err;
    2297                 :            :         }
    2298                 :            : 
    2299                 :            :         return 0;
    2300                 :            : }
    2301                 :            : 
    2302                 :            : int
    2303                 :          0 : iavf_request_queues(struct rte_eth_dev *dev, uint16_t num)
    2304                 :            : {
    2305                 :          0 :         struct iavf_adapter *adapter =
    2306                 :          0 :                 IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
    2307                 :            :         struct iavf_info *vf =  IAVF_DEV_PRIVATE_TO_VF(adapter);
    2308                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2309                 :            :         struct virtchnl_vf_res_request vfres;
    2310                 :            :         struct iavf_cmd_info args;
    2311                 :            :         uint16_t num_queue_pairs;
    2312                 :            :         int err;
    2313                 :            :         int i = 0;
    2314                 :            : 
    2315         [ #  # ]:          0 :         if (!(vf->vf_res->vf_cap_flags &
    2316                 :            :                 VIRTCHNL_VF_OFFLOAD_REQ_QUEUES)) {
    2317                 :          0 :                 PMD_DRV_LOG(ERR, "request queues not supported");
    2318                 :          0 :                 return -1;
    2319                 :            :         }
    2320                 :            : 
    2321         [ #  # ]:          0 :         if (num == 0) {
    2322                 :          0 :                 PMD_DRV_LOG(ERR, "queue number cannot be zero");
    2323                 :          0 :                 return -1;
    2324                 :            :         }
    2325                 :          0 :         vfres.num_queue_pairs = num;
    2326                 :            : 
    2327                 :          0 :         args.ops = VIRTCHNL_OP_REQUEST_QUEUES;
    2328                 :          0 :         args.in_args = (u8 *)&vfres;
    2329                 :          0 :         args.in_args_size = sizeof(vfres);
    2330                 :          0 :         args.out_buffer = msg_buf;
    2331                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2332                 :            : 
    2333         [ #  # ]:          0 :         if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) {
    2334                 :          0 :                 iavf_phc_sync_alarm_stop(dev);
    2335                 :          0 :                 err = iavf_execute_vf_cmd_safe(adapter, &args);
    2336                 :          0 :                 iavf_phc_sync_alarm_start(dev);
    2337                 :            :         } else {
    2338                 :          0 :                 iavf_phc_sync_alarm_stop(dev);
    2339                 :          0 :                 rte_eal_alarm_cancel(iavf_dev_alarm_handler, dev);
    2340                 :          0 :                 err = iavf_execute_vf_cmd_safe(adapter, &args);
    2341                 :          0 :                 rte_eal_alarm_set(IAVF_ALARM_INTERVAL,
    2342                 :            :                                   iavf_dev_alarm_handler, dev);
    2343                 :          0 :                 iavf_phc_sync_alarm_start(dev);
    2344                 :            :         }
    2345                 :            : 
    2346         [ #  # ]:          0 :         if (err) {
    2347                 :          0 :                 PMD_DRV_LOG(ERR, "fail to execute command OP_REQUEST_QUEUES");
    2348                 :          0 :                 return err;
    2349                 :            :         }
    2350                 :            : 
    2351                 :            :         /* wait for interrupt notification vf is resetting */
    2352         [ #  # ]:          0 :         while (i++ < MAX_TRY_TIMES) {
    2353         [ #  # ]:          0 :                 if (vf->vf_reset)
    2354                 :            :                         break;
    2355                 :          0 :                 iavf_msec_delay(ASQ_DELAY_MS);
    2356                 :            :         }
    2357                 :            : 
    2358                 :            :         /* request queues succeeded, vf is resetting */
    2359         [ #  # ]:          0 :         if (vf->vf_reset) {
    2360                 :          0 :                 PMD_DRV_LOG(INFO, "vf is resetting");
    2361                 :          0 :                 return 0;
    2362                 :            :         }
    2363                 :            : 
    2364                 :            :         /* request additional queues failed, return available number */
    2365                 :          0 :         num_queue_pairs =
    2366                 :          0 :           ((struct virtchnl_vf_res_request *)args.out_buffer)->num_queue_pairs;
    2367                 :          0 :         PMD_DRV_LOG(ERR, "request queues failed, only %u queues "
    2368                 :            :                 "available", num_queue_pairs);
    2369                 :            : 
    2370                 :          0 :         return -1;
    2371                 :            : }
    2372                 :            : 
    2373                 :            : int
    2374                 :          0 : iavf_get_max_rss_queue_region(struct iavf_adapter *adapter)
    2375                 :            : {
    2376                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    2377                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2378                 :            :         struct iavf_cmd_info args;
    2379                 :            :         uint16_t qregion_width;
    2380                 :            :         int err;
    2381                 :            : 
    2382                 :          0 :         args.ops = VIRTCHNL_OP_GET_MAX_RSS_QREGION;
    2383                 :          0 :         args.in_args = NULL;
    2384                 :          0 :         args.in_args_size = 0;
    2385                 :          0 :         args.out_buffer = msg_buf;
    2386                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2387                 :            : 
    2388                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2389         [ #  # ]:          0 :         if (err) {
    2390                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to execute command of VIRTCHNL_OP_GET_MAX_RSS_QREGION");
    2391                 :          0 :                 return err;
    2392                 :            :         }
    2393                 :            : 
    2394                 :          0 :         qregion_width =
    2395                 :          0 :         ((struct virtchnl_max_rss_qregion *)args.out_buffer)->qregion_width;
    2396                 :            : 
    2397                 :          0 :         vf->max_rss_qregion = (uint16_t)(1 << qregion_width);
    2398                 :            : 
    2399                 :          0 :         return 0;
    2400                 :            : }
    2401                 :            : 
    2402                 :            : 
    2403                 :            : 
    2404                 :            : int
    2405                 :          0 : iavf_ipsec_crypto_request(struct iavf_adapter *adapter,
    2406                 :            :                 uint8_t *msg, size_t msg_len,
    2407                 :            :                 uint8_t *resp_msg, size_t resp_msg_len)
    2408                 :            : {
    2409                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2410                 :            :         struct iavf_cmd_info args;
    2411                 :            :         int err;
    2412                 :            : 
    2413                 :          0 :         args.ops = VIRTCHNL_OP_INLINE_IPSEC_CRYPTO;
    2414                 :          0 :         args.in_args = msg;
    2415                 :          0 :         args.in_args_size = msg_len;
    2416                 :          0 :         args.out_buffer = msg_buf;
    2417                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2418                 :            : 
    2419                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2420         [ #  # ]:          0 :         if (err) {
    2421                 :          0 :                 PMD_DRV_LOG(ERR, "fail to execute command %s",
    2422                 :            :                                 "OP_INLINE_IPSEC_CRYPTO");
    2423                 :          0 :                 return err;
    2424                 :            :         }
    2425                 :            : 
    2426                 :          0 :         memcpy(resp_msg, args.out_buffer, resp_msg_len);
    2427                 :            : 
    2428                 :          0 :         return 0;
    2429                 :            : }
    2430                 :            : 
    2431                 :            : int
    2432                 :          0 : iavf_set_vf_quanta_size(struct iavf_adapter *adapter, u16 start_queue_id, u16 num_queues)
    2433                 :            : {
    2434                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2435                 :            :         struct iavf_cmd_info args;
    2436                 :            :         struct virtchnl_quanta_cfg q_quanta;
    2437                 :            :         int err;
    2438                 :            : 
    2439         [ #  # ]:          0 :         if (adapter->devargs.quanta_size == 0)
    2440                 :            :                 return 0;
    2441                 :            : 
    2442                 :          0 :         q_quanta.quanta_size = adapter->devargs.quanta_size;
    2443                 :          0 :         q_quanta.queue_select.type = VIRTCHNL_QUEUE_TYPE_TX;
    2444                 :          0 :         q_quanta.queue_select.start_queue_id = start_queue_id;
    2445                 :          0 :         q_quanta.queue_select.num_queues = num_queues;
    2446                 :            : 
    2447                 :          0 :         args.ops = VIRTCHNL_OP_CONFIG_QUANTA;
    2448                 :          0 :         args.in_args = (uint8_t *)&q_quanta;
    2449                 :          0 :         args.in_args_size = sizeof(q_quanta);
    2450                 :          0 :         args.out_buffer = msg_buf;
    2451                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2452                 :            : 
    2453                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2454         [ #  # ]:          0 :         if (err) {
    2455                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to execute command VIRTCHNL_OP_CONFIG_QUANTA");
    2456                 :          0 :                 return err;
    2457                 :            :         }
    2458                 :            : 
    2459                 :            :         return 0;
    2460                 :            : }
    2461                 :            : 
    2462                 :            : int
    2463                 :          0 : iavf_get_ptp_cap(struct iavf_adapter *adapter)
    2464                 :            : {
    2465                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    2466                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2467                 :            :         struct virtchnl_ptp_caps ptp_caps;
    2468                 :            :         struct iavf_cmd_info args;
    2469                 :            :         int err;
    2470                 :            : 
    2471                 :          0 :         ptp_caps.caps = VIRTCHNL_1588_PTP_CAP_RX_TSTAMP |
    2472                 :            :                         VIRTCHNL_1588_PTP_CAP_READ_PHC;
    2473                 :            : 
    2474                 :          0 :         args.ops = VIRTCHNL_OP_1588_PTP_GET_CAPS;
    2475                 :          0 :         args.in_args = (uint8_t *)&ptp_caps;
    2476                 :          0 :         args.in_args_size = sizeof(ptp_caps);
    2477                 :          0 :         args.out_buffer = msg_buf;
    2478                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2479                 :            : 
    2480                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2481         [ #  # ]:          0 :         if (err) {
    2482                 :          0 :                 PMD_DRV_LOG(ERR,
    2483                 :            :                             "Failed to execute command of OP_1588_PTP_GET_CAPS");
    2484                 :          0 :                 return err;
    2485                 :            :         }
    2486                 :            : 
    2487                 :          0 :         vf->ptp_caps = ((struct virtchnl_ptp_caps *)args.out_buffer)->caps;
    2488                 :            : 
    2489                 :          0 :         return 0;
    2490                 :            : }
    2491                 :            : 
    2492                 :            : int
    2493                 :          0 : iavf_get_phc_time(struct ci_rx_queue *rxq)
    2494                 :            : {
    2495                 :          0 :         struct iavf_adapter *adapter = rxq->iavf_vsi->adapter;
    2496                 :            :         struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
    2497                 :          0 :         uint8_t msg_buf[IAVF_AQ_BUF_SZ] = {0};
    2498                 :            :         struct virtchnl_phc_time phc_time;
    2499                 :            :         struct iavf_cmd_info args;
    2500                 :            :         int err = 0;
    2501                 :            : 
    2502                 :          0 :         args.ops = VIRTCHNL_OP_1588_PTP_GET_TIME;
    2503                 :          0 :         args.in_args = (uint8_t *)&phc_time;
    2504                 :          0 :         args.in_args_size = sizeof(phc_time);
    2505                 :          0 :         args.out_buffer = msg_buf;
    2506                 :          0 :         args.out_size = IAVF_AQ_BUF_SZ;
    2507                 :            : 
    2508                 :          0 :         rte_spinlock_lock(&vf->phc_time_aq_lock);
    2509                 :          0 :         err = iavf_execute_vf_cmd_safe(adapter, &args);
    2510         [ #  # ]:          0 :         if (err) {
    2511                 :          0 :                 PMD_DRV_LOG(ERR,
    2512                 :            :                             "Failed to execute command of VIRTCHNL_OP_1588_PTP_GET_TIME");
    2513                 :          0 :                 goto out;
    2514                 :            :         }
    2515                 :          0 :         rxq->phc_time = ((struct virtchnl_phc_time *)args.out_buffer)->time;
    2516                 :            : 
    2517                 :          0 : out:
    2518                 :            :         rte_spinlock_unlock(&vf->phc_time_aq_lock);
    2519                 :          0 :         return err;
    2520                 :            : }

Generated by: LCOV version 1.14