LCOV - code coverage report
Current view: top level - drivers/net/enetc - enetc4_vf.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 2 672 0.3 %
Date: 2026-08-01 17:54:00 Functions: 2 33 6.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 251 0.4 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2024-2026 NXP
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <stdbool.h>
       6                 :            : #include <rte_kvargs.h>
       7                 :            : #include <rte_random.h>
       8                 :            : #include <dpaax_iova_table.h>
       9                 :            : #include "enetc_logs.h"
      10                 :            : #include "enetc.h"
      11                 :            : 
      12                 :            : #define ENETC4_VSI_DISABLE              "enetc4_vsi_disable"
      13                 :            : #define ENETC4_VSI_TIMEOUT              "enetc4_vsi_timeout"
      14                 :            : #define ENETC4_VSI_DELAY                "enetc4_vsi_delay"
      15                 :            : #define ENETC4_NC_MEMORY                "nc"
      16                 :            : 
      17                 :            : static void
      18                 :          0 : enetc4_vf_get_devarg_nc(struct rte_eth_dev *dev)
      19                 :            : {
      20                 :            :         struct enetc_eth_hw *hw =
      21                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
      22                 :          0 :         struct rte_devargs *devargs = dev->device->devargs;
      23                 :            :         struct rte_kvargs *kvlist;
      24                 :            :         const char *val;
      25                 :            : 
      26         [ #  # ]:          0 :         if (!devargs)
      27                 :            :                 return;
      28                 :            : 
      29                 :          0 :         kvlist = rte_kvargs_parse(devargs->args, NULL);
      30         [ #  # ]:          0 :         if (!kvlist)
      31                 :            :                 return;
      32                 :            : 
      33                 :          0 :         val = rte_kvargs_get(kvlist, ENETC4_NC_MEMORY);
      34   [ #  #  #  # ]:          0 :         if (val && atoi(val) == 1)
      35                 :          0 :                 hw->nc_mode = 1;
      36                 :            : 
      37                 :          0 :         rte_kvargs_free(kvlist);
      38                 :            : }
      39                 :            : 
      40                 :            : #define ENETC_CRC_TABLE_SIZE            256
      41                 :            : #define ENETC_POLY                      0x1021
      42                 :            : #define ENETC_CRC_INIT                  0xffff
      43                 :            : #define ENETC_BYTE_SIZE                 8
      44                 :            : #define ENETC_MSB_BIT                   0x8000
      45                 :            : 
      46                 :            : uint16_t enetc_crc_table[ENETC_CRC_TABLE_SIZE];
      47                 :            : bool enetc_crc_gen;
      48                 :            : 
      49                 :            : /* Supported Rx offloads */
      50                 :            : static uint64_t dev_rx_offloads_sup =
      51                 :            :         RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
      52                 :            :         RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
      53                 :            :         RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
      54                 :            :         RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
      55                 :            :         RTE_ETH_RX_OFFLOAD_SCATTER;
      56                 :            : 
      57                 :            : /* Supported Tx offloads */
      58                 :            : static uint64_t dev_tx_offloads_sup =
      59                 :            :         RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
      60                 :            :         RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
      61                 :            :         RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
      62                 :            :         RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
      63                 :            : 
      64                 :            : static void
      65                 :          0 : enetc_gen_crc_table(void)
      66                 :            : {
      67                 :            :         uint16_t crc = 0;
      68                 :            :         uint16_t c;
      69                 :            : 
      70         [ #  # ]:          0 :         for (int i = 0; i < ENETC_CRC_TABLE_SIZE; i++) {
      71                 :            :                 crc = 0;
      72                 :          0 :                 c = i << ENETC_BYTE_SIZE;
      73         [ #  # ]:          0 :                 for (int j = 0; j < ENETC_BYTE_SIZE; j++) {
      74         [ #  # ]:          0 :                         if ((crc ^ c) & ENETC_MSB_BIT)
      75                 :          0 :                                 crc = (crc << 1) ^ ENETC_POLY;
      76                 :            :                         else
      77                 :          0 :                                 crc = crc << 1;
      78                 :          0 :                         c = c << 1;
      79                 :            :                 }
      80                 :            : 
      81                 :          0 :                 enetc_crc_table[i] = crc;
      82                 :            :         }
      83                 :            : 
      84                 :          0 :         enetc_crc_gen = true;
      85                 :          0 : }
      86                 :            : 
      87                 :            : static uint16_t
      88                 :            : enetc_crc_calc(uint16_t crc, const uint8_t *buffer, size_t len)
      89                 :            : {
      90                 :            :         uint8_t data;
      91                 :            : 
      92   [ #  #  #  #  :          0 :         while (len--) {
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
      93                 :          0 :                 data = *buffer;
      94                 :          0 :                 crc = (crc << 8) ^ enetc_crc_table[((crc >> 8) ^ data) & 0xff];
      95                 :          0 :                 buffer++;
      96                 :            :         }
      97                 :            :         return crc;
      98                 :            : }
      99                 :            : 
     100                 :            : static int
     101                 :          0 : enetc4_vf_dev_infos_get(struct rte_eth_dev *dev,
     102                 :            :                         struct rte_eth_dev_info *dev_info)
     103                 :            : {
     104                 :            :         struct enetc_eth_hw *hw =
     105                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     106                 :            : 
     107                 :          0 :         PMD_INIT_FUNC_TRACE();
     108                 :            : 
     109                 :          0 :         dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
     110                 :            :                 .nb_max = MAX_BD_COUNT,
     111                 :            :                 .nb_min = MIN_BD_COUNT,
     112                 :            :                 .nb_align = BD_ALIGN,
     113                 :            :                 .nb_seg_max = ENETC4_MAX_SEGS,
     114                 :            :                 .nb_mtu_seg_max = ENETC4_MAX_SEGS,
     115                 :            :         };
     116                 :          0 :         dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
     117                 :            :                 .nb_max = MAX_BD_COUNT,
     118                 :            :                 .nb_min = MIN_BD_COUNT,
     119                 :            :                 .nb_align = BD_ALIGN,
     120                 :            :                 .nb_seg_max = ENETC4_MAX_SEGS,
     121                 :            :                 .nb_mtu_seg_max = ENETC4_MAX_SEGS,
     122                 :            :         };
     123                 :          0 :         dev_info->max_rx_queues = hw->max_rx_queues;
     124                 :          0 :         dev_info->max_tx_queues = hw->max_tx_queues;
     125                 :          0 :         dev_info->max_rx_pktlen = ENETC4_MAC_MAXFRM_SIZE;
     126                 :          0 :         dev_info->max_mtu = dev_info->max_rx_pktlen - (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN);
     127                 :          0 :         dev_info->max_mac_addrs = ENETC4_MAC_ENTRIES;
     128                 :          0 :         dev_info->rx_offload_capa = dev_rx_offloads_sup;
     129                 :          0 :         dev_info->tx_offload_capa = dev_tx_offloads_sup;
     130                 :          0 :         dev_info->flow_type_rss_offloads = ENETC_RSS_OFFLOAD_ALL;
     131                 :            : 
     132                 :          0 :         return 0;
     133                 :            : }
     134                 :            : 
     135                 :            : 
     136                 :            : int
     137                 :          0 : enetc4_vf_dev_stop(struct rte_eth_dev *dev __rte_unused)
     138                 :            : {
     139                 :          0 :         PMD_INIT_FUNC_TRACE();
     140                 :            : 
     141                 :          0 :         return 0;
     142                 :            : }
     143                 :            : 
     144                 :            : static int
     145                 :          0 : enetc4_vf_dev_start(struct rte_eth_dev *dev __rte_unused)
     146                 :            : {
     147                 :          0 :         PMD_INIT_FUNC_TRACE();
     148                 :            : 
     149                 :          0 :         return 0;
     150                 :            : }
     151                 :            : 
     152                 :            : static int
     153                 :          0 : enetc4_vf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
     154                 :            :                     struct eth_queue_stats *qstats __rte_unused)
     155                 :            : {
     156                 :            :         struct enetc_eth_hw *hw =
     157                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     158                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     159                 :            :         struct enetc_bdr *rx_ring;
     160                 :            :         uint8_t i;
     161                 :            : 
     162                 :          0 :         PMD_INIT_FUNC_TRACE();
     163                 :          0 :         stats->ipackets = enetc4_rd(enetc_hw, ENETC4_SIRFRM0);
     164                 :          0 :         stats->opackets = enetc4_rd(enetc_hw, ENETC4_SITFRM0);
     165                 :          0 :         stats->ibytes = enetc4_rd(enetc_hw, ENETC4_SIROCT0);
     166                 :          0 :         stats->obytes = enetc4_rd(enetc_hw, ENETC4_SITOCT0);
     167                 :          0 :         stats->oerrors = enetc4_rd(enetc_hw, ENETC4_SITDFCR);
     168         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_rx_queues; i++) {
     169                 :          0 :                 rx_ring = dev->data->rx_queues[i];
     170                 :          0 :                 stats->ierrors += rx_ring->ierrors;
     171                 :            :         }
     172                 :          0 :         return 0;
     173                 :            : }
     174                 :            : 
     175                 :            : 
     176                 :            : static void
     177                 :            : enetc_msg_vf_fill_common_hdr(struct enetc_msg_swbd *msg,
     178                 :            :                                         uint8_t class_id, uint8_t cmd_id, uint8_t proto_ver,
     179                 :            :                                         uint8_t len, uint8_t cookie)
     180                 :            : {
     181                 :          0 :         struct enetc_msg_cmd_header *hdr = msg->vaddr;
     182                 :            : 
     183                 :          0 :         hdr->class_id = class_id;
     184                 :          0 :         hdr->cmd_id = cmd_id;
     185                 :          0 :         hdr->proto_ver = proto_ver;
     186                 :          0 :         hdr->len = len;
     187                 :          0 :         hdr->cookie = cookie;
     188                 :            :         /* Incrementing msg 2 bytes ahead as the first two bytes are for CRC */
     189                 :          0 :         hdr->csum = rte_cpu_to_be_16(enetc_crc_calc(ENETC_CRC_INIT,
     190                 :            :                                 (uint8_t *)msg->vaddr + sizeof(uint16_t),
     191                 :            :                                 msg->size - sizeof(uint16_t)));
     192                 :            : 
     193                 :            :         dcbf(hdr);
     194                 :          0 : }
     195                 :            : 
     196                 :            : /* Messaging */
     197                 :            : static void
     198                 :            : enetc4_msg_vsi_write_msg(struct enetc_hw *hw,
     199                 :            :                 struct enetc_msg_swbd *msg)
     200                 :            : {
     201                 :            :         uint32_t val;
     202                 :            : 
     203         [ #  # ]:          0 :         val = enetc_vsi_set_msize(msg->size) | lower_32_bits(msg->dma);
     204                 :          0 :         enetc_wr(hw, ENETC4_VSIMSGSNDAR1, upper_32_bits(msg->dma));
     205                 :          0 :         enetc_wr(hw, ENETC4_VSIMSGSNDAR0, val);
     206                 :          0 : }
     207                 :            : 
     208                 :            : static void
     209                 :            : enetc4_msg_vsi_reply_msg(struct enetc_hw *enetc_hw, struct enetc_psi_reply_msg *reply_msg)
     210                 :            : {
     211                 :            :         int vsimsgsr;
     212                 :            :         int8_t class_id = 0;
     213                 :            :         uint8_t status = 0;
     214                 :            : 
     215                 :          0 :         vsimsgsr = enetc_rd(enetc_hw, ENETC4_VSIMSGSR);
     216                 :            : 
     217                 :            :         /* Extracting 8 bits of message result in class_id */
     218                 :          0 :         class_id |= ((ENETC_SIMSGSR_GET_MC(vsimsgsr) >> 8) & 0xff);
     219                 :            : 
     220                 :            :         /* Extracting 4 bits of message result in status */
     221                 :          0 :         status |= ((ENETC_SIMSGSR_GET_MC(vsimsgsr) >> 4) & 0xf);
     222                 :            : 
     223                 :          0 :         reply_msg->class_id = class_id;
     224                 :          0 :         reply_msg->status = status;
     225                 :          0 : }
     226                 :            : 
     227                 :            : static void
     228                 :            : enetc4_msg_get_psi_msg(struct enetc_hw *enetc_hw, struct enetc_psi_reply_msg *reply_msg)
     229                 :            : {
     230                 :            :         int vsimsgrr;
     231                 :            :         int8_t class_id = 0;
     232                 :            :         uint8_t status = 0;
     233                 :            : 
     234                 :          0 :         vsimsgrr = enetc_rd(enetc_hw, ENETC4_VSIMSGRR);
     235                 :            : 
     236                 :            :         /* Extracting 8 bits of message result in class_id */
     237                 :          0 :         class_id |= ((ENETC_SIMSGSR_GET_MC(vsimsgrr) >> 8) & 0xff);
     238                 :            : 
     239                 :            :         /* Extracting 4 bits of message result in status */
     240                 :          0 :         status |= ((ENETC_SIMSGSR_GET_MC(vsimsgrr) >> 4) & 0xf);
     241                 :            : 
     242                 :          0 :         reply_msg->class_id = class_id;
     243                 :          0 :         reply_msg->status = status;
     244                 :            : }
     245                 :            : 
     246                 :            : static void
     247                 :          0 : enetc4_process_psi_msg(struct rte_eth_dev *eth_dev, struct enetc_hw *enetc_hw)
     248                 :            : {
     249                 :            :         struct enetc_psi_reply_msg *msg;
     250                 :            :         struct rte_eth_link link;
     251                 :            :         int ret = 0;
     252                 :            : 
     253                 :          0 :         msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
     254         [ #  # ]:          0 :         if (!msg) {
     255                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for msg");
     256                 :          0 :                 return;
     257                 :            :         }
     258                 :            : 
     259                 :          0 :         rte_eth_linkstatus_get(eth_dev, &link);
     260                 :            :         enetc4_msg_get_psi_msg(enetc_hw, msg);
     261                 :            : 
     262         [ #  # ]:          0 :         if (msg->class_id == ENETC_CLASS_ID_LINK_STATUS) {
     263      [ #  #  # ]:          0 :                 switch (msg->status) {
     264                 :          0 :                 case ENETC_LINK_UP:
     265                 :          0 :                         ENETC_PMD_DEBUG("Link is up");
     266                 :          0 :                         link.link_status = RTE_ETH_LINK_UP;
     267                 :          0 :                         break;
     268                 :          0 :                 case ENETC_LINK_DOWN:
     269                 :          0 :                         ENETC_PMD_DEBUG("Link is down");
     270                 :          0 :                         link.link_status = RTE_ETH_LINK_DOWN;
     271                 :          0 :                         break;
     272                 :          0 :                 default:
     273                 :          0 :                         ENETC_PMD_ERR("Unknown link status 0x%x", msg->status);
     274                 :          0 :                         break;
     275                 :            :                 }
     276                 :            :                 ret = rte_eth_linkstatus_set(eth_dev, &link);
     277                 :            :                 if (!ret)
     278                 :          0 :                         ENETC_PMD_DEBUG("Link status has been changed");
     279                 :            : 
     280                 :            :                 /* Process user registered callback */
     281                 :          0 :                 rte_eth_dev_callback_process(eth_dev,
     282                 :            :                         RTE_ETH_EVENT_INTR_LSC, NULL);
     283                 :            :         } else {
     284                 :          0 :                 ENETC_PMD_ERR("Wrong message 0x%x", msg->class_id);
     285                 :            :         }
     286                 :            : 
     287                 :          0 :         rte_free(msg);
     288                 :            : }
     289                 :            : 
     290                 :            : static int
     291                 :          0 : enetc4_msg_vsi_send(struct enetc_eth_hw *hw, struct enetc_msg_swbd *msg)
     292                 :            : {
     293                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     294         [ #  # ]:          0 :         int timeout = hw->vsi_timeout ? (int)hw->vsi_timeout :
     295                 :            :                                         ENETC4_DEF_VSI_WAIT_TIMEOUT_UPDATE;
     296         [ #  # ]:          0 :         int delay_us = hw->vsi_delay ? (int)hw->vsi_delay :
     297                 :            :                                        ENETC4_DEF_VSI_WAIT_DELAY_UPDATE;
     298                 :            :         uint8_t class_id = 0;
     299                 :            :         int err = 0;
     300                 :            :         int vsimsgsr;
     301                 :            : 
     302                 :            :         enetc4_msg_vsi_write_msg(enetc_hw, msg);
     303                 :            : 
     304                 :            :         do {
     305                 :          0 :                 vsimsgsr = enetc_rd(enetc_hw, ENETC4_VSIMSGSR);
     306         [ #  # ]:          0 :                 if (!(vsimsgsr & ENETC4_VSIMSGSR_MB))
     307                 :            :                         break;
     308                 :          0 :                 rte_delay_us(delay_us);
     309         [ #  # ]:          0 :         } while (--timeout);
     310                 :            : 
     311         [ #  # ]:          0 :         if (!timeout) {
     312                 :          0 :                 ENETC_PMD_ERR("Message not processed by PSI");
     313                 :          0 :                 return -ETIMEDOUT;
     314                 :            :         }
     315                 :            :         /* check for message delivery error */
     316         [ #  # ]:          0 :         if (vsimsgsr & ENETC4_VSIMSGSR_MS) {
     317                 :          0 :                 ENETC_PMD_ERR("Transfer error when copying the data");
     318                 :          0 :                 return -EIO;
     319                 :            :         }
     320                 :            : 
     321                 :          0 :         class_id |= ((ENETC_SIMSGSR_GET_MC(vsimsgsr) >> 8) & 0xff);
     322                 :            : 
     323                 :            :         /* Check the user-defined completion status. */
     324         [ #  # ]:          0 :         if (class_id != ENETC_MSG_CLASS_ID_CMD_SUCCESS) {
     325   [ #  #  #  #  :          0 :                 switch (class_id) {
             #  #  #  #  
                      # ]
     326                 :          0 :                 case ENETC_MSG_CLASS_ID_PERMISSION_DENY:
     327                 :          0 :                         ENETC_PMD_ERR("Permission denied");
     328                 :            :                         err = -EACCES;
     329                 :          0 :                         break;
     330                 :          0 :                 case ENETC_MSG_CLASS_ID_CMD_NOT_SUPPORT:
     331                 :          0 :                         ENETC_PMD_ERR("Command not supported");
     332                 :            :                         err = -EOPNOTSUPP;
     333                 :          0 :                         break;
     334                 :          0 :                 case ENETC_MSG_CLASS_ID_PSI_BUSY:
     335                 :          0 :                         ENETC_PMD_ERR("PSI Busy");
     336                 :            :                         err = -EBUSY;
     337                 :          0 :                         break;
     338                 :          0 :                 case ENETC_MSG_CLASS_ID_CMD_TIMEOUT:
     339                 :          0 :                         ENETC_PMD_ERR("Command timeout");
     340                 :            :                         err = -ETIME;
     341                 :          0 :                         break;
     342                 :          0 :                 case ENETC_MSG_CLASS_ID_CRC_ERROR:
     343                 :          0 :                         ENETC_PMD_ERR("CRC error");
     344                 :            :                         err = -EIO;
     345                 :          0 :                         break;
     346                 :          0 :                 case ENETC_MSG_CLASS_ID_PROTO_NOT_SUPPORT:
     347                 :          0 :                         ENETC_PMD_ERR("Protocol Version not supported");
     348                 :            :                         err = -EOPNOTSUPP;
     349                 :          0 :                         break;
     350                 :          0 :                 case ENETC_MSG_CLASS_ID_INVALID_MSG_LEN:
     351                 :          0 :                         ENETC_PMD_ERR("Invalid message length");
     352                 :            :                         err = -EINVAL;
     353                 :          0 :                         break;
     354                 :            :                 case ENETC_CLASS_ID_MAC_FILTER:
     355                 :            :                 case ENETC_CLASS_ID_LINK_STATUS:
     356                 :            :                 case ENETC_CLASS_ID_LINK_SPEED:
     357                 :            :                         break;
     358                 :          0 :                 default:
     359                 :            :                         err = -EIO;
     360                 :            :                 }
     361                 :            :         }
     362                 :            : 
     363                 :            :         return err;
     364                 :            : }
     365                 :            : 
     366                 :            : static int
     367                 :          0 : enetc4_vf_set_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
     368                 :            : {
     369                 :          0 :         struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     370                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     371                 :            :         struct enetc_msg_cmd_set_primary_mac *cmd;
     372                 :            :         struct enetc_msg_swbd *msg;
     373                 :            :         struct enetc_psi_reply_msg *reply_msg;
     374                 :            :         uint32_t msg_size;
     375                 :            :         int err = 0;
     376                 :            : 
     377                 :          0 :         PMD_INIT_FUNC_TRACE();
     378                 :          0 :         reply_msg = rte_zmalloc(NULL, sizeof(*reply_msg), RTE_CACHE_LINE_SIZE);
     379         [ #  # ]:          0 :         if (!reply_msg) {
     380                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for reply_msg");
     381                 :          0 :                 return -ENOMEM;
     382                 :            :         }
     383                 :            : 
     384                 :          0 :         msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
     385         [ #  # ]:          0 :         if (!msg) {
     386                 :          0 :                 ENETC_PMD_ERR("Failed to alloc msg");
     387                 :            :                 err = -ENOMEM;
     388                 :          0 :                 rte_free(reply_msg);
     389                 :          0 :                 return err;
     390                 :            :         }
     391                 :            : 
     392                 :            :         msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_set_primary_mac),
     393                 :            :                                 ENETC_VSI_PSI_MSG_SIZE);
     394                 :          0 :         msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
     395         [ #  # ]:          0 :         if (!msg->vaddr) {
     396                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for msg");
     397                 :          0 :                 rte_free(msg);
     398                 :          0 :                 rte_free(reply_msg);
     399                 :          0 :                 return -ENOMEM;
     400                 :            :         }
     401                 :            : 
     402                 :          0 :         msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
     403                 :          0 :         msg->size = msg_size;
     404                 :            : 
     405                 :          0 :         cmd = (struct enetc_msg_cmd_set_primary_mac *)msg->vaddr;
     406                 :            : 
     407                 :          0 :         cmd->count = 0;
     408                 :          0 :         memcpy(&cmd->addr.addr_bytes, addr, sizeof(struct rte_ether_addr));
     409                 :            : 
     410                 :            :         enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_MAC_FILTER,
     411                 :            :                                         ENETC_CMD_ID_SET_PRIMARY_MAC, 0, 0, 0);
     412                 :            : 
     413                 :            :         /* send the command and wait */
     414                 :          0 :         err = enetc4_msg_vsi_send(hw, msg);
     415         [ #  # ]:          0 :         if (err) {
     416                 :          0 :                 ENETC_PMD_ERR("VSI message send error");
     417                 :          0 :                 goto end;
     418                 :            :         }
     419                 :            : 
     420                 :            :         enetc4_msg_vsi_reply_msg(enetc_hw, reply_msg);
     421                 :            : 
     422         [ #  # ]:          0 :         if (reply_msg->class_id == ENETC_CLASS_ID_MAC_FILTER) {
     423      [ #  #  # ]:          0 :                 switch (reply_msg->status) {
     424                 :          0 :                 case ENETC_INVALID_MAC_ADDR:
     425                 :          0 :                         ENETC_PMD_ERR("Invalid MAC address");
     426                 :            :                         err = -EINVAL;
     427                 :            :                         break;
     428                 :          0 :                 case ENETC_DUPLICATE_MAC_ADDR:
     429                 :          0 :                         ENETC_PMD_ERR("Duplicate MAC address");
     430                 :            :                         err = -EINVAL;
     431                 :            :                         break;
     432                 :            :                 default:
     433                 :            :                         err = -EINVAL;
     434                 :            :                         break;
     435                 :            :                 }
     436                 :            :         }
     437                 :            : 
     438                 :            :         if (err) {
     439                 :          0 :                 ENETC_PMD_ERR("VSI command execute error!");
     440                 :          0 :                 goto end;
     441                 :            :         }
     442                 :            : 
     443                 :          0 :         rte_ether_addr_copy((struct rte_ether_addr *)&cmd->addr,
     444                 :          0 :                         &dev->data->mac_addrs[0]);
     445                 :            : 
     446                 :          0 : end:
     447                 :            :         /* free memory no longer required */
     448                 :          0 :         rte_free(msg->vaddr);
     449                 :          0 :         rte_free(reply_msg);
     450                 :          0 :         rte_free(msg);
     451                 :          0 :         return err;
     452                 :            : }
     453                 :            : 
     454                 :            : static int
     455                 :          0 : enetc4_vf_promisc_send_message(struct rte_eth_dev *dev, bool promisc_en)
     456                 :            : {
     457                 :          0 :         struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     458                 :            :         struct enetc_msg_cmd_set_promisc *cmd;
     459                 :            :         struct enetc_msg_swbd *msg;
     460                 :            :         uint32_t msg_size;
     461                 :            :         int err = 0;
     462                 :            : 
     463                 :          0 :         msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
     464         [ #  # ]:          0 :         if (!msg) {
     465                 :          0 :                 ENETC_PMD_ERR("Failed to alloc msg");
     466                 :            :                 err = -ENOMEM;
     467                 :          0 :                 return err;
     468                 :            :         }
     469                 :            : 
     470                 :            :         msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_set_promisc), ENETC_VSI_PSI_MSG_SIZE);
     471                 :          0 :         msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
     472         [ #  # ]:          0 :         if (!msg->vaddr) {
     473                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for msg");
     474                 :          0 :                 rte_free(msg);
     475                 :          0 :                 return -ENOMEM;
     476                 :            :         }
     477                 :            : 
     478                 :          0 :         msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
     479                 :          0 :         msg->size = msg_size;
     480                 :            : 
     481                 :          0 :         cmd = (struct enetc_msg_cmd_set_promisc *)msg->vaddr;
     482                 :            : 
     483                 :            :         /* op_type is based on the result of message format
     484                 :            :          *    7  6      1       0
     485                 :            :               type   promisc  flush
     486                 :            :          */
     487                 :            : 
     488         [ #  # ]:          0 :         if (promisc_en)
     489                 :          0 :                 cmd->op_type = ENETC_PROMISC_ENABLE;
     490                 :            :         else
     491                 :          0 :                 cmd->op_type = ENETC_PROMISC_DISABLE;
     492                 :            : 
     493                 :            :         enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_MAC_FILTER,
     494                 :            :                                 ENETC_CMD_ID_SET_MAC_PROMISCUOUS, 0, 0, 0);
     495                 :            : 
     496                 :            :         /* send the command and wait */
     497                 :          0 :         err = enetc4_msg_vsi_send(hw, msg);
     498         [ #  # ]:          0 :         if (err) {
     499                 :          0 :                 ENETC_PMD_ERR("VSI message send error");
     500                 :          0 :                 goto end;
     501                 :            :         }
     502                 :            : 
     503                 :          0 : end:
     504                 :            :         /* free memory no longer required */
     505                 :          0 :         rte_free(msg->vaddr);
     506                 :          0 :         rte_free(msg);
     507                 :          0 :         return err;
     508                 :            : }
     509                 :            : 
     510                 :            : static int
     511                 :          0 : enetc4_vf_allmulti_send_message(struct rte_eth_dev *dev, bool mc_promisc)
     512                 :            : {
     513                 :          0 :         struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     514                 :            :         struct enetc_msg_cmd_set_promisc *cmd;
     515                 :            :         struct enetc_msg_swbd *msg;
     516                 :            :         uint32_t msg_size;
     517                 :            :         int err = 0;
     518                 :            : 
     519                 :          0 :         msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
     520         [ #  # ]:          0 :         if (!msg) {
     521                 :          0 :                 ENETC_PMD_ERR("Failed to alloc msg");
     522                 :            :                 err = -ENOMEM;
     523                 :          0 :                 return err;
     524                 :            :         }
     525                 :            : 
     526                 :            :         msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_set_promisc),
     527                 :            :                                 ENETC_VSI_PSI_MSG_SIZE);
     528                 :          0 :         msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
     529         [ #  # ]:          0 :         if (!msg->vaddr) {
     530                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for msg");
     531                 :          0 :                 rte_free(msg);
     532                 :          0 :                 return -ENOMEM;
     533                 :            :         }
     534                 :            : 
     535                 :          0 :         msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
     536                 :          0 :         msg->size = msg_size;
     537                 :            : 
     538                 :          0 :         cmd = (struct enetc_msg_cmd_set_promisc *)msg->vaddr;
     539                 :            : 
     540                 :            :         /* op_type is based on the result of message format
     541                 :            :          *    7  6      1       0
     542                 :            :               type   promisc  flush
     543                 :            :          */
     544                 :            : 
     545         [ #  # ]:          0 :         if (mc_promisc)
     546                 :          0 :                 cmd->op_type = ENETC_ALLMULTI_PROMISC_EN;
     547                 :            :         else
     548                 :          0 :                 cmd->op_type = ENETC_ALLMULTI_PROMISC_DIS;
     549                 :            : 
     550                 :            :         enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_MAC_FILTER,
     551                 :            :                                 ENETC_CMD_ID_SET_MAC_PROMISCUOUS, 0, 0, 0);
     552                 :            : 
     553                 :            :         /* send the command and wait */
     554                 :          0 :         err = enetc4_msg_vsi_send(hw, msg);
     555         [ #  # ]:          0 :         if (err) {
     556                 :          0 :                 ENETC_PMD_ERR("VSI message send error");
     557                 :          0 :                 goto end;
     558                 :            :         }
     559                 :            : 
     560                 :          0 : end:
     561                 :            :         /* free memory no longer required */
     562                 :          0 :         rte_free(msg->vaddr);
     563                 :          0 :         rte_free(msg);
     564                 :          0 :         return err;
     565                 :            : }
     566                 :            : 
     567                 :            : 
     568                 :            : static int
     569                 :          0 : enetc4_vf_multicast_enable(struct rte_eth_dev *dev)
     570                 :            : {
     571                 :            :         int err;
     572                 :            : 
     573                 :          0 :         PMD_INIT_FUNC_TRACE();
     574                 :          0 :         err = enetc4_vf_allmulti_send_message(dev, true);
     575         [ #  # ]:          0 :         if (err) {
     576                 :          0 :                 ENETC_PMD_ERR("Failed to enable multicast promiscuous mode");
     577                 :          0 :                 return err;
     578                 :            :         }
     579                 :            : 
     580                 :            :         return 0;
     581                 :            : }
     582                 :            : 
     583                 :            : static int
     584                 :          0 : enetc4_vf_multicast_disable(struct rte_eth_dev *dev)
     585                 :            : {
     586                 :            :         int err;
     587                 :            : 
     588                 :          0 :         PMD_INIT_FUNC_TRACE();
     589                 :          0 :         err = enetc4_vf_allmulti_send_message(dev, false);
     590         [ #  # ]:          0 :         if (err) {
     591                 :          0 :                 ENETC_PMD_ERR("Failed to disable multicast promiscuous mode");
     592                 :          0 :                 return err;
     593                 :            :         }
     594                 :            : 
     595                 :            :         return 0;
     596                 :            : }
     597                 :            : 
     598                 :            : static int
     599                 :          0 : enetc4_vf_promisc_enable(struct rte_eth_dev *dev)
     600                 :            : {
     601                 :            :         int err;
     602                 :            : 
     603                 :          0 :         PMD_INIT_FUNC_TRACE();
     604                 :          0 :         err = enetc4_vf_promisc_send_message(dev, true);
     605         [ #  # ]:          0 :         if (err) {
     606                 :          0 :                 ENETC_PMD_ERR("Failed to enable promiscuous mode");
     607                 :          0 :                 return err;
     608                 :            :         }
     609                 :            : 
     610                 :            :         return 0;
     611                 :            : }
     612                 :            : 
     613                 :            : static int
     614                 :          0 : enetc4_vf_promisc_disable(struct rte_eth_dev *dev)
     615                 :            : {
     616                 :            :         int err;
     617                 :            : 
     618                 :          0 :         PMD_INIT_FUNC_TRACE();
     619                 :          0 :         err = enetc4_vf_promisc_send_message(dev, false);
     620         [ #  # ]:          0 :         if (err) {
     621                 :          0 :                 ENETC_PMD_ERR("Failed to disable promiscuous mode");
     622                 :          0 :                 return err;
     623                 :            :         }
     624                 :            : 
     625                 :            :         return 0;
     626                 :            : }
     627                 :            : 
     628                 :            : static int
     629                 :          0 : enetc4_vf_get_link_status(struct rte_eth_dev *dev, struct enetc_psi_reply_msg *reply_msg)
     630                 :            : {
     631                 :          0 :         struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     632                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     633                 :            :         struct enetc_msg_swbd *msg;
     634                 :            :         uint32_t msg_size;
     635                 :            :         int err = 0;
     636                 :            : 
     637                 :          0 :         msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
     638         [ #  # ]:          0 :         if (!msg) {
     639                 :          0 :                 ENETC_PMD_ERR("Failed to alloc msg");
     640                 :            :                 err = -ENOMEM;
     641                 :          0 :                 return err;
     642                 :            :         }
     643                 :            : 
     644                 :            :         msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_get_link_status),
     645                 :            :                         ENETC_VSI_PSI_MSG_SIZE);
     646                 :          0 :         msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
     647         [ #  # ]:          0 :         if (!msg->vaddr) {
     648                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for msg");
     649                 :          0 :                 rte_free(msg);
     650                 :          0 :                 return -ENOMEM;
     651                 :            :         }
     652                 :            : 
     653                 :          0 :         msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
     654                 :          0 :         msg->size = msg_size;
     655                 :            : 
     656                 :            :         enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_LINK_STATUS,
     657                 :            :                         ENETC_CMD_ID_GET_LINK_STATUS, 0, 0, 0);
     658                 :            : 
     659                 :            :         /* send the command and wait */
     660                 :          0 :         err = enetc4_msg_vsi_send(hw, msg);
     661         [ #  # ]:          0 :         if (err) {
     662                 :          0 :                 ENETC_PMD_ERR("VSI message send error");
     663                 :          0 :                 goto end;
     664                 :            :         }
     665                 :            : 
     666                 :            :         enetc4_msg_vsi_reply_msg(enetc_hw, reply_msg);
     667                 :          0 : end:
     668                 :            :         /* free memory no longer required */
     669                 :          0 :         rte_free(msg->vaddr);
     670                 :          0 :         rte_free(msg);
     671                 :          0 :         return err;
     672                 :            : }
     673                 :            : 
     674                 :            : static int
     675                 :          0 : enetc4_vf_get_link_speed(struct rte_eth_dev *dev, struct enetc_psi_reply_msg *reply_msg)
     676                 :            : {
     677                 :          0 :         struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     678                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     679                 :            :         struct enetc_msg_swbd *msg;
     680                 :            :         uint32_t msg_size;
     681                 :            :         int err = 0;
     682                 :            : 
     683                 :          0 :         msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
     684         [ #  # ]:          0 :         if (!msg) {
     685                 :          0 :                 ENETC_PMD_ERR("Failed to alloc msg");
     686                 :            :                 err = -ENOMEM;
     687                 :          0 :                 return err;
     688                 :            :         }
     689                 :            : 
     690                 :            :         msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_get_link_speed),
     691                 :            :                                 ENETC_VSI_PSI_MSG_SIZE);
     692                 :          0 :         msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
     693         [ #  # ]:          0 :         if (!msg->vaddr) {
     694                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for msg");
     695                 :          0 :                 rte_free(msg);
     696                 :          0 :                 return -ENOMEM;
     697                 :            :         }
     698                 :            : 
     699                 :          0 :         msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
     700                 :          0 :         msg->size = msg_size;
     701                 :            : 
     702                 :            :         enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_LINK_SPEED,
     703                 :            :                         ENETC_CMD_ID_GET_LINK_SPEED, 0, 0, 0);
     704                 :            : 
     705                 :            :         /* send the command and wait */
     706                 :          0 :         err = enetc4_msg_vsi_send(hw, msg);
     707         [ #  # ]:          0 :         if (err) {
     708                 :          0 :                 ENETC_PMD_ERR("VSI message send error");
     709                 :          0 :                 goto end;
     710                 :            :         }
     711                 :            : 
     712                 :            :         enetc4_msg_vsi_reply_msg(enetc_hw, reply_msg);
     713                 :          0 : end:
     714                 :            :         /* free memory no longer required */
     715                 :          0 :         rte_free(msg->vaddr);
     716                 :          0 :         rte_free(msg);
     717                 :          0 :         return err;
     718                 :            : }
     719                 :            : 
     720                 :            : static int
     721                 :          0 : enetc4_vf_link_update_dummy(struct rte_eth_dev *dev __rte_unused,
     722                 :            :                             int wait_to_complete __rte_unused)
     723                 :            : {
     724                 :          0 :         return 0;
     725                 :            : }
     726                 :            : 
     727                 :            : static int
     728                 :          0 : enetc4_vf_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
     729                 :            : {
     730                 :            :         struct enetc_psi_reply_msg *reply_msg;
     731                 :            :         struct rte_eth_link link;
     732                 :            :         int err;
     733                 :            : 
     734                 :          0 :         PMD_INIT_FUNC_TRACE();
     735                 :          0 :         reply_msg = rte_zmalloc(NULL, sizeof(*reply_msg), RTE_CACHE_LINE_SIZE);
     736         [ #  # ]:          0 :         if (!reply_msg) {
     737                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for reply_msg");
     738                 :          0 :                 return -ENOMEM;
     739                 :            :         }
     740                 :            : 
     741                 :            :         memset(&link, 0, sizeof(struct rte_eth_link));
     742                 :            : 
     743                 :          0 :         err = enetc4_vf_get_link_status(dev, reply_msg);
     744         [ #  # ]:          0 :         if (err) {
     745                 :          0 :                 ENETC_PMD_ERR("Failed to get link status");
     746                 :          0 :                 rte_free(reply_msg);
     747                 :          0 :                 return err;
     748                 :            :         }
     749                 :            : 
     750         [ #  # ]:          0 :         if (reply_msg->class_id == ENETC_CLASS_ID_LINK_STATUS) {
     751      [ #  #  # ]:          0 :                 switch (reply_msg->status) {
     752                 :          0 :                 case ENETC_LINK_UP:
     753                 :          0 :                         link.link_status = RTE_ETH_LINK_UP;
     754                 :          0 :                         break;
     755                 :            :                 case ENETC_LINK_DOWN:
     756                 :            :                         link.link_status = RTE_ETH_LINK_DOWN;
     757                 :            :                         break;
     758                 :          0 :                 default:
     759                 :          0 :                         ENETC_PMD_ERR("Unknown link status");
     760                 :          0 :                         break;
     761                 :            :                 }
     762                 :            :         } else {
     763                 :          0 :                 ENETC_PMD_ERR("Wrong reply message");
     764                 :          0 :                 return -1;
     765                 :            :         }
     766                 :            : 
     767                 :          0 :         err = enetc4_vf_get_link_speed(dev, reply_msg);
     768         [ #  # ]:          0 :         if (err) {
     769                 :          0 :                 ENETC_PMD_ERR("Failed to get link speed");
     770                 :          0 :                 rte_free(reply_msg);
     771                 :          0 :                 return err;
     772                 :            :         }
     773                 :            : 
     774         [ #  # ]:          0 :         if (reply_msg->class_id == ENETC_CLASS_ID_LINK_SPEED) {
     775   [ #  #  #  #  :          0 :                 switch (reply_msg->status) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     776                 :          0 :                 case ENETC_SPEED_UNKNOWN:
     777                 :          0 :                         ENETC_PMD_DEBUG("Speed unknown");
     778                 :            :                         link.link_speed = RTE_ETH_SPEED_NUM_NONE;
     779                 :          0 :                         break;
     780                 :          0 :                 case ENETC_SPEED_10_HALF_DUPLEX:
     781                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_10M;
     782                 :            :                         link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
     783                 :          0 :                         break;
     784                 :          0 :                 case ENETC_SPEED_10_FULL_DUPLEX:
     785                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_10M;
     786                 :          0 :                         link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     787                 :          0 :                         break;
     788                 :          0 :                 case ENETC_SPEED_100_HALF_DUPLEX:
     789                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_100M;
     790                 :            :                         link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
     791                 :          0 :                         break;
     792                 :          0 :                 case ENETC_SPEED_100_FULL_DUPLEX:
     793                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_100M;
     794                 :          0 :                         link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     795                 :          0 :                         break;
     796                 :          0 :                 case ENETC_SPEED_1000:
     797                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_1G;
     798                 :          0 :                         link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     799                 :          0 :                         break;
     800                 :          0 :                 case ENETC_SPEED_2500:
     801                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_2_5G;
     802                 :          0 :                         link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     803                 :          0 :                         break;
     804                 :          0 :                 case ENETC_SPEED_5000:
     805                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_5G;
     806                 :          0 :                         link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     807                 :          0 :                         break;
     808                 :          0 :                 case ENETC_SPEED_10G:
     809                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_10G;
     810                 :          0 :                         link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     811                 :          0 :                         break;
     812                 :          0 :                 case ENETC_SPEED_25G:
     813                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_25G;
     814                 :          0 :                         link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     815                 :          0 :                         break;
     816                 :          0 :                 case ENETC_SPEED_50G:
     817                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_50G;
     818                 :          0 :                         link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     819                 :          0 :                         break;
     820                 :          0 :                 case ENETC_SPEED_100G:
     821                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_100G;
     822                 :          0 :                         link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
     823                 :          0 :                         break;
     824                 :          0 :                 case ENETC_SPEED_NOT_SUPPORTED:
     825                 :          0 :                         ENETC_PMD_DEBUG("Speed not supported");
     826                 :          0 :                         link.link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
     827                 :          0 :                         break;
     828                 :          0 :                 default:
     829                 :          0 :                         ENETC_PMD_ERR("Unknown speed status");
     830                 :          0 :                         break;
     831                 :            :                 }
     832                 :            :         } else {
     833                 :          0 :                 ENETC_PMD_ERR("Wrong reply message");
     834                 :          0 :                 return -1;
     835                 :            :         }
     836                 :            : 
     837                 :          0 :         link.link_autoneg = 1;
     838                 :            : 
     839                 :          0 :         rte_eth_linkstatus_set(dev, &link);
     840                 :            : 
     841                 :          0 :         rte_free(reply_msg);
     842                 :          0 :         return 0;
     843                 :            : }
     844                 :            : 
     845                 :            : static int
     846                 :          0 : enetc4_vf_vlan_promisc(struct rte_eth_dev *dev, bool promisc_en)
     847                 :            : {
     848                 :          0 :         struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     849                 :            :         struct enetc_msg_cmd_set_vlan_promisc *cmd;
     850                 :            :         struct enetc_msg_swbd *msg;
     851                 :            :         uint32_t msg_size;
     852                 :            :         int err = 0;
     853                 :            : 
     854                 :          0 :         msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
     855         [ #  # ]:          0 :         if (!msg) {
     856                 :          0 :                 ENETC_PMD_ERR("Failed to alloc msg");
     857                 :            :                 err = -ENOMEM;
     858                 :          0 :                 return err;
     859                 :            :         }
     860                 :            : 
     861                 :            :         msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_set_vlan_promisc),
     862                 :            :                                 ENETC_VSI_PSI_MSG_SIZE);
     863                 :          0 :         msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
     864         [ #  # ]:          0 :         if (!msg->vaddr) {
     865                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for msg");
     866                 :          0 :                 rte_free(msg);
     867                 :          0 :                 return -ENOMEM;
     868                 :            :         }
     869                 :          0 :         msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
     870                 :          0 :         msg->size = msg_size;
     871                 :            : 
     872                 :          0 :         cmd = (struct enetc_msg_cmd_set_vlan_promisc *)msg->vaddr;
     873                 :            :         /* op is based on the result of message format
     874                 :            :          *         1      0
     875                 :            :          *      promisc flush
     876                 :            :          */
     877                 :            : 
     878         [ #  # ]:          0 :         if (promisc_en)
     879                 :          0 :                 cmd->op = ENETC_PROMISC_VLAN_ENABLE;
     880                 :            :         else
     881                 :          0 :                 cmd->op = ENETC_PROMISC_VLAN_DISABLE;
     882                 :            : 
     883                 :            :         enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_VLAN_FILTER,
     884                 :            :                                 ENETC_CMD_ID_SET_VLAN_PROMISCUOUS, 0, 0, 0);
     885                 :            : 
     886                 :            :         /* send the command and wait */
     887                 :          0 :         err = enetc4_msg_vsi_send(hw, msg);
     888         [ #  # ]:          0 :         if (err) {
     889                 :          0 :                 ENETC_PMD_ERR("VSI message send error");
     890                 :          0 :                 goto end;
     891                 :            :         }
     892                 :            : 
     893                 :          0 : end:
     894                 :            :         /* free memory no longer required */
     895                 :          0 :         rte_free(msg->vaddr);
     896                 :          0 :         rte_free(msg);
     897                 :          0 :         return err;
     898                 :            : }
     899                 :            : 
     900                 :            : static int
     901                 :          0 : enetc4_vf_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *addr,
     902                 :            :                         uint32_t index __rte_unused, uint32_t pool __rte_unused)
     903                 :            : {
     904                 :          0 :         struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     905                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     906                 :            :         struct enetc_msg_cmd_set_primary_mac *cmd;
     907                 :            :         struct enetc_msg_swbd *msg;
     908                 :            :         struct enetc_psi_reply_msg *reply_msg;
     909                 :            :         uint32_t msg_size;
     910                 :            :         int err = 0;
     911                 :            : 
     912                 :          0 :         PMD_INIT_FUNC_TRACE();
     913                 :            : 
     914                 :            :         if (!rte_is_valid_assigned_ether_addr(addr))
     915                 :            :                 return -EINVAL;
     916                 :            : 
     917                 :          0 :         reply_msg = rte_zmalloc(NULL, sizeof(*reply_msg), RTE_CACHE_LINE_SIZE);
     918         [ #  # ]:          0 :         if (!reply_msg) {
     919                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for reply_msg");
     920                 :          0 :                 return -ENOMEM;
     921                 :            :         }
     922                 :            : 
     923                 :          0 :         msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
     924         [ #  # ]:          0 :         if (!msg) {
     925                 :          0 :                 ENETC_PMD_ERR("Failed to alloc msg");
     926                 :            :                 err = -ENOMEM;
     927                 :          0 :                 rte_free(reply_msg);
     928                 :          0 :                 return err;
     929                 :            :         }
     930                 :            : 
     931                 :            :         msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_set_primary_mac),
     932                 :            :                         ENETC_VSI_PSI_MSG_SIZE);
     933                 :          0 :         msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
     934         [ #  # ]:          0 :         if (!msg->vaddr) {
     935                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for msg");
     936                 :          0 :                 rte_free(msg);
     937                 :          0 :                 rte_free(reply_msg);
     938                 :          0 :                 return -ENOMEM;
     939                 :            :         }
     940                 :          0 :         msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
     941                 :          0 :         msg->size = msg_size;
     942                 :          0 :         cmd = (struct enetc_msg_cmd_set_primary_mac *)msg->vaddr;
     943                 :          0 :         memcpy(&cmd->addr.addr_bytes, addr, sizeof(struct rte_ether_addr));
     944                 :          0 :         cmd->count = 1;
     945                 :            : 
     946                 :            :         enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_MAC_FILTER,
     947                 :            :                         ENETC_MSG_ADD_EXACT_MAC_ENTRIES, 0, 0, 0);
     948                 :            : 
     949                 :            :         /* send the command and wait */
     950                 :          0 :         err = enetc4_msg_vsi_send(hw, msg);
     951         [ #  # ]:          0 :         if (err) {
     952                 :          0 :                 ENETC_PMD_ERR("VSI message send error");
     953                 :          0 :                 goto end;
     954                 :            :         }
     955                 :            : 
     956                 :            :         enetc4_msg_vsi_reply_msg(enetc_hw, reply_msg);
     957                 :            : 
     958         [ #  # ]:          0 :         if (reply_msg->class_id == ENETC_CLASS_ID_MAC_FILTER) {
     959   [ #  #  #  # ]:          0 :                 switch (reply_msg->status) {
     960                 :          0 :                 case ENETC_INVALID_MAC_ADDR:
     961                 :          0 :                         ENETC_PMD_ERR("Invalid MAC address");
     962                 :            :                         err = -EINVAL;
     963                 :            :                         break;
     964                 :          0 :                 case ENETC_DUPLICATE_MAC_ADDR:
     965                 :          0 :                         ENETC_PMD_ERR("Duplicate MAC address");
     966                 :            :                         err = -EINVAL;
     967                 :            :                         break;
     968                 :          0 :                 case ENETC_MAC_FILTER_NO_RESOURCE:
     969                 :          0 :                         ENETC_PMD_ERR("Not enough exact-match entries available");
     970                 :            :                         err = -EINVAL;
     971                 :            :                         break;
     972                 :            :                 default:
     973                 :            :                         err = -EINVAL;
     974                 :            :                         break;
     975                 :            :                 }
     976                 :            :         }
     977                 :            : 
     978                 :            :         if (err) {
     979                 :          0 :                 ENETC_PMD_ERR("VSI command execute error!");
     980                 :          0 :                 goto end;
     981                 :            :         }
     982                 :            : 
     983                 :          0 : end:
     984                 :            :         /* free memory no longer required */
     985                 :          0 :         rte_free(msg->vaddr);
     986                 :          0 :         rte_free(reply_msg);
     987                 :          0 :         rte_free(msg);
     988                 :          0 :         return err;
     989                 :            : }
     990                 :            : 
     991                 :          0 : static int enetc4_vf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
     992                 :            : {
     993                 :          0 :         struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     994                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
     995                 :            :         struct enetc_msg_vlan_exact_filter *cmd;
     996                 :            :         struct enetc_msg_swbd *msg;
     997                 :            :         struct enetc_psi_reply_msg *reply_msg;
     998                 :            :         uint32_t msg_size;
     999                 :            :         int err = 0;
    1000                 :            : 
    1001                 :          0 :         PMD_INIT_FUNC_TRACE();
    1002                 :            : 
    1003                 :          0 :         reply_msg = rte_zmalloc(NULL, sizeof(*reply_msg), RTE_CACHE_LINE_SIZE);
    1004         [ #  # ]:          0 :         if (!reply_msg) {
    1005                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for reply_msg");
    1006                 :          0 :                 return -ENOMEM;
    1007                 :            :         }
    1008                 :            : 
    1009                 :          0 :         msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
    1010         [ #  # ]:          0 :         if (!msg) {
    1011                 :          0 :                 ENETC_PMD_ERR("Failed to alloc msg");
    1012                 :            :                 err = -ENOMEM;
    1013                 :          0 :                 rte_free(reply_msg);
    1014                 :          0 :                 return err;
    1015                 :            :         }
    1016                 :            : 
    1017                 :            :         msg_size = RTE_ALIGN(sizeof(struct enetc_msg_vlan_exact_filter),
    1018                 :            :                         ENETC_VSI_PSI_MSG_SIZE);
    1019                 :          0 :         msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
    1020         [ #  # ]:          0 :         if (!msg->vaddr) {
    1021                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for msg");
    1022                 :          0 :                 rte_free(msg);
    1023                 :          0 :                 rte_free(reply_msg);
    1024                 :          0 :                 return -ENOMEM;
    1025                 :            :         }
    1026                 :          0 :         msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
    1027                 :          0 :         msg->size = msg_size;
    1028                 :          0 :         cmd = (struct enetc_msg_vlan_exact_filter *)msg->vaddr;
    1029                 :          0 :         cmd->vlan_count = 1;
    1030                 :          0 :         cmd->vlan_id = vlan_id;
    1031                 :            : 
    1032                 :            :         /* TPID 2-bit encoding value is taken from the H/W block guide:
    1033                 :            :          *      00b Standard C-VLAN 0x8100
    1034                 :            :          *      01b Standard S-VLAN 0x88A8
    1035                 :            :          *      10b Custom VLAN as defined by CVLANR1[ETYPE]
    1036                 :            :          *      11b Custom VLAN as defined by CVLANR2[ETYPE]
    1037                 :            :          * Currently Standard C-VLAN is supported. To support others in future.
    1038                 :            :          */
    1039                 :          0 :         cmd->tpid = 0;
    1040                 :            : 
    1041         [ #  # ]:          0 :         if (on) {
    1042                 :            :                 enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_VLAN_FILTER,
    1043                 :            :                                 ENETC_MSG_ADD_EXACT_VLAN_ENTRIES, 0, 0, 0);
    1044                 :            :         } else {
    1045                 :            :                 enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_VLAN_FILTER,
    1046                 :            :                                 ENETC_MSG_REMOVE_EXACT_VLAN_ENTRIES, 0, 0, 0);
    1047                 :            :         }
    1048                 :            : 
    1049                 :            :         /* send the command and wait */
    1050                 :          0 :         err = enetc4_msg_vsi_send(hw, msg);
    1051         [ #  # ]:          0 :         if (err) {
    1052                 :          0 :                 ENETC_PMD_ERR("VSI message send error");
    1053                 :          0 :                 goto end;
    1054                 :            :         }
    1055                 :            : 
    1056                 :            :         enetc4_msg_vsi_reply_msg(enetc_hw, reply_msg);
    1057                 :            : 
    1058         [ #  # ]:          0 :         if (reply_msg->class_id == ENETC_CLASS_ID_VLAN_FILTER) {
    1059   [ #  #  #  #  :          0 :                 switch (reply_msg->status) {
                      # ]
    1060                 :          0 :                 case ENETC_INVALID_VLAN_ENTRY:
    1061                 :          0 :                         ENETC_PMD_ERR("VLAN entry not valid");
    1062                 :            :                         err = -EINVAL;
    1063                 :            :                         break;
    1064                 :          0 :                 case ENETC_DUPLICATE_VLAN_ENTRY:
    1065                 :          0 :                         ENETC_PMD_ERR("Duplicated VLAN entry");
    1066                 :            :                         err = -EINVAL;
    1067                 :            :                         break;
    1068                 :          0 :                 case ENETC_VLAN_ENTRY_NOT_FOUND:
    1069                 :          0 :                         ENETC_PMD_ERR("VLAN entry not found");
    1070                 :            :                         err = -EINVAL;
    1071                 :            :                         break;
    1072                 :          0 :                 case ENETC_VLAN_NO_RESOURCE:
    1073                 :          0 :                         ENETC_PMD_ERR("Not enough exact-match entries available");
    1074                 :            :                         err = -EINVAL;
    1075                 :            :                         break;
    1076                 :            :                 default:
    1077                 :            :                         err = -EINVAL;
    1078                 :            :                         break;
    1079                 :            :                 }
    1080                 :            :         }
    1081                 :            : 
    1082                 :            :         if (err) {
    1083                 :          0 :                 ENETC_PMD_ERR("VSI command execute error!");
    1084                 :          0 :                 goto end;
    1085                 :            :         }
    1086                 :            : 
    1087                 :          0 : end:
    1088                 :            :         /* free memory no longer required */
    1089                 :          0 :         rte_free(msg->vaddr);
    1090                 :          0 :         rte_free(reply_msg);
    1091                 :          0 :         rte_free(msg);
    1092                 :          0 :         return err;
    1093                 :            : }
    1094                 :            : 
    1095                 :          0 : static int enetc4_vf_vlan_offload_set(struct rte_eth_dev *dev, int mask __rte_unused)
    1096                 :            : {
    1097                 :            :         int err = 0;
    1098                 :            : 
    1099                 :          0 :         PMD_INIT_FUNC_TRACE();
    1100                 :            : 
    1101         [ #  # ]:          0 :         if (dev->data->dev_conf.rxmode.offloads) {
    1102                 :          0 :                 ENETC_PMD_DEBUG("VLAN filter table entry inserted:"
    1103                 :            :                                         "Disabling VLAN promisc mode");
    1104                 :          0 :                 err = enetc4_vf_vlan_promisc(dev, false);
    1105         [ #  # ]:          0 :                 if (err) {
    1106                 :          0 :                         ENETC_PMD_ERR("Added VLAN filter table entry:"
    1107                 :            :                                         "Failed to disable promiscuous mode");
    1108                 :          0 :                         return err;
    1109                 :            :                 }
    1110                 :            :         } else {
    1111                 :          0 :                 ENETC_PMD_DEBUG("Enabling VLAN promisc mode");
    1112                 :          0 :                 err = enetc4_vf_vlan_promisc(dev, true);
    1113         [ #  # ]:          0 :                 if (err) {
    1114                 :          0 :                         ENETC_PMD_ERR("Vlan filter table empty:"
    1115                 :            :                                         "Failed to enable promiscuous mode");
    1116                 :          0 :                         return err;
    1117                 :            :                 }
    1118                 :            :         }
    1119                 :            : 
    1120                 :            :         return 0;
    1121                 :            : }
    1122                 :            : 
    1123                 :            : static int
    1124                 :          0 : enetc4_vf_mtu_set(struct rte_eth_dev *dev __rte_unused, uint16_t mtu __rte_unused)
    1125                 :            : {
    1126                 :          0 :         return 0;
    1127                 :            : }
    1128                 :            : 
    1129                 :            : static int
    1130                 :          0 : enetc4_vf_link_register_notif(struct rte_eth_dev *dev, bool enable)
    1131                 :            : {
    1132                 :          0 :         struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    1133                 :            :         struct enetc_msg_swbd *msg;
    1134                 :            :         struct rte_eth_link link;
    1135                 :            :         uint32_t msg_size;
    1136                 :            :         int err = 0;
    1137                 :            :         uint8_t cmd;
    1138                 :            : 
    1139                 :          0 :         PMD_INIT_FUNC_TRACE();
    1140                 :            :         memset(&link, 0, sizeof(struct rte_eth_link));
    1141                 :          0 :         msg = rte_zmalloc(NULL, sizeof(*msg), RTE_CACHE_LINE_SIZE);
    1142         [ #  # ]:          0 :         if (!msg) {
    1143                 :          0 :                 ENETC_PMD_ERR("Failed to alloc msg");
    1144                 :            :                 err = -ENOMEM;
    1145                 :          0 :                 return err;
    1146                 :            :         }
    1147                 :            : 
    1148                 :            :         msg_size = RTE_ALIGN(sizeof(struct enetc_msg_cmd_get_link_status), ENETC_VSI_PSI_MSG_SIZE);
    1149                 :          0 :         msg->vaddr = rte_zmalloc(NULL, msg_size, 0);
    1150         [ #  # ]:          0 :         if (!msg->vaddr) {
    1151                 :          0 :                 ENETC_PMD_ERR("Failed to alloc memory for msg");
    1152                 :          0 :                 rte_free(msg);
    1153                 :          0 :                 return -ENOMEM;
    1154                 :            :         }
    1155                 :            : 
    1156                 :          0 :         msg->dma = rte_mem_virt2iova((const void *)msg->vaddr);
    1157                 :          0 :         msg->size = msg_size;
    1158         [ #  # ]:          0 :         if (enable)
    1159                 :            :                 cmd = ENETC_CMD_ID_REGISTER_LINK_NOTIF;
    1160                 :            :         else
    1161                 :            :                 cmd = ENETC_CMD_ID_UNREGISTER_LINK_NOTIF;
    1162                 :            :         enetc_msg_vf_fill_common_hdr(msg, ENETC_CLASS_ID_LINK_STATUS,
    1163                 :            :                         cmd, 0, 0, 0);
    1164                 :            : 
    1165                 :            :         /* send the command and wait */
    1166                 :          0 :         err = enetc4_msg_vsi_send(hw, msg);
    1167         [ #  # ]:          0 :         if (err)
    1168                 :          0 :                 ENETC_PMD_ERR("VSI msg error for link status notification");
    1169                 :            : 
    1170                 :            :         /* free memory no longer required */
    1171                 :          0 :         rte_free(msg->vaddr);
    1172                 :          0 :         rte_free(msg);
    1173                 :            : 
    1174                 :          0 :         return err;
    1175                 :            : }
    1176                 :            : 
    1177                 :            : /*
    1178                 :            :  * The set of PCI devices this driver supports
    1179                 :            :  */
    1180                 :            : static const struct rte_pci_id pci_vf_id_enetc4_map[] = {
    1181                 :            :         { RTE_PCI_DEVICE(PCI_VENDOR_ID_NXP, ENETC4_DEV_ID_VF) },
    1182                 :            :         { .vendor_id = 0, /* sentinel */ },
    1183                 :            : };
    1184                 :            : 
    1185                 :            : /* Features supported by this driver */
    1186                 :            : /* ops table used when VSI messaging is disabled */
    1187                 :            : static const struct eth_dev_ops enetc4_vf_ops_no_vsi_m = {
    1188                 :            :         .dev_configure        = enetc4_dev_configure,
    1189                 :            :         .dev_start            = enetc4_vf_dev_start,
    1190                 :            :         .dev_stop             = enetc4_vf_dev_stop,
    1191                 :            :         .dev_close            = enetc4_dev_close,
    1192                 :            :         .stats_get            = enetc4_vf_stats_get,
    1193                 :            :         .dev_infos_get        = enetc4_vf_dev_infos_get,
    1194                 :            :         .mtu_set              = enetc4_vf_mtu_set,
    1195                 :            :         .link_update          = enetc4_vf_link_update_dummy,
    1196                 :            :         .rx_queue_setup       = enetc4_rx_queue_setup,
    1197                 :            :         .rx_queue_start       = enetc4_rx_queue_start,
    1198                 :            :         .rx_queue_stop        = enetc4_rx_queue_stop,
    1199                 :            :         .rx_queue_release     = enetc4_rx_queue_release,
    1200                 :            :         .tx_queue_setup       = enetc4_tx_queue_setup,
    1201                 :            :         .tx_queue_start       = enetc4_tx_queue_start,
    1202                 :            :         .tx_queue_stop        = enetc4_tx_queue_stop,
    1203                 :            :         .tx_queue_release     = enetc4_tx_queue_release,
    1204                 :            :         .dev_supported_ptypes_get = enetc4_supported_ptypes_get,
    1205                 :            : };
    1206                 :            : 
    1207                 :            : static const struct eth_dev_ops enetc4_vf_ops = {
    1208                 :            :         .dev_configure        = enetc4_dev_configure,
    1209                 :            :         .dev_start            = enetc4_vf_dev_start,
    1210                 :            :         .dev_stop             = enetc4_vf_dev_stop,
    1211                 :            :         .dev_close            = enetc4_dev_close,
    1212                 :            :         .stats_get            = enetc4_vf_stats_get,
    1213                 :            :         .dev_infos_get        = enetc4_vf_dev_infos_get,
    1214                 :            :         .mtu_set              = enetc4_vf_mtu_set,
    1215                 :            :         .mac_addr_set         = enetc4_vf_set_mac_addr,
    1216                 :            :         .mac_addr_add         = enetc4_vf_mac_addr_add,
    1217                 :            :         .promiscuous_enable   = enetc4_vf_promisc_enable,
    1218                 :            :         .promiscuous_disable  = enetc4_vf_promisc_disable,
    1219                 :            :         .allmulticast_enable  = enetc4_vf_multicast_enable,
    1220                 :            :         .allmulticast_disable = enetc4_vf_multicast_disable,
    1221                 :            :         .link_update          = enetc4_vf_link_update,
    1222                 :            :         .vlan_filter_set      = enetc4_vf_vlan_filter_set,
    1223                 :            :         .vlan_offload_set     = enetc4_vf_vlan_offload_set,
    1224                 :            :         .rx_queue_setup       = enetc4_rx_queue_setup,
    1225                 :            :         .rx_queue_start       = enetc4_rx_queue_start,
    1226                 :            :         .rx_queue_stop        = enetc4_rx_queue_stop,
    1227                 :            :         .rx_queue_release     = enetc4_rx_queue_release,
    1228                 :            :         .tx_queue_setup       = enetc4_tx_queue_setup,
    1229                 :            :         .tx_queue_start       = enetc4_tx_queue_start,
    1230                 :            :         .tx_queue_stop        = enetc4_tx_queue_stop,
    1231                 :            :         .tx_queue_release     = enetc4_tx_queue_release,
    1232                 :            :         .dev_supported_ptypes_get = enetc4_supported_ptypes_get,
    1233                 :            : };
    1234                 :            : 
    1235                 :            : static int
    1236                 :          0 : enetc4_vf_mac_init(struct enetc_eth_hw *hw, struct rte_eth_dev *eth_dev)
    1237                 :            : {
    1238                 :          0 :         uint32_t *mac = (uint32_t *)hw->mac.addr;
    1239                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
    1240                 :            :         uint32_t high_mac = 0;
    1241                 :            :         uint16_t low_mac = 0;
    1242                 :            :         char vf_eth_name[ENETC_ETH_NAMESIZE];
    1243                 :            : 
    1244                 :          0 :         PMD_INIT_FUNC_TRACE();
    1245                 :            : 
    1246                 :            :         /* Enabling Station Interface */
    1247                 :          0 :         enetc4_wr(enetc_hw, ENETC_SIMR, ENETC_SIMR_EN);
    1248                 :          0 :         *mac = (uint32_t)enetc_rd(enetc_hw, ENETC_SIPMAR0);
    1249                 :            :         high_mac = (uint32_t)*mac;
    1250                 :            :         mac++;
    1251                 :          0 :         *mac = (uint16_t)enetc_rd(enetc_hw, ENETC_SIPMAR1);
    1252                 :            :         low_mac = (uint16_t)*mac;
    1253                 :            : 
    1254         [ #  # ]:          0 :         if ((high_mac | low_mac) == 0) {
    1255                 :            :                 char *first_byte;
    1256                 :          0 :                 ENETC_PMD_NOTICE("MAC is not available for this SI, "
    1257                 :            :                                  "set random MAC");
    1258                 :            :                 mac = (uint32_t *)hw->mac.addr;
    1259                 :          0 :                 *mac = (uint32_t)rte_rand();
    1260                 :            :                 first_byte = (char *)mac;
    1261                 :          0 :                 *first_byte &= 0xfe;    /* clear multicast bit */
    1262                 :          0 :                 *first_byte |= 0x02;    /* set local assignment bit (IEEE802) */
    1263                 :          0 :                 enetc4_port_wr(enetc_hw, ENETC4_PMAR0, *mac);
    1264                 :            :                 mac++;
    1265                 :          0 :                 *mac = (uint16_t)rte_rand();
    1266                 :          0 :                 enetc4_port_wr(enetc_hw, ENETC4_PMAR1, *mac);
    1267                 :          0 :                 enetc_print_ethaddr("New address: ",
    1268                 :            :                         (const struct rte_ether_addr *)hw->mac.addr);
    1269                 :            :         }
    1270                 :            : 
    1271                 :            :         /* Allocate memory for storing MAC addresses */
    1272                 :          0 :         snprintf(vf_eth_name, sizeof(vf_eth_name), "enetc4_vf_eth_%d", eth_dev->data->port_id);
    1273                 :          0 :         eth_dev->data->mac_addrs = rte_zmalloc(vf_eth_name,
    1274                 :            :                                         RTE_ETHER_ADDR_LEN, 0);
    1275         [ #  # ]:          0 :         if (!eth_dev->data->mac_addrs) {
    1276                 :          0 :                 ENETC_PMD_ERR("Failed to allocate %d bytes needed to "
    1277                 :            :                               "store MAC addresses",
    1278                 :            :                               RTE_ETHER_ADDR_LEN * 1);
    1279                 :          0 :                 return -ENOMEM;
    1280                 :            :         }
    1281                 :            : 
    1282         [ #  # ]:          0 :         if (!enetc_crc_gen)
    1283                 :          0 :                 enetc_gen_crc_table();
    1284                 :            : 
    1285                 :            :         /* Copy the permanent MAC address */
    1286                 :            :         rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.addr,
    1287                 :            :                              &eth_dev->data->mac_addrs[0]);
    1288                 :            : 
    1289                 :          0 :         return 0;
    1290                 :            : }
    1291                 :            : 
    1292                 :            : static void
    1293                 :          0 : enetc_vf_enable_mr_int(struct enetc_hw *hw, bool en)
    1294                 :            : {
    1295                 :            :         uint32_t val;
    1296                 :            : 
    1297                 :          0 :         val = enetc_rd(hw, ENETC4_VSIIER);
    1298                 :          0 :         val &= ~ENETC4_VSIIER_MRIE;
    1299         [ #  # ]:          0 :         val |= (en) ? ENETC4_VSIIER_MRIE : 0;
    1300                 :          0 :         enetc_wr(hw, ENETC4_VSIIER, val);
    1301                 :          0 :         ENETC_PMD_DEBUG("Interrupt enable status (VSIIER) = 0x%x", val);
    1302                 :          0 : }
    1303                 :            : 
    1304                 :            : static void
    1305                 :          0 : enetc4_dev_interrupt_handler(void *param)
    1306                 :            : {
    1307                 :            :         struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
    1308                 :            :         struct enetc_eth_hw *hw =
    1309                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
    1310                 :          0 :         struct enetc_hw *enetc_hw = &hw->hw;
    1311                 :            :         uint32_t status;
    1312                 :            : 
    1313                 :            :         /* Disable interrupts before process */
    1314                 :          0 :         enetc_vf_enable_mr_int(enetc_hw, false);
    1315                 :            : 
    1316                 :          0 :         status = enetc_rd(enetc_hw, ENETC4_VSIIDR);
    1317                 :          0 :         ENETC_PMD_DEBUG("Got INTR VSIIDR status = 0x%0x", status);
    1318                 :            :         /* Check for PSI to VSI message interrupt */
    1319         [ #  # ]:          0 :         if (!(status & ENETC4_VSIIER_MRIE)) {
    1320                 :          0 :                 ENETC_PMD_ERR("Interrupt is not PSI to VSI");
    1321                 :          0 :                 goto intr_clear;
    1322                 :            :         }
    1323                 :            : 
    1324                 :          0 :         enetc4_process_psi_msg(eth_dev, enetc_hw);
    1325                 :          0 : intr_clear:
    1326                 :            :         /* Clear Interrupts */
    1327                 :          0 :         enetc_wr(enetc_hw, ENETC4_VSIIDR, 0xffffffff);
    1328                 :          0 :         enetc_vf_enable_mr_int(enetc_hw, true);
    1329                 :          0 : }
    1330                 :            : 
    1331                 :            : static int
    1332                 :          0 : enetc4_vf_dev_init(struct rte_eth_dev *eth_dev)
    1333                 :            : {
    1334                 :          0 :         struct enetc_eth_hw *hw =
    1335                 :          0 :                             ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
    1336                 :          0 :         struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(eth_dev, *pci_dev);
    1337                 :            :         int error = 0;
    1338                 :            :         uint32_t si_cap;
    1339                 :            :         struct enetc_hw *enetc_hw = &hw->hw;
    1340                 :            : 
    1341                 :          0 :         PMD_INIT_FUNC_TRACE();
    1342                 :            : 
    1343                 :            :         /* check if VSI messaging should be disabled via devarg */
    1344         [ #  # ]:          0 :         if (eth_dev->device->devargs) {
    1345                 :            :                 struct rte_kvargs *kvlist;
    1346                 :            : 
    1347                 :          0 :                 kvlist = rte_kvargs_parse(eth_dev->device->devargs->args,
    1348                 :            :                                           NULL);
    1349         [ #  # ]:          0 :                 if (kvlist) {
    1350                 :            :                         const char *val;
    1351                 :            : 
    1352         [ #  # ]:          0 :                         if (rte_kvargs_count(kvlist, ENETC4_VSI_DISABLE) != 0) {
    1353                 :          0 :                                 ENETC_PMD_NOTICE("VSI messaging disabled by devarg");
    1354                 :          0 :                                 eth_dev->dev_ops = &enetc4_vf_ops_no_vsi_m;
    1355                 :            :                         } else {
    1356                 :          0 :                                 eth_dev->dev_ops = &enetc4_vf_ops;
    1357                 :            :                         }
    1358                 :            : 
    1359                 :            :                         /* parse optional VSI-PSI timeout devarg */
    1360                 :          0 :                         val = rte_kvargs_get(kvlist, ENETC4_VSI_TIMEOUT);
    1361         [ #  # ]:          0 :                         if (val) {
    1362                 :          0 :                                 errno = 0;
    1363                 :          0 :                                 hw->vsi_timeout = (uint32_t)strtoul(val, NULL, 0);
    1364   [ #  #  #  # ]:          0 :                                 if (errno != 0 || hw->vsi_timeout == 0) {
    1365                 :          0 :                                         ENETC_PMD_ERR("Invalid VSI Timeout value = %u",
    1366                 :            :                                                         hw->vsi_timeout);
    1367                 :          0 :                                         rte_kvargs_free(kvlist);
    1368                 :          0 :                                         return -1;
    1369                 :            :                                 }
    1370                 :          0 :                                 ENETC_PMD_NOTICE("VSI timeout set to %u", hw->vsi_timeout);
    1371                 :            :                         }
    1372                 :            : 
    1373                 :            :                         /* parse optional VSI-PSI delay devarg */
    1374                 :          0 :                         val = rte_kvargs_get(kvlist, ENETC4_VSI_DELAY);
    1375         [ #  # ]:          0 :                         if (val) {
    1376                 :          0 :                                 errno = 0;
    1377                 :          0 :                                 hw->vsi_delay = (uint32_t)strtoul(val, NULL, 0);
    1378   [ #  #  #  # ]:          0 :                                 if (errno != 0 || hw->vsi_delay == 0) {
    1379                 :          0 :                                         ENETC_PMD_ERR("Invalid VSI Delay value = %u",
    1380                 :            :                                                         hw->vsi_delay);
    1381                 :          0 :                                         rte_kvargs_free(kvlist);
    1382                 :          0 :                                         return -1;
    1383                 :            :                                 }
    1384                 :          0 :                                 ENETC_PMD_NOTICE("VSI delay set to %u us", hw->vsi_delay);
    1385                 :            :                         }
    1386                 :            : 
    1387                 :          0 :                         rte_kvargs_free(kvlist);
    1388                 :            :                 } else {
    1389                 :          0 :                         eth_dev->dev_ops = &enetc4_vf_ops;
    1390                 :            :                 }
    1391                 :            :         } else {
    1392                 :          0 :                 eth_dev->dev_ops = &enetc4_vf_ops;
    1393                 :            :         }
    1394                 :            : 
    1395                 :          0 :         enetc4_dev_hw_init(eth_dev);
    1396                 :            : 
    1397                 :          0 :         hw->nc_mode = 0;
    1398                 :          0 :         enetc4_vf_get_devarg_nc(eth_dev);
    1399         [ #  # ]:          0 :         if (hw->nc_mode) {
    1400                 :          0 :                 eth_dev->rx_pkt_burst = &enetc_recv_pkts_nc;
    1401                 :          0 :                 eth_dev->tx_pkt_burst = &enetc_xmit_pkts_nc;
    1402                 :          0 :                 ENETC_PMD_LOG(INFO, "nc=1: using non-cacheable BD ops (_nc)");
    1403                 :            :         }
    1404                 :            : 
    1405                 :          0 :         si_cap = enetc_rd(enetc_hw, ENETC_SICAPR0);
    1406                 :          0 :         hw->max_tx_queues = si_cap & ENETC_SICAPR0_BDR_MASK;
    1407                 :          0 :         hw->max_rx_queues = (si_cap >> 16) & ENETC_SICAPR0_BDR_MASK;
    1408                 :            : 
    1409                 :          0 :         ENETC_PMD_DEBUG("Max RX queues = %d Max TX queues = %d",
    1410                 :            :                         hw->max_rx_queues, hw->max_tx_queues);
    1411                 :          0 :         error = enetc4_vf_mac_init(hw, eth_dev);
    1412         [ #  # ]:          0 :         if (error != 0) {
    1413                 :          0 :                 ENETC_PMD_ERR("MAC initialization failed!!");
    1414                 :          0 :                 return -1;
    1415                 :            :         }
    1416                 :            : 
    1417         [ #  # ]:          0 :         if (rte_eal_iova_mode() == RTE_IOVA_PA)
    1418                 :          0 :                 dpaax_iova_table_populate();
    1419                 :            : 
    1420                 :          0 :         ENETC_PMD_DEBUG("port_id %d vendorID=0x%x deviceID=0x%x",
    1421                 :            :                         eth_dev->data->port_id, pci_dev->id.vendor_id,
    1422                 :            :                         pci_dev->id.device_id);
    1423                 :            :         /* update link if VSI messaging is enabled */
    1424         [ #  # ]:          0 :         if (eth_dev->dev_ops == &enetc4_vf_ops)
    1425                 :          0 :                 enetc4_vf_link_update(eth_dev, 0);
    1426                 :            : 
    1427                 :            :         return 0;
    1428                 :            : }
    1429                 :            : 
    1430                 :            : static int
    1431                 :          0 : enetc4_vf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
    1432                 :            :                     struct rte_pci_device *pci_dev)
    1433                 :            : {
    1434                 :          0 :         return rte_eth_dev_pci_generic_probe(pci_dev,
    1435                 :            :                                              sizeof(struct enetc_eth_adapter),
    1436                 :            :                                              enetc4_vf_dev_init);
    1437                 :            : }
    1438                 :            : 
    1439                 :            : int
    1440                 :          0 : enetc4_vf_dev_intr(struct rte_eth_dev *eth_dev, bool enable)
    1441                 :            : {
    1442                 :            :         struct enetc_eth_hw *hw =
    1443                 :          0 :                 ENETC_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
    1444                 :          0 :         struct enetc_hw *enetc_hw = &hw->hw;
    1445                 :          0 :         struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(eth_dev, *pci_dev);
    1446                 :          0 :         struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
    1447                 :            :         int ret = 0;
    1448                 :            : 
    1449                 :          0 :         PMD_INIT_FUNC_TRACE();
    1450   [ #  #  #  # ]:          0 :         if (!(intr_handle && rte_intr_fd_get(intr_handle))) {
    1451                 :          0 :                 ENETC_PMD_ERR("No INTR handle");
    1452                 :          0 :                 return -1;
    1453                 :            :         }
    1454         [ #  # ]:          0 :         if (enable) {
    1455                 :            :                 /* if the interrupts were configured on this devices*/
    1456                 :          0 :                 ret = rte_intr_callback_register(intr_handle,
    1457                 :            :                                 enetc4_dev_interrupt_handler, eth_dev);
    1458         [ #  # ]:          0 :                 if (ret) {
    1459                 :          0 :                         ENETC_PMD_ERR("Failed to register INTR callback %d", ret);
    1460                 :          0 :                         return ret;
    1461                 :            :                 }
    1462                 :            :                 /* set one IRQ entry for PSI-to-VSI messaging */
    1463                 :            :                 /* Vector index 0 */
    1464                 :          0 :                 enetc_wr(enetc_hw, ENETC4_SIMSIVR, ENETC4_SI_INT_IDX);
    1465                 :            : 
    1466                 :            :                 /* enable uio/vfio intr/eventfd mapping */
    1467                 :          0 :                 ret = rte_intr_enable(intr_handle);
    1468         [ #  # ]:          0 :                 if (ret) {
    1469                 :          0 :                         ENETC_PMD_ERR("Failed to enable INTR %d", ret);
    1470                 :          0 :                         goto intr_enable_fail;
    1471                 :            :                 }
    1472                 :            : 
    1473                 :            :                 /* Enable message received interrupt */
    1474                 :          0 :                 enetc_vf_enable_mr_int(enetc_hw, true);
    1475                 :          0 :                 ret = enetc4_vf_link_register_notif(eth_dev, true);
    1476         [ #  # ]:          0 :                 if (ret) {
    1477                 :          0 :                         ENETC_PMD_ERR("Failed to register link notifications %d", ret);
    1478                 :          0 :                         goto disable;
    1479                 :            :                 }
    1480                 :            : 
    1481                 :            :                 return ret;
    1482                 :            :         }
    1483                 :            : 
    1484                 :          0 :         ret = enetc4_vf_link_register_notif(eth_dev, false);
    1485         [ #  # ]:          0 :         if (ret)
    1486                 :          0 :                 ENETC_PMD_WARN("Failed to un-register link notification %d", ret);
    1487                 :          0 : disable:
    1488                 :          0 :         enetc_vf_enable_mr_int(enetc_hw, false);
    1489                 :          0 :         ret = rte_intr_disable(intr_handle);
    1490         [ #  # ]:          0 :         if (ret)
    1491                 :          0 :                 ENETC_PMD_WARN("Failed to disable INTR %d", ret);
    1492                 :          0 : intr_enable_fail:
    1493                 :          0 :         rte_intr_callback_unregister(intr_handle,
    1494                 :            :                         enetc4_dev_interrupt_handler, eth_dev);
    1495                 :            : 
    1496                 :          0 :         return ret;
    1497                 :            : }
    1498                 :            : 
    1499                 :            : static struct rte_pci_driver rte_enetc4_vf_pmd = {
    1500                 :            :         .id_table = pci_vf_id_enetc4_map,
    1501                 :            :         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
    1502                 :            :         .probe = enetc4_vf_pci_probe,
    1503                 :            :         .remove = enetc4_pci_remove,
    1504                 :            : };
    1505                 :            : 
    1506                 :        303 : RTE_PMD_REGISTER_PCI(net_enetc4_vf, rte_enetc4_vf_pmd);
    1507                 :            : RTE_PMD_REGISTER_PCI_TABLE(net_enetc4_vf, pci_vf_id_enetc4_map);
    1508                 :            : RTE_PMD_REGISTER_KMOD_DEP(net_enetc4_vf, "* igb_uio | uio_pci_generic");
    1509                 :            : RTE_PMD_REGISTER_PARAM_STRING(net_enetc4_vf,
    1510                 :            :                               ENETC4_VSI_DISABLE "=<any> "
    1511                 :            :                               ENETC4_VSI_TIMEOUT "=<uint> "
    1512                 :            :                               ENETC4_VSI_DELAY "=<uint> "
    1513                 :            :                               ENETC4_NC_MEMORY "=<int>");
    1514         [ -  + ]:        303 : RTE_LOG_REGISTER_DEFAULT(enetc4_vf_logtype_pmd, NOTICE);

Generated by: LCOV version 1.14