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 B7180A0540; Thu, 7 Jul 2022 04:42:01 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 49ACF40A7B; Thu, 7 Jul 2022 04:42:01 +0200 (CEST) Received: from mail-pf1-f176.google.com (mail-pf1-f176.google.com [209.85.210.176]) by mails.dpdk.org (Postfix) with ESMTP id 1A422406B4 for ; Thu, 7 Jul 2022 04:42:00 +0200 (CEST) Received: by mail-pf1-f176.google.com with SMTP id o12so3051741pfp.5 for ; Wed, 06 Jul 2022 19:42:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vvdntech-in.20210112.gappssmtp.com; s=20210112; h=message-id:date:mime-version:user-agent:subject:content-language:to :cc:references:from:in-reply-to:content-transfer-encoding; bh=oOJ6z3MDZ59ci6wPcyyKx06yfnDnvd92LTgRr3gjX6g=; b=ewH7UaCU/MsU8hANwcwZJgI3N6swzz3AJYdY3mT7Ii6hg6hRwdC7rhqjyVvpNtt1// WoAjToN+e//AKkrUULRoByOO5ndI72P29NMa+C57b11bc3LXubVKRUXv/0GWqKNPlVRM ul/Zvzl7rRnVcnpe5l/Uskv5pdDJjmYWEqyhhUkPxws+FvGv4ZRSb3mOFFTtAfZbFNTm RM/5LNiWEhjTHvYKajimwS3YOEocDvQ9eWem4pYxOomgH/h0Er3npSqmZ4lRPaSViBu7 cr0t9u1RBiA9tpqxIx9dkI8OaB7OwehHzGQMi22oPpg70RgoyvxunP5QWTvXkkU3OGfB 2KrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=oOJ6z3MDZ59ci6wPcyyKx06yfnDnvd92LTgRr3gjX6g=; b=Uztxbs0b0nrUUGZgI0CkTiRfMXlhAdSa+J+qoUiMgVKJzHkbtyr5Gf6agHrci8e3k8 DUx8s5aGRmOfCIG+oAmNmtEWI2mYue+CqFCzQCiwqXaAVCzJBDDuCoxfslG8rNVkSQ7J S+4QtShIXQ5h9gtp+RpJwQCHSeeUciF0v3sxkI72gr2opn/j2ofMrE9x321H1O4R7yj4 JHYHBDwbVleYxN1YXxCz03kcFx8XG29e7FvzNt5LGMX/BqozCb01uNJmmyIU6MgobfAy 6MKStKuALLJ+n74YIGqhaeSZvSXBQV3uqXHiDlK5dHCDx4tEZh19S52XfjmF+zBTNnPZ NWMQ== X-Gm-Message-State: AJIora/K7tP41kR6eLJETvkLOrXNpsbZU5smhvMuzG54RqUXh6M1hDpu ZCRR8gJM/vgQy7Amm2WvYrT0yA== X-Google-Smtp-Source: AGRyM1vSx2wSozV9bdSCiCq8I/tnrtIAybekcpBpemhF4JFwW9amIxSb6WWl9tB69VaHeT4TqAyBLA== X-Received: by 2002:a05:6a00:24cc:b0:50d:58bf:5104 with SMTP id d12-20020a056a0024cc00b0050d58bf5104mr49584442pfv.36.1657161719127; Wed, 06 Jul 2022 19:41:59 -0700 (PDT) Received: from [172.24.1.88] ([49.249.29.178]) by smtp.gmail.com with ESMTPSA id p47-20020a056a0026ef00b0050dc7628150sm25592435pfw.42.2022.07.06.19.41.56 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 06 Jul 2022 19:41:58 -0700 (PDT) Message-ID: <06eada6b-266d-891b-69e4-dd2d76ed7712@vvdntech.in> Date: Thu, 7 Jul 2022 08:11:54 +0530 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.9.1 Subject: Re: [RFC PATCH 05/29] net/qdma: add device init and uninit functions Content-Language: en-US To: Stephen Hemminger Cc: dev@dpdk.org, maxime.coquelin@redhat.com, david.marchand@redhat.com References: <20220706075219.517046-1-aman.kumar@vvdntech.in> <20220706075219.517046-6-aman.kumar@vvdntech.in> <20220706083509.58b3c01e@hermes.local> From: Aman Kumar In-Reply-To: <20220706083509.58b3c01e@hermes.local> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit 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 On 06/07/22 9:05 pm, Stephen Hemminger wrote: > On Wed, 6 Jul 2022 13:21:55 +0530 > Aman Kumar wrote: > >> +/* parse a sysfs file containing one integer value */ >> +static int parse_sysfs_value(const char *filename, uint32_t *val) >> +{ >> + FILE *f; >> + char buf[BUFSIZ]; >> + char *end = NULL; >> + >> + f = fopen(filename, "r"); >> + if (f == NULL) { >> + PMD_DRV_LOG(ERR, "%s(): Failed to open sysfs file %s\n", >> + __func__, filename); >> + return -1; >> + } >> + >> + if (fgets(buf, sizeof(buf), f) == NULL) { >> + PMD_DRV_LOG(ERR, "%s(): Failed to read sysfs value %s\n", >> + __func__, filename); >> + fclose(f); >> + return -1; >> + } >> + *val = (uint32_t)strtoul(buf, &end, 0); >> + if ((buf[0] == '\0') || end == NULL || (*end != '\n')) { >> + PMD_DRV_LOG(ERR, "%s(): Failed to parse sysfs value %s\n", >> + __func__, filename); >> + fclose(f); >> + return -1; >> + } >> + fclose(f); >> + return 0; >> +} > Why reinvent eal_parse_sysfs_value? I'll rework this and adapt to existing DPDK APIs. > >> +/* Split up a pci address into its constituent parts. */ >> +static int parse_pci_addr_format(const char *buf, >> + int bufsize, struct rte_pci_addr *addr) >> +{ >> + /* first split on ':' */ >> + union splitaddr { >> + struct { >> + char *domain; >> + char *bus; >> + char *devid; >> + char *function; >> + }; >> + /* last element-separator is "." not ":" */ >> + char *str[PCI_FMT_NVAL]; >> + } splitaddr; >> + >> + char *buf_copy = strndup(buf, bufsize); >> + if (buf_copy == NULL) { >> + PMD_DRV_LOG(ERR, "Failed to get pci address duplicate copy\n"); >> + return -1; >> + } >> + >> + if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':') >> + != PCI_FMT_NVAL - 1) { >> + PMD_DRV_LOG(ERR, "Failed to split pci address string\n"); >> + goto error; >> + } >> + >> + /* final split is on '.' between devid and function */ >> + splitaddr.function = strchr(splitaddr.devid, '.'); >> + if (splitaddr.function == NULL) { >> + PMD_DRV_LOG(ERR, "Failed to split pci devid and function\n"); >> + goto error; >> + } >> + *splitaddr.function++ = '\0'; >> + >> + /* now convert to int values */ >> + addr->domain = strtoul(splitaddr.domain, NULL, 16); >> + addr->bus = strtoul(splitaddr.bus, NULL, 16); >> + addr->devid = strtoul(splitaddr.devid, NULL, 16); >> + addr->function = strtoul(splitaddr.function, NULL, 10); >> + >> + free(buf_copy); /* free the copy made with strdup */ >> + return 0; >> + >> +error: >> + free(buf_copy); >> + return -1; >> +} > Looks like you didn't see rte_pci_addr_parse.. I'll rework this and adapt to existing DPDK APIs. >> +/* Get max pci bus number from the corresponding pci bridge device */ >> +static int get_max_pci_bus_num(uint8_t start_bus, uint8_t *end_bus) >> +{ >> + char dirname[PATH_MAX]; >> + char filename[PATH_MAX]; >> + char cfgname[PATH_MAX]; >> + struct rte_pci_addr addr; >> + struct dirent *dp; >> + uint32_t pci_class_code; >> + uint8_t sec_bus_num, sub_bus_num; >> + DIR *dir; >> + int ret, fd; >> + >> + /* Initialize end bus number to zero */ >> + *end_bus = 0; >> + >> + /* Open pci devices directory */ >> + dir = opendir(rte_pci_get_sysfs_path()); >> + if (dir == NULL) { >> + PMD_DRV_LOG(ERR, "%s(): opendir failed\n", >> + __func__); >> + return -1; >> + } >> + >> + while ((dp = readdir(dir)) != NULL) { >> + if (dp->d_name[0] == '.') >> + continue; >> + >> + /* Split pci address to get bus, devid and function numbers */ >> + if (parse_pci_addr_format(dp->d_name, >> + sizeof(dp->d_name), &addr) != 0) >> + continue; >> + >> + snprintf(dirname, sizeof(dirname), "%s/%s", >> + rte_pci_get_sysfs_path(), dp->d_name); >> + >> + /* get class code */ >> + snprintf(filename, sizeof(filename), "%s/class", dirname); >> + if (parse_sysfs_value(filename, &pci_class_code) < 0) { >> + PMD_DRV_LOG(ERR, "Failed to get pci class code\n"); >> + goto error; >> + } >> + >> + /* Get max pci number from pci bridge device */ >> + if ((((pci_class_code >> PCI_CONFIG_CLASS_CODE_SHIFT) & 0xFF) == >> + PCI_CONFIG_BRIDGE_DEVICE)) { >> + snprintf(cfgname, sizeof(cfgname), >> + "%s/config", dirname); >> + fd = open(cfgname, O_RDWR); >> + if (fd < 0) { >> + PMD_DRV_LOG(ERR, "Failed to open %s\n", >> + cfgname); >> + goto error; >> + } >> + >> + /* get secondary bus number */ >> + ret = pread(fd, &sec_bus_num, sizeof(uint8_t), >> + PCI_SECONDARY_BUS); >> + if (ret == -1) { >> + PMD_DRV_LOG(ERR, "Failed to read secondary bus number\n"); >> + close(fd); >> + goto error; >> + } >> + >> + /* get subordinate bus number */ >> + ret = pread(fd, &sub_bus_num, sizeof(uint8_t), >> + PCI_SUBORDINATE_BUS); >> + if (ret == -1) { >> + PMD_DRV_LOG(ERR, "Failed to read subordinate bus number\n"); >> + close(fd); >> + goto error; >> + } >> + >> + /* Get max bus number by checking if given bus number >> + * falls in between secondary and subordinate bus >> + * numbers of this pci bridge device. >> + */ >> + if (start_bus >= sec_bus_num && >> + start_bus <= sub_bus_num) { >> + *end_bus = sub_bus_num; >> + close(fd); >> + closedir(dir); >> + return 0; >> + } >> + >> + close(fd); >> + } >> + } >> + >> +error: >> + closedir(dir); >> + return -1; >> +} >> + >> /** >> * DPDK callback to register a PCI device. >> * >> @@ -39,7 +232,12 @@ static struct rte_pci_id qdma_pci_id_tbl[] = { >> */ >> static int qdma_eth_dev_init(struct rte_eth_dev *dev) >> { >> + struct qdma_pci_dev *dma_priv; >> + uint8_t *baseaddr; >> + int i, idx, ret; >> struct rte_pci_device *pci_dev; >> + uint16_t num_vfs; >> + uint8_t max_pci_bus = 0; >> >> /* sanity checks */ >> if (dev == NULL) >> @@ -59,6 +257,88 @@ static int qdma_eth_dev_init(struct rte_eth_dev *dev) >> if (rte_eal_process_type() != RTE_PROC_PRIMARY) >> return 0; >> >> + /* allocate space for a single Ethernet MAC address */ >> + dev->data->mac_addrs = rte_zmalloc("qdma", RTE_ETHER_ADDR_LEN * 1, 0); >> + if (dev->data->mac_addrs == NULL) >> + return -ENOMEM; >> + >> + /* Copy some dummy Ethernet MAC address for QDMA device >> + * This will change in real NIC device... >> + * TODO: Read MAC from EEPROM >> + */ >> + for (i = 0; i < RTE_ETHER_ADDR_LEN; ++i) >> + dev->data->mac_addrs[0].addr_bytes[i] = 0x15 + i; > If you don't have a real EEPROM to read, use rte_eth_random_addr() instead. We do have an on-board EEPROM, but accessing it is not straight forward hardware wise as it is behind FPGA control. The hardware team is working to simplify this. Meanwhile we were just using dummy values, but it is smart to use existing APIs. I'll adapt to rte_eth_random_addr() in v2. Will also look for other places where I can reuse existing DPDK APIs. Thanks. > >> + >> + /* Init system & device */ >> + dma_priv = (struct qdma_pci_dev *)dev->data->dev_private; >> + dma_priv->is_vf = 0; >> + dma_priv->is_master = 0; >> + dma_priv->vf_online_count = 0; >> + dma_priv->timer_count = DEFAULT_TIMER_CNT_TRIG_MODE_TIMER; >> + >> + dma_priv->en_desc_prefetch = 0; /* Keep prefetch default to 0 */ >> + dma_priv->cmpt_desc_len = 0; >> + dma_priv->c2h_bypass_mode = 0; >> + dma_priv->h2c_bypass_mode = 0; >> + >> + dma_priv->config_bar_idx = DEFAULT_PF_CONFIG_BAR; >> + dma_priv->bypass_bar_idx = BAR_ID_INVALID; >> + dma_priv->user_bar_idx = BAR_ID_INVALID; >> + >> + /* Check and handle device devargs */ >> + if (qdma_check_kvargs(dev->device->devargs, dma_priv)) { >> + PMD_DRV_LOG(INFO, "devargs failed\n"); >> + rte_free(dev->data->mac_addrs); >> + return -EINVAL; >> + } >> + >> + /* Store BAR address and length of Config BAR */ >> + baseaddr = (uint8_t *) >> + pci_dev->mem_resource[dma_priv->config_bar_idx].addr; >> + dma_priv->bar_addr[dma_priv->config_bar_idx] = baseaddr; >> + >> + idx = qdma_identify_bars(dev); >> + if (idx < 0) { >> + rte_free(dev->data->mac_addrs); >> + return -EINVAL; >> + } >> + >> + /* Store BAR address and length of AXI Master Lite BAR(user bar) */ >> + if (dma_priv->user_bar_idx >= 0) { >> + baseaddr = (uint8_t *) >> + pci_dev->mem_resource[dma_priv->user_bar_idx].addr; >> + dma_priv->bar_addr[dma_priv->user_bar_idx] = baseaddr; >> + } >> + >> + PMD_DRV_LOG(INFO, "QDMA device driver probe:"); >> + >> + ret = get_max_pci_bus_num(pci_dev->addr.bus, &max_pci_bus); >> + if (ret != 0 && !max_pci_bus) { >> + PMD_DRV_LOG(ERR, "Failed to get max pci bus number\n"); >> + rte_free(dev->data->mac_addrs); >> + return -EINVAL; >> + } >> + PMD_DRV_LOG(INFO, "PCI max bus number : 0x%x", max_pci_bus); >> + >> + if (!dma_priv->reset_in_progress) { >> + num_vfs = pci_dev->max_vfs; >> + if (num_vfs) { >> + dma_priv->vfinfo = rte_zmalloc("vfinfo", >> + sizeof(struct qdma_vf_info) * num_vfs, 0); >> + if (dma_priv->vfinfo == NULL) { >> + PMD_DRV_LOG(ERR, "Cannot allocate memory for private VF info\n"); >> + return -ENOMEM; >> + } >> + >> + /* Mark all VFs with invalid function id mapping*/ >> + for (i = 0; i < num_vfs; i++) >> + dma_priv->vfinfo[i].func_id = >> + QDMA_FUNC_ID_INVALID; >> + } >> + } >> + >> + dma_priv->reset_in_progress = 0; >> + >> return 0; >> }