LCOV - code coverage report
Current view: top level - drivers/net/xsc - xsc_dev.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 3 166 1.8 %
Date: 2025-03-01 20:23:48 Functions: 1 24 4.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 64 1.6 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2025 Yunsilicon Technology Co., Ltd.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <stdlib.h>
       6                 :            : #include <unistd.h>
       7                 :            : #include <sys/stat.h>
       8                 :            : #include <fcntl.h>
       9                 :            : #include <limits.h>
      10                 :            : #include <sys/mman.h>
      11                 :            : 
      12                 :            : #include <rte_pci.h>
      13                 :            : #include <rte_bus_pci.h>
      14                 :            : #include <bus_pci_driver.h>
      15                 :            : #include <rte_kvargs.h>
      16                 :            : #include <rte_eal_paging.h>
      17                 :            : #include <rte_bitops.h>
      18                 :            : 
      19                 :            : #include "xsc_log.h"
      20                 :            : #include "xsc_defs.h"
      21                 :            : #include "xsc_dev.h"
      22                 :            : #include "xsc_cmd.h"
      23                 :            : 
      24                 :            : #define XSC_DEV_DEF_FLOW_MODE   7
      25                 :            : 
      26                 :            : TAILQ_HEAD(xsc_dev_ops_list, xsc_dev_ops);
      27                 :            : static struct xsc_dev_ops_list dev_ops_list = TAILQ_HEAD_INITIALIZER(dev_ops_list);
      28                 :            : 
      29                 :            : static const struct xsc_dev_ops *
      30                 :            : xsc_dev_ops_get(enum rte_pci_kernel_driver kdrv)
      31                 :            : {
      32                 :            :         const struct xsc_dev_ops *ops;
      33                 :            : 
      34         [ #  # ]:          0 :         TAILQ_FOREACH(ops, &dev_ops_list, entry) {
      35         [ #  # ]:          0 :                 if (ops->kdrv == kdrv)
      36                 :            :                         return ops;
      37                 :            :         }
      38                 :            : 
      39                 :            :         return NULL;
      40                 :            : }
      41                 :            : 
      42                 :            : void
      43                 :        252 : xsc_dev_ops_register(struct xsc_dev_ops *new_ops)
      44                 :            : {
      45                 :            :         struct xsc_dev_ops *ops;
      46                 :            : 
      47         [ -  + ]:        252 :         TAILQ_FOREACH(ops, &dev_ops_list, entry) {
      48         [ #  # ]:          0 :                 if (ops->kdrv == new_ops->kdrv) {
      49                 :          0 :                         PMD_DRV_LOG(ERR, "xsc dev ops exists, kdrv=%d", new_ops->kdrv);
      50                 :          0 :                         return;
      51                 :            :                 }
      52                 :            :         }
      53                 :            : 
      54                 :        252 :         TAILQ_INSERT_TAIL(&dev_ops_list, new_ops, entry);
      55                 :            : }
      56                 :            : 
      57                 :            : int
      58                 :          0 : xsc_dev_mailbox_exec(struct xsc_dev *xdev, void *data_in,
      59                 :            :                      int in_len, void *data_out, int out_len)
      60                 :            : {
      61                 :          0 :         return xdev->dev_ops->mailbox_exec(xdev, data_in, in_len,
      62                 :            :                                            data_out, out_len);
      63                 :            : }
      64                 :            : 
      65                 :            : int
      66                 :          0 : xsc_dev_set_link_up(struct xsc_dev *xdev)
      67                 :            : {
      68         [ #  # ]:          0 :         if (xdev->dev_ops->set_link_up == NULL)
      69                 :            :                 return -ENOTSUP;
      70                 :            : 
      71                 :          0 :         return xdev->dev_ops->set_link_up(xdev);
      72                 :            : }
      73                 :            : 
      74                 :            : int
      75                 :          0 : xsc_dev_set_link_down(struct xsc_dev *xdev)
      76                 :            : {
      77         [ #  # ]:          0 :         if (xdev->dev_ops->set_link_down == NULL)
      78                 :            :                 return -ENOTSUP;
      79                 :            : 
      80                 :          0 :         return xdev->dev_ops->set_link_down(xdev);
      81                 :            : }
      82                 :            : 
      83                 :            : int
      84                 :          0 : xsc_dev_link_update(struct xsc_dev *xdev, uint8_t funcid_type, int wait_to_complete)
      85                 :            : {
      86         [ #  # ]:          0 :         if (xdev->dev_ops->link_update == NULL)
      87                 :            :                 return -ENOTSUP;
      88                 :            : 
      89                 :          0 :         return xdev->dev_ops->link_update(xdev, funcid_type, wait_to_complete);
      90                 :            : }
      91                 :            : 
      92                 :            : int
      93                 :          0 : xsc_dev_set_mtu(struct xsc_dev *xdev, uint16_t mtu)
      94                 :            : {
      95                 :          0 :         return xdev->dev_ops->set_mtu(xdev, mtu);
      96                 :            : }
      97                 :            : 
      98                 :            : int
      99                 :          0 : xsc_dev_get_mac(struct xsc_dev *xdev, uint8_t *mac)
     100                 :            : {
     101                 :          0 :         return xdev->dev_ops->get_mac(xdev, mac);
     102                 :            : }
     103                 :            : 
     104                 :            : int
     105                 :          0 : xsc_dev_destroy_qp(struct xsc_dev *xdev, void *qp)
     106                 :            : {
     107                 :          0 :         return xdev->dev_ops->destroy_qp(qp);
     108                 :            : }
     109                 :            : 
     110                 :            : int
     111                 :          0 : xsc_dev_destroy_cq(struct xsc_dev *xdev, void *cq)
     112                 :            : {
     113                 :          0 :         return xdev->dev_ops->destroy_cq(cq);
     114                 :            : }
     115                 :            : 
     116                 :            : int
     117                 :          0 : xsc_dev_modify_qp_status(struct xsc_dev *xdev, uint32_t qpn, int num, int opcode)
     118                 :            : {
     119                 :          0 :         return xdev->dev_ops->modify_qp_status(xdev, qpn, num, opcode);
     120                 :            : }
     121                 :            : 
     122                 :            : int
     123                 :          0 : xsc_dev_modify_qp_qostree(struct xsc_dev *xdev, uint16_t qpn)
     124                 :            : {
     125                 :          0 :         return xdev->dev_ops->modify_qp_qostree(xdev, qpn);
     126                 :            : }
     127                 :            : 
     128                 :            : int
     129                 :          0 : xsc_dev_rx_cq_create(struct xsc_dev *xdev, struct xsc_rx_cq_params *cq_params,
     130                 :            :                      struct xsc_rx_cq_info *cq_info)
     131                 :            : {
     132                 :          0 :         return xdev->dev_ops->rx_cq_create(xdev, cq_params, cq_info);
     133                 :            : }
     134                 :            : 
     135                 :            : int
     136                 :          0 : xsc_dev_tx_cq_create(struct xsc_dev *xdev, struct xsc_tx_cq_params *cq_params,
     137                 :            :                      struct xsc_tx_cq_info *cq_info)
     138                 :            : {
     139                 :          0 :         return xdev->dev_ops->tx_cq_create(xdev, cq_params, cq_info);
     140                 :            : }
     141                 :            : 
     142                 :            : int
     143                 :          0 : xsc_dev_tx_qp_create(struct xsc_dev *xdev, struct xsc_tx_qp_params *qp_params,
     144                 :            :                      struct xsc_tx_qp_info *qp_info)
     145                 :            : {
     146                 :          0 :         return xdev->dev_ops->tx_qp_create(xdev, qp_params, qp_info);
     147                 :            : }
     148                 :            : 
     149                 :            : int
     150                 :          0 : xsc_dev_close(struct xsc_dev *xdev, int repr_id)
     151                 :            : {
     152                 :          0 :         xsc_dev_clear_pct(xdev, repr_id);
     153                 :          0 :         return xdev->dev_ops->dev_close(xdev);
     154                 :            : }
     155                 :            : 
     156                 :            : int
     157                 :          0 : xsc_dev_rss_key_modify(struct xsc_dev *xdev, uint8_t *rss_key, uint8_t rss_key_len)
     158                 :            : {
     159                 :          0 :         struct xsc_cmd_modify_nic_hca_mbox_in in = {};
     160                 :          0 :         struct xsc_cmd_modify_nic_hca_mbox_out out = {};
     161                 :            :         uint8_t rss_caps_mask = 0;
     162                 :            :         int ret, key_len = 0;
     163                 :            : 
     164                 :          0 :         in.hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_MODIFY_NIC_HCA);
     165                 :            : 
     166                 :          0 :         key_len = RTE_MIN(rss_key_len, XSC_RSS_HASH_KEY_LEN);
     167         [ #  # ]:          0 :         rte_memcpy(in.rss.hash_key, rss_key, key_len);
     168                 :            :         rss_caps_mask |= RTE_BIT32(XSC_RSS_HASH_KEY_UPDATE);
     169                 :            : 
     170                 :          0 :         in.rss.caps_mask = rss_caps_mask;
     171                 :          0 :         in.rss.rss_en = 1;
     172                 :          0 :         in.nic.caps_mask = rte_cpu_to_be_16(RTE_BIT32(XSC_TBM_CAP_RSS));
     173                 :          0 :         in.nic.caps = in.nic.caps_mask;
     174                 :            : 
     175                 :          0 :         ret = xsc_dev_mailbox_exec(xdev, &in, sizeof(in), &out, sizeof(out));
     176   [ #  #  #  # ]:          0 :         if (ret != 0 || out.hdr.status != 0)
     177                 :          0 :                 return -1;
     178                 :            :         return 0;
     179                 :            : }
     180                 :            : 
     181                 :            : static int
     182                 :          0 : xsc_dev_alloc_vfos_info(struct xsc_dev *xdev)
     183                 :            : {
     184                 :            :         struct xsc_hwinfo *hwinfo;
     185                 :            :         int base_lp = 0;
     186                 :            : 
     187         [ #  # ]:          0 :         if (xsc_dev_is_vf(xdev))
     188                 :            :                 return 0;
     189                 :            : 
     190                 :            :         hwinfo = &xdev->hwinfo;
     191         [ #  # ]:          0 :         if (hwinfo->pcie_no == 1) {
     192                 :          0 :                 xdev->vfrep_offset = hwinfo->func_id -
     193                 :          0 :                         hwinfo->pcie1_pf_funcid_base +
     194                 :          0 :                         hwinfo->pcie0_pf_funcid_top -
     195                 :          0 :                         hwinfo->pcie0_pf_funcid_base  + 1;
     196                 :            :         } else {
     197                 :          0 :                 xdev->vfrep_offset = hwinfo->func_id - hwinfo->pcie0_pf_funcid_base;
     198                 :            :         }
     199                 :            : 
     200                 :            :         base_lp = XSC_VFREP_BASE_LOGICAL_PORT;
     201         [ #  # ]:          0 :         if (xdev->devargs.nic_mode == XSC_NIC_MODE_LEGACY)
     202                 :          0 :                 base_lp += xdev->vfrep_offset;
     203                 :          0 :         xdev->vfos_logical_in_port = base_lp;
     204                 :          0 :         return 0;
     205                 :            : }
     206                 :            : 
     207                 :            : static void
     208                 :          0 : xsc_dev_args_parse(struct xsc_dev *xdev, struct rte_devargs *devargs)
     209                 :            : {
     210                 :            :         struct rte_kvargs *kvlist;
     211                 :            :         struct xsc_devargs *xdevargs = &xdev->devargs;
     212                 :            :         const char *tmp;
     213                 :            : 
     214                 :          0 :         kvlist = rte_kvargs_parse(devargs->args, NULL);
     215         [ #  # ]:          0 :         if (kvlist == NULL)
     216                 :            :                 return;
     217                 :            : 
     218                 :          0 :         tmp = rte_kvargs_get(kvlist, XSC_PPH_MODE_ARG);
     219         [ #  # ]:          0 :         if (tmp != NULL)
     220                 :          0 :                 xdevargs->pph_mode = atoi(tmp);
     221                 :            :         else
     222                 :          0 :                 xdevargs->pph_mode = XSC_PPH_NONE;
     223                 :            : 
     224                 :          0 :         tmp = rte_kvargs_get(kvlist, XSC_NIC_MODE_ARG);
     225         [ #  # ]:          0 :         if (tmp != NULL)
     226                 :          0 :                 xdevargs->nic_mode = atoi(tmp);
     227                 :            :         else
     228                 :          0 :                 xdevargs->nic_mode = XSC_NIC_MODE_LEGACY;
     229                 :            : 
     230                 :          0 :         tmp = rte_kvargs_get(kvlist, XSC_FLOW_MODE_ARG);
     231         [ #  # ]:          0 :         if (tmp != NULL)
     232                 :          0 :                 xdevargs->flow_mode = atoi(tmp);
     233                 :            :         else
     234                 :          0 :                 xdevargs->flow_mode = XSC_DEV_DEF_FLOW_MODE;
     235                 :            : 
     236                 :          0 :         rte_kvargs_free(kvlist);
     237                 :            : }
     238                 :            : 
     239                 :            : int
     240                 :          0 : xsc_dev_qp_set_id_get(struct xsc_dev *xdev, int repr_id)
     241                 :            : {
     242         [ #  # ]:          0 :         if (xsc_dev_is_vf(xdev))
     243                 :            :                 return 0;
     244                 :            : 
     245                 :          0 :         return (repr_id % 511 + 1);
     246                 :            : }
     247                 :            : 
     248                 :            : static void
     249                 :          0 : xsc_repr_info_init(struct xsc_dev *xdev, struct xsc_repr_info *info,
     250                 :            :                    enum xsc_port_type port_type,
     251                 :            :                    enum xsc_funcid_type funcid_type, int32_t repr_id)
     252                 :            : {
     253                 :            :         int qp_set_id, logical_port;
     254                 :            :         struct xsc_hwinfo *hwinfo = &xdev->hwinfo;
     255                 :            : 
     256                 :          0 :         info->repr_id = repr_id;
     257                 :          0 :         info->port_type = port_type;
     258         [ #  # ]:          0 :         if (port_type == XSC_PORT_TYPE_UPLINK_BOND) {
     259                 :          0 :                 info->pf_bond = 1;
     260                 :          0 :                 info->funcid = XSC_PHYPORT_LAG_FUNCID << 14;
     261         [ #  # ]:          0 :         } else if (port_type == XSC_PORT_TYPE_UPLINK) {
     262                 :          0 :                 info->pf_bond = -1;
     263                 :          0 :                 info->funcid = funcid_type << 14;
     264         [ #  # ]:          0 :         } else if (port_type == XSC_PORT_TYPE_PFVF) {
     265                 :          0 :                 info->funcid = funcid_type << 14;
     266                 :            :         }
     267                 :            : 
     268                 :          0 :         qp_set_id = xsc_dev_qp_set_id_get(xdev, repr_id);
     269         [ #  # ]:          0 :         if (xsc_dev_is_vf(xdev))
     270                 :          0 :                 logical_port = xdev->hwinfo.func_id +
     271                 :          0 :                                xdev->hwinfo.funcid_to_logic_port_off;
     272                 :            :         else
     273                 :          0 :                 logical_port = xdev->vfos_logical_in_port + qp_set_id - 1;
     274                 :            : 
     275                 :          0 :         info->logical_port = logical_port;
     276                 :          0 :         info->local_dstinfo = logical_port;
     277                 :          0 :         info->peer_logical_port = hwinfo->mac_phy_port;
     278                 :          0 :         info->peer_dstinfo = hwinfo->mac_phy_port;
     279                 :          0 : }
     280                 :            : 
     281                 :            : int
     282                 :          0 : xsc_dev_repr_ports_probe(struct xsc_dev *xdev, int nb_repr_ports, int max_eth_ports)
     283                 :            : {
     284                 :            :         int funcid_type;
     285                 :            :         struct xsc_repr_port *repr_port;
     286                 :            :         int i;
     287                 :            : 
     288                 :          0 :         PMD_INIT_FUNC_TRACE();
     289                 :            : 
     290                 :          0 :         xdev->num_repr_ports = nb_repr_ports + XSC_PHY_PORT_NUM;
     291         [ #  # ]:          0 :         if (xdev->num_repr_ports > max_eth_ports) {
     292                 :          0 :                 PMD_DRV_LOG(ERR, "Repr ports num %u, should be less than max %u",
     293                 :            :                             xdev->num_repr_ports, max_eth_ports);
     294                 :          0 :                 return -EINVAL;
     295                 :            :         }
     296                 :            : 
     297                 :          0 :         xdev->repr_ports = rte_zmalloc(NULL,
     298                 :          0 :                                        sizeof(struct xsc_repr_port) * xdev->num_repr_ports,
     299                 :            :                                        RTE_CACHE_LINE_SIZE);
     300         [ #  # ]:          0 :         if (xdev->repr_ports == NULL) {
     301                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to allocate memory for repr ports");
     302                 :          0 :                 return -ENOMEM;
     303                 :            :         }
     304                 :            : 
     305                 :          0 :         funcid_type = (xdev->devargs.nic_mode == XSC_NIC_MODE_SWITCHDEV) ?
     306         [ #  # ]:          0 :                 XSC_VF_IOCTL_FUNCID : XSC_PHYPORT_MAC_FUNCID;
     307                 :            : 
     308                 :            :         /* PF representor use the last repr_ports */
     309                 :          0 :         repr_port = &xdev->repr_ports[xdev->num_repr_ports - 1];
     310                 :          0 :         xsc_repr_info_init(xdev, &repr_port->info, XSC_PORT_TYPE_UPLINK,
     311                 :            :                            XSC_PHYPORT_MAC_FUNCID, xdev->num_repr_ports - 1);
     312                 :          0 :         repr_port->info.ifindex = xdev->ifindex;
     313                 :          0 :         repr_port->xdev = xdev;
     314                 :          0 :         LIST_INIT(&repr_port->def_pct_list);
     315                 :            : 
     316                 :            :         /* VF representor start from 0 */
     317         [ #  # ]:          0 :         for (i = 0; i < nb_repr_ports; i++) {
     318                 :          0 :                 repr_port = &xdev->repr_ports[i];
     319                 :          0 :                 xsc_repr_info_init(xdev, &repr_port->info,
     320                 :            :                                    XSC_PORT_TYPE_PFVF, funcid_type, i);
     321                 :          0 :                 repr_port->xdev = xdev;
     322                 :          0 :                 LIST_INIT(&repr_port->def_pct_list);
     323                 :            :         }
     324                 :            : 
     325                 :            :         return 0;
     326                 :            : }
     327                 :            : 
     328                 :            : void
     329                 :          0 : xsc_dev_uninit(struct xsc_dev *xdev)
     330                 :            : {
     331                 :          0 :         PMD_INIT_FUNC_TRACE();
     332                 :          0 :         xsc_dev_pct_uninit();
     333                 :          0 :         xsc_dev_close(xdev, XSC_DEV_REPR_ID_INVALID);
     334                 :          0 :         rte_free(xdev);
     335                 :          0 : }
     336                 :            : 
     337                 :            : int
     338                 :          0 : xsc_dev_init(struct rte_pci_device *pci_dev, struct xsc_dev **xdev)
     339                 :            : {
     340                 :            :         struct xsc_dev *d;
     341                 :            :         int ret;
     342                 :            : 
     343                 :          0 :         PMD_INIT_FUNC_TRACE();
     344                 :            : 
     345                 :          0 :         d = rte_zmalloc(NULL, sizeof(*d), RTE_CACHE_LINE_SIZE);
     346         [ #  # ]:          0 :         if (d == NULL) {
     347                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to alloc memory for xsc_dev");
     348                 :          0 :                 return -ENOMEM;
     349                 :            :         }
     350                 :            : 
     351                 :          0 :         d->dev_ops = xsc_dev_ops_get(pci_dev->kdrv);
     352         [ #  # ]:          0 :         if (d->dev_ops == NULL) {
     353                 :          0 :                 PMD_DRV_LOG(ERR, "Could not get dev_ops, kdrv=%d", pci_dev->kdrv);
     354                 :          0 :                 return -ENODEV;
     355                 :            :         }
     356                 :            : 
     357                 :          0 :         d->pci_dev = pci_dev;
     358                 :            : 
     359         [ #  # ]:          0 :         if (d->dev_ops->dev_init)
     360                 :          0 :                 d->dev_ops->dev_init(d);
     361                 :            : 
     362                 :          0 :         xsc_dev_args_parse(d, pci_dev->device.devargs);
     363                 :            : 
     364                 :          0 :         ret = xsc_dev_alloc_vfos_info(d);
     365         [ #  # ]:          0 :         if (ret) {
     366                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to alloc vfos info");
     367                 :            :                 ret = -EINVAL;
     368                 :          0 :                 goto hwinfo_init_fail;
     369                 :            :         }
     370                 :            : 
     371                 :          0 :         ret = xsc_dev_pct_init();
     372         [ #  # ]:          0 :         if (ret) {
     373                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to init xsc pct");
     374                 :            :                 ret = -EINVAL;
     375                 :          0 :                 goto hwinfo_init_fail;
     376                 :            :         }
     377                 :            : 
     378                 :          0 :         *xdev = d;
     379                 :            : 
     380                 :          0 :         return 0;
     381                 :            : 
     382                 :          0 : hwinfo_init_fail:
     383                 :          0 :         xsc_dev_uninit(d);
     384                 :          0 :         return ret;
     385                 :            : }
     386                 :            : 
     387                 :            : bool
     388                 :          0 : xsc_dev_is_vf(struct xsc_dev *xdev)
     389                 :            : {
     390                 :          0 :         uint16_t device_id = xdev->pci_dev->id.device_id;
     391                 :            : 
     392                 :          0 :         if (device_id == XSC_PCI_DEV_ID_MSVF ||
     393         [ #  # ]:          0 :             device_id == XSC_PCI_DEV_ID_MVHVF)
     394                 :          0 :                 return true;
     395                 :            : 
     396                 :            :         return false;
     397                 :            : }

Generated by: LCOV version 1.14