LCOV - code coverage report
Current view: top level - drivers/net/thunderx/base - nicvf_hw.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 309 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 38 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 208 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2016 Cavium, Inc
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <unistd.h>
       6                 :            : #include <math.h>
       7                 :            : #include <errno.h>
       8                 :            : #include <stdarg.h>
       9                 :            : #include <stdint.h>
      10                 :            : #include <stdio.h>
      11                 :            : #include <stdlib.h>
      12                 :            : #include <string.h>
      13                 :            : #include <assert.h>
      14                 :            : 
      15                 :            : #include "nicvf_plat.h"
      16                 :            : 
      17                 :            : struct nicvf_reg_info {
      18                 :            :         uint32_t offset;
      19                 :            :         const char *name;
      20                 :            : };
      21                 :            : 
      22                 :            : #define NICVF_REG_POLL_ITER_NR   (10)
      23                 :            : #define NICVF_REG_POLL_DELAY_US  (2000)
      24                 :            : #define NICVF_REG_INFO(reg) {reg, #reg}
      25                 :            : 
      26                 :            : static const struct nicvf_reg_info nicvf_reg_tbl[] = {
      27                 :            :         NICVF_REG_INFO(NIC_VF_CFG),
      28                 :            :         NICVF_REG_INFO(NIC_VF_PF_MAILBOX_0_1),
      29                 :            :         NICVF_REG_INFO(NIC_VF_INT),
      30                 :            :         NICVF_REG_INFO(NIC_VF_INT_W1S),
      31                 :            :         NICVF_REG_INFO(NIC_VF_ENA_W1C),
      32                 :            :         NICVF_REG_INFO(NIC_VF_ENA_W1S),
      33                 :            :         NICVF_REG_INFO(NIC_VNIC_RSS_CFG),
      34                 :            :         NICVF_REG_INFO(NIC_VNIC_RQ_GEN_CFG),
      35                 :            : };
      36                 :            : 
      37                 :            : static const struct nicvf_reg_info nicvf_multi_reg_tbl[] = {
      38                 :            :         {NIC_VNIC_RSS_KEY_0_4 + 0,  "NIC_VNIC_RSS_KEY_0"},
      39                 :            :         {NIC_VNIC_RSS_KEY_0_4 + 8,  "NIC_VNIC_RSS_KEY_1"},
      40                 :            :         {NIC_VNIC_RSS_KEY_0_4 + 16, "NIC_VNIC_RSS_KEY_2"},
      41                 :            :         {NIC_VNIC_RSS_KEY_0_4 + 24, "NIC_VNIC_RSS_KEY_3"},
      42                 :            :         {NIC_VNIC_RSS_KEY_0_4 + 32, "NIC_VNIC_RSS_KEY_4"},
      43                 :            :         {NIC_VNIC_TX_STAT_0_4 + 0,  "NIC_VNIC_STAT_TX_OCTS"},
      44                 :            :         {NIC_VNIC_TX_STAT_0_4 + 8,  "NIC_VNIC_STAT_TX_UCAST"},
      45                 :            :         {NIC_VNIC_TX_STAT_0_4 + 16,  "NIC_VNIC_STAT_TX_BCAST"},
      46                 :            :         {NIC_VNIC_TX_STAT_0_4 + 24,  "NIC_VNIC_STAT_TX_MCAST"},
      47                 :            :         {NIC_VNIC_TX_STAT_0_4 + 32,  "NIC_VNIC_STAT_TX_DROP"},
      48                 :            :         {NIC_VNIC_RX_STAT_0_13 + 0,  "NIC_VNIC_STAT_RX_OCTS"},
      49                 :            :         {NIC_VNIC_RX_STAT_0_13 + 8,  "NIC_VNIC_STAT_RX_UCAST"},
      50                 :            :         {NIC_VNIC_RX_STAT_0_13 + 16, "NIC_VNIC_STAT_RX_BCAST"},
      51                 :            :         {NIC_VNIC_RX_STAT_0_13 + 24, "NIC_VNIC_STAT_RX_MCAST"},
      52                 :            :         {NIC_VNIC_RX_STAT_0_13 + 32, "NIC_VNIC_STAT_RX_RED"},
      53                 :            :         {NIC_VNIC_RX_STAT_0_13 + 40, "NIC_VNIC_STAT_RX_RED_OCTS"},
      54                 :            :         {NIC_VNIC_RX_STAT_0_13 + 48, "NIC_VNIC_STAT_RX_ORUN"},
      55                 :            :         {NIC_VNIC_RX_STAT_0_13 + 56, "NIC_VNIC_STAT_RX_ORUN_OCTS"},
      56                 :            :         {NIC_VNIC_RX_STAT_0_13 + 64, "NIC_VNIC_STAT_RX_FCS"},
      57                 :            :         {NIC_VNIC_RX_STAT_0_13 + 72, "NIC_VNIC_STAT_RX_L2ERR"},
      58                 :            :         {NIC_VNIC_RX_STAT_0_13 + 80, "NIC_VNIC_STAT_RX_DRP_BCAST"},
      59                 :            :         {NIC_VNIC_RX_STAT_0_13 + 88, "NIC_VNIC_STAT_RX_DRP_MCAST"},
      60                 :            :         {NIC_VNIC_RX_STAT_0_13 + 96, "NIC_VNIC_STAT_RX_DRP_L3BCAST"},
      61                 :            :         {NIC_VNIC_RX_STAT_0_13 + 104, "NIC_VNIC_STAT_RX_DRP_L3MCAST"},
      62                 :            : };
      63                 :            : 
      64                 :            : static const struct nicvf_reg_info nicvf_qset_cq_reg_tbl[] = {
      65                 :            :         NICVF_REG_INFO(NIC_QSET_CQ_0_7_CFG),
      66                 :            :         NICVF_REG_INFO(NIC_QSET_CQ_0_7_CFG2),
      67                 :            :         NICVF_REG_INFO(NIC_QSET_CQ_0_7_THRESH),
      68                 :            :         NICVF_REG_INFO(NIC_QSET_CQ_0_7_BASE),
      69                 :            :         NICVF_REG_INFO(NIC_QSET_CQ_0_7_HEAD),
      70                 :            :         NICVF_REG_INFO(NIC_QSET_CQ_0_7_TAIL),
      71                 :            :         NICVF_REG_INFO(NIC_QSET_CQ_0_7_DOOR),
      72                 :            :         NICVF_REG_INFO(NIC_QSET_CQ_0_7_STATUS),
      73                 :            :         NICVF_REG_INFO(NIC_QSET_CQ_0_7_STATUS2),
      74                 :            :         NICVF_REG_INFO(NIC_QSET_CQ_0_7_DEBUG),
      75                 :            : };
      76                 :            : 
      77                 :            : static const struct nicvf_reg_info nicvf_qset_rq_reg_tbl[] = {
      78                 :            :         NICVF_REG_INFO(NIC_QSET_RQ_0_7_CFG),
      79                 :            :         NICVF_REG_INFO(NIC_QSET_RQ_0_7_STATUS0),
      80                 :            :         NICVF_REG_INFO(NIC_QSET_RQ_0_7_STATUS1),
      81                 :            : };
      82                 :            : 
      83                 :            : static const struct nicvf_reg_info nicvf_qset_sq_reg_tbl[] = {
      84                 :            :         NICVF_REG_INFO(NIC_QSET_SQ_0_7_CFG),
      85                 :            :         NICVF_REG_INFO(NIC_QSET_SQ_0_7_THRESH),
      86                 :            :         NICVF_REG_INFO(NIC_QSET_SQ_0_7_BASE),
      87                 :            :         NICVF_REG_INFO(NIC_QSET_SQ_0_7_HEAD),
      88                 :            :         NICVF_REG_INFO(NIC_QSET_SQ_0_7_TAIL),
      89                 :            :         NICVF_REG_INFO(NIC_QSET_SQ_0_7_DOOR),
      90                 :            :         NICVF_REG_INFO(NIC_QSET_SQ_0_7_STATUS),
      91                 :            :         NICVF_REG_INFO(NIC_QSET_SQ_0_7_DEBUG),
      92                 :            :         NICVF_REG_INFO(NIC_QSET_SQ_0_7_STATUS0),
      93                 :            :         NICVF_REG_INFO(NIC_QSET_SQ_0_7_STATUS1),
      94                 :            : };
      95                 :            : 
      96                 :            : static const struct nicvf_reg_info nicvf_qset_rbdr_reg_tbl[] = {
      97                 :            :         NICVF_REG_INFO(NIC_QSET_RBDR_0_1_CFG),
      98                 :            :         NICVF_REG_INFO(NIC_QSET_RBDR_0_1_THRESH),
      99                 :            :         NICVF_REG_INFO(NIC_QSET_RBDR_0_1_BASE),
     100                 :            :         NICVF_REG_INFO(NIC_QSET_RBDR_0_1_HEAD),
     101                 :            :         NICVF_REG_INFO(NIC_QSET_RBDR_0_1_TAIL),
     102                 :            :         NICVF_REG_INFO(NIC_QSET_RBDR_0_1_DOOR),
     103                 :            :         NICVF_REG_INFO(NIC_QSET_RBDR_0_1_STATUS0),
     104                 :            :         NICVF_REG_INFO(NIC_QSET_RBDR_0_1_STATUS1),
     105                 :            :         NICVF_REG_INFO(NIC_QSET_RBDR_0_1_PRFCH_STATUS),
     106                 :            : };
     107                 :            : 
     108                 :            : int
     109                 :          0 : nicvf_base_init(struct nicvf *nic)
     110                 :            : {
     111                 :          0 :         nic->hwcap = 0;
     112         [ #  # ]:          0 :         if (nic->subsystem_device_id == 0)
     113                 :            :                 return NICVF_ERR_BASE_INIT;
     114                 :            : 
     115         [ #  # ]:          0 :         if (nicvf_hw_version(nic) == PCI_SUB_DEVICE_ID_CN88XX_PASS2_NICVF)
     116                 :          0 :                 nic->hwcap |= NICVF_CAP_TUNNEL_PARSING | NICVF_CAP_CQE_RX2;
     117                 :            : 
     118         [ #  # ]:          0 :         if (nicvf_hw_version(nic) == PCI_SUB_DEVICE_ID_CN81XX_NICVF)
     119                 :          0 :                 nic->hwcap |= NICVF_CAP_TUNNEL_PARSING | NICVF_CAP_CQE_RX2;
     120                 :            : 
     121         [ #  # ]:          0 :         if (nicvf_hw_version(nic) == PCI_SUB_DEVICE_ID_CN83XX_NICVF)
     122                 :          0 :                 nic->hwcap |= NICVF_CAP_TUNNEL_PARSING | NICVF_CAP_CQE_RX2 |
     123                 :            :                                 NICVF_CAP_DISABLE_APAD;
     124                 :            : 
     125                 :            :         return NICVF_OK;
     126                 :            : }
     127                 :            : 
     128                 :            : /* dump on stdout if data is NULL */
     129                 :            : int
     130                 :          0 : nicvf_reg_dump(struct nicvf *nic,  uint64_t *data)
     131                 :            : {
     132                 :            :         uint32_t i, q;
     133                 :            :         bool dump_stdout;
     134                 :            : 
     135                 :            :         dump_stdout = data ? 0 : 1;
     136                 :            : 
     137         [ #  # ]:          0 :         for (i = 0; i < NICVF_ARRAY_SIZE(nicvf_reg_tbl); i++)
     138         [ #  # ]:          0 :                 if (dump_stdout)
     139                 :          0 :                         nicvf_log("%24s  = 0x%" PRIx64 "\n",
     140                 :            :                                 nicvf_reg_tbl[i].name,
     141                 :            :                                 nicvf_reg_read(nic, nicvf_reg_tbl[i].offset));
     142                 :            :                 else
     143                 :          0 :                         *data++ = nicvf_reg_read(nic, nicvf_reg_tbl[i].offset);
     144                 :            : 
     145         [ #  # ]:          0 :         for (i = 0; i < NICVF_ARRAY_SIZE(nicvf_multi_reg_tbl); i++)
     146         [ #  # ]:          0 :                 if (dump_stdout)
     147                 :          0 :                         nicvf_log("%24s  = 0x%" PRIx64 "\n",
     148                 :            :                                 nicvf_multi_reg_tbl[i].name,
     149                 :            :                                 nicvf_reg_read(nic,
     150                 :            :                                         nicvf_multi_reg_tbl[i].offset));
     151                 :            :                 else
     152                 :          0 :                         *data++ = nicvf_reg_read(nic,
     153                 :          0 :                                         nicvf_multi_reg_tbl[i].offset);
     154                 :            : 
     155         [ #  # ]:          0 :         for (q = 0; q < MAX_CMP_QUEUES_PER_QS; q++)
     156         [ #  # ]:          0 :                 for (i = 0; i < NICVF_ARRAY_SIZE(nicvf_qset_cq_reg_tbl); i++)
     157         [ #  # ]:          0 :                         if (dump_stdout)
     158                 :          0 :                                 nicvf_log("%30s(%d)  = 0x%" PRIx64 "\n",
     159                 :            :                                         nicvf_qset_cq_reg_tbl[i].name, q,
     160                 :            :                                         nicvf_queue_reg_read(nic,
     161                 :            :                                         nicvf_qset_cq_reg_tbl[i].offset, q));
     162                 :            :                         else
     163                 :          0 :                                 *data++ = nicvf_queue_reg_read(nic,
     164                 :          0 :                                         nicvf_qset_cq_reg_tbl[i].offset, q);
     165                 :            : 
     166         [ #  # ]:          0 :         for (q = 0; q < MAX_RCV_QUEUES_PER_QS; q++)
     167         [ #  # ]:          0 :                 for (i = 0; i < NICVF_ARRAY_SIZE(nicvf_qset_rq_reg_tbl); i++)
     168         [ #  # ]:          0 :                         if (dump_stdout)
     169                 :          0 :                                 nicvf_log("%30s(%d)  = 0x%" PRIx64 "\n",
     170                 :            :                                         nicvf_qset_rq_reg_tbl[i].name, q,
     171                 :            :                                         nicvf_queue_reg_read(nic,
     172                 :            :                                         nicvf_qset_rq_reg_tbl[i].offset, q));
     173                 :            :                         else
     174                 :          0 :                                 *data++ = nicvf_queue_reg_read(nic,
     175                 :          0 :                                         nicvf_qset_rq_reg_tbl[i].offset, q);
     176                 :            : 
     177         [ #  # ]:          0 :         for (q = 0; q < MAX_SND_QUEUES_PER_QS; q++)
     178         [ #  # ]:          0 :                 for (i = 0; i < NICVF_ARRAY_SIZE(nicvf_qset_sq_reg_tbl); i++)
     179         [ #  # ]:          0 :                         if (dump_stdout)
     180                 :          0 :                                 nicvf_log("%30s(%d)  = 0x%" PRIx64 "\n",
     181                 :            :                                         nicvf_qset_sq_reg_tbl[i].name, q,
     182                 :            :                                         nicvf_queue_reg_read(nic,
     183                 :            :                                         nicvf_qset_sq_reg_tbl[i].offset, q));
     184                 :            :                         else
     185                 :          0 :                                 *data++ = nicvf_queue_reg_read(nic,
     186                 :          0 :                                         nicvf_qset_sq_reg_tbl[i].offset, q);
     187                 :            : 
     188         [ #  # ]:          0 :         for (q = 0; q < MAX_RCV_BUF_DESC_RINGS_PER_QS; q++)
     189         [ #  # ]:          0 :                 for (i = 0; i < NICVF_ARRAY_SIZE(nicvf_qset_rbdr_reg_tbl); i++)
     190         [ #  # ]:          0 :                         if (dump_stdout)
     191                 :          0 :                                 nicvf_log("%30s(%d)  = 0x%" PRIx64 "\n",
     192                 :            :                                         nicvf_qset_rbdr_reg_tbl[i].name, q,
     193                 :            :                                         nicvf_queue_reg_read(nic,
     194                 :            :                                         nicvf_qset_rbdr_reg_tbl[i].offset, q));
     195                 :            :                         else
     196                 :          0 :                                 *data++ = nicvf_queue_reg_read(nic,
     197                 :          0 :                                         nicvf_qset_rbdr_reg_tbl[i].offset, q);
     198                 :          0 :         return 0;
     199                 :            : }
     200                 :            : 
     201                 :            : int
     202                 :          0 : nicvf_reg_get_count(void)
     203                 :            : {
     204                 :            :         int nr_regs;
     205                 :            : 
     206                 :            :         nr_regs = NICVF_ARRAY_SIZE(nicvf_reg_tbl);
     207                 :            :         nr_regs += NICVF_ARRAY_SIZE(nicvf_multi_reg_tbl);
     208                 :            :         nr_regs += NICVF_ARRAY_SIZE(nicvf_qset_cq_reg_tbl) *
     209                 :            :                         MAX_CMP_QUEUES_PER_QS;
     210                 :            :         nr_regs += NICVF_ARRAY_SIZE(nicvf_qset_rq_reg_tbl) *
     211                 :            :                         MAX_RCV_QUEUES_PER_QS;
     212                 :            :         nr_regs += NICVF_ARRAY_SIZE(nicvf_qset_sq_reg_tbl) *
     213                 :            :                         MAX_SND_QUEUES_PER_QS;
     214                 :            :         nr_regs += NICVF_ARRAY_SIZE(nicvf_qset_rbdr_reg_tbl) *
     215                 :            :                         MAX_RCV_BUF_DESC_RINGS_PER_QS;
     216                 :            : 
     217                 :          0 :         return nr_regs;
     218                 :            : }
     219                 :            : 
     220                 :            : static int
     221                 :            : nicvf_qset_config_internal(struct nicvf *nic, bool enable)
     222                 :            : {
     223                 :            :         int ret;
     224                 :          0 :         struct pf_qs_cfg pf_qs_cfg = {.value = 0};
     225                 :            : 
     226                 :          0 :         pf_qs_cfg.ena = enable ? 1 : 0;
     227                 :          0 :         pf_qs_cfg.vnic = nic->vf_id;
     228                 :          0 :         ret = nicvf_mbox_qset_config(nic, &pf_qs_cfg);
     229   [ #  #  #  # ]:          0 :         return ret ? NICVF_ERR_SET_QS : 0;
     230                 :            : }
     231                 :            : 
     232                 :            : /* Requests PF to assign and enable Qset */
     233                 :            : int
     234                 :          0 : nicvf_qset_config(struct nicvf *nic)
     235                 :            : {
     236                 :            :         /* Enable Qset */
     237                 :          0 :         return nicvf_qset_config_internal(nic, true);
     238                 :            : }
     239                 :            : 
     240                 :            : int
     241                 :          0 : nicvf_qset_reclaim(struct nicvf *nic)
     242                 :            : {
     243                 :            :         /* Disable Qset */
     244                 :          0 :         return nicvf_qset_config_internal(nic, false);
     245                 :            : }
     246                 :            : 
     247                 :            : static int
     248                 :          0 : cmpfunc(const void *a, const void *b)
     249                 :            : {
     250                 :          0 :         return (*(const uint32_t *)a - *(const uint32_t *)b);
     251                 :            : }
     252                 :            : 
     253                 :            : static uint32_t
     254                 :          0 : nicvf_roundup_list(uint32_t val, uint32_t list[], uint32_t entries)
     255                 :            : {
     256                 :            :         uint32_t i;
     257                 :            : 
     258                 :          0 :         qsort(list, entries, sizeof(uint32_t), cmpfunc);
     259         [ #  # ]:          0 :         for (i = 0; i < entries; i++)
     260         [ #  # ]:          0 :                 if (val <= list[i])
     261                 :            :                         break;
     262                 :            :         /* Not in the list */
     263         [ #  # ]:          0 :         if (i >= entries)
     264                 :            :                 return 0;
     265                 :            :         else
     266                 :          0 :                 return list[i];
     267                 :            : }
     268                 :            : 
     269                 :            : static void
     270                 :          0 : nicvf_handle_qset_err_intr(struct nicvf *nic)
     271                 :            : {
     272                 :            :         uint16_t qidx;
     273                 :            :         uint64_t status;
     274                 :            : 
     275                 :          0 :         nicvf_log("%s (VF%d)\n", __func__, nic->vf_id);
     276                 :          0 :         nicvf_reg_dump(nic, NULL);
     277                 :            : 
     278         [ #  # ]:          0 :         for (qidx = 0; qidx < MAX_CMP_QUEUES_PER_QS; qidx++) {
     279         [ #  # ]:          0 :                 status = nicvf_queue_reg_read(
     280                 :            :                                 nic, NIC_QSET_CQ_0_7_STATUS, qidx);
     281         [ #  # ]:          0 :                 if (!(status & NICVF_CQ_ERR_MASK))
     282                 :          0 :                         continue;
     283                 :            : 
     284         [ #  # ]:          0 :                 if (status & NICVF_CQ_WR_FULL)
     285                 :          0 :                         nicvf_log("[%d]NICVF_CQ_WR_FULL\n", qidx);
     286         [ #  # ]:          0 :                 if (status & NICVF_CQ_WR_DISABLE)
     287                 :          0 :                         nicvf_log("[%d]NICVF_CQ_WR_DISABLE\n", qidx);
     288         [ #  # ]:          0 :                 if (status & NICVF_CQ_WR_FAULT)
     289                 :          0 :                         nicvf_log("[%d]NICVF_CQ_WR_FAULT\n", qidx);
     290                 :            :                 nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_STATUS, qidx, 0);
     291                 :            :         }
     292                 :            : 
     293         [ #  # ]:          0 :         for (qidx = 0; qidx < MAX_SND_QUEUES_PER_QS; qidx++) {
     294         [ #  # ]:          0 :                 status = nicvf_queue_reg_read(
     295                 :            :                                 nic, NIC_QSET_SQ_0_7_STATUS, qidx);
     296                 :          0 :                 if (!(status & NICVF_SQ_ERR_MASK))
     297                 :          0 :                         continue;
     298                 :            : 
     299         [ #  # ]:          0 :                 if (status & NICVF_SQ_ERR_STOPPED)
     300                 :          0 :                         nicvf_log("[%d]NICVF_SQ_ERR_STOPPED\n", qidx);
     301         [ #  # ]:          0 :                 if (status & NICVF_SQ_ERR_SEND)
     302                 :          0 :                         nicvf_log("[%d]NICVF_SQ_ERR_SEND\n", qidx);
     303         [ #  # ]:          0 :                 if (status & NICVF_SQ_ERR_DPE)
     304                 :          0 :                         nicvf_log("[%d]NICVF_SQ_ERR_DPE\n", qidx);
     305                 :            :                 nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_STATUS, qidx, 0);
     306                 :            :         }
     307                 :            : 
     308         [ #  # ]:          0 :         for (qidx = 0; qidx < MAX_RCV_BUF_DESC_RINGS_PER_QS; qidx++) {
     309         [ #  # ]:          0 :                 status = nicvf_queue_reg_read(nic,
     310                 :            :                                 NIC_QSET_RBDR_0_1_STATUS0, qidx);
     311                 :            :                 status &= NICVF_RBDR_FIFO_STATE_MASK;
     312                 :            :                 status >>= NICVF_RBDR_FIFO_STATE_SHIFT;
     313                 :            : 
     314         [ #  # ]:          0 :                 if (status == RBDR_FIFO_STATE_FAIL)
     315                 :          0 :                         nicvf_log("[%d]RBDR_FIFO_STATE_FAIL\n", qidx);
     316                 :            :                 nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_STATUS0, qidx, 0);
     317                 :            :         }
     318                 :            : 
     319                 :            :         nicvf_disable_all_interrupts(nic);
     320                 :            :         abort();
     321                 :            : }
     322                 :            : 
     323                 :            : /*
     324                 :            :  * Handle poll mode driver interested "mbox" and "queue-set error" interrupts.
     325                 :            :  * This function is not re-entrant.
     326                 :            :  * The caller should provide proper serialization.
     327                 :            :  */
     328                 :            : int
     329         [ #  # ]:          0 : nicvf_reg_poll_interrupts(struct nicvf *nic)
     330                 :            : {
     331                 :            :         int msg = 0;
     332                 :            :         uint64_t intr;
     333                 :            : 
     334                 :            :         intr = nicvf_reg_read(nic, NIC_VF_INT);
     335         [ #  # ]:          0 :         if (intr & NICVF_INTR_MBOX_MASK) {
     336                 :            :                 nicvf_reg_write(nic, NIC_VF_INT, NICVF_INTR_MBOX_MASK);
     337                 :          0 :                 msg = nicvf_handle_mbx_intr(nic);
     338                 :            :         }
     339         [ #  # ]:          0 :         if (intr & NICVF_INTR_QS_ERR_MASK) {
     340                 :            :                 nicvf_reg_write(nic, NIC_VF_INT, NICVF_INTR_QS_ERR_MASK);
     341                 :          0 :                 nicvf_handle_qset_err_intr(nic);
     342                 :            :         }
     343                 :          0 :         return msg;
     344                 :            : }
     345                 :            : 
     346                 :            : static int
     347                 :            : nicvf_qset_poll_reg(struct nicvf *nic, uint16_t qidx, uint32_t offset,
     348                 :            :                     uint32_t bit_pos, uint32_t bits, uint64_t val)
     349                 :            : {
     350                 :            :         uint64_t bit_mask;
     351                 :            :         uint64_t reg_val;
     352                 :            :         int timeout = NICVF_REG_POLL_ITER_NR;
     353                 :            : 
     354                 :            :         bit_mask = (1ULL << bits) - 1;
     355                 :            :         bit_mask = (bit_mask << bit_pos);
     356                 :            : 
     357   [ #  #  #  #  :          0 :         while (timeout) {
          #  #  #  #  #  
                      # ]
     358                 :            :                 reg_val = nicvf_queue_reg_read(nic, offset, qidx);
     359   [ #  #  #  #  :          0 :                 if (((reg_val & bit_mask) >> bit_pos) == val)
          #  #  #  #  #  
                      # ]
     360                 :            :                         return NICVF_OK;
     361                 :          0 :                 nicvf_delay_us(NICVF_REG_POLL_DELAY_US);
     362                 :          0 :                 timeout--;
     363                 :            :         }
     364                 :            :         return NICVF_ERR_REG_POLL;
     365                 :            : }
     366                 :            : 
     367                 :            : int
     368                 :          0 : nicvf_qset_rbdr_reclaim(struct nicvf *nic, uint16_t qidx)
     369                 :            : {
     370                 :            :         uint64_t status;
     371                 :            :         int timeout = NICVF_REG_POLL_ITER_NR;
     372                 :          0 :         struct nicvf_rbdr *rbdr = nic->rbdr;
     373                 :            : 
     374                 :            :         /* Save head and tail pointers for freeing up buffers */
     375         [ #  # ]:          0 :         if (rbdr) {
     376                 :          0 :                 rbdr->head = nicvf_queue_reg_read(nic,
     377                 :          0 :                                 NIC_QSET_RBDR_0_1_HEAD, qidx) >> 3;
     378                 :          0 :                 rbdr->tail = nicvf_queue_reg_read(nic,
     379                 :          0 :                                 NIC_QSET_RBDR_0_1_TAIL, qidx) >> 3;
     380                 :          0 :                 rbdr->next_tail = rbdr->tail;
     381                 :            :         }
     382                 :            : 
     383                 :            :         /* Reset RBDR */
     384                 :          0 :         nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_CFG, qidx,
     385                 :            :                                 NICVF_RBDR_RESET);
     386                 :            : 
     387                 :            :         /* Disable RBDR */
     388                 :            :         nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_CFG, qidx, 0);
     389         [ #  # ]:          0 :         if (nicvf_qset_poll_reg(nic, qidx, NIC_QSET_RBDR_0_1_STATUS0,
     390                 :            :                                 62, 2, 0x00))
     391                 :            :                 return NICVF_ERR_RBDR_DISABLE;
     392                 :            : 
     393                 :            :         while (1) {
     394                 :            :                 status = nicvf_queue_reg_read(nic,
     395                 :            :                                 NIC_QSET_RBDR_0_1_PRFCH_STATUS, qidx);
     396         [ #  # ]:          0 :                 if ((status & 0xFFFFFFFF) == ((status >> 32) & 0xFFFFFFFF))
     397                 :            :                         break;
     398                 :          0 :                 nicvf_delay_us(NICVF_REG_POLL_DELAY_US);
     399                 :          0 :                 timeout--;
     400         [ #  # ]:          0 :                 if (!timeout)
     401                 :            :                         return NICVF_ERR_RBDR_PREFETCH;
     402                 :            :         }
     403                 :            : 
     404                 :            :         nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_CFG, qidx,
     405                 :            :                         NICVF_RBDR_RESET);
     406         [ #  # ]:          0 :         if (nicvf_qset_poll_reg(nic, qidx,
     407                 :            :                         NIC_QSET_RBDR_0_1_STATUS0, 62, 2, 0x02))
     408                 :            :                 return NICVF_ERR_RBDR_RESET1;
     409                 :            : 
     410                 :            :         nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_CFG, qidx, 0x00);
     411         [ #  # ]:          0 :         if (nicvf_qset_poll_reg(nic, qidx,
     412                 :            :                         NIC_QSET_RBDR_0_1_STATUS0, 62, 2, 0x00))
     413                 :          0 :                 return NICVF_ERR_RBDR_RESET2;
     414                 :            : 
     415                 :            :         return NICVF_OK;
     416                 :            : }
     417                 :            : 
     418                 :            : static int
     419         [ #  # ]:          0 : nicvf_qsize_regbit(uint32_t len, uint32_t len_shift)
     420                 :            : {
     421                 :            :         int val;
     422                 :            : 
     423                 :          0 :         val = nicvf_log2_u32(len) - len_shift;
     424                 :            : 
     425         [ #  # ]:          0 :         assert(val >= NICVF_QSIZE_MIN_VAL);
     426         [ #  # ]:          0 :         assert(val <= NICVF_QSIZE_MAX_VAL);
     427                 :          0 :         return val;
     428                 :            : }
     429                 :            : 
     430                 :            : int
     431                 :          0 : nicvf_qset_rbdr_config(struct nicvf *nic, uint16_t qidx)
     432                 :            : {
     433                 :            :         int ret;
     434                 :            :         uint64_t head, tail;
     435                 :          0 :         struct nicvf_rbdr *rbdr = nic->rbdr;
     436                 :          0 :         struct rbdr_cfg rbdr_cfg = {.value = 0};
     437                 :            : 
     438                 :          0 :         ret = nicvf_qset_rbdr_reclaim(nic, qidx);
     439         [ #  # ]:          0 :         if (ret)
     440                 :            :                 return ret;
     441                 :            : 
     442                 :            :         /* Set descriptor base address */
     443                 :          0 :         nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_BASE, qidx, rbdr->phys);
     444                 :            : 
     445                 :            :         /* Enable RBDR  & set queue size */
     446                 :          0 :         rbdr_cfg.ena = 1;
     447                 :            :         rbdr_cfg.reset = 0;
     448                 :            :         rbdr_cfg.ldwb = 0;
     449                 :          0 :         rbdr_cfg.qsize = nicvf_qsize_regbit(rbdr->qlen_mask + 1,
     450                 :            :                                                 RBDR_SIZE_SHIFT);
     451                 :            :         rbdr_cfg.avg_con = 0;
     452                 :          0 :         rbdr_cfg.lines = rbdr->buffsz / 128;
     453                 :            : 
     454         [ #  # ]:          0 :         nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_CFG, qidx, rbdr_cfg.value);
     455                 :            : 
     456                 :            :         /* Verify proper RBDR reset */
     457                 :            :         head = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_HEAD, qidx);
     458                 :            :         tail = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_TAIL, qidx);
     459                 :            : 
     460         [ #  # ]:          0 :         if (head | tail)
     461                 :          0 :                 return NICVF_ERR_RBDR_RESET;
     462                 :            : 
     463                 :            :         return NICVF_OK;
     464                 :            : }
     465                 :            : 
     466                 :            : uint32_t
     467                 :          0 : nicvf_qsize_rbdr_roundup(uint32_t val)
     468                 :            : {
     469                 :          0 :         uint32_t list[] = {RBDR_QUEUE_SZ_8K, RBDR_QUEUE_SZ_16K,
     470                 :            :                         RBDR_QUEUE_SZ_32K, RBDR_QUEUE_SZ_64K,
     471                 :            :                         RBDR_QUEUE_SZ_128K, RBDR_QUEUE_SZ_256K,
     472                 :            :                         RBDR_QUEUE_SZ_512K};
     473                 :          0 :         return nicvf_roundup_list(val, list, NICVF_ARRAY_SIZE(list));
     474                 :            : }
     475                 :            : 
     476                 :            : int
     477                 :          0 : nicvf_qset_rbdr_precharge(void *dev, struct nicvf *nic,
     478                 :            :                           uint16_t ridx, rbdr_pool_get_handler handler,
     479                 :            :                           uint32_t max_buffs)
     480                 :            : {
     481                 :            :         struct rbdr_entry_t *desc, *desc0;
     482                 :          0 :         struct nicvf_rbdr *rbdr = nic->rbdr;
     483                 :            :         uint32_t count;
     484                 :            :         nicvf_iova_addr_t phy;
     485                 :            : 
     486         [ #  # ]:          0 :         assert(rbdr != NULL);
     487                 :          0 :         desc = rbdr->desc;
     488                 :            :         count = 0;
     489                 :            :         /* Don't fill beyond max numbers of desc */
     490         [ #  # ]:          0 :         while (count < rbdr->qlen_mask) {
     491         [ #  # ]:          0 :                 if (count >= max_buffs)
     492                 :            :                         break;
     493                 :          0 :                 desc0 = desc + count;
     494                 :          0 :                 phy = handler(dev, nic);
     495         [ #  # ]:          0 :                 if (phy) {
     496                 :          0 :                         desc0->full_addr = phy;
     497                 :          0 :                         count++;
     498                 :            :                 } else {
     499                 :            :                         break;
     500                 :            :                 }
     501                 :            :         }
     502                 :          0 :         nicvf_smp_wmb();
     503                 :          0 :         nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_DOOR, ridx, count);
     504                 :          0 :         rbdr->tail = nicvf_queue_reg_read(nic,
     505                 :          0 :                                 NIC_QSET_RBDR_0_1_TAIL, ridx) >> 3;
     506                 :          0 :         rbdr->next_tail = rbdr->tail;
     507                 :          0 :         nicvf_smp_rmb();
     508                 :          0 :         return 0;
     509                 :            : }
     510                 :            : 
     511                 :            : int
     512                 :          0 : nicvf_qset_rbdr_active(struct nicvf *nic, uint16_t qidx)
     513                 :            : {
     514                 :          0 :         return nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_STATUS0, qidx);
     515                 :            : }
     516                 :            : 
     517                 :            : int
     518                 :          0 : nicvf_qset_sq_reclaim(struct nicvf *nic, uint16_t qidx)
     519                 :            : {
     520                 :            :         uint64_t head, tail;
     521                 :            :         struct sq_cfg sq_cfg;
     522                 :            : 
     523         [ #  # ]:          0 :         sq_cfg.value = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_CFG, qidx);
     524                 :            : 
     525                 :            :         /* Disable send queue */
     526                 :            :         nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_CFG, qidx, 0);
     527                 :            : 
     528                 :            :         /* Check if SQ is stopped */
     529   [ #  #  #  # ]:          0 :         if (sq_cfg.ena && nicvf_qset_poll_reg(nic, qidx, NIC_QSET_SQ_0_7_STATUS,
     530                 :            :                                 NICVF_SQ_STATUS_STOPPED_BIT, 1, 0x01))
     531                 :            :                 return NICVF_ERR_SQ_DISABLE;
     532                 :            : 
     533                 :            :         /* Reset send queue */
     534                 :            :         nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_CFG, qidx, NICVF_SQ_RESET);
     535                 :          0 :         head = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_HEAD, qidx) >> 4;
     536                 :          0 :         tail = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_TAIL, qidx) >> 4;
     537         [ #  # ]:          0 :         if (head | tail)
     538                 :          0 :                 return  NICVF_ERR_SQ_RESET;
     539                 :            : 
     540                 :            :         return 0;
     541                 :            : }
     542                 :            : 
     543                 :            : int
     544                 :          0 : nicvf_qset_sq_config(struct nicvf *nic, uint16_t qidx, struct nicvf_txq *txq)
     545                 :            : {
     546                 :            :         int ret;
     547                 :          0 :         struct sq_cfg sq_cfg = {.value = 0};
     548                 :            : 
     549                 :          0 :         ret = nicvf_qset_sq_reclaim(nic, qidx);
     550         [ #  # ]:          0 :         if (ret)
     551                 :            :                 return ret;
     552                 :            : 
     553                 :            :         /* Send a mailbox msg to PF to config SQ */
     554         [ #  # ]:          0 :         if (nicvf_mbox_sq_config(nic, qidx))
     555                 :            :                 return  NICVF_ERR_SQ_PF_CFG;
     556                 :            : 
     557                 :            :         /* Set queue base address */
     558                 :          0 :         nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_BASE, qidx, txq->phys);
     559                 :            : 
     560                 :            :         /* Enable send queue  & set queue size */
     561                 :            :         sq_cfg.cq_limit = 0;
     562                 :          0 :         sq_cfg.ena = 1;
     563                 :            :         sq_cfg.reset = 0;
     564                 :            :         sq_cfg.ldwb = 0;
     565                 :          0 :         sq_cfg.qsize = nicvf_qsize_regbit(txq->qlen_mask + 1, SND_QSIZE_SHIFT);
     566                 :            :         sq_cfg.tstmp_bgx_intf = 0;
     567                 :          0 :         nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_CFG, qidx, sq_cfg.value);
     568                 :            : 
     569                 :            :         /* Ring doorbell so that H/W restarts processing SQEs */
     570                 :            :         nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_DOOR, qidx, 0);
     571                 :            : 
     572                 :          0 :         return 0;
     573                 :            : }
     574                 :            : 
     575                 :            : uint32_t
     576                 :          0 : nicvf_qsize_sq_roundup(uint32_t val)
     577                 :            : {
     578                 :          0 :         uint32_t list[] = {SND_QUEUE_SZ_1K, SND_QUEUE_SZ_2K,
     579                 :            :                         SND_QUEUE_SZ_4K, SND_QUEUE_SZ_8K,
     580                 :            :                         SND_QUEUE_SZ_16K, SND_QUEUE_SZ_32K,
     581                 :            :                         SND_QUEUE_SZ_64K};
     582                 :          0 :         return nicvf_roundup_list(val, list, NICVF_ARRAY_SIZE(list));
     583                 :            : }
     584                 :            : 
     585                 :            : int
     586                 :          0 : nicvf_qset_rq_reclaim(struct nicvf *nic, uint16_t qidx)
     587                 :            : {
     588                 :            :         /* Disable receive queue */
     589                 :          0 :         nicvf_queue_reg_write(nic, NIC_QSET_RQ_0_7_CFG, qidx, 0);
     590                 :          0 :         return nicvf_mbox_rq_sync(nic);
     591                 :            : }
     592                 :            : 
     593                 :            : int
     594                 :          0 : nicvf_qset_rq_config(struct nicvf *nic, uint16_t qidx, struct nicvf_rxq *rxq)
     595                 :            : {
     596                 :          0 :         struct pf_rq_cfg pf_rq_cfg = {.value = 0};
     597                 :            :         struct rq_cfg rq_cfg = {.value = 0};
     598                 :            : 
     599         [ #  # ]:          0 :         if (nicvf_qset_rq_reclaim(nic, qidx))
     600                 :            :                 return NICVF_ERR_RQ_CLAIM;
     601                 :            : 
     602                 :          0 :         pf_rq_cfg.strip_pre_l2 = 0;
     603                 :            :         /* First cache line of RBDR data will be allocated into L2C */
     604                 :          0 :         pf_rq_cfg.caching = RQ_CACHE_ALLOC_FIRST;
     605                 :          0 :         pf_rq_cfg.cq_qs = nic->vf_id;
     606                 :          0 :         pf_rq_cfg.cq_idx = qidx;
     607                 :          0 :         pf_rq_cfg.rbdr_cont_qs = nic->vf_id;
     608                 :          0 :         pf_rq_cfg.rbdr_cont_idx = 0;
     609                 :          0 :         pf_rq_cfg.rbdr_strt_qs = nic->vf_id;
     610                 :          0 :         pf_rq_cfg.rbdr_strt_idx = 0;
     611                 :            : 
     612                 :            :         /* Send a mailbox msg to PF to config RQ */
     613         [ #  # ]:          0 :         if (nicvf_mbox_rq_config(nic, qidx, &pf_rq_cfg))
     614                 :            :                 return NICVF_ERR_RQ_PF_CFG;
     615                 :            : 
     616                 :            :         /* Select Rx backpressure */
     617         [ #  # ]:          0 :         if (nicvf_mbox_rq_bp_config(nic, qidx, rxq->rx_drop_en))
     618                 :            :                 return NICVF_ERR_RQ_BP_CFG;
     619                 :            : 
     620                 :            :         /* Send a mailbox msg to PF to config RQ drop */
     621         [ #  # ]:          0 :         if (nicvf_mbox_rq_drop_config(nic, qidx, rxq->rx_drop_en))
     622                 :            :                 return NICVF_ERR_RQ_DROP_CFG;
     623                 :            : 
     624                 :            :         /* Enable Receive queue */
     625                 :            :         rq_cfg.ena = 1;
     626                 :          0 :         nicvf_queue_reg_write(nic, NIC_QSET_RQ_0_7_CFG, qidx, rq_cfg.value);
     627                 :            : 
     628                 :          0 :         return 0;
     629                 :            : }
     630                 :            : 
     631                 :            : int
     632                 :          0 : nicvf_qset_cq_reclaim(struct nicvf *nic, uint16_t qidx)
     633                 :            : {
     634                 :            :         uint64_t tail, head;
     635                 :            : 
     636                 :            :         /* Disable completion queue */
     637                 :          0 :         nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG, qidx, 0);
     638         [ #  # ]:          0 :         if (nicvf_qset_poll_reg(nic, qidx, NIC_QSET_CQ_0_7_CFG, 42, 1, 0))
     639                 :            :                 return NICVF_ERR_CQ_DISABLE;
     640                 :            : 
     641                 :            :         /* Reset completion queue */
     642                 :            :         nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG, qidx, NICVF_CQ_RESET);
     643                 :          0 :         tail = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_TAIL, qidx) >> 9;
     644                 :          0 :         head = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_HEAD, qidx) >> 9;
     645         [ #  # ]:          0 :         if (head | tail)
     646                 :            :                 return  NICVF_ERR_CQ_RESET;
     647                 :            : 
     648                 :            :         /* Disable timer threshold (doesn't get reset upon CQ reset) */
     649                 :            :         nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG2, qidx, 0);
     650                 :          0 :         return 0;
     651                 :            : }
     652                 :            : 
     653                 :            : int
     654                 :          0 : nicvf_qset_cq_config(struct nicvf *nic, uint16_t qidx, struct nicvf_rxq *rxq)
     655                 :            : {
     656                 :            :         int ret;
     657                 :          0 :         struct cq_cfg cq_cfg = {.value = 0};
     658                 :            : 
     659                 :          0 :         ret = nicvf_qset_cq_reclaim(nic, qidx);
     660         [ #  # ]:          0 :         if (ret)
     661                 :            :                 return ret;
     662                 :            : 
     663                 :            :         /* Set completion queue base address */
     664                 :          0 :         nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_BASE, qidx, rxq->phys);
     665                 :            : 
     666                 :          0 :         cq_cfg.ena = 1;
     667                 :            :         cq_cfg.reset = 0;
     668                 :            :         /* Writes of CQE will be allocated into L2C */
     669                 :          0 :         cq_cfg.caching = 1;
     670                 :          0 :         cq_cfg.qsize = nicvf_qsize_regbit(rxq->qlen_mask + 1, CMP_QSIZE_SHIFT);
     671                 :            :         cq_cfg.avg_con = 0;
     672                 :          0 :         nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG, qidx, cq_cfg.value);
     673                 :            : 
     674                 :            :         /* Set threshold value for interrupt generation */
     675                 :            :         nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_THRESH, qidx, 0);
     676                 :            :         nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG2, qidx, 0);
     677                 :          0 :         return 0;
     678                 :            : }
     679                 :            : 
     680                 :            : uint32_t
     681                 :          0 : nicvf_qsize_cq_roundup(uint32_t val)
     682                 :            : {
     683                 :          0 :         uint32_t list[] = {CMP_QUEUE_SZ_1K, CMP_QUEUE_SZ_2K,
     684                 :            :                         CMP_QUEUE_SZ_4K, CMP_QUEUE_SZ_8K,
     685                 :            :                         CMP_QUEUE_SZ_16K, CMP_QUEUE_SZ_32K,
     686                 :            :                         CMP_QUEUE_SZ_64K};
     687                 :          0 :         return nicvf_roundup_list(val, list, NICVF_ARRAY_SIZE(list));
     688                 :            : }
     689                 :            : 
     690                 :            : 
     691                 :            : void
     692         [ #  # ]:          0 : nicvf_vlan_hw_strip(struct nicvf *nic, bool enable)
     693                 :            : {
     694                 :            :         uint64_t val;
     695                 :            : 
     696                 :            :         val = nicvf_reg_read(nic, NIC_VNIC_RQ_GEN_CFG);
     697         [ #  # ]:          0 :         if (enable)
     698                 :          0 :                 val |= (STRIP_FIRST_VLAN << 25);
     699                 :            :         else
     700                 :          0 :                 val &= ~((STRIP_SECOND_VLAN | STRIP_FIRST_VLAN) << 25);
     701                 :            : 
     702                 :          0 :         nic->vlan_strip = enable;
     703                 :            :         nicvf_reg_write(nic, NIC_VNIC_RQ_GEN_CFG, val);
     704                 :          0 : }
     705                 :            : 
     706                 :            : void
     707                 :          0 : nicvf_first_skip_config(struct nicvf *nic, uint8_t num_dwords)
     708                 :            : {
     709                 :            :         uint64_t val;
     710                 :            : 
     711                 :            :         val = nicvf_reg_read(nic, NIC_VNIC_RQ_GEN_CFG);
     712                 :          0 :         val &= ~(0xfULL);
     713                 :          0 :         val |= (num_dwords & 0xf);
     714                 :            : 
     715                 :            :         nicvf_reg_write(nic, NIC_VNIC_RQ_GEN_CFG, val);
     716                 :          0 : }
     717                 :            : 
     718                 :            : void
     719                 :          0 : nicvf_apad_config(struct nicvf *nic, bool enable)
     720                 :            : {
     721                 :            :         uint64_t val;
     722                 :            : 
     723                 :            :         /* APAD always enabled in this device */
     724         [ #  # ]:          0 :         if (!(nic->hwcap & NICVF_CAP_DISABLE_APAD))
     725                 :            :                 return;
     726                 :            : 
     727                 :            :         val = nicvf_reg_read(nic, NIC_VNIC_RQ_GEN_CFG);
     728         [ #  # ]:          0 :         if (enable)
     729                 :          0 :                 val &= ~(1ULL << NICVF_QS_RQ_DIS_APAD_SHIFT);
     730                 :            :         else
     731                 :          0 :                 val |= (1ULL << NICVF_QS_RQ_DIS_APAD_SHIFT);
     732                 :            : 
     733                 :            :         nicvf_reg_write(nic, NIC_VNIC_RQ_GEN_CFG, val);
     734                 :            : }
     735                 :            : 
     736                 :            : void
     737                 :          0 : nicvf_rss_set_key(struct nicvf *nic, uint8_t *key)
     738                 :            : {
     739                 :            :         int idx;
     740                 :            :         uint64_t addr, val;
     741                 :            :         uint64_t *keyptr = (uint64_t *)key;
     742                 :            : 
     743                 :            :         addr = NIC_VNIC_RSS_KEY_0_4;
     744         [ #  # ]:          0 :         for (idx = 0; idx < RSS_HASH_KEY_SIZE; idx++) {
     745         [ #  # ]:          0 :                 val = nicvf_cpu_to_be_64(*keyptr);
     746                 :            :                 nicvf_reg_write(nic, addr, val);
     747                 :          0 :                 addr += sizeof(uint64_t);
     748                 :          0 :                 keyptr++;
     749                 :            :         }
     750                 :          0 : }
     751                 :            : 
     752                 :            : void
     753                 :          0 : nicvf_rss_get_key(struct nicvf *nic, uint8_t *key)
     754                 :            : {
     755                 :            :         int idx;
     756                 :            :         uint64_t addr, val;
     757                 :            :         uint64_t *keyptr = (uint64_t *)key;
     758                 :            : 
     759                 :            :         addr = NIC_VNIC_RSS_KEY_0_4;
     760         [ #  # ]:          0 :         for (idx = 0; idx < RSS_HASH_KEY_SIZE; idx++) {
     761                 :            :                 val = nicvf_reg_read(nic, addr);
     762         [ #  # ]:          0 :                 *keyptr = nicvf_be_to_cpu_64(val);
     763                 :          0 :                 addr += sizeof(uint64_t);
     764                 :          0 :                 keyptr++;
     765                 :            :         }
     766                 :          0 : }
     767                 :            : 
     768                 :            : void
     769                 :          0 : nicvf_rss_set_cfg(struct nicvf *nic, uint64_t val)
     770                 :            : {
     771                 :            :         nicvf_reg_write(nic, NIC_VNIC_RSS_CFG, val);
     772                 :          0 : }
     773                 :            : 
     774                 :            : uint64_t
     775                 :          0 : nicvf_rss_get_cfg(struct nicvf *nic)
     776                 :            : {
     777                 :          0 :         return nicvf_reg_read(nic, NIC_VNIC_RSS_CFG);
     778                 :            : }
     779                 :            : 
     780                 :            : int
     781                 :          0 : nicvf_rss_reta_update(struct nicvf *nic, uint8_t *tbl, uint32_t max_count)
     782                 :            : {
     783                 :            :         uint32_t idx;
     784                 :            :         struct nicvf_rss_reta_info *rss = &nic->rss_info;
     785                 :            : 
     786                 :            :         /* result will be stored in nic->rss_info.rss_size */
     787         [ #  # ]:          0 :         if (nicvf_mbox_get_rss_size(nic))
     788                 :            :                 return NICVF_ERR_RSS_GET_SZ;
     789                 :            : 
     790         [ #  # ]:          0 :         assert(rss->rss_size > 0);
     791                 :          0 :         rss->hash_bits = (uint8_t)nicvf_log2_u32(rss->rss_size);
     792   [ #  #  #  # ]:          0 :         for (idx = 0; idx < rss->rss_size && idx < max_count; idx++)
     793                 :          0 :                 rss->ind_tbl[idx] = tbl[idx];
     794                 :            : 
     795         [ #  # ]:          0 :         if (nicvf_mbox_config_rss(nic))
     796                 :          0 :                 return NICVF_ERR_RSS_TBL_UPDATE;
     797                 :            : 
     798                 :            :         return NICVF_OK;
     799                 :            : }
     800                 :            : 
     801                 :            : int
     802                 :          0 : nicvf_rss_reta_query(struct nicvf *nic, uint8_t *tbl, uint32_t max_count)
     803                 :            : {
     804                 :            :         uint32_t idx;
     805                 :            :         struct nicvf_rss_reta_info *rss = &nic->rss_info;
     806                 :            : 
     807                 :            :         /* result will be stored in nic->rss_info.rss_size */
     808         [ #  # ]:          0 :         if (nicvf_mbox_get_rss_size(nic))
     809                 :            :                 return NICVF_ERR_RSS_GET_SZ;
     810                 :            : 
     811         [ #  # ]:          0 :         assert(rss->rss_size > 0);
     812                 :          0 :         rss->hash_bits = (uint8_t)nicvf_log2_u32(rss->rss_size);
     813                 :            : 
     814   [ #  #  #  # ]:          0 :         for (idx = 0; idx < rss->rss_size && idx < max_count; idx++)
     815                 :          0 :                 tbl[idx] = rss->ind_tbl[idx];
     816                 :            : 
     817                 :            :         return NICVF_OK;
     818                 :            : }
     819                 :            : 
     820                 :            : int
     821                 :          0 : nicvf_rss_config(struct nicvf *nic, uint32_t  qcnt, uint64_t cfg)
     822                 :            : {
     823                 :            :         uint32_t idx;
     824                 :            :         uint8_t default_reta[NIC_MAX_RSS_IDR_TBL_SIZE];
     825                 :          0 :         uint8_t default_key[RSS_HASH_KEY_BYTE_SIZE] = {
     826                 :            :                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
     827                 :            :                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
     828                 :            :                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
     829                 :            :                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
     830                 :            :                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD
     831                 :            :         };
     832                 :            : 
     833         [ #  # ]:          0 :         if (nic->cpi_alg != CPI_ALG_NONE)
     834                 :            :                 return -EINVAL;
     835                 :            : 
     836         [ #  # ]:          0 :         if (cfg == 0)
     837                 :            :                 return -EINVAL;
     838                 :            : 
     839                 :            :         /* Update default RSS key and cfg */
     840                 :          0 :         nicvf_rss_set_key(nic, default_key);
     841                 :          0 :         nicvf_rss_set_cfg(nic, cfg);
     842                 :            : 
     843                 :            :         /* Update default RSS RETA */
     844         [ #  # ]:          0 :         for (idx = 0; idx < NIC_MAX_RSS_IDR_TBL_SIZE; idx++)
     845                 :          0 :                 default_reta[idx] = idx % qcnt;
     846                 :            : 
     847                 :          0 :         return nicvf_rss_reta_update(nic, default_reta,
     848                 :            :                         NIC_MAX_RSS_IDR_TBL_SIZE);
     849                 :            : }
     850                 :            : 
     851                 :            : int
     852                 :          0 : nicvf_rss_term(struct nicvf *nic)
     853                 :            : {
     854                 :            :         uint32_t idx;
     855                 :            :         uint8_t disable_rss[NIC_MAX_RSS_IDR_TBL_SIZE];
     856                 :            : 
     857                 :          0 :         nicvf_rss_set_cfg(nic, 0);
     858                 :            :         /* Redirect the output to 0th queue  */
     859         [ #  # ]:          0 :         for (idx = 0; idx < NIC_MAX_RSS_IDR_TBL_SIZE; idx++)
     860                 :          0 :                 disable_rss[idx] = 0;
     861                 :            : 
     862                 :          0 :         return nicvf_rss_reta_update(nic, disable_rss,
     863                 :            :                         NIC_MAX_RSS_IDR_TBL_SIZE);
     864                 :            : }
     865                 :            : 
     866                 :            : int
     867                 :          0 : nicvf_loopback_config(struct nicvf *nic, bool enable)
     868                 :            : {
     869   [ #  #  #  # ]:          0 :         if (enable && nic->loopback_supported == 0)
     870                 :            :                 return NICVF_ERR_LOOPBACK_CFG;
     871                 :            : 
     872                 :          0 :         return nicvf_mbox_loopback_config(nic, enable);
     873                 :            : }
     874                 :            : 
     875                 :            : void
     876                 :          0 : nicvf_hw_get_stats(struct nicvf *nic, struct nicvf_hw_stats *stats)
     877                 :            : {
     878                 :          0 :         stats->rx_bytes = NICVF_GET_RX_STATS(RX_OCTS);
     879                 :          0 :         stats->rx_ucast_frames = NICVF_GET_RX_STATS(RX_UCAST);
     880                 :          0 :         stats->rx_bcast_frames = NICVF_GET_RX_STATS(RX_BCAST);
     881                 :          0 :         stats->rx_mcast_frames = NICVF_GET_RX_STATS(RX_MCAST);
     882                 :          0 :         stats->rx_fcs_errors = NICVF_GET_RX_STATS(RX_FCS);
     883                 :          0 :         stats->rx_l2_errors = NICVF_GET_RX_STATS(RX_L2ERR);
     884                 :          0 :         stats->rx_drop_red = NICVF_GET_RX_STATS(RX_RED);
     885                 :          0 :         stats->rx_drop_red_bytes = NICVF_GET_RX_STATS(RX_RED_OCTS);
     886                 :          0 :         stats->rx_drop_overrun = NICVF_GET_RX_STATS(RX_ORUN);
     887                 :          0 :         stats->rx_drop_overrun_bytes = NICVF_GET_RX_STATS(RX_ORUN_OCTS);
     888                 :          0 :         stats->rx_drop_bcast = NICVF_GET_RX_STATS(RX_DRP_BCAST);
     889                 :          0 :         stats->rx_drop_mcast = NICVF_GET_RX_STATS(RX_DRP_MCAST);
     890                 :          0 :         stats->rx_drop_l3_bcast = NICVF_GET_RX_STATS(RX_DRP_L3BCAST);
     891                 :          0 :         stats->rx_drop_l3_mcast = NICVF_GET_RX_STATS(RX_DRP_L3MCAST);
     892                 :            : 
     893                 :          0 :         stats->tx_bytes_ok = NICVF_GET_TX_STATS(TX_OCTS);
     894                 :          0 :         stats->tx_ucast_frames_ok = NICVF_GET_TX_STATS(TX_UCAST);
     895                 :          0 :         stats->tx_bcast_frames_ok = NICVF_GET_TX_STATS(TX_BCAST);
     896                 :          0 :         stats->tx_mcast_frames_ok = NICVF_GET_TX_STATS(TX_MCAST);
     897                 :          0 :         stats->tx_drops = NICVF_GET_TX_STATS(TX_DROP);
     898                 :          0 : }
     899                 :            : 
     900                 :            : void
     901                 :          0 : nicvf_hw_get_rx_qstats(struct nicvf *nic, struct nicvf_hw_rx_qstats *qstats,
     902                 :            :                        uint16_t qidx)
     903                 :            : {
     904                 :          0 :         qstats->q_rx_bytes =
     905                 :          0 :                 nicvf_queue_reg_read(nic, NIC_QSET_RQ_0_7_STATUS0, qidx);
     906                 :          0 :         qstats->q_rx_packets =
     907                 :            :                 nicvf_queue_reg_read(nic, NIC_QSET_RQ_0_7_STATUS1, qidx);
     908                 :          0 : }
     909                 :            : 
     910                 :            : void
     911                 :          0 : nicvf_hw_get_tx_qstats(struct nicvf *nic, struct nicvf_hw_tx_qstats *qstats,
     912                 :            :                        uint16_t qidx)
     913                 :            : {
     914                 :          0 :         qstats->q_tx_bytes =
     915                 :          0 :                 nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STATUS0, qidx);
     916                 :          0 :         qstats->q_tx_packets =
     917                 :            :                 nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STATUS1, qidx);
     918                 :          0 : }

Generated by: LCOV version 1.14