DPDK patches and discussions
 help / color / mirror / Atom feed
From: Aman Kumar <aman.kumar@vvdntech.in>
To: Stephen Hemminger <stephen@networkplumber.org>
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
Date: Thu, 7 Jul 2022 08:11:54 +0530	[thread overview]
Message-ID: <06eada6b-266d-891b-69e4-dd2d76ed7712@vvdntech.in> (raw)
In-Reply-To: <20220706083509.58b3c01e@hermes.local>

On 06/07/22 9:05 pm, Stephen Hemminger wrote:
> On Wed,  6 Jul 2022 13:21:55 +0530
> Aman Kumar <aman.kumar@vvdntech.in> 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;
>>   }



  reply	other threads:[~2022-07-07  2:42 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-06  7:51 [RFC PATCH 00/29] cover letter for net/qdma PMD Aman Kumar
2022-07-06  7:51 ` [RFC PATCH 01/29] net/qdma: add net PMD template Aman Kumar
2022-07-06  7:51 ` [RFC PATCH 02/29] maintainers: add maintainer for net/qdma PMD Aman Kumar
2022-07-06  7:51 ` [RFC PATCH 03/29] net/meson.build: add support to compile net qdma Aman Kumar
2022-07-06  7:51 ` [RFC PATCH 04/29] net/qdma: add logging support Aman Kumar
2022-07-06 15:27   ` Stephen Hemminger
2022-07-07  2:32     ` Aman Kumar
2022-07-06  7:51 ` [RFC PATCH 05/29] net/qdma: add device init and uninit functions Aman Kumar
2022-07-06 15:35   ` Stephen Hemminger
2022-07-07  2:41     ` Aman Kumar [this message]
2022-07-06  7:51 ` [RFC PATCH 06/29] net/qdma: add qdma access library Aman Kumar
2022-07-06  7:51 ` [RFC PATCH 07/29] net/qdma: add supported qdma version Aman Kumar
2022-07-06  7:51 ` [RFC PATCH 08/29] net/qdma: qdma hardware initialization Aman Kumar
2022-07-06  7:51 ` [RFC PATCH 09/29] net/qdma: define device modes and data structure Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 10/29] net/qdma: add net PMD ops template Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 11/29] net/qdma: add configure close and reset ethdev ops Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 12/29] net/qdma: add routine for Rx queue initialization Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 13/29] net/qdma: add callback support for Rx queue count Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 14/29] net/qdma: add routine for Tx queue initialization Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 15/29] net/qdma: add queue cleanup PMD ops Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 16/29] net/qdma: add start and stop apis Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 17/29] net/qdma: add Tx burst API Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 18/29] net/qdma: add Tx queue reclaim routine Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 19/29] net/qdma: add callback function for Tx desc status Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 20/29] net/qdma: add Rx burst API Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 21/29] net/qdma: add mailbox communication library Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 22/29] net/qdma: mbox API adaptation in Rx/Tx init Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 23/29] net/qdma: add support for VF interfaces Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 24/29] net/qdma: add Rx/Tx queue setup routine for VF devices Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 25/29] net/qdma: add basic PMD ops for VF Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 26/29] net/qdma: add datapath burst API " Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 27/29] net/qdma: add device specific APIs for export Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 28/29] net/qdma: add additional debug APIs Aman Kumar
2022-07-06  7:52 ` [RFC PATCH 29/29] net/qdma: add stats PMD ops for PF and VF Aman Kumar
2022-07-07  6:57 ` [RFC PATCH 00/29] cover letter for net/qdma PMD Thomas Monjalon
2022-07-07 13:55   ` Aman Kumar
2022-07-07 14:15     ` Thomas Monjalon
2022-07-07 14:19       ` Hemant Agrawal
2022-07-18 18:15         ` aman.kumar
2022-07-19 12:12           ` Thomas Monjalon
2022-07-19 17:22             ` aman.kumar
2023-07-02 23:36               ` Stephen Hemminger
2023-07-03  9:15                 ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=06eada6b-266d-891b-69e4-dd2d76ed7712@vvdntech.in \
    --to=aman.kumar@vvdntech.in \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --cc=maxime.coquelin@redhat.com \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).