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

Generated by: LCOV version 1.14