LCOV - code coverage report
Current view: top level - drivers/net/xsc - xsc_np.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 163 0.0 %
Date: 2025-03-01 20:23:48 Functions: 0 20 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 56 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2025 Yunsilicon Technology Co., Ltd.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_bitmap.h>
       6                 :            : #include <rte_malloc.h>
       7                 :            : 
       8                 :            : #include "xsc_log.h"
       9                 :            : #include "xsc_defs.h"
      10                 :            : #include "xsc_np.h"
      11                 :            : #include "xsc_cmd.h"
      12                 :            : #include "xsc_dev.h"
      13                 :            : 
      14                 :            : #define XSC_RSS_HASH_FUNC_TOPELIZ       0x1
      15                 :            : #define XSC_LOGIC_PORT_MASK             0x07FF
      16                 :            : 
      17                 :            : #define XSC_DEV_DEF_PCT_IDX_MIN         128
      18                 :            : #define XSC_DEV_DEF_PCT_IDX_MAX         138
      19                 :            : 
      20                 :            : /* Each board has a PCT manager*/
      21                 :            : static struct xsc_dev_pct_mgr xsc_pct_mgr;
      22                 :            : 
      23                 :            : enum xsc_np_type {
      24                 :            :         XSC_NP_IPAT             = 0,
      25                 :            :         XSC_NP_PCT_V4           = 4,
      26                 :            :         XSC_NP_EPAT             = 19,
      27                 :            :         XSC_NP_VFOS             = 31,
      28                 :            :         XSC_NP_PG_QP_SET_ID     = 41,
      29                 :            :         XSC_NP_MAX
      30                 :            : };
      31                 :            : 
      32                 :            : enum xsc_np_opcode {
      33                 :            :         XSC_NP_OP_ADD,
      34                 :            :         XSC_NP_OP_DEL,
      35                 :            :         XSC_NP_OP_GET,
      36                 :            :         XSC_NP_OP_CLR,
      37                 :            :         XSC_NP_OP_MOD,
      38                 :            :         XSC_NP_OP_MAX
      39                 :            : };
      40                 :            : 
      41                 :            : struct xsc_np_mbox_in {
      42                 :            :         struct xsc_cmd_inbox_hdr hdr;
      43                 :            :         rte_be16_t len;
      44                 :            :         rte_be16_t rsvd;
      45                 :            :         uint8_t data[];
      46                 :            : };
      47                 :            : 
      48                 :            : struct xsc_np_mbox_out {
      49                 :            :         struct xsc_cmd_outbox_hdr hdr;
      50                 :            :         rte_be32_t error;
      51                 :            :         rte_be16_t len;
      52                 :            :         rte_be16_t rsvd;
      53                 :            :         uint8_t data[];
      54                 :            : };
      55                 :            : 
      56                 :            : struct xsc_np_data_tl {
      57                 :            :         uint16_t table;
      58                 :            :         uint16_t opmod;
      59                 :            :         uint16_t length;
      60                 :            :         uint16_t rsvd;
      61                 :            : };
      62                 :            : 
      63                 :            : enum xsc_hash_tmpl {
      64                 :            :         XSC_HASH_TMPL_IDX_IP_PORTS_IP6_PORTS = 0,
      65                 :            :         XSC_HASH_TMPL_IDX_IP_IP6,
      66                 :            :         XSC_HASH_TMPL_IDX_IP_PORTS_IP6,
      67                 :            :         XSC_HASH_TMPL_IDX_IP_IP6_PORTS,
      68                 :            :         XSC_HASH_TMPL_IDX_MAX,
      69                 :            : };
      70                 :            : 
      71                 :            : static const int xsc_rss_hash_tmplate[XSC_HASH_TMPL_IDX_MAX] = {
      72                 :            :         XSC_RSS_HASH_BIT_IPV4_SIP | XSC_RSS_HASH_BIT_IPV4_DIP |
      73                 :            :         XSC_RSS_HASH_BIT_IPV6_SIP | XSC_RSS_HASH_BIT_IPV6_DIP |
      74                 :            :         XSC_RSS_HASH_BIT_IPV4_SPORT | XSC_RSS_HASH_BIT_IPV4_DPORT |
      75                 :            :         XSC_RSS_HASH_BIT_IPV6_SPORT | XSC_RSS_HASH_BIT_IPV6_DPORT,
      76                 :            : 
      77                 :            :         XSC_RSS_HASH_BIT_IPV4_SIP | XSC_RSS_HASH_BIT_IPV4_DIP |
      78                 :            :         XSC_RSS_HASH_BIT_IPV6_SIP | XSC_RSS_HASH_BIT_IPV6_DIP,
      79                 :            : 
      80                 :            :         XSC_RSS_HASH_BIT_IPV4_SIP | XSC_RSS_HASH_BIT_IPV4_DIP |
      81                 :            :         XSC_RSS_HASH_BIT_IPV6_SIP | XSC_RSS_HASH_BIT_IPV6_DIP |
      82                 :            :         XSC_RSS_HASH_BIT_IPV4_SPORT | XSC_RSS_HASH_BIT_IPV4_DPORT,
      83                 :            : 
      84                 :            :         XSC_RSS_HASH_BIT_IPV4_SIP | XSC_RSS_HASH_BIT_IPV4_DIP |
      85                 :            :         XSC_RSS_HASH_BIT_IPV6_SIP | XSC_RSS_HASH_BIT_IPV6_DIP |
      86                 :            :         XSC_RSS_HASH_BIT_IPV6_SPORT | XSC_RSS_HASH_BIT_IPV6_DPORT,
      87                 :            : };
      88                 :            : 
      89                 :            : static uint8_t
      90                 :          0 : xsc_rss_hash_template_get(struct rte_eth_rss_conf *rss_conf)
      91                 :            : {
      92                 :            :         int rss_hf = 0;
      93                 :            :         int i = 0;
      94                 :            :         uint8_t idx = 0;
      95                 :            :         uint8_t outer = 1;
      96                 :            : 
      97         [ #  # ]:          0 :         if (rss_conf->rss_hf & RTE_ETH_RSS_IP) {
      98                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV4_SIP;
      99                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV4_DIP;
     100                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV6_SIP;
     101                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV6_DIP;
     102                 :            :         }
     103                 :            : 
     104         [ #  # ]:          0 :         if ((rss_conf->rss_hf & RTE_ETH_RSS_UDP) ||
     105                 :            :             (rss_conf->rss_hf & RTE_ETH_RSS_TCP)) {
     106                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV4_SPORT;
     107                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV4_DPORT;
     108                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV6_SPORT;
     109                 :          0 :                 rss_hf |= XSC_RSS_HASH_BIT_IPV6_DPORT;
     110                 :            :         }
     111                 :            : 
     112         [ #  # ]:          0 :         if (rss_conf->rss_hf & RTE_ETH_RSS_L3_SRC_ONLY) {
     113                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV4_SIP;
     114                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV6_SIP;
     115                 :            :                 rss_hf &= ~XSC_RSS_HASH_BIT_IPV4_DIP;
     116                 :          0 :                 rss_hf &= ~XSC_RSS_HASH_BIT_IPV6_DIP;
     117                 :            :         }
     118                 :            : 
     119         [ #  # ]:          0 :         if (rss_conf->rss_hf & RTE_ETH_RSS_L3_DST_ONLY) {
     120                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV4_DIP;
     121                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV6_DIP;
     122                 :            :                 rss_hf &= ~XSC_RSS_HASH_BIT_IPV4_SIP;
     123                 :          0 :                 rss_hf &= ~XSC_RSS_HASH_BIT_IPV6_SIP;
     124                 :            :         }
     125                 :            : 
     126         [ #  # ]:          0 :         if (rss_conf->rss_hf & RTE_ETH_RSS_L4_SRC_ONLY) {
     127                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV4_SPORT;
     128                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV6_SPORT;
     129                 :            :                 rss_hf &= ~XSC_RSS_HASH_BIT_IPV4_DPORT;
     130                 :          0 :                 rss_hf &= ~XSC_RSS_HASH_BIT_IPV6_DPORT;
     131                 :            :         }
     132                 :            : 
     133         [ #  # ]:          0 :         if (rss_conf->rss_hf & RTE_ETH_RSS_L4_DST_ONLY) {
     134                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV4_DPORT;
     135                 :            :                 rss_hf |= XSC_RSS_HASH_BIT_IPV6_DPORT;
     136                 :            :                 rss_hf &= ~XSC_RSS_HASH_BIT_IPV4_SPORT;
     137                 :          0 :                 rss_hf &= ~XSC_RSS_HASH_BIT_IPV6_SPORT;
     138                 :            :         }
     139                 :            : 
     140                 :            :         if ((rss_conf->rss_hf & RTE_ETH_RSS_LEVEL_PMD_DEFAULT) ||
     141                 :            :             (rss_conf->rss_hf & RTE_ETH_RSS_LEVEL_OUTERMOST))
     142                 :            :                 outer = 1;
     143                 :            : 
     144         [ #  # ]:          0 :         if (rss_conf->rss_hf & RTE_ETH_RSS_LEVEL_INNERMOST)
     145                 :            :                 outer = 0;
     146                 :            : 
     147         [ #  # ]:          0 :         for (i = 0; i < XSC_HASH_TMPL_IDX_MAX; i++) {
     148         [ #  # ]:          0 :                 if (xsc_rss_hash_tmplate[i] == rss_hf) {
     149                 :          0 :                         idx = i;
     150                 :          0 :                         break;
     151                 :            :                 }
     152                 :            :         }
     153                 :            : 
     154                 :          0 :         idx = (idx << 1) | outer;
     155                 :          0 :         return idx;
     156                 :            : }
     157                 :            : 
     158                 :            : static int
     159                 :          0 : xsc_dev_np_exec(struct xsc_dev *xdev, void *cmd, int len, int table, int opmod)
     160                 :            : {
     161                 :            :         struct xsc_np_data_tl *tl;
     162                 :            :         struct xsc_np_mbox_in *in;
     163                 :            :         struct xsc_np_mbox_out *out;
     164                 :            :         int in_len;
     165                 :            :         int out_len;
     166                 :            :         int data_len;
     167                 :            :         int cmd_len;
     168                 :            :         int ret;
     169                 :            : 
     170                 :          0 :         data_len = sizeof(struct xsc_np_data_tl) + len;
     171                 :          0 :         in_len = sizeof(struct xsc_np_mbox_in) + data_len;
     172                 :          0 :         out_len = sizeof(struct xsc_np_mbox_out) + data_len;
     173                 :          0 :         cmd_len = RTE_MAX(in_len, out_len);
     174         [ #  # ]:          0 :         in = malloc(cmd_len);
     175                 :            :         memset(in, 0, cmd_len);
     176                 :            :         if (in == NULL) {
     177                 :            :                 rte_errno = ENOMEM;
     178                 :            :                 PMD_DRV_LOG(ERR, "Failed to alloc np cmd memory");
     179                 :            :                 return -rte_errno;
     180                 :            :         }
     181                 :            : 
     182                 :          0 :         in->hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_EXEC_NP);
     183         [ #  # ]:          0 :         in->len = rte_cpu_to_be_16(data_len);
     184                 :            : 
     185                 :            :         tl = (struct xsc_np_data_tl *)in->data;
     186                 :          0 :         tl->length = len;
     187                 :          0 :         tl->table = table;
     188                 :          0 :         tl->opmod = opmod;
     189         [ #  # ]:          0 :         if (cmd && len)
     190                 :          0 :                 memcpy(tl + 1, cmd, len);
     191                 :            : 
     192                 :            :         out = (struct xsc_np_mbox_out *)in;
     193                 :          0 :         ret = xsc_dev_mailbox_exec(xdev, in, in_len, out, out_len);
     194                 :            : 
     195                 :          0 :         free(in);
     196                 :            :         return ret;
     197                 :            : }
     198                 :            : 
     199                 :            : int
     200                 :          0 : xsc_dev_create_pct(struct xsc_dev *xdev, int repr_id,
     201                 :            :                    uint16_t logical_in_port, uint16_t dst_info)
     202                 :            : {
     203                 :            :         int ret;
     204                 :            :         struct xsc_np_pct_v4_add add;
     205                 :          0 :         struct xsc_repr_port *repr = &xdev->repr_ports[repr_id];
     206                 :          0 :         struct xsc_dev_pct_list *pct_list = &repr->def_pct_list;
     207                 :            : 
     208                 :            :         memset(&add, 0, sizeof(add));
     209                 :          0 :         add.key.logical_in_port = logical_in_port & XSC_LOGIC_PORT_MASK;
     210                 :          0 :         add.mask.logical_in_port = XSC_LOGIC_PORT_MASK;
     211                 :          0 :         add.action.dst_info = dst_info;
     212                 :          0 :         add.pct_idx = xsc_dev_pct_idx_alloc();
     213         [ #  # ]:          0 :         if (add.pct_idx == XSC_DEV_PCT_IDX_INVALID)
     214                 :            :                 return -1;
     215                 :            : 
     216                 :          0 :         ret = xsc_dev_np_exec(xdev, &add, sizeof(add), XSC_NP_PCT_V4, XSC_NP_OP_ADD);
     217         [ #  # ]:          0 :         if (unlikely(ret != 0)) {
     218                 :          0 :                 xsc_dev_pct_idx_free(add.pct_idx);
     219                 :          0 :                 return -1;
     220                 :            :         }
     221                 :            : 
     222                 :          0 :         xsc_dev_pct_entry_insert(pct_list, add.key.logical_in_port, add.pct_idx);
     223                 :          0 :         return 0;
     224                 :            : }
     225                 :            : 
     226                 :            : int
     227                 :          0 : xsc_dev_destroy_pct(struct xsc_dev *xdev, uint16_t logical_in_port, uint32_t pct_idx)
     228                 :            : {
     229                 :            :         struct xsc_np_pct_v4_del del;
     230                 :            : 
     231                 :            :         memset(&del, 0, sizeof(del));
     232                 :          0 :         del.key.logical_in_port = logical_in_port & XSC_LOGIC_PORT_MASK;
     233                 :          0 :         del.mask.logical_in_port = XSC_LOGIC_PORT_MASK;
     234                 :          0 :         del.pct_idx = pct_idx;
     235                 :          0 :         return xsc_dev_np_exec(xdev, &del, sizeof(del), XSC_NP_PCT_V4, XSC_NP_OP_DEL);
     236                 :            : }
     237                 :            : 
     238                 :            : void
     239                 :          0 : xsc_dev_clear_pct(struct xsc_dev *xdev, int repr_id)
     240                 :            : {
     241                 :            :         struct xsc_repr_port *repr;
     242                 :            :         struct xsc_dev_pct_entry *pct_entry;
     243                 :            :         struct xsc_dev_pct_list *pct_list;
     244                 :            : 
     245         [ #  # ]:          0 :         if (repr_id == XSC_DEV_REPR_ID_INVALID)
     246                 :            :                 return;
     247                 :            : 
     248                 :          0 :         repr = &xdev->repr_ports[repr_id];
     249                 :          0 :         pct_list = &repr->def_pct_list;
     250                 :            : 
     251         [ #  # ]:          0 :         while ((pct_entry = xsc_dev_pct_first_get(pct_list)) != NULL) {
     252                 :          0 :                 xsc_dev_destroy_pct(xdev, pct_entry->logic_port, pct_entry->pct_idx);
     253                 :          0 :                 xsc_dev_pct_entry_remove(pct_entry);
     254                 :            :         }
     255                 :            : }
     256                 :            : 
     257                 :            : int
     258                 :          0 : xsc_dev_create_ipat(struct xsc_dev *xdev, uint16_t logic_in_port, uint16_t dst_info)
     259                 :            : {
     260                 :            :         struct xsc_np_ipat add;
     261                 :            : 
     262                 :            :         memset(&add, 0, sizeof(add));
     263                 :          0 :         add.key.logical_in_port = logic_in_port;
     264                 :          0 :         add.action.dst_info = dst_info;
     265                 :          0 :         add.action.vld = 1;
     266                 :          0 :         return xsc_dev_np_exec(xdev, &add, sizeof(add), XSC_NP_IPAT, XSC_NP_OP_ADD);
     267                 :            : }
     268                 :            : 
     269                 :            : int
     270                 :          0 : xsc_dev_get_ipat_vld(struct xsc_dev *xdev, uint16_t logic_in_port)
     271                 :            : {
     272                 :            :         int ret;
     273                 :            :         struct xsc_np_ipat get;
     274                 :            : 
     275                 :            :         memset(&get, 0, sizeof(get));
     276                 :          0 :         get.key.logical_in_port = logic_in_port;
     277                 :            : 
     278                 :          0 :         ret = xsc_dev_np_exec(xdev, &get, sizeof(get), XSC_NP_IPAT, XSC_NP_OP_GET);
     279         [ #  # ]:          0 :         if (ret != 0)
     280                 :          0 :                 PMD_DRV_LOG(ERR, "Get ipat vld failed, logic in port=%u", logic_in_port);
     281                 :            : 
     282                 :          0 :         return get.action.vld;
     283                 :            : }
     284                 :            : 
     285                 :            : int
     286                 :          0 : xsc_dev_destroy_ipat(struct xsc_dev *xdev, uint16_t logic_in_port)
     287                 :            : {
     288                 :            :         struct xsc_ipat_key del;
     289                 :            : 
     290                 :            :         memset(&del, 0, sizeof(del));
     291                 :          0 :         del.logical_in_port = logic_in_port;
     292                 :          0 :         return xsc_dev_np_exec(xdev, &del, sizeof(del), XSC_NP_IPAT, XSC_NP_OP_DEL);
     293                 :            : }
     294                 :            : 
     295                 :            : int
     296                 :          0 : xsc_dev_create_epat(struct xsc_dev *xdev, uint16_t dst_info, uint8_t dst_port,
     297                 :            :                     uint16_t qpn_ofst, uint8_t qp_num, struct rte_eth_rss_conf *rss_conf)
     298                 :            : {
     299                 :            :         struct xsc_np_epat_add add;
     300                 :            : 
     301                 :            :         memset(&add, 0, sizeof(add));
     302                 :          0 :         add.key.dst_info = dst_info;
     303                 :          0 :         add.action.dst_port = dst_port;
     304                 :          0 :         add.action.vld = 1;
     305                 :          0 :         add.action.rx_qp_id_ofst = qpn_ofst;
     306                 :          0 :         add.action.qp_num = qp_num - 1;
     307                 :          0 :         add.action.rss_en = 1;
     308                 :          0 :         add.action.rss_hash_func = XSC_RSS_HASH_FUNC_TOPELIZ;
     309                 :          0 :         add.action.rss_hash_template = xsc_rss_hash_template_get(rss_conf);
     310                 :            : 
     311                 :          0 :         return xsc_dev_np_exec(xdev, &add, sizeof(add), XSC_NP_EPAT, XSC_NP_OP_ADD);
     312                 :            : }
     313                 :            : 
     314                 :            : int
     315                 :          0 : xsc_dev_vf_modify_epat(struct xsc_dev *xdev, uint16_t dst_info, uint16_t qpn_ofst,
     316                 :            :                        uint8_t qp_num, struct rte_eth_rss_conf *rss_conf)
     317                 :            : {
     318                 :            :         struct xsc_np_epat_mod mod;
     319                 :            : 
     320                 :            :         memset(&mod, 0, sizeof(mod));
     321                 :          0 :         mod.flags = XSC_EPAT_VLD_FLAG | XSC_EPAT_RX_QP_ID_OFST_FLAG |
     322                 :            :                     XSC_EPAT_QP_NUM_FLAG | XSC_EPAT_HAS_PPH_FLAG |
     323                 :            :                     XSC_EPAT_RSS_EN_FLAG | XSC_EPAT_RSS_HASH_TEMPLATE_FLAG |
     324                 :            :                     XSC_EPAT_RSS_HASH_FUNC_FLAG;
     325                 :            : 
     326                 :          0 :         mod.key.dst_info = dst_info;
     327                 :          0 :         mod.action.vld = 1;
     328                 :          0 :         mod.action.rx_qp_id_ofst = qpn_ofst;
     329                 :          0 :         mod.action.qp_num = qp_num - 1;
     330                 :          0 :         mod.action.rss_en = 1;
     331                 :          0 :         mod.action.rss_hash_func = XSC_RSS_HASH_FUNC_TOPELIZ;
     332                 :          0 :         mod.action.rss_hash_template = xsc_rss_hash_template_get(rss_conf);
     333                 :            : 
     334                 :          0 :         return xsc_dev_np_exec(xdev, &mod, sizeof(mod), XSC_NP_EPAT, XSC_NP_OP_MOD);
     335                 :            : }
     336                 :            : 
     337                 :            : int
     338                 :          0 : xsc_dev_set_qpsetid(struct xsc_dev *xdev, uint32_t txqpn, uint16_t qp_set_id)
     339                 :            : {
     340                 :            :         int ret;
     341                 :            :         struct xsc_pg_set_id add;
     342                 :          0 :         uint16_t qp_id_base = xdev->hwinfo.raw_qp_id_base;
     343                 :            : 
     344                 :            :         memset(&add, 0, sizeof(add));
     345                 :          0 :         add.key.qp_id = txqpn - qp_id_base;
     346                 :          0 :         add.action.qp_set_id = qp_set_id;
     347                 :            : 
     348                 :          0 :         ret = xsc_dev_np_exec(xdev, &add, sizeof(add), XSC_NP_PG_QP_SET_ID, XSC_NP_OP_ADD);
     349         [ #  # ]:          0 :         if (ret != 0)
     350                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to set qp %u setid %u", txqpn, qp_set_id);
     351                 :            : 
     352                 :          0 :         return ret;
     353                 :            : }
     354                 :            : 
     355                 :            : int
     356                 :          0 : xsc_dev_destroy_epat(struct xsc_dev *xdev, uint16_t dst_info)
     357                 :            : {
     358                 :            :         struct xsc_epat_key del;
     359                 :            : 
     360                 :            :         memset(&del, 0, sizeof(del));
     361                 :            : 
     362                 :          0 :         del.dst_info = dst_info;
     363                 :          0 :         return xsc_dev_np_exec(xdev, &del, sizeof(del), XSC_NP_EPAT, XSC_NP_OP_DEL);
     364                 :            : }
     365                 :            : 
     366                 :            : int
     367                 :          0 : xsc_dev_create_vfos_baselp(struct xsc_dev *xdev)
     368                 :            : {
     369                 :            :         int ret;
     370                 :            :         struct xsc_np_vfso add;
     371                 :            : 
     372                 :            :         memset(&add, 0, sizeof(add));
     373                 :          0 :         add.key.src_port = xdev->vfrep_offset;
     374                 :          0 :         add.action.ofst = xdev->vfos_logical_in_port;
     375                 :            : 
     376                 :          0 :         ret = xsc_dev_np_exec(xdev, &add, sizeof(add), XSC_NP_VFOS, XSC_NP_OP_ADD);
     377         [ #  # ]:          0 :         if (ret != 0)
     378                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to set vfos, port=%u, offset=%u",
     379                 :            :                             add.key.src_port, add.action.ofst);
     380                 :            : 
     381                 :          0 :         return ret;
     382                 :            : }
     383                 :            : 
     384                 :            : void
     385                 :          0 : xsc_dev_pct_uninit(void)
     386                 :            : {
     387                 :            :         rte_bitmap_free(xsc_pct_mgr.bmp_pct);
     388                 :          0 :         rte_free(xsc_pct_mgr.bmp_mem);
     389                 :          0 : }
     390                 :            : 
     391                 :            : int
     392                 :          0 : xsc_dev_pct_init(void)
     393                 :            : {
     394                 :            :         int ret;
     395                 :            :         uint8_t *bmp_mem;
     396                 :            :         uint32_t pos, pct_sz, bmp_sz;
     397                 :            : 
     398         [ #  # ]:          0 :         if (xsc_pct_mgr.bmp_mem != NULL)
     399                 :            :                 return 0;
     400                 :            : 
     401                 :            :         pct_sz = XSC_DEV_DEF_PCT_IDX_MAX - XSC_DEV_DEF_PCT_IDX_MIN + 1;
     402                 :          0 :         bmp_sz = rte_bitmap_get_memory_footprint(pct_sz);
     403                 :          0 :         bmp_mem = rte_zmalloc(NULL, bmp_sz, RTE_CACHE_LINE_SIZE);
     404         [ #  # ]:          0 :         if (bmp_mem == NULL) {
     405                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to alloc pct bitmap memory");
     406                 :            :                 ret = -ENOMEM;
     407                 :          0 :                 goto pct_init_fail;
     408                 :            :         }
     409                 :            : 
     410                 :          0 :         xsc_pct_mgr.bmp_mem = bmp_mem;
     411                 :          0 :         xsc_pct_mgr.bmp_pct = rte_bitmap_init(pct_sz, bmp_mem, bmp_sz);
     412         [ #  # ]:          0 :         if (xsc_pct_mgr.bmp_pct == NULL) {
     413                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to init pct bitmap");
     414                 :            :                 ret = -EINVAL;
     415                 :          0 :                 goto pct_init_fail;
     416                 :            :         }
     417                 :            : 
     418                 :            :         /* Mark all pct bitmap available */
     419         [ #  # ]:          0 :         for (pos = 0; pos < pct_sz; pos++)
     420                 :          0 :                 rte_bitmap_set(xsc_pct_mgr.bmp_pct, pos);
     421                 :            : 
     422                 :            :         return 0;
     423                 :            : 
     424                 :          0 : pct_init_fail:
     425                 :          0 :         xsc_dev_pct_uninit();
     426                 :          0 :         return ret;
     427                 :            : }
     428                 :            : 
     429                 :            : uint32_t
     430                 :          0 : xsc_dev_pct_idx_alloc(void)
     431                 :            : {
     432                 :            :         int ret;
     433                 :          0 :         uint64_t slab = 0;
     434                 :          0 :         uint32_t pos = 0;
     435                 :            : 
     436                 :          0 :         ret = rte_bitmap_scan(xsc_pct_mgr.bmp_pct, &pos, &slab);
     437         [ #  # ]:          0 :         if (ret != 0) {
     438                 :          0 :                 pos += rte_bsf64(slab);
     439                 :          0 :                 rte_bitmap_clear(xsc_pct_mgr.bmp_pct, pos);
     440                 :          0 :                 return (pos + XSC_DEV_DEF_PCT_IDX_MIN);
     441                 :            :         }
     442                 :            : 
     443                 :          0 :         PMD_DRV_LOG(ERR, "Failed to alloc xsc pct idx");
     444                 :          0 :         return XSC_DEV_PCT_IDX_INVALID;
     445                 :            : }
     446                 :            : 
     447                 :            : void
     448                 :          0 : xsc_dev_pct_idx_free(uint32_t pct_idx)
     449                 :            : {
     450                 :          0 :         rte_bitmap_set(xsc_pct_mgr.bmp_pct, pct_idx - XSC_DEV_DEF_PCT_IDX_MIN);
     451                 :          0 : }
     452                 :            : 
     453                 :            : int
     454                 :          0 : xsc_dev_pct_entry_insert(struct xsc_dev_pct_list *pct_list,
     455                 :            :                          uint32_t logic_port, uint32_t pct_idx)
     456                 :            : {
     457                 :            :         struct xsc_dev_pct_entry *pct_entry;
     458                 :            : 
     459                 :          0 :         pct_entry = rte_zmalloc(NULL, sizeof(struct xsc_dev_pct_entry), RTE_CACHE_LINE_SIZE);
     460         [ #  # ]:          0 :         if (pct_entry == NULL) {
     461                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to alloc pct entry memory");
     462                 :          0 :                 return -ENOMEM;
     463                 :            :         }
     464                 :            : 
     465                 :          0 :         pct_entry->logic_port = logic_port;
     466                 :          0 :         pct_entry->pct_idx = pct_idx;
     467         [ #  # ]:          0 :         LIST_INSERT_HEAD(pct_list, pct_entry, next);
     468                 :            : 
     469                 :          0 :         return 0;
     470                 :            : }
     471                 :            : 
     472                 :            : struct xsc_dev_pct_entry *
     473                 :          0 : xsc_dev_pct_first_get(struct xsc_dev_pct_list *pct_list)
     474                 :            : {
     475                 :            :         struct xsc_dev_pct_entry *pct_entry;
     476                 :            : 
     477                 :          0 :         pct_entry = LIST_FIRST(pct_list);
     478                 :          0 :         return pct_entry;
     479                 :            : }
     480                 :            : 
     481                 :            : int
     482                 :          0 : xsc_dev_pct_entry_remove(struct xsc_dev_pct_entry *pct_entry)
     483                 :            : {
     484         [ #  # ]:          0 :         if (pct_entry == NULL)
     485                 :            :                 return -1;
     486                 :            : 
     487                 :          0 :         xsc_dev_pct_idx_free(pct_entry->pct_idx);
     488         [ #  # ]:          0 :         LIST_REMOVE(pct_entry, next);
     489                 :          0 :         rte_free(pct_entry);
     490                 :            : 
     491                 :          0 :         return 0;
     492                 :            : }

Generated by: LCOV version 1.14