LCOV - code coverage report
Current view: top level - drivers/net/hinic/base - hinic_pmd_nicio.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 358 0.0 %
Date: 2024-04-01 19:00:53 Functions: 0 28 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 106 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2017 Huawei Technologies Co., Ltd
       3                 :            :  */
       4                 :            : #include <bus_pci_driver.h>
       5                 :            : 
       6                 :            : #include "hinic_compat.h"
       7                 :            : #include "hinic_pmd_hwdev.h"
       8                 :            : #include "hinic_pmd_hwif.h"
       9                 :            : #include "hinic_pmd_wq.h"
      10                 :            : #include "hinic_pmd_mgmt.h"
      11                 :            : #include "hinic_pmd_cmdq.h"
      12                 :            : #include "hinic_pmd_cfg.h"
      13                 :            : #include "hinic_pmd_niccfg.h"
      14                 :            : #include "hinic_pmd_nicio.h"
      15                 :            : 
      16                 :            : #define WQ_PREFETCH_MAX                 6
      17                 :            : #define WQ_PREFETCH_MIN                 1
      18                 :            : #define WQ_PREFETCH_THRESHOLD           256
      19                 :            : 
      20                 :            : #define DEFAULT_RX_BUF_SIZE             ((u16)0xB)
      21                 :            : 
      22                 :            : enum {
      23                 :            :         RECYCLE_MODE_NIC = 0x0,
      24                 :            :         RECYCLE_MODE_DPDK = 0x1,
      25                 :            : };
      26                 :            : 
      27                 :            : /* Queue buffer related define */
      28                 :            : enum hinic_rx_buf_size {
      29                 :            :         HINIC_RX_BUF_SIZE_32B = 0x20,
      30                 :            :         HINIC_RX_BUF_SIZE_64B = 0x40,
      31                 :            :         HINIC_RX_BUF_SIZE_96B = 0x60,
      32                 :            :         HINIC_RX_BUF_SIZE_128B = 0x80,
      33                 :            :         HINIC_RX_BUF_SIZE_192B = 0xC0,
      34                 :            :         HINIC_RX_BUF_SIZE_256B = 0x100,
      35                 :            :         HINIC_RX_BUF_SIZE_384B = 0x180,
      36                 :            :         HINIC_RX_BUF_SIZE_512B = 0x200,
      37                 :            :         HINIC_RX_BUF_SIZE_768B = 0x300,
      38                 :            :         HINIC_RX_BUF_SIZE_1K = 0x400,
      39                 :            :         HINIC_RX_BUF_SIZE_1_5K = 0x600,
      40                 :            :         HINIC_RX_BUF_SIZE_2K = 0x800,
      41                 :            :         HINIC_RX_BUF_SIZE_3K = 0xC00,
      42                 :            :         HINIC_RX_BUF_SIZE_4K = 0x1000,
      43                 :            :         HINIC_RX_BUF_SIZE_8K = 0x2000,
      44                 :            :         HINIC_RX_BUF_SIZE_16K = 0x4000,
      45                 :            : };
      46                 :            : 
      47                 :            : const u32 hinic_hw_rx_buf_size[] = {
      48                 :            :         HINIC_RX_BUF_SIZE_32B,
      49                 :            :         HINIC_RX_BUF_SIZE_64B,
      50                 :            :         HINIC_RX_BUF_SIZE_96B,
      51                 :            :         HINIC_RX_BUF_SIZE_128B,
      52                 :            :         HINIC_RX_BUF_SIZE_192B,
      53                 :            :         HINIC_RX_BUF_SIZE_256B,
      54                 :            :         HINIC_RX_BUF_SIZE_384B,
      55                 :            :         HINIC_RX_BUF_SIZE_512B,
      56                 :            :         HINIC_RX_BUF_SIZE_768B,
      57                 :            :         HINIC_RX_BUF_SIZE_1K,
      58                 :            :         HINIC_RX_BUF_SIZE_1_5K,
      59                 :            :         HINIC_RX_BUF_SIZE_2K,
      60                 :            :         HINIC_RX_BUF_SIZE_3K,
      61                 :            :         HINIC_RX_BUF_SIZE_4K,
      62                 :            :         HINIC_RX_BUF_SIZE_8K,
      63                 :            :         HINIC_RX_BUF_SIZE_16K,
      64                 :            : };
      65                 :            : 
      66                 :            : struct hinic_qp_ctxt_header {
      67                 :            :         u16     num_queues;
      68                 :            :         u16     queue_type;
      69                 :            :         u32     addr_offset;
      70                 :            : };
      71                 :            : 
      72                 :            : struct hinic_sq_ctxt {
      73                 :            :         u32     ceq_attr;
      74                 :            : 
      75                 :            :         u32     ci_owner;
      76                 :            : 
      77                 :            :         u32     wq_pfn_hi;
      78                 :            :         u32     wq_pfn_lo;
      79                 :            : 
      80                 :            :         u32     pref_cache;
      81                 :            :         u32     pref_owner;
      82                 :            :         u32     pref_wq_pfn_hi_ci;
      83                 :            :         u32     pref_wq_pfn_lo;
      84                 :            : 
      85                 :            :         u32     rsvd8;
      86                 :            :         u32     rsvd9;
      87                 :            : 
      88                 :            :         u32     wq_block_pfn_hi;
      89                 :            :         u32     wq_block_pfn_lo;
      90                 :            : };
      91                 :            : 
      92                 :            : struct hinic_rq_ctxt {
      93                 :            :         u32     ceq_attr;
      94                 :            : 
      95                 :            :         u32     pi_intr_attr;
      96                 :            : 
      97                 :            :         u32     wq_pfn_hi_ci;
      98                 :            :         u32     wq_pfn_lo;
      99                 :            : 
     100                 :            :         u32     pref_cache;
     101                 :            :         u32     pref_owner;
     102                 :            : 
     103                 :            :         u32     pref_wq_pfn_hi_ci;
     104                 :            :         u32     pref_wq_pfn_lo;
     105                 :            : 
     106                 :            :         u32     pi_paddr_hi;
     107                 :            :         u32     pi_paddr_lo;
     108                 :            : 
     109                 :            :         u32     wq_block_pfn_hi;
     110                 :            :         u32     wq_block_pfn_lo;
     111                 :            : };
     112                 :            : 
     113                 :            : struct hinic_sq_ctxt_block {
     114                 :            :         struct hinic_qp_ctxt_header     cmdq_hdr;
     115                 :            :         struct hinic_sq_ctxt            sq_ctxt[HINIC_Q_CTXT_MAX];
     116                 :            : };
     117                 :            : 
     118                 :            : struct hinic_rq_ctxt_block {
     119                 :            :         struct hinic_qp_ctxt_header     cmdq_hdr;
     120                 :            :         struct hinic_rq_ctxt            rq_ctxt[HINIC_Q_CTXT_MAX];
     121                 :            : };
     122                 :            : 
     123                 :            : struct hinic_clean_queue_ctxt {
     124                 :            :         struct hinic_qp_ctxt_header     cmdq_hdr;
     125                 :            :         u32                             ctxt_size;
     126                 :            : };
     127                 :            : 
     128                 :            : 
     129                 :            : static void
     130                 :            : hinic_qp_prepare_cmdq_header(struct hinic_qp_ctxt_header *qp_ctxt_hdr,
     131                 :            :                              enum hinic_qp_ctxt_type ctxt_type,
     132                 :            :                              u16 num_queues, u16 max_queues, u16 q_id)
     133                 :            : {
     134                 :          0 :         qp_ctxt_hdr->queue_type = ctxt_type;
     135                 :          0 :         qp_ctxt_hdr->num_queues = num_queues;
     136                 :            : 
     137                 :            :         if (ctxt_type == HINIC_QP_CTXT_TYPE_SQ)
     138                 :            :                 qp_ctxt_hdr->addr_offset =
     139                 :          0 :                                 SQ_CTXT_OFFSET(max_queues, max_queues, q_id);
     140                 :            :         else
     141                 :            :                 qp_ctxt_hdr->addr_offset =
     142                 :          0 :                                 RQ_CTXT_OFFSET(max_queues, max_queues, q_id);
     143                 :            : 
     144                 :          0 :         qp_ctxt_hdr->addr_offset = SIZE_16BYTES(qp_ctxt_hdr->addr_offset);
     145                 :            : 
     146                 :          0 :         hinic_cpu_to_be32(qp_ctxt_hdr, sizeof(*qp_ctxt_hdr));
     147                 :            : }
     148                 :            : 
     149                 :          0 : static void hinic_sq_prepare_ctxt(struct hinic_sq *sq, u16 global_qpn,
     150                 :            :                            struct hinic_sq_ctxt *sq_ctxt)
     151                 :            : {
     152                 :          0 :         struct hinic_wq *wq = sq->wq;
     153                 :            :         u64 wq_page_addr;
     154                 :            :         u64 wq_page_pfn, wq_block_pfn;
     155                 :            :         u32 wq_page_pfn_hi, wq_page_pfn_lo;
     156                 :            :         u32 wq_block_pfn_hi, wq_block_pfn_lo;
     157                 :            :         u16 pi_start, ci_start;
     158                 :            : 
     159                 :          0 :         ci_start = (u16)(wq->cons_idx);
     160                 :          0 :         pi_start = (u16)(wq->prod_idx);
     161                 :            : 
     162                 :            :         /* read the first page from the HW table */
     163                 :          0 :         wq_page_addr = wq->queue_buf_paddr;
     164                 :            : 
     165                 :          0 :         wq_page_pfn = WQ_PAGE_PFN(wq_page_addr);
     166                 :          0 :         wq_page_pfn_hi = upper_32_bits(wq_page_pfn);
     167                 :          0 :         wq_page_pfn_lo = lower_32_bits(wq_page_pfn);
     168                 :            : 
     169                 :          0 :         wq_block_pfn = WQ_BLOCK_PFN(wq_page_addr);
     170                 :          0 :         wq_block_pfn_hi = upper_32_bits(wq_block_pfn);
     171                 :          0 :         wq_block_pfn_lo = lower_32_bits(wq_block_pfn);
     172                 :            : 
     173                 :            :         /* must config as ceq disabled */
     174                 :          0 :         sq_ctxt->ceq_attr = SQ_CTXT_CEQ_ATTR_SET(global_qpn, GLOBAL_SQ_ID) |
     175                 :            :                                 SQ_CTXT_CEQ_ATTR_SET(0, ARM) |
     176                 :          0 :                                 SQ_CTXT_CEQ_ATTR_SET(0, CEQ_ID) |
     177                 :            :                                 SQ_CTXT_CEQ_ATTR_SET(0, EN);
     178                 :            : 
     179                 :          0 :         sq_ctxt->ci_owner = SQ_CTXT_CI_SET(ci_start, IDX) |
     180                 :            :                                 SQ_CTXT_CI_SET(1, OWNER);
     181                 :            : 
     182                 :          0 :         sq_ctxt->wq_pfn_hi =
     183                 :          0 :                         SQ_CTXT_WQ_PAGE_SET(wq_page_pfn_hi, HI_PFN) |
     184                 :          0 :                         SQ_CTXT_WQ_PAGE_SET(pi_start, PI);
     185                 :            : 
     186                 :          0 :         sq_ctxt->wq_pfn_lo = wq_page_pfn_lo;
     187                 :            : 
     188                 :          0 :         sq_ctxt->pref_cache =
     189                 :            :                 SQ_CTXT_PREF_SET(WQ_PREFETCH_MIN, CACHE_MIN) |
     190                 :            :                 SQ_CTXT_PREF_SET(WQ_PREFETCH_MAX, CACHE_MAX) |
     191                 :            :                 SQ_CTXT_PREF_SET(WQ_PREFETCH_THRESHOLD, CACHE_THRESHOLD);
     192                 :            : 
     193                 :          0 :         sq_ctxt->pref_owner = 1;
     194                 :            : 
     195                 :          0 :         sq_ctxt->pref_wq_pfn_hi_ci =
     196                 :          0 :                 SQ_CTXT_PREF_SET(ci_start, CI) |
     197                 :            :                 SQ_CTXT_PREF_SET(wq_page_pfn_hi, WQ_PFN_HI);
     198                 :            : 
     199                 :          0 :         sq_ctxt->pref_wq_pfn_lo = wq_page_pfn_lo;
     200                 :            : 
     201                 :          0 :         sq_ctxt->wq_block_pfn_hi =
     202                 :            :                 SQ_CTXT_WQ_BLOCK_SET(wq_block_pfn_hi, PFN_HI);
     203                 :            : 
     204                 :          0 :         sq_ctxt->wq_block_pfn_lo = wq_block_pfn_lo;
     205                 :            : 
     206                 :          0 :         hinic_cpu_to_be32(sq_ctxt, sizeof(*sq_ctxt));
     207                 :          0 : }
     208                 :            : 
     209                 :          0 : static void hinic_rq_prepare_ctxt(struct hinic_rq *rq,
     210                 :            :                         struct hinic_rq_ctxt *rq_ctxt)
     211                 :            : {
     212                 :          0 :         struct hinic_wq *wq = rq->wq;
     213                 :            :         u64 wq_page_addr;
     214                 :            :         u64 wq_page_pfn, wq_block_pfn;
     215                 :            :         u32 wq_page_pfn_hi, wq_page_pfn_lo;
     216                 :            :         u32 wq_block_pfn_hi, wq_block_pfn_lo;
     217                 :            :         u16 pi_start, ci_start;
     218                 :            : 
     219                 :          0 :         ci_start = (u16)(wq->cons_idx);
     220                 :          0 :         pi_start = (u16)(wq->prod_idx);
     221                 :            : 
     222                 :            :         /* read the first page from the HW table */
     223                 :          0 :         wq_page_addr = wq->queue_buf_paddr;
     224                 :            : 
     225                 :          0 :         wq_page_pfn = WQ_PAGE_PFN(wq_page_addr);
     226                 :          0 :         wq_page_pfn_hi = upper_32_bits(wq_page_pfn);
     227                 :          0 :         wq_page_pfn_lo = lower_32_bits(wq_page_pfn);
     228                 :            : 
     229                 :          0 :         wq_block_pfn = WQ_BLOCK_PFN(wq_page_addr);
     230                 :          0 :         wq_block_pfn_hi = upper_32_bits(wq_block_pfn);
     231                 :          0 :         wq_block_pfn_lo = lower_32_bits(wq_block_pfn);
     232                 :            : 
     233                 :            :         /* config as ceq disable, but must set msix state disable */
     234                 :          0 :         rq_ctxt->ceq_attr = RQ_CTXT_CEQ_ATTR_SET(0, EN) |
     235                 :            :                             RQ_CTXT_CEQ_ATTR_SET(1, OWNER);
     236                 :            : 
     237                 :          0 :         rq_ctxt->pi_intr_attr = RQ_CTXT_PI_SET(pi_start, IDX) |
     238                 :          0 :                                 RQ_CTXT_PI_SET(rq->msix_entry_idx, INTR) |
     239                 :            :                                 RQ_CTXT_PI_SET(0, CEQ_ARM);
     240                 :            : 
     241                 :          0 :         rq_ctxt->wq_pfn_hi_ci = RQ_CTXT_WQ_PAGE_SET(wq_page_pfn_hi, HI_PFN) |
     242                 :          0 :                                 RQ_CTXT_WQ_PAGE_SET(ci_start, CI);
     243                 :            : 
     244                 :          0 :         rq_ctxt->wq_pfn_lo = wq_page_pfn_lo;
     245                 :            : 
     246                 :          0 :         rq_ctxt->pref_cache =
     247                 :            :                 RQ_CTXT_PREF_SET(WQ_PREFETCH_MIN, CACHE_MIN) |
     248                 :            :                 RQ_CTXT_PREF_SET(WQ_PREFETCH_MAX, CACHE_MAX) |
     249                 :            :                 RQ_CTXT_PREF_SET(WQ_PREFETCH_THRESHOLD, CACHE_THRESHOLD);
     250                 :            : 
     251                 :          0 :         rq_ctxt->pref_owner = 1;
     252                 :            : 
     253                 :          0 :         rq_ctxt->pref_wq_pfn_hi_ci =
     254                 :            :                 RQ_CTXT_PREF_SET(wq_page_pfn_hi, WQ_PFN_HI) |
     255                 :            :                 RQ_CTXT_PREF_SET(ci_start, CI);
     256                 :            : 
     257                 :          0 :         rq_ctxt->pref_wq_pfn_lo = wq_page_pfn_lo;
     258                 :            : 
     259                 :          0 :         rq_ctxt->pi_paddr_hi = upper_32_bits(rq->pi_dma_addr);
     260                 :          0 :         rq_ctxt->pi_paddr_lo = lower_32_bits(rq->pi_dma_addr);
     261                 :            : 
     262                 :          0 :         rq_ctxt->wq_block_pfn_hi =
     263                 :            :                 RQ_CTXT_WQ_BLOCK_SET(wq_block_pfn_hi, PFN_HI);
     264                 :            : 
     265                 :          0 :         rq_ctxt->wq_block_pfn_lo = wq_block_pfn_lo;
     266                 :            : 
     267                 :          0 :         hinic_cpu_to_be32(rq_ctxt, sizeof(*rq_ctxt));
     268                 :          0 : }
     269                 :            : 
     270                 :          0 : static int init_sq_ctxts(struct hinic_nic_io *nic_io)
     271                 :            : {
     272                 :          0 :         struct hinic_hwdev *hwdev = nic_io->hwdev;
     273                 :            :         struct hinic_sq_ctxt_block *sq_ctxt_block;
     274                 :            :         struct hinic_sq_ctxt *sq_ctxt;
     275                 :            :         struct hinic_cmd_buf *cmd_buf;
     276                 :            :         struct hinic_qp *qp;
     277                 :          0 :         u64 out_param = EIO;
     278                 :            :         u16 q_id, curr_id, global_qpn, max_ctxts, i;
     279                 :            :         int err = 0;
     280                 :            : 
     281                 :          0 :         cmd_buf = hinic_alloc_cmd_buf(hwdev);
     282         [ #  # ]:          0 :         if (!cmd_buf) {
     283                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate cmd buf");
     284                 :          0 :                 return -ENOMEM;
     285                 :            :         }
     286                 :            : 
     287                 :            :         q_id = 0;
     288                 :            :         /* sq and rq number may not equal */
     289         [ #  # ]:          0 :         while (q_id < nic_io->num_sqs) {
     290                 :          0 :                 sq_ctxt_block = cmd_buf->buf;
     291                 :          0 :                 sq_ctxt = sq_ctxt_block->sq_ctxt;
     292                 :            : 
     293                 :          0 :                 max_ctxts = (nic_io->num_sqs - q_id) > HINIC_Q_CTXT_MAX ?
     294                 :          0 :                                 HINIC_Q_CTXT_MAX : (nic_io->num_sqs - q_id);
     295                 :            : 
     296                 :          0 :                 hinic_qp_prepare_cmdq_header(&sq_ctxt_block->cmdq_hdr,
     297                 :            :                                              HINIC_QP_CTXT_TYPE_SQ, max_ctxts,
     298                 :          0 :                                              nic_io->max_qps, q_id);
     299                 :            : 
     300         [ #  # ]:          0 :                 for (i = 0; i < max_ctxts; i++) {
     301                 :          0 :                         curr_id = q_id + i;
     302                 :          0 :                         qp = &nic_io->qps[curr_id];
     303                 :          0 :                         global_qpn = nic_io->global_qpn + curr_id;
     304                 :            : 
     305                 :          0 :                         hinic_sq_prepare_ctxt(&qp->sq, global_qpn, &sq_ctxt[i]);
     306                 :            :                 }
     307                 :            : 
     308                 :          0 :                 cmd_buf->size = SQ_CTXT_SIZE(max_ctxts);
     309                 :            : 
     310                 :          0 :                 err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
     311                 :            :                                              HINIC_MOD_L2NIC,
     312                 :            :                                              HINIC_UCODE_CMD_MDY_QUEUE_CONTEXT,
     313                 :            :                                              cmd_buf, &out_param, 0);
     314   [ #  #  #  # ]:          0 :                 if (err || out_param != 0) {
     315                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to set SQ ctxts, err: %d",
     316                 :            :                                 err);
     317                 :            :                         err = -EIO;
     318                 :          0 :                         break;
     319                 :            :                 }
     320                 :            : 
     321                 :          0 :                 q_id += max_ctxts;
     322                 :            :         }
     323                 :            : 
     324                 :          0 :         hinic_free_cmd_buf(hwdev, cmd_buf);
     325                 :            : 
     326                 :          0 :         return err;
     327                 :            : }
     328                 :            : 
     329                 :          0 : static int init_rq_ctxts(struct hinic_nic_io *nic_io)
     330                 :            : {
     331                 :          0 :         struct hinic_hwdev *hwdev = nic_io->hwdev;
     332                 :            :         struct hinic_rq_ctxt_block *rq_ctxt_block;
     333                 :            :         struct hinic_rq_ctxt *rq_ctxt;
     334                 :            :         struct hinic_cmd_buf *cmd_buf;
     335                 :            :         struct hinic_qp *qp;
     336                 :          0 :         u64 out_param = 0;
     337                 :            :         u16 q_id, curr_id, max_ctxts, i;
     338                 :            :         int err = 0;
     339                 :            : 
     340                 :          0 :         cmd_buf = hinic_alloc_cmd_buf(hwdev);
     341         [ #  # ]:          0 :         if (!cmd_buf) {
     342                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate cmd buf");
     343                 :          0 :                 return -ENOMEM;
     344                 :            :         }
     345                 :            : 
     346                 :            :         q_id = 0;
     347                 :            :         /* sq and rq number may not equal */
     348         [ #  # ]:          0 :         while (q_id < nic_io->num_rqs) {
     349                 :          0 :                 rq_ctxt_block = cmd_buf->buf;
     350                 :          0 :                 rq_ctxt = rq_ctxt_block->rq_ctxt;
     351                 :            : 
     352                 :          0 :                 max_ctxts = (nic_io->num_rqs - q_id) > HINIC_Q_CTXT_MAX ?
     353                 :          0 :                                 HINIC_Q_CTXT_MAX : (nic_io->num_rqs - q_id);
     354                 :            : 
     355                 :          0 :                 hinic_qp_prepare_cmdq_header(&rq_ctxt_block->cmdq_hdr,
     356                 :            :                                              HINIC_QP_CTXT_TYPE_RQ, max_ctxts,
     357                 :          0 :                                              nic_io->max_qps, q_id);
     358                 :            : 
     359         [ #  # ]:          0 :                 for (i = 0; i < max_ctxts; i++) {
     360                 :          0 :                         curr_id = q_id + i;
     361                 :          0 :                         qp = &nic_io->qps[curr_id];
     362                 :            : 
     363                 :          0 :                         hinic_rq_prepare_ctxt(&qp->rq, &rq_ctxt[i]);
     364                 :            :                 }
     365                 :            : 
     366                 :          0 :                 cmd_buf->size = RQ_CTXT_SIZE(max_ctxts);
     367                 :            : 
     368                 :          0 :                 err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
     369                 :            :                                              HINIC_MOD_L2NIC,
     370                 :            :                                              HINIC_UCODE_CMD_MDY_QUEUE_CONTEXT,
     371                 :            :                                              cmd_buf, &out_param, 0);
     372   [ #  #  #  # ]:          0 :                 if ((err) || out_param != 0) {
     373                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to set RQ ctxts");
     374                 :            :                         err = -EIO;
     375                 :          0 :                         break;
     376                 :            :                 }
     377                 :            : 
     378                 :          0 :                 q_id += max_ctxts;
     379                 :            :         }
     380                 :            : 
     381                 :          0 :         hinic_free_cmd_buf(hwdev, cmd_buf);
     382                 :            : 
     383                 :          0 :         return err;
     384                 :            : }
     385                 :            : 
     386                 :          0 : static int init_qp_ctxts(struct hinic_nic_io *nic_io)
     387                 :            : {
     388   [ #  #  #  # ]:          0 :         return (init_sq_ctxts(nic_io) || init_rq_ctxts(nic_io));
     389                 :            : }
     390                 :            : 
     391                 :          0 : static int clean_queue_offload_ctxt(struct hinic_nic_io *nic_io,
     392                 :            :                                     enum hinic_qp_ctxt_type ctxt_type)
     393                 :            : {
     394                 :          0 :         struct hinic_hwdev *hwdev = nic_io->hwdev;
     395                 :            :         struct hinic_clean_queue_ctxt *ctxt_block;
     396                 :            :         struct hinic_cmd_buf *cmd_buf;
     397                 :          0 :         u64 out_param = 0;
     398                 :            :         int err;
     399                 :            : 
     400                 :          0 :         cmd_buf = hinic_alloc_cmd_buf(hwdev);
     401         [ #  # ]:          0 :         if (!cmd_buf) {
     402                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate cmd buf");
     403                 :          0 :                 return -ENOMEM;
     404                 :            :         }
     405                 :            : 
     406                 :          0 :         ctxt_block = cmd_buf->buf;
     407                 :          0 :         ctxt_block->cmdq_hdr.num_queues = nic_io->max_qps;
     408                 :          0 :         ctxt_block->cmdq_hdr.queue_type = ctxt_type;
     409                 :          0 :         ctxt_block->cmdq_hdr.addr_offset = 0;
     410                 :            : 
     411                 :            :         /* TSO/LRO ctxt size: 0x0:0B; 0x1:160B; 0x2:200B; 0x3:240B */
     412                 :          0 :         ctxt_block->ctxt_size = 0x3;
     413                 :            : 
     414                 :          0 :         hinic_cpu_to_be32(ctxt_block, sizeof(*ctxt_block));
     415                 :            : 
     416                 :          0 :         cmd_buf->size = sizeof(*ctxt_block);
     417                 :            : 
     418                 :          0 :         err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
     419                 :            :                                      HINIC_MOD_L2NIC,
     420                 :            :                                      HINIC_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
     421                 :            :                                      cmd_buf, &out_param, 0);
     422                 :            : 
     423   [ #  #  #  # ]:          0 :         if ((err) || (out_param)) {
     424                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to clean queue offload ctxts");
     425                 :            :                 err = -EIO;
     426                 :            :         }
     427                 :            : 
     428                 :          0 :         hinic_free_cmd_buf(hwdev, cmd_buf);
     429                 :            : 
     430                 :          0 :         return err;
     431                 :            : }
     432                 :            : 
     433                 :          0 : static int clean_qp_offload_ctxt(struct hinic_nic_io *nic_io)
     434                 :            : {
     435                 :            :         /* clean LRO/TSO context space */
     436   [ #  #  #  # ]:          0 :         return (clean_queue_offload_ctxt(nic_io, HINIC_QP_CTXT_TYPE_SQ) ||
     437                 :          0 :                 clean_queue_offload_ctxt(nic_io, HINIC_QP_CTXT_TYPE_RQ));
     438                 :            : }
     439                 :            : 
     440                 :            : /**
     441                 :            :  * get_hw_rx_buf_size - translate rx_buf_size into hw_rx_buf_size
     442                 :            :  * @rx_buf_sz: receive buffer size
     443                 :            :  * @return
     444                 :            :  *   hw rx buffer size
     445                 :            :  */
     446                 :          0 : static u16 get_hw_rx_buf_size(u32 rx_buf_sz)
     447                 :            : {
     448                 :            :         u16 num_hw_types = sizeof(hinic_hw_rx_buf_size)
     449                 :            :                            / sizeof(hinic_hw_rx_buf_size[0]);
     450                 :            :         u16 i;
     451                 :            : 
     452         [ #  # ]:          0 :         for (i = 0; i < num_hw_types; i++) {
     453         [ #  # ]:          0 :                 if (hinic_hw_rx_buf_size[i] == rx_buf_sz)
     454                 :          0 :                         return i;
     455                 :            :         }
     456                 :            : 
     457                 :          0 :         PMD_DRV_LOG(ERR, "Hw can't support rx buf size of %u", rx_buf_sz);
     458                 :            : 
     459                 :          0 :         return DEFAULT_RX_BUF_SIZE;     /* default 2K */
     460                 :            : }
     461                 :            : 
     462                 :            : /**
     463                 :            :  * hinic_set_root_ctxt - init root context in NIC
     464                 :            :  * @hwdev: the hardware interface of a nic device
     465                 :            :  * @rq_depth: the depth of receive queue
     466                 :            :  * @sq_depth: the depth of transmit queue
     467                 :            :  * @rx_buf_sz: receive buffer size from app
     468                 :            :  * Return: 0 on success, negative error value otherwise.
     469                 :            :  */
     470                 :            : static int
     471                 :          0 : hinic_set_root_ctxt(void *hwdev, u16 rq_depth, u16 sq_depth, int rx_buf_sz)
     472                 :            : {
     473                 :            :         struct hinic_root_ctxt root_ctxt;
     474                 :          0 :         u16 out_size = sizeof(root_ctxt);
     475                 :            :         int err;
     476                 :            : 
     477                 :            :         memset(&root_ctxt, 0, sizeof(root_ctxt));
     478                 :          0 :         root_ctxt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
     479                 :          0 :         root_ctxt.func_idx = hinic_global_func_id(hwdev);
     480                 :          0 :         root_ctxt.ppf_idx = hinic_ppf_idx(hwdev);
     481                 :          0 :         root_ctxt.set_cmdq_depth = 0;
     482                 :          0 :         root_ctxt.cmdq_depth = 0;
     483                 :          0 :         root_ctxt.lro_en = 1;
     484                 :          0 :         root_ctxt.rq_depth  = (u16)ilog2(rq_depth);
     485                 :          0 :         root_ctxt.rx_buf_sz = get_hw_rx_buf_size(rx_buf_sz);
     486                 :          0 :         root_ctxt.sq_depth  = (u16)ilog2(sq_depth);
     487                 :            : 
     488                 :          0 :         err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
     489                 :            :                                      HINIC_MGMT_CMD_VAT_SET,
     490                 :            :                                      &root_ctxt, sizeof(root_ctxt),
     491                 :            :                                      &root_ctxt, &out_size, 0);
     492   [ #  #  #  #  :          0 :         if (err || !out_size || root_ctxt.mgmt_msg_head.status) {
                   #  # ]
     493                 :          0 :                 PMD_DRV_LOG(ERR,
     494                 :            :                         "Set root context failed, err: %d, status: 0x%x, out_size: 0x%x",
     495                 :            :                         err, root_ctxt.mgmt_msg_head.status, out_size);
     496                 :          0 :                 return -EIO;
     497                 :            :         }
     498                 :            : 
     499                 :            :         return 0;
     500                 :            : }
     501                 :            : 
     502                 :            : /**
     503                 :            :  * hinic_clean_root_ctxt - clean root context table in NIC
     504                 :            :  * @hwdev: the hardware interface of a nic device
     505                 :            :  * @return
     506                 :            :  *   0 on success,
     507                 :            :  *   negative error value otherwise.
     508                 :            :  */
     509                 :          0 : static int hinic_clean_root_ctxt(void *hwdev)
     510                 :            : {
     511                 :            :         struct hinic_root_ctxt root_ctxt;
     512                 :          0 :         u16 out_size = sizeof(root_ctxt);
     513                 :            :         int err;
     514                 :            : 
     515                 :            :         memset(&root_ctxt, 0, sizeof(root_ctxt));
     516                 :          0 :         root_ctxt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
     517                 :          0 :         root_ctxt.func_idx = hinic_global_func_id(hwdev);
     518                 :          0 :         root_ctxt.ppf_idx = hinic_ppf_idx(hwdev);
     519                 :          0 :         root_ctxt.set_cmdq_depth = 0;
     520                 :          0 :         root_ctxt.cmdq_depth = 0;
     521                 :          0 :         root_ctxt.lro_en = 0;
     522                 :          0 :         root_ctxt.rq_depth  = 0;
     523                 :          0 :         root_ctxt.rx_buf_sz = 0;
     524                 :          0 :         root_ctxt.sq_depth  = 0;
     525                 :            : 
     526                 :          0 :         err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
     527                 :            :                                      HINIC_MGMT_CMD_VAT_SET,
     528                 :            :                                      &root_ctxt, sizeof(root_ctxt),
     529                 :            :                                      &root_ctxt, &out_size, 0);
     530   [ #  #  #  #  :          0 :         if (err || !out_size || root_ctxt.mgmt_msg_head.status) {
                   #  # ]
     531                 :          0 :                 PMD_DRV_LOG(ERR,
     532                 :            :                         "Clean root context failed, err: %d, status: 0x%x, out_size: 0x%x",
     533                 :            :                         err, root_ctxt.mgmt_msg_head.status, out_size);
     534                 :          0 :                 return -EIO;
     535                 :            :         }
     536                 :            : 
     537                 :            :         return 0;
     538                 :            : }
     539                 :            : 
     540                 :            : /* init qps ctxt and set sq ci attr and arm all sq and set vat page_size */
     541                 :          0 : int hinic_init_qp_ctxts(struct hinic_hwdev *hwdev)
     542                 :            : {
     543                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     544                 :            :         struct hinic_sq_attr sq_attr;
     545                 :            :         u16 q_id;
     546                 :            :         int err, rx_buf_sz;
     547                 :            : 
     548                 :            :         /* set vat page size to max queue depth page_size */
     549                 :          0 :         err = hinic_set_pagesize(hwdev, HINIC_PAGE_SIZE_DPDK);
     550         [ #  # ]:          0 :         if (err != HINIC_OK) {
     551                 :          0 :                 PMD_DRV_LOG(ERR, "Set vat page size: %d failed, rc: %d",
     552                 :            :                         HINIC_PAGE_SIZE_DPDK, err);
     553                 :          0 :                 return err;
     554                 :            :         }
     555                 :            : 
     556         [ #  # ]:          0 :         if (hwdev->cmdqs->status & HINIC_CMDQ_SET_FAIL) {
     557                 :          0 :                 err = hinic_reinit_cmdq_ctxts(hwdev);
     558         [ #  # ]:          0 :                 if (err) {
     559                 :          0 :                         PMD_DRV_LOG(ERR, "Reinit cmdq context failed when dev start, err: %d",
     560                 :            :                                 err);
     561                 :          0 :                         return err;
     562                 :            :                 }
     563                 :            :         }
     564                 :            : 
     565                 :          0 :         err = init_qp_ctxts(nic_io);
     566         [ #  # ]:          0 :         if (err) {
     567                 :          0 :                 PMD_DRV_LOG(ERR, "Init QP ctxts failed, rc: %d", err);
     568                 :          0 :                 return err;
     569                 :            :         }
     570                 :            : 
     571                 :            :         /* clean LRO/TSO context space */
     572                 :          0 :         err = clean_qp_offload_ctxt(nic_io);
     573         [ #  # ]:          0 :         if (err) {
     574                 :          0 :                 PMD_DRV_LOG(ERR, "Clean qp offload ctxts failed, rc: %d", err);
     575                 :          0 :                 return err;
     576                 :            :         }
     577                 :            : 
     578                 :          0 :         rx_buf_sz = nic_io->rq_buf_size;
     579                 :            : 
     580                 :            :         /* update rx buf size to function table */
     581                 :          0 :         err = hinic_set_rx_vhd_mode(hwdev, HINIC_VHD_TYPE_0B, rx_buf_sz);
     582         [ #  # ]:          0 :         if (err) {
     583                 :          0 :                 PMD_DRV_LOG(ERR, "Set rx vhd mode failed, rc: %d", err);
     584                 :          0 :                 return err;
     585                 :            :         }
     586                 :            : 
     587                 :          0 :         err = hinic_set_root_ctxt(hwdev, nic_io->rq_depth,
     588                 :          0 :                                   nic_io->sq_depth, rx_buf_sz);
     589         [ #  # ]:          0 :         if (err) {
     590                 :          0 :                 PMD_DRV_LOG(ERR, "Set root context failed, rc: %d", err);
     591                 :          0 :                 return err;
     592                 :            :         }
     593                 :            : 
     594         [ #  # ]:          0 :         for (q_id = 0; q_id < nic_io->num_sqs; q_id++) {
     595                 :          0 :                 sq_attr.ci_dma_base =
     596                 :          0 :                         HINIC_CI_PADDR(nic_io->ci_dma_base, q_id) >> 2;
     597                 :            :                 /* performance: sq ci update threshold as 8 */
     598                 :          0 :                 sq_attr.pending_limit = 1;
     599                 :          0 :                 sq_attr.coalescing_time = 1;
     600                 :          0 :                 sq_attr.intr_en = 0;
     601                 :          0 :                 sq_attr.l2nic_sqn = q_id;
     602                 :          0 :                 sq_attr.dma_attr_off = 0;
     603                 :          0 :                 err = hinic_set_ci_table(hwdev, q_id, &sq_attr);
     604         [ #  # ]:          0 :                 if (err) {
     605                 :          0 :                         PMD_DRV_LOG(ERR, "Set ci table failed, rc: %d", err);
     606                 :          0 :                         goto set_cons_idx_table_err;
     607                 :            :                 }
     608                 :            :         }
     609                 :            : 
     610                 :            :         return 0;
     611                 :            : 
     612                 :            : set_cons_idx_table_err:
     613                 :          0 :         (void)hinic_clean_root_ctxt(hwdev);
     614                 :          0 :         return err;
     615                 :            : }
     616                 :            : 
     617                 :          0 : void hinic_free_qp_ctxts(struct hinic_hwdev *hwdev)
     618                 :            : {
     619                 :            :         int err;
     620                 :            : 
     621                 :          0 :         err = hinic_clean_root_ctxt(hwdev);
     622         [ #  # ]:          0 :         if (err)
     623                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to clean root ctxt");
     624                 :          0 : }
     625                 :            : 
     626                 :          0 : static int hinic_init_nic_hwdev(struct hinic_hwdev *hwdev)
     627                 :            : {
     628                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     629                 :            :         u16 global_qpn, rx_buf_sz;
     630                 :            :         int err;
     631                 :            : 
     632                 :          0 :         err = hinic_get_base_qpn(hwdev, &global_qpn);
     633         [ #  # ]:          0 :         if (err) {
     634                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to get base qpn");
     635                 :          0 :                 goto err_init_nic_hwdev;
     636                 :            :         }
     637                 :            : 
     638                 :          0 :         nic_io->global_qpn = global_qpn;
     639         [ #  # ]:          0 :         rx_buf_sz = HINIC_IS_VF(hwdev) ? RX_BUF_LEN_1_5K : RX_BUF_LEN_16K;
     640                 :          0 :         err = hinic_init_function_table(hwdev, rx_buf_sz);
     641         [ #  # ]:          0 :         if (err) {
     642                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to init function table");
     643                 :          0 :                 goto err_init_nic_hwdev;
     644                 :            :         }
     645                 :            : 
     646                 :          0 :         err = hinic_vf_func_init(hwdev);
     647         [ #  # ]:          0 :         if (err) {
     648                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to init nic mbox");
     649                 :          0 :                 goto err_init_nic_hwdev;
     650                 :            :         }
     651                 :            : 
     652                 :          0 :         err = hinic_set_fast_recycle_mode(hwdev, RECYCLE_MODE_DPDK);
     653         [ #  # ]:          0 :         if (err) {
     654                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to set fast recycle mode");
     655                 :          0 :                 goto err_init_nic_hwdev;
     656                 :            :         }
     657                 :            : 
     658                 :            :         return 0;
     659                 :            : 
     660                 :            : err_init_nic_hwdev:
     661                 :            :         return err;
     662                 :            : }
     663                 :            : 
     664                 :            : static void hinic_free_nic_hwdev(struct hinic_hwdev *hwdev)
     665                 :            : {
     666                 :          0 :         hinic_vf_func_free(hwdev);
     667                 :            : }
     668                 :            : 
     669                 :          0 : int hinic_rx_tx_flush(struct hinic_hwdev *hwdev)
     670                 :            : {
     671                 :          0 :         return hinic_func_rx_tx_flush(hwdev);
     672                 :            : }
     673                 :            : 
     674                 :          0 : int hinic_get_sq_free_wqebbs(struct hinic_hwdev *hwdev, u16 q_id)
     675                 :            : {
     676                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     677                 :          0 :         struct hinic_wq *wq = &nic_io->sq_wq[q_id];
     678                 :            : 
     679                 :          0 :         return (wq->delta) - 1;
     680                 :            : }
     681                 :            : 
     682                 :          0 : int hinic_get_rq_free_wqebbs(struct hinic_hwdev *hwdev, u16 q_id)
     683                 :            : {
     684                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     685                 :          0 :         struct hinic_wq *wq = &nic_io->rq_wq[q_id];
     686                 :            : 
     687                 :          0 :         return (wq->delta) - 1;
     688                 :            : }
     689                 :            : 
     690                 :          0 : u16 hinic_get_sq_local_ci(struct hinic_hwdev *hwdev, u16 q_id)
     691                 :            : {
     692                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     693                 :          0 :         struct hinic_wq *wq = &nic_io->sq_wq[q_id];
     694                 :            : 
     695                 :          0 :         return (wq->cons_idx) & wq->mask;
     696                 :            : }
     697                 :            : 
     698                 :          0 : void hinic_return_sq_wqe(struct hinic_hwdev *hwdev, u16 q_id,
     699                 :            :                          int num_wqebbs, u16 owner)
     700                 :            : {
     701                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     702                 :          0 :         struct hinic_sq *sq = &nic_io->qps[q_id].sq;
     703                 :            : 
     704         [ #  # ]:          0 :         if (owner != sq->owner)
     705                 :          0 :                 sq->owner = owner;
     706                 :            : 
     707                 :          0 :         sq->wq->delta += num_wqebbs;
     708                 :          0 :         sq->wq->prod_idx -= num_wqebbs;
     709                 :          0 : }
     710                 :            : 
     711                 :          0 : void hinic_update_sq_local_ci(struct hinic_hwdev *hwdev,
     712                 :            :                               u16 q_id, int wqebb_cnt)
     713                 :            : {
     714                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     715                 :          0 :         struct hinic_sq *sq = &nic_io->qps[q_id].sq;
     716                 :            : 
     717                 :          0 :         hinic_put_wqe(sq->wq, wqebb_cnt);
     718                 :          0 : }
     719                 :            : 
     720                 :          0 : void *hinic_get_rq_wqe(struct hinic_hwdev *hwdev, u16 q_id, u16 *pi)
     721                 :            : {
     722                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     723                 :          0 :         struct hinic_rq *rq = &nic_io->qps[q_id].rq;
     724                 :            : 
     725                 :          0 :         return hinic_get_wqe(rq->wq, 1, pi);
     726                 :            : }
     727                 :            : 
     728                 :          0 : void hinic_return_rq_wqe(struct hinic_hwdev *hwdev, u16 q_id, int num_wqebbs)
     729                 :            : {
     730                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     731                 :          0 :         struct hinic_rq *rq = &nic_io->qps[q_id].rq;
     732                 :            : 
     733                 :          0 :         rq->wq->delta += num_wqebbs;
     734                 :          0 :         rq->wq->prod_idx -= num_wqebbs;
     735                 :          0 : }
     736                 :            : 
     737                 :          0 : u16 hinic_get_rq_local_ci(struct hinic_hwdev *hwdev, u16 q_id)
     738                 :            : {
     739                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     740                 :          0 :         struct hinic_wq *wq = &nic_io->rq_wq[q_id];
     741                 :            : 
     742                 :          0 :         return (wq->cons_idx) & wq->mask;
     743                 :            : }
     744                 :            : 
     745                 :          0 : void hinic_update_rq_local_ci(struct hinic_hwdev *hwdev, u16 q_id, int wqe_cnt)
     746                 :            : {
     747                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     748                 :          0 :         struct hinic_rq *rq = &nic_io->qps[q_id].rq;
     749                 :            : 
     750                 :          0 :         hinic_put_wqe(rq->wq, wqe_cnt);
     751                 :          0 : }
     752                 :            : 
     753                 :          0 : static int hinic_alloc_nicio(struct hinic_hwdev *hwdev)
     754                 :            : {
     755                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     756                 :          0 :         struct rte_pci_device *pdev = hwdev->pcidev_hdl;
     757                 :            :         u16 max_qps, num_qp;
     758                 :            :         int err;
     759                 :            : 
     760                 :          0 :         max_qps = hinic_func_max_qnum(hwdev);
     761                 :            : 
     762                 :          0 :         nic_io->max_qps = max_qps;
     763                 :          0 :         nic_io->num_qps = max_qps;
     764                 :            :         num_qp = max_qps;
     765                 :            : 
     766                 :          0 :         nic_io->qps = kzalloc_aligned(num_qp * sizeof(*nic_io->qps),
     767                 :            :                                       GFP_KERNEL);
     768         [ #  # ]:          0 :         if (!nic_io->qps) {
     769                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate qps");
     770                 :            :                 err = -ENOMEM;
     771                 :          0 :                 goto alloc_qps_err;
     772                 :            :         }
     773                 :            : 
     774                 :          0 :         nic_io->ci_vaddr_base = dma_zalloc_coherent(hwdev,
     775                 :          0 :                                     CI_TABLE_SIZE(num_qp, HINIC_PAGE_SIZE),
     776                 :            :                                     &nic_io->ci_dma_base,
     777                 :          0 :                                     pdev->device.numa_node);
     778         [ #  # ]:          0 :         if (!nic_io->ci_vaddr_base) {
     779                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate ci area");
     780                 :            :                 err = -ENOMEM;
     781                 :          0 :                 goto ci_base_err;
     782                 :            :         }
     783                 :            : 
     784                 :          0 :         nic_io->sq_wq = kzalloc_aligned(num_qp * sizeof(*nic_io->sq_wq),
     785                 :            :                                         GFP_KERNEL);
     786         [ #  # ]:          0 :         if (!nic_io->sq_wq) {
     787                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate sq wq array");
     788                 :            :                 err = -ENOMEM;
     789                 :          0 :                 goto sq_wq_err;
     790                 :            :         }
     791                 :            : 
     792                 :          0 :         nic_io->rq_wq = kzalloc_aligned(num_qp * sizeof(*nic_io->rq_wq),
     793                 :            :                                         GFP_KERNEL);
     794         [ #  # ]:          0 :         if (!nic_io->rq_wq) {
     795                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate rq wq array");
     796                 :            :                 err = -ENOMEM;
     797                 :          0 :                 goto rq_wq_err;
     798                 :            :         }
     799                 :            : 
     800                 :            :         return HINIC_OK;
     801                 :            : 
     802                 :            : rq_wq_err:
     803                 :          0 :         kfree(nic_io->sq_wq);
     804                 :            : 
     805                 :          0 : sq_wq_err:
     806                 :          0 :         dma_free_coherent(hwdev, CI_TABLE_SIZE(num_qp, HINIC_PAGE_SIZE),
     807                 :            :                           nic_io->ci_vaddr_base, nic_io->ci_dma_base);
     808                 :            : 
     809                 :          0 : ci_base_err:
     810                 :          0 :         kfree(nic_io->qps);
     811                 :            : 
     812                 :            : alloc_qps_err:
     813                 :            :         return err;
     814                 :            : }
     815                 :            : 
     816                 :          0 : static void hinic_free_nicio(struct hinic_hwdev *hwdev)
     817                 :            : {
     818                 :          0 :         struct hinic_nic_io *nic_io = hwdev->nic_io;
     819                 :            : 
     820                 :            :         /* nic_io->rq_wq */
     821                 :          0 :         kfree(nic_io->rq_wq);
     822                 :            : 
     823                 :            :         /* nic_io->sq_wq */
     824                 :          0 :         kfree(nic_io->sq_wq);
     825                 :            : 
     826                 :            :         /* nic_io->ci_vaddr_base */
     827                 :          0 :         dma_free_coherent(hwdev,
     828                 :          0 :                           CI_TABLE_SIZE(nic_io->max_qps, HINIC_PAGE_SIZE),
     829                 :            :                           nic_io->ci_vaddr_base, nic_io->ci_dma_base);
     830                 :            : 
     831                 :            :         /* nic_io->qps */
     832                 :          0 :         kfree(nic_io->qps);
     833                 :          0 : }
     834                 :            : 
     835                 :            : /* alloc nic hwdev and init function table */
     836                 :          0 : int hinic_init_nicio(struct hinic_hwdev *hwdev)
     837                 :            : {
     838                 :            :         int rc;
     839                 :            : 
     840                 :          0 :         hwdev->nic_io = rte_zmalloc("hinic_nicio", sizeof(*hwdev->nic_io),
     841                 :            :                                       RTE_CACHE_LINE_SIZE);
     842         [ #  # ]:          0 :         if (!hwdev->nic_io) {
     843                 :          0 :                 PMD_DRV_LOG(ERR, "Allocate nic_io failed, dev_name: %s",
     844                 :            :                             hwdev->pcidev_hdl->name);
     845                 :          0 :                 return -ENOMEM;
     846                 :            :         }
     847                 :          0 :         hwdev->nic_io->hwdev = hwdev;
     848                 :            : 
     849                 :            :         /* alloc root working queue set */
     850                 :          0 :         rc = hinic_alloc_nicio(hwdev);
     851         [ #  # ]:          0 :         if (rc) {
     852                 :          0 :                 PMD_DRV_LOG(ERR, "Allocate nic_io failed, dev_name: %s",
     853                 :            :                             hwdev->pcidev_hdl->name);
     854                 :          0 :                 goto allc_nicio_fail;
     855                 :            :         }
     856                 :            : 
     857                 :          0 :         rc = hinic_init_nic_hwdev(hwdev);
     858         [ #  # ]:          0 :         if (rc) {
     859                 :          0 :                 PMD_DRV_LOG(ERR, "Initialize hwdev failed, dev_name: %s",
     860                 :            :                             hwdev->pcidev_hdl->name);
     861                 :          0 :                 goto init_nic_hwdev_fail;
     862                 :            :         }
     863                 :            : 
     864                 :            :         return 0;
     865                 :            : 
     866                 :            : init_nic_hwdev_fail:
     867                 :          0 :         hinic_free_nicio(hwdev);
     868                 :            : 
     869                 :          0 : allc_nicio_fail:
     870                 :          0 :         rte_free(hwdev->nic_io);
     871                 :          0 :         return rc;
     872                 :            : }
     873                 :            : 
     874                 :          0 : void hinic_deinit_nicio(struct hinic_hwdev *hwdev)
     875                 :            : {
     876                 :          0 :         hinic_free_nicio(hwdev);
     877                 :            : 
     878                 :            :         hinic_free_nic_hwdev(hwdev);
     879                 :            : 
     880                 :          0 :         rte_free(hwdev->nic_io);
     881                 :          0 :         hwdev->nic_io = NULL;
     882                 :          0 : }
     883                 :            : 
     884                 :            : /**
     885                 :            :  * hinic_convert_rx_buf_size - convert rx buffer size to hw size
     886                 :            :  * @rx_buf_sz: receive buffer size of mbuf
     887                 :            :  * @match_sz: receive buffer size of hardware
     888                 :            :  * @return
     889                 :            :  *   0 on success,
     890                 :            :  *   negative error value otherwise.
     891                 :            :  */
     892                 :          0 : int hinic_convert_rx_buf_size(u32 rx_buf_sz, u32 *match_sz)
     893                 :            : {
     894                 :            :         u32 i, num_hw_types, best_match_sz;
     895                 :            : 
     896         [ #  # ]:          0 :         if (unlikely(!match_sz || rx_buf_sz < HINIC_RX_BUF_SIZE_32B))
     897                 :            :                 return -EINVAL;
     898                 :            : 
     899         [ #  # ]:          0 :         if (rx_buf_sz >= HINIC_RX_BUF_SIZE_16K) {
     900                 :            :                 best_match_sz =  HINIC_RX_BUF_SIZE_16K;
     901                 :          0 :                 goto size_matched;
     902                 :            :         }
     903                 :            : 
     904                 :            :         num_hw_types = sizeof(hinic_hw_rx_buf_size) /
     905                 :            :                 sizeof(hinic_hw_rx_buf_size[0]);
     906                 :            :         best_match_sz = hinic_hw_rx_buf_size[0];
     907         [ #  # ]:          0 :         for (i = 0; i < num_hw_types; i++) {
     908         [ #  # ]:          0 :                 if (rx_buf_sz == hinic_hw_rx_buf_size[i]) {
     909                 :            :                         best_match_sz = hinic_hw_rx_buf_size[i];
     910                 :            :                         break;
     911         [ #  # ]:          0 :                 } else if (rx_buf_sz < hinic_hw_rx_buf_size[i]) {
     912                 :            :                         break;
     913                 :            :                 }
     914                 :            :                 best_match_sz = hinic_hw_rx_buf_size[i];
     915                 :            :         }
     916                 :            : 
     917                 :          0 : size_matched:
     918                 :          0 :         *match_sz = best_match_sz;
     919                 :            : 
     920                 :          0 :         return 0;
     921                 :            : }

Generated by: LCOV version 1.14