From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6FCA8A0540; Wed, 6 Jul 2022 09:56:49 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AB20842905; Wed, 6 Jul 2022 09:56:33 +0200 (CEST) Received: from mail-pg1-f174.google.com (mail-pg1-f174.google.com [209.85.215.174]) by mails.dpdk.org (Postfix) with ESMTP id 3003442B82 for ; Wed, 6 Jul 2022 09:56:32 +0200 (CEST) Received: by mail-pg1-f174.google.com with SMTP id i190so796560pge.7 for ; Wed, 06 Jul 2022 00:56:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vvdntech-in.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BkQEBo5BytwtDtDPJN5tlkESvPcjjXyDNgbfWQVmeB8=; b=K8I1MgyVi0P1AcG584TYUgSiBSo7gP0jMx3bMaelOx4x71y5cWyJ51vT2Lqr0S55Tg AsQVR0aITrSvmI8WQWX/aeKEwfgkUc1RS1nZyb9nvVvf9l4vmeK37S8qP5JS2KViWJ9z xZVHmIeHMqQ5mflqqwDzGqxS2Ax0Xs5wld1VNgbS1sUxNi2wsZ3qqdRCcO1CJxwYqrw9 t4Z7vTKeM9XjQftszSZ2ZSLdsqOxvGyJN/61jGTinJSwPCw6In/Hs3kuk/qJkZ0C66Ut Y/X2YJicDAb5QO5JIbcOoDMFnYevPQ+1LHVMm/YpmXcfjmGX/qJfJc7R+JK0tq/U4Z9K j+lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BkQEBo5BytwtDtDPJN5tlkESvPcjjXyDNgbfWQVmeB8=; b=2z1p2imv2sIlYvqBgyZ9HWL3ja/TzZsEJeKWX2Z6UK04H/NrprPOzBSeZXtKZvf5Kk VeOO+swz4ddBAR2YkOD+5f97fhG9lwDflDh2n9I0Loo1bt2+rTyzQHppTqj1mNq0rAsJ KT8Qx2rcZxw350PhjyGhGTlOr2Bd40TcjJbZK3u8UQe/v1+sZeAYChTpH37z/SYzPiiG 25KGUF7V54+xByjg8uOMGaW2eVU3J/DHWMGmIG/iqcoq/rsw4aTi5EJh7A7xbZm/Bb+Z 0h+o8VCtNwZj1wwP1efgMbwJn5vqQfZemuSWH8FoHdKUnPsQVrJ5cBnMmdZ96F4rl1JL 4L+A== X-Gm-Message-State: AJIora8rnI7CZH7tZ+DJqvERAa18kSAEbdAQmQZYOmBSRo8SSCF5KRg/ B+500El1x5RF3i6C4tACL1r3pgNwUtUzRyXc X-Google-Smtp-Source: AGRyM1t7ez1E5WPVA48kzi2lFoAgFqisfv/srGJtRlRAl6vP+siGT0qStf2Tel4MGOzjI89IC5IjTg== X-Received: by 2002:a63:610a:0:b0:412:94d2:912c with SMTP id v10-20020a63610a000000b0041294d2912cmr2129051pgb.134.1657094191161; Wed, 06 Jul 2022 00:56:31 -0700 (PDT) Received: from 470--5GDC--BLR.blore.vvdntech.com ([106.51.39.131]) by smtp.gmail.com with ESMTPSA id r4-20020a17090a438400b001ef81574355sm7378805pjg.12.2022.07.06.00.56.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Jul 2022 00:56:30 -0700 (PDT) From: Aman Kumar To: dev@dpdk.org Cc: maxime.coquelin@redhat.com, david.marchand@redhat.com, aman.kumar@vvdntech.in Subject: [RFC PATCH 08/29] net/qdma: qdma hardware initialization Date: Wed, 6 Jul 2022 13:21:58 +0530 Message-Id: <20220706075219.517046-9-aman.kumar@vvdntech.in> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220706075219.517046-1-aman.kumar@vvdntech.in> References: <20220706075219.517046-1-aman.kumar@vvdntech.in> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org add hardware initialization as per qdma_access lib. Fetch hardware version and other details and bind to proper qdma layer. Signed-off-by: Aman Kumar --- drivers/net/qdma/qdma.h | 13 +- drivers/net/qdma/qdma_common.c | 52 +++++++- drivers/net/qdma/qdma_ethdev.c | 225 ++++++++++++++++++++++++++++++++- 3 files changed, 286 insertions(+), 4 deletions(-) diff --git a/drivers/net/qdma/qdma.h b/drivers/net/qdma/qdma.h index 4bc61d2a08..db59cddd25 100644 --- a/drivers/net/qdma/qdma.h +++ b/drivers/net/qdma/qdma.h @@ -15,6 +15,8 @@ #include #include #include + +#include "qdma_resource_mgmt.h" #include "qdma_log.h" #define QDMA_NUM_BARS (6) @@ -23,6 +25,8 @@ #define QDMA_FUNC_ID_INVALID 0xFFFF +#define DEFAULT_QUEUE_BASE (0) + #define DEFAULT_TIMER_CNT_TRIG_MODE_TIMER (5) enum dma_data_direction { @@ -186,6 +190,9 @@ struct qdma_pci_dev { */ uint32_t dma_device_index; + /* Device capabilities */ + struct qdma_dev_attributes dev_cap; + uint8_t cmpt_desc_len; uint8_t c2h_bypass_mode; uint8_t h2c_bypass_mode; @@ -210,6 +217,9 @@ struct qdma_pci_dev { struct queue_info *q_info; uint8_t init_q_range; + /* Pointer to QDMA access layer function pointers */ + struct qdma_hw_access *hw_access; + struct qdma_vf_info *vfinfo; uint8_t vf_online_count; @@ -218,8 +228,9 @@ struct qdma_pci_dev { }; int qdma_identify_bars(struct rte_eth_dev *dev); +int qdma_get_hw_version(struct rte_eth_dev *dev); int qdma_check_kvargs(struct rte_devargs *devargs, struct qdma_pci_dev *qdma_dev); - +void qdma_check_errors(void *arg); #endif /* ifndef __QDMA_H__ */ diff --git a/drivers/net/qdma/qdma_common.c b/drivers/net/qdma/qdma_common.c index c0c5162f0f..0ea920f255 100644 --- a/drivers/net/qdma/qdma_common.c +++ b/drivers/net/qdma/qdma_common.c @@ -10,6 +10,7 @@ #include #include #include "qdma.h" +#include "qdma_access_common.h" #include #include @@ -199,7 +200,8 @@ int qdma_check_kvargs(struct rte_devargs *devargs, int qdma_identify_bars(struct rte_eth_dev *dev) { - int bar_len, i; + int bar_len, i, ret; + uint8_t usr_bar; struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); struct qdma_pci_dev *dma_priv; @@ -213,6 +215,24 @@ int qdma_identify_bars(struct rte_eth_dev *dev) return -1; } + /* Find AXI Master Lite(user bar) */ + ret = dma_priv->hw_access->qdma_get_user_bar(dev, + dma_priv->is_vf, dma_priv->func_id, &usr_bar); + if (ret != QDMA_SUCCESS || + pci_dev->mem_resource[usr_bar].len == 0) { + if (dma_priv->ip_type == QDMA_VERSAL_HARD_IP) { + if (pci_dev->mem_resource[1].len == 0) + dma_priv->user_bar_idx = 2; + else + dma_priv->user_bar_idx = 1; + } else { + dma_priv->user_bar_idx = -1; + PMD_DRV_LOG(INFO, "Cannot find AXI Master Lite BAR"); + } + } else { + dma_priv->user_bar_idx = usr_bar; + } + /* Find AXI Bridge Master bar(bypass bar) */ for (i = 0; i < QDMA_NUM_BARS; i++) { bar_len = pci_dev->mem_resource[i].len; @@ -234,3 +254,33 @@ int qdma_identify_bars(struct rte_eth_dev *dev) return 0; } +int qdma_get_hw_version(struct rte_eth_dev *dev) +{ + int ret; + struct qdma_pci_dev *dma_priv; + struct qdma_hw_version_info version_info; + + dma_priv = (struct qdma_pci_dev *)dev->data->dev_private; + ret = dma_priv->hw_access->qdma_get_version(dev, + dma_priv->is_vf, &version_info); + if (ret < 0) + return dma_priv->hw_access->qdma_get_error_code(ret); + + dma_priv->rtl_version = version_info.rtl_version; + dma_priv->vivado_rel = version_info.vivado_release; + dma_priv->device_type = version_info.device_type; + dma_priv->ip_type = version_info.ip_type; + + PMD_DRV_LOG(INFO, "QDMA RTL VERSION : %s\n", + version_info.qdma_rtl_version_str); + PMD_DRV_LOG(INFO, "QDMA DEVICE TYPE : %s\n", + version_info.qdma_device_type_str); + PMD_DRV_LOG(INFO, "QDMA VIVADO RELEASE ID : %s\n", + version_info.qdma_vivado_release_id_str); + if (version_info.ip_type == QDMA_VERSAL_HARD_IP) { + PMD_DRV_LOG(INFO, "QDMA VERSAL IP TYPE : %s\n", + version_info.qdma_ip_type_str); + } + + return 0; +} diff --git a/drivers/net/qdma/qdma_ethdev.c b/drivers/net/qdma/qdma_ethdev.c index c2ed6a52bb..bc902e607f 100644 --- a/drivers/net/qdma/qdma_ethdev.c +++ b/drivers/net/qdma/qdma_ethdev.c @@ -22,11 +22,27 @@ #include #include "qdma.h" +#include "qdma_version.h" +#include "qdma_access_common.h" +#include "qdma_access_export.h" +/* Poll for QDMA errors every 1 second */ +#define QDMA_ERROR_POLL_FRQ (1000000) #define PCI_CONFIG_BRIDGE_DEVICE (6) #define PCI_CONFIG_CLASS_CODE_SHIFT (16) #define MAX_PCIE_CAPABILITY (48) +static void qdma_device_attributes_get(struct rte_eth_dev *dev); + +/* Poll for any QDMA errors */ +void qdma_check_errors(void *arg) +{ + struct qdma_pci_dev *qdma_dev; + qdma_dev = ((struct rte_eth_dev *)arg)->data->dev_private; + qdma_dev->hw_access->qdma_hw_error_process(arg); + rte_eal_alarm_set(QDMA_ERROR_POLL_FRQ, qdma_check_errors, arg); +} + /* * The set of PCI devices this driver supports */ @@ -43,6 +59,92 @@ static struct rte_pci_id qdma_pci_id_tbl[] = { { .vendor_id = 0, /* sentinel */ }, }; +static void qdma_device_attributes_get(struct rte_eth_dev *dev) +{ + struct qdma_pci_dev *qdma_dev; + + qdma_dev = (struct qdma_pci_dev *)dev->data->dev_private; + qdma_dev->hw_access->qdma_get_device_attributes(dev, + &qdma_dev->dev_cap); + + /* Check DPDK configured queues per port */ + if (qdma_dev->dev_cap.num_qs > RTE_MAX_QUEUES_PER_PORT) + qdma_dev->dev_cap.num_qs = RTE_MAX_QUEUES_PER_PORT; + + PMD_DRV_LOG(INFO, "qmax = %d, mm %d, st %d.\n", + qdma_dev->dev_cap.num_qs, qdma_dev->dev_cap.mm_en, + qdma_dev->dev_cap.st_en); +} + +static inline uint8_t pcie_find_cap(const struct rte_pci_device *pci_dev, + uint8_t cap) +{ + uint8_t pcie_cap_pos = 0; + uint8_t pcie_cap_id = 0; + int ttl = MAX_PCIE_CAPABILITY; + int ret; + + ret = rte_pci_read_config(pci_dev, &pcie_cap_pos, sizeof(uint8_t), + PCI_CAPABILITY_LIST); + if (ret < 0) { + PMD_DRV_LOG(ERR, "PCIe config space read failed..\n"); + return 0; + } + + while (ttl-- && pcie_cap_pos >= PCI_STD_HEADER_SIZEOF) { + pcie_cap_pos &= ~3; + + ret = rte_pci_read_config(pci_dev, + &pcie_cap_id, sizeof(uint8_t), + (pcie_cap_pos + PCI_CAP_LIST_ID)); + if (ret < 0) { + PMD_DRV_LOG(ERR, "PCIe config space read failed..\n"); + return 0; + } + + if (pcie_cap_id == 0xff) + break; + + if (pcie_cap_id == cap) + return pcie_cap_pos; + + ret = rte_pci_read_config(pci_dev, + &pcie_cap_pos, sizeof(uint8_t), + (pcie_cap_pos + PCI_CAP_LIST_NEXT)); + if (ret < 0) { + PMD_DRV_LOG(ERR, "PCIe config space read failed..\n"); + return 0; + } + } + + return 0; +} + +static void pcie_perf_enable(const struct rte_pci_device *pci_dev) +{ + uint16_t value; + uint8_t pcie_cap_pos = pcie_find_cap(pci_dev, PCI_CAP_ID_EXP); + + if (!pcie_cap_pos) + return; + + if (pcie_cap_pos > 0) { + if (rte_pci_read_config(pci_dev, &value, sizeof(uint16_t), + pcie_cap_pos + PCI_EXP_DEVCTL) < 0) { + PMD_DRV_LOG(ERR, "PCIe config space read failed..\n"); + return; + } + + value |= (PCI_EXP_DEVCTL_EXT_TAG | PCI_EXP_DEVCTL_RELAX_EN); + + if (rte_pci_write_config(pci_dev, &value, sizeof(uint16_t), + pcie_cap_pos + PCI_EXP_DEVCTL) < 0) { + PMD_DRV_LOG(ERR, "PCIe config space write failed..\n"); + return; + } + } +} + /* parse a sysfs file containing one integer value */ static int parse_sysfs_value(const char *filename, uint32_t *val) { @@ -234,7 +336,7 @@ static int qdma_eth_dev_init(struct rte_eth_dev *dev) { struct qdma_pci_dev *dma_priv; uint8_t *baseaddr; - int i, idx, ret; + int i, idx, ret, qbase; struct rte_pci_device *pci_dev; uint16_t num_vfs; uint8_t max_pci_bus = 0; @@ -297,8 +399,30 @@ static int qdma_eth_dev_init(struct rte_eth_dev *dev) pci_dev->mem_resource[dma_priv->config_bar_idx].addr; dma_priv->bar_addr[dma_priv->config_bar_idx] = baseaddr; + /* Assigning QDMA access layer function pointers based on the HW design */ + dma_priv->hw_access = rte_zmalloc("hwaccess", + sizeof(struct qdma_hw_access), 0); + if (dma_priv->hw_access == NULL) { + rte_free(dev->data->mac_addrs); + return -ENOMEM; + } + idx = qdma_hw_access_init(dev, dma_priv->is_vf, dma_priv->hw_access); + if (idx < 0) { + rte_free(dma_priv->hw_access); + rte_free(dev->data->mac_addrs); + return -EINVAL; + } + + idx = qdma_get_hw_version(dev); + if (idx < 0) { + rte_free(dma_priv->hw_access); + rte_free(dev->data->mac_addrs); + return -EINVAL; + } + idx = qdma_identify_bars(dev); if (idx < 0) { + rte_free(dma_priv->hw_access); rte_free(dev->data->mac_addrs); return -EINVAL; } @@ -312,14 +436,99 @@ static int qdma_eth_dev_init(struct rte_eth_dev *dev) PMD_DRV_LOG(INFO, "QDMA device driver probe:"); + /* Getting the device attributes from the Hardware */ + qdma_device_attributes_get(dev); + + /* Create master resource node for queue management on the given + * bus number. Node will be created only once per bus number. + */ + qbase = DEFAULT_QUEUE_BASE; + ret = get_max_pci_bus_num(pci_dev->addr.bus, &max_pci_bus); - if (ret != 0 && !max_pci_bus) { + if (ret != QDMA_SUCCESS && !max_pci_bus) { PMD_DRV_LOG(ERR, "Failed to get max pci bus number\n"); + rte_free(dma_priv->hw_access); rte_free(dev->data->mac_addrs); return -EINVAL; } PMD_DRV_LOG(INFO, "PCI max bus number : 0x%x", max_pci_bus); + ret = qdma_master_resource_create(pci_dev->addr.bus, max_pci_bus, + qbase, dma_priv->dev_cap.num_qs, + &dma_priv->dma_device_index); + if (ret == -QDMA_ERR_NO_MEM) { + rte_free(dma_priv->hw_access); + rte_free(dev->data->mac_addrs); + return -ENOMEM; + } + + dma_priv->hw_access->qdma_get_function_number(dev, + &dma_priv->func_id); + PMD_DRV_LOG(INFO, "PF function ID: %d", dma_priv->func_id); + + /* CSR programming is done once per given board or bus number, + * done by the master PF + */ + if (ret == QDMA_SUCCESS) { + RTE_LOG(INFO, PMD, "QDMA PMD VERSION: %s\n", QDMA_PMD_VERSION); + dma_priv->hw_access->qdma_set_default_global_csr(dev); + for (i = 0; i < dma_priv->dev_cap.mm_channel_max; i++) { + if (dma_priv->dev_cap.mm_en) { + /* Enable MM C2H Channel */ + dma_priv->hw_access->qdma_mm_channel_conf(dev, + i, 1, 1); + /* Enable MM H2C Channel */ + dma_priv->hw_access->qdma_mm_channel_conf(dev, + i, 0, 1); + } else { + /* Disable MM C2H Channel */ + dma_priv->hw_access->qdma_mm_channel_conf(dev, + i, 1, 0); + /* Disable MM H2C Channel */ + dma_priv->hw_access->qdma_mm_channel_conf(dev, + i, 0, 0); + } + } + + ret = dma_priv->hw_access->qdma_init_ctxt_memory(dev); + if (ret < 0) { + PMD_DRV_LOG(ERR, + "%s: Failed to initialize ctxt memory, err = %d\n", + __func__, ret); + return -EINVAL; + } + + dma_priv->hw_access->qdma_hw_error_enable(dev, + dma_priv->hw_access->qdma_max_errors); + if (ret < 0) { + PMD_DRV_LOG(ERR, + "%s: Failed to enable hw errors, err = %d\n", + __func__, ret); + return -EINVAL; + } + + rte_eal_alarm_set(QDMA_ERROR_POLL_FRQ, qdma_check_errors, + (void *)dev); + dma_priv->is_master = 1; + } + + /* + * Create an entry for the device in board list if not already + * created + */ + ret = qdma_dev_entry_create(dma_priv->dma_device_index, + dma_priv->func_id); + if (ret != QDMA_SUCCESS && + ret != -QDMA_ERR_RM_DEV_EXISTS) { + PMD_DRV_LOG(ERR, "PF-%d(DEVFN) qdma_dev_entry_create failed: %d\n", + dma_priv->func_id, ret); + rte_free(dma_priv->hw_access); + rte_free(dev->data->mac_addrs); + return -ENOMEM; + } + + pcie_perf_enable(pci_dev); + if (!dma_priv->reset_in_progress) { num_vfs = pci_dev->max_vfs; if (num_vfs) { @@ -358,6 +567,14 @@ static int qdma_eth_dev_uninit(struct rte_eth_dev *dev) /* only uninitialize in the primary process */ if (rte_eal_process_type() != RTE_PROC_PRIMARY) return -EPERM; + /* cancel pending polls */ + if (qdma_dev->is_master) + rte_eal_alarm_cancel(qdma_check_errors, (void *)dev); + + /* Remove the device node from the board list */ + qdma_dev_entry_destroy(qdma_dev->dma_device_index, + qdma_dev->func_id); + qdma_master_resource_destroy(qdma_dev->dma_device_index); dev->dev_ops = NULL; dev->rx_pkt_burst = NULL; @@ -381,6 +598,10 @@ static int qdma_eth_dev_uninit(struct rte_eth_dev *dev) qdma_dev->q_info = NULL; } + if (qdma_dev->hw_access != NULL) { + rte_free(qdma_dev->hw_access); + qdma_dev->hw_access = NULL; + } return 0; } -- 2.36.1