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 BEE03A0540; Wed, 6 Jul 2022 17:35:16 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7874340687; Wed, 6 Jul 2022 17:35:16 +0200 (CEST) Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) by mails.dpdk.org (Postfix) with ESMTP id BDF4F40156 for ; Wed, 6 Jul 2022 17:35:14 +0200 (CEST) Received: by mail-pl1-f182.google.com with SMTP id m14so13948126plg.5 for ; Wed, 06 Jul 2022 08:35:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20210112.gappssmtp.com; s=20210112; h=date:from:to:cc:subject:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=buQJi+3Dml5E0T+1r6EhNH6SbadTLU87omFtKb4MPPM=; b=lL2bcL9AQTng2t6CcakFRyiUo4Q0lUZwTCbYOKF70DweCl64IROY+7Ra+lp2xMwFdC WNeRDd1+y+q37oNqqU2LI6POv8ecLYJ3AUfgWeZG1Q+HPGfRV/uLgNSaQGAMS6Iu7CAI +IwYlRJB3OdBTHgQXwYgEi+/AS+Qfb9/3PP1uE2flq6QxqXGheM1aLDtzZ1TMtFPyXE0 jO4UaRp4zForyp6xbWFGkPbN3GcvapPkxwtfvG8qR5GhK92pSzovSo0SnqYQXfGtvHzZ 06/uh+DVD7YfY76kn8wqvxMZLDIGHISpQ8ndI2OXskmCtJY0NAqxThfjoC4N3sXFHqjT gQGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=buQJi+3Dml5E0T+1r6EhNH6SbadTLU87omFtKb4MPPM=; b=JZLKaoBoK7W2RN6bOXnVmVcwP5g5F5FlhUiHXfMuDFd8sXrUyl95s0hQw/rhG6E2DU zYAfP2oTFu8/QOWv5WpBqLP85pXzdB9y5giYD4oDKg+a0FLoxDJ1vd2z91od2Y16oB5Z KRCEWYh1eSYX2ABsOVALSP2JE/krRDu3jPE/+BnaYthO2MsI834LArFYWqfy8StEl+IZ BiG04pQeSHO+rjeEVscL70LbPHym4Cj3kX2OQ16DW3s3cVSevMlWPsYtL5c22xLJlm2M p/53S9Kl+66rGvRMh517LOtFEjgZ6L0PIExQuwKtd9xYYc89Dx2DviS0mrPqU741NuJo sycw== X-Gm-Message-State: AJIora8NPliMk0BFnYC3oMs5uOXGzqyvdGFwzo9seNhIpLsfROBUeO5P wFuwTLHq6pMoJ/b5HgjbZBMQhZAEDNDdUI0+ X-Google-Smtp-Source: AGRyM1sD/ZJFKTfsP3dtdOjb6uvWrggcptjXevV6n5Cqsw2G/UwXj4/koV59YxhlD7Uc6l1+BPwr1A== X-Received: by 2002:a17:90b:e95:b0:1ef:825f:cb40 with SMTP id fv21-20020a17090b0e9500b001ef825fcb40mr23618414pjb.29.1657121713855; Wed, 06 Jul 2022 08:35:13 -0700 (PDT) Received: from hermes.local (204-195-112-199.wavecable.com. [204.195.112.199]) by smtp.gmail.com with ESMTPSA id j8-20020a170903028800b0016c0080df84sm1932620plr.254.2022.07.06.08.35.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Jul 2022 08:35:13 -0700 (PDT) Date: Wed, 6 Jul 2022 08:35:09 -0700 From: Stephen Hemminger To: Aman Kumar Cc: dev@dpdk.org, maxime.coquelin@redhat.com, david.marchand@redhat.com Subject: Re: [RFC PATCH 05/29] net/qdma: add device init and uninit functions Message-ID: <20220706083509.58b3c01e@hermes.local> In-Reply-To: <20220706075219.517046-6-aman.kumar@vvdntech.in> References: <20220706075219.517046-1-aman.kumar@vvdntech.in> <20220706075219.517046-6-aman.kumar@vvdntech.in> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII 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 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? > +/* 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.. > +/* 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. > + > + /* 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; > }