dpdk/drivers/raw/octeontx2_ep/otx2_ep_rawdev.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(C) 2019 Marvell International Ltd.
   3 */
   4#include <string.h>
   5#include <unistd.h>
   6
   7#include <rte_bus.h>
   8#include <rte_bus_pci.h>
   9#include <rte_eal.h>
  10#include <rte_lcore.h>
  11#include <rte_mempool.h>
  12#include <rte_pci.h>
  13
  14#include <rte_common.h>
  15#include <rte_rawdev.h>
  16#include <rte_rawdev_pmd.h>
  17
  18#include "otx2_common.h"
  19#include "otx2_ep_rawdev.h"
  20#include "otx2_ep_vf.h"
  21
  22static const struct rte_pci_id pci_sdp_vf_map[] = {
  23        {
  24                RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
  25                               PCI_DEVID_OCTEONTX2_EP_VF)
  26        },
  27        {
  28                .vendor_id = 0,
  29        },
  30};
  31
  32/* SDP_VF default configuration */
  33const struct sdp_config default_sdp_conf = {
  34        /* IQ attributes */
  35        .iq                        = {
  36                .max_iqs           = SDP_VF_CFG_IO_QUEUES,
  37                .instr_type        = SDP_VF_64BYTE_INSTR,
  38                .pending_list_size = (SDP_VF_MAX_IQ_DESCRIPTORS *
  39                                      SDP_VF_CFG_IO_QUEUES),
  40        },
  41
  42        /* OQ attributes */
  43        .oq                        = {
  44                .max_oqs           = SDP_VF_CFG_IO_QUEUES,
  45                .info_ptr          = SDP_VF_OQ_INFOPTR_MODE,
  46                .refill_threshold  = SDP_VF_OQ_REFIL_THRESHOLD,
  47        },
  48
  49        .num_iqdef_descs           = SDP_VF_MAX_IQ_DESCRIPTORS,
  50        .num_oqdef_descs           = SDP_VF_MAX_OQ_DESCRIPTORS,
  51        .oqdef_buf_size            = SDP_VF_OQ_BUF_SIZE,
  52
  53};
  54
  55const struct sdp_config*
  56sdp_get_defconf(struct sdp_device *sdp_dev __rte_unused)
  57{
  58        const struct sdp_config *default_conf = NULL;
  59
  60        default_conf = &default_sdp_conf;
  61
  62        return default_conf;
  63}
  64
  65static int
  66sdp_vfdev_exit(struct rte_rawdev *rawdev)
  67{
  68        struct sdp_device *sdpvf;
  69        uint32_t rawdev_queues, q;
  70
  71        otx2_info("%s:", __func__);
  72
  73        sdpvf = (struct sdp_device *)rawdev->dev_private;
  74
  75        sdpvf->fn_list.disable_io_queues(sdpvf);
  76
  77        rawdev_queues = sdpvf->num_oqs;
  78        for (q = 0; q < rawdev_queues; q++) {
  79                if (sdp_delete_oqs(sdpvf, q)) {
  80                        otx2_err("Failed to delete OQ:%d", q);
  81                        return -ENOMEM;
  82                }
  83        }
  84        otx2_info("Num OQs:%d freed", sdpvf->num_oqs);
  85
  86        /* Free the oqbuf_pool */
  87        rte_mempool_free(sdpvf->enqdeq_mpool);
  88        sdpvf->enqdeq_mpool = NULL;
  89
  90        otx2_info("Enqdeq_mpool free done");
  91
  92        rawdev_queues = sdpvf->num_iqs;
  93        for (q = 0; q < rawdev_queues; q++) {
  94                if (sdp_delete_iqs(sdpvf, q)) {
  95                        otx2_err("Failed to delete IQ:%d", q);
  96                        return -ENOMEM;
  97                }
  98        }
  99        otx2_sdp_dbg("Num IQs:%d freed", sdpvf->num_iqs);
 100
 101        return 0;
 102}
 103
 104static int
 105sdp_chip_specific_setup(struct sdp_device *sdpvf)
 106{
 107        struct rte_pci_device *pdev = sdpvf->pci_dev;
 108        uint32_t dev_id = pdev->id.device_id;
 109        int ret;
 110
 111        switch (dev_id) {
 112        case PCI_DEVID_OCTEONTX2_EP_VF:
 113                sdpvf->chip_id = PCI_DEVID_OCTEONTX2_EP_VF;
 114                ret = sdp_vf_setup_device(sdpvf);
 115
 116                break;
 117        default:
 118                otx2_err("Unsupported device");
 119                ret = -EINVAL;
 120        }
 121
 122        if (!ret)
 123                otx2_info("SDP dev_id[%d]", dev_id);
 124
 125        return ret;
 126}
 127
 128/* SDP VF device initialization */
 129static int
 130sdp_vfdev_init(struct sdp_device *sdpvf)
 131{
 132        uint32_t rawdev_queues, q;
 133
 134        if (sdp_chip_specific_setup(sdpvf)) {
 135                otx2_err("Chip specific setup failed");
 136                goto setup_fail;
 137        }
 138
 139        if (sdpvf->fn_list.setup_device_regs(sdpvf)) {
 140                otx2_err("Failed to configure device registers");
 141                goto setup_fail;
 142        }
 143
 144        rawdev_queues = (uint32_t)(sdpvf->sriov_info.rings_per_vf);
 145
 146        /* Rawdev queues setup for enqueue/dequeue */
 147        for (q = 0; q < rawdev_queues; q++) {
 148                if (sdp_setup_iqs(sdpvf, q)) {
 149                        otx2_err("Failed to setup IQs");
 150                        goto iq_fail;
 151                }
 152        }
 153        otx2_info("Total[%d] IQs setup", sdpvf->num_iqs);
 154
 155        for (q = 0; q < rawdev_queues; q++) {
 156                if (sdp_setup_oqs(sdpvf, q)) {
 157                        otx2_err("Failed to setup OQs");
 158                        goto oq_fail;
 159                }
 160        }
 161        otx2_info("Total [%d] OQs setup", sdpvf->num_oqs);
 162
 163        /* Enable IQ/OQ for this device */
 164        sdpvf->fn_list.enable_io_queues(sdpvf);
 165
 166        /* Send OQ desc credits for OQs, credits are always
 167         * sent after the OQs are enabled.
 168         */
 169        for (q = 0; q < rawdev_queues; q++) {
 170                rte_write32(sdpvf->droq[q]->nb_desc,
 171                            sdpvf->droq[q]->pkts_credit_reg);
 172
 173                rte_io_mb();
 174                otx2_info("OQ[%d] dbells [%d]", q,
 175                rte_read32(sdpvf->droq[q]->pkts_credit_reg));
 176        }
 177
 178        rte_wmb();
 179
 180        otx2_info("SDP Device is Ready");
 181
 182        return 0;
 183
 184/* Error handling  */
 185oq_fail:
 186        /* Free the allocated OQs */
 187        for (q = 0; q < sdpvf->num_oqs; q++)
 188                sdp_delete_oqs(sdpvf, q);
 189
 190iq_fail:
 191        /* Free the allocated IQs */
 192        for (q = 0; q < sdpvf->num_iqs; q++)
 193                sdp_delete_iqs(sdpvf, q);
 194
 195setup_fail:
 196        return -ENOMEM;
 197}
 198
 199static int
 200sdp_rawdev_start(struct rte_rawdev *dev)
 201{
 202        dev->started = 1;
 203
 204        return 0;
 205}
 206
 207static void
 208sdp_rawdev_stop(struct rte_rawdev *dev)
 209{
 210        dev->started = 0;
 211}
 212
 213static int
 214sdp_rawdev_close(struct rte_rawdev *dev)
 215{
 216        int ret;
 217        ret = sdp_vfdev_exit(dev);
 218        if (ret) {
 219                otx2_err(" SDP_EP rawdev exit error");
 220                return ret;
 221        }
 222
 223        return 0;
 224}
 225
 226static int
 227sdp_rawdev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config,
 228                size_t config_size)
 229{
 230        struct sdp_rawdev_info *app_info = (struct sdp_rawdev_info *)config;
 231        struct sdp_device *sdpvf;
 232
 233        if (app_info == NULL || config_size != sizeof(*app_info)) {
 234                otx2_err("Application config info [NULL] or incorrect size");
 235                return -EINVAL;
 236        }
 237
 238        sdpvf = (struct sdp_device *)dev->dev_private;
 239
 240        sdpvf->conf = app_info->app_conf;
 241        sdpvf->enqdeq_mpool = app_info->enqdeq_mpool;
 242
 243        sdp_vfdev_init(sdpvf);
 244
 245        return 0;
 246
 247}
 248
 249/* SDP VF endpoint rawdev ops */
 250static const struct rte_rawdev_ops sdp_rawdev_ops = {
 251        .dev_configure  = sdp_rawdev_configure,
 252        .dev_start      = sdp_rawdev_start,
 253        .dev_stop       = sdp_rawdev_stop,
 254        .dev_close      = sdp_rawdev_close,
 255        .enqueue_bufs   = sdp_rawdev_enqueue,
 256        .dequeue_bufs   = sdp_rawdev_dequeue,
 257        .dev_selftest   = sdp_rawdev_selftest,
 258};
 259
 260static int
 261otx2_sdp_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
 262                      struct rte_pci_device *pci_dev)
 263{
 264        char name[RTE_RAWDEV_NAME_MAX_LEN];
 265        struct sdp_device *sdpvf = NULL;
 266        struct rte_rawdev *sdp_rawdev;
 267        uint16_t vf_id;
 268
 269        /* Single process support */
 270        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 271                return 0;
 272
 273        if (pci_dev->mem_resource[0].addr)
 274                otx2_info("SDP_EP BAR0 is mapped:");
 275        else {
 276                otx2_err("SDP_EP: Failed to map device BARs");
 277                otx2_err("BAR0 %p\n BAR2 %p",
 278                        pci_dev->mem_resource[0].addr,
 279                        pci_dev->mem_resource[2].addr);
 280                return -ENODEV;
 281        }
 282
 283        memset(name, 0, sizeof(name));
 284        snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
 285                 pci_dev->addr.bus, pci_dev->addr.devid,
 286                 pci_dev->addr.function);
 287
 288        /* Allocate rawdev pmd */
 289        sdp_rawdev = rte_rawdev_pmd_allocate(name,
 290                                             sizeof(struct sdp_device),
 291                                             rte_socket_id());
 292
 293        if (sdp_rawdev == NULL) {
 294                otx2_err("SDP_EP VF rawdev allocation failed");
 295                return -ENOMEM;
 296        }
 297
 298        sdp_rawdev->dev_ops = &sdp_rawdev_ops;
 299        sdp_rawdev->device = &pci_dev->device;
 300        sdp_rawdev->driver_name = pci_dev->driver->driver.name;
 301
 302        sdpvf = (struct sdp_device *)sdp_rawdev->dev_private;
 303        sdpvf->hw_addr = pci_dev->mem_resource[0].addr;
 304        sdpvf->pci_dev = pci_dev;
 305
 306        /* Discover the VF number being probed */
 307        vf_id = ((pci_dev->addr.devid & 0x1F) << 3) |
 308                 (pci_dev->addr.function & 0x7);
 309
 310        vf_id -= 1;
 311        sdpvf->vf_num = vf_id;
 312
 313        otx2_info("SDP_EP VF[%d] probe done", vf_id);
 314
 315        return 0;
 316}
 317
 318static int
 319otx2_sdp_rawdev_remove(struct rte_pci_device *pci_dev)
 320{
 321        char name[RTE_RAWDEV_NAME_MAX_LEN];
 322        struct rte_rawdev *rawdev;
 323        struct sdp_device *sdpvf;
 324
 325        /* Single process support */
 326        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 327                return 0;
 328
 329        if (pci_dev == NULL) {
 330                otx2_err("SDP_EP:invalid pci_dev!");
 331                return -EINVAL;
 332        }
 333
 334
 335        memset(name, 0, sizeof(name));
 336        snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "SDPEP:%x:%02x.%x",
 337                 pci_dev->addr.bus, pci_dev->addr.devid,
 338                 pci_dev->addr.function);
 339
 340        rawdev = rte_rawdev_pmd_get_named_dev(name);
 341        if (rawdev == NULL) {
 342                otx2_err("SDP_EP: invalid device name (%s)", name);
 343                return -EINVAL;
 344        }
 345
 346        sdpvf = (struct sdp_device *)rawdev->dev_private;
 347        otx2_info("Removing SDP_EP VF[%d] ", sdpvf->vf_num);
 348
 349        /* rte_rawdev_close is called by pmd_release */
 350        return rte_rawdev_pmd_release(rawdev);
 351}
 352
 353static struct rte_pci_driver rte_sdp_rawdev_pmd = {
 354        .id_table  = pci_sdp_vf_map,
 355        .drv_flags = (RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA),
 356        .probe     = otx2_sdp_rawdev_probe,
 357        .remove    = otx2_sdp_rawdev_remove,
 358};
 359
 360RTE_PMD_REGISTER_PCI(sdp_rawdev_pci_driver, rte_sdp_rawdev_pmd);
 361RTE_PMD_REGISTER_PCI_TABLE(sdp_rawdev_pci_driver, pci_sdp_vf_map);
 362RTE_PMD_REGISTER_KMOD_DEP(sdp_rawdev_pci_driver, "vfio-pci");
 363