DPDK-dev Archive on lore.kernel.org
 help / color / Atom feed
* [dpdk-dev] [PATCH v1] net/ice: support device-specific DDP package loading
@ 2019-08-29 13:17 Ting Xu
  2019-08-29 18:08 ` Stillwell Jr, Paul M
  2019-09-03 14:29 ` [dpdk-dev] [PATCH v3] " Ting Xu
  0 siblings, 2 replies; 16+ messages in thread
From: Ting Xu @ 2019-08-29 13:17 UTC (permalink / raw)
  To: dev; +Cc: wenzhuo.lu, qiming.yang, qi.z.zhang

This patch adds the feature that supports loading DDP package
according to the device serial number. Prior to loading the
default DDP package (ice.pkg), the driver will check for the
presence of a device-specific DDP package with the name containing
64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
during initialization. Users can use "lspci -vs" to get the device
serial number.
The pkg search path are /lib/firmware/intel/ice/ddp/ and
/lib/firmware/updates/intel/ice/ddp/. If the package exists,
the driver will download it to the device instead of the default
one. The loaded package type (OS default and COMMS) will be
stored in ice_adapter->active_pkg_type. The package version is
stored in ice_hw->active_pkg_ver.

Signed-off-by: Ting Xu <ting.xu@intel.com>
---
 drivers/net/ice/ice_ethdev.c | 132 ++++++++++++++++++++++++++++++++++-
 drivers/net/ice/ice_ethdev.h |   8 +++
 2 files changed, 139 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 686d6f00f..92eafdd1f 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -28,7 +28,15 @@ static const char * const ice_valid_args[] = {
 };
 
 #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
+
+/* DDP package search path */
 #define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
+
+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
+#define ICE_MAX_PKG_FILENAME_SIZE   256
 
 int ice_logtype_init;
 int ice_logtype_driver;
@@ -1265,15 +1273,134 @@ ice_pf_setup(struct ice_pf *pf)
 	return 0;
 }
 
+/* PCIe configuration space setting */
+#define PCI_CFG_SPACE_SIZE          256
+#define PCI_CFG_SPACE_EXP_SIZE      4096
+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
+#define PCI_EXT_CAP_ID_DSN          0x03
+
+static int
+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = PCI_CFG_SPACE_SIZE;
+
+	/* minimum 8 bytes per capability */
+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+		return -1;
+	}
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (PCI_EXT_CAP_ID(header) == cap)
+			return pos;
+
+		pos = PCI_EXT_CAP_NEXT(header);
+
+		if (pos < PCI_CFG_SPACE_SIZE)
+			break;
+
+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/* Extract device serial number from PCIe Configuration Space and
+ * determine the pkg file path according to the DSN.
+ */
+static int
+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
+{
+	int pos;
+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
+	uint32_t dword;
+	uint32_t dsn_low, dsn_high;
+
+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
+
+	if (pos) {
+		rte_pci_read_config(pci_dev, &dword, 4, pos + 4);
+		dsn_low = dword;
+		rte_pci_read_config(pci_dev, &dword, 4, pos + 8);
+		dsn_high = dword;
+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
+	} else {
+		PMD_INIT_LOG(INFO, "Failed to read device serial number\n");
+		strncpy(pkg_file, ICE_DFLT_PKG_FILE, ICE_MAX_PKG_FILENAME_SIZE);
+
+		return 0;
+	}
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strncat(pkg_file, opt_ddp_filename,
+		ICE_MAX_PKG_FILENAME_SIZE), 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strncat(pkg_file, opt_ddp_filename,
+		ICE_MAX_PKG_FILENAME_SIZE), 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_DFLT_PKG_FILE, ICE_MAX_PKG_FILENAME_SIZE);
+
+	return 0;
+}
+
+static enum ice_pkg_type
+ice_get_pkg_type(struct ice_hw *hw)
+{
+	enum ice_pkg_type package_type;
+
+	/* store the activated package type (OS default or Comms) */
+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_COMMS;
+	else
+		package_type = ICE_PKG_TYPE_UNKNOWN;
+
+	PMD_INIT_LOG(INFO, "Activated package is: %d.%d.%d.%d, %s\n",
+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
+		hw->active_pkg_name);
+
+	return package_type;
+}
+
 static int ice_load_pkg(struct rte_eth_dev *dev)
 {
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	const char *pkg_file = ICE_DFLT_PKG_FILE;
+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
 	int err;
 	uint8_t *buf;
 	int buf_len;
 	FILE *file;
 	struct stat fstat;
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct ice_adapter *ad =
+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	ice_pkg_file_search_path(pci_dev, pkg_file);
 
 	file = fopen(pkg_file, "rb");
 	if (!file)  {
@@ -1313,6 +1440,9 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
 		goto fail_exit;
 	}
+
+	ad->active_pkg_type = ice_get_pkg_type(hw);
+
 	err = ice_init_hw_tbls(hw);
 	if (err) {
 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 5063960a8..d1d07641d 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -124,6 +124,13 @@
 #define ICE_ETH_OVERHEAD \
 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
 
+/* DDP package type */
+enum ice_pkg_type {
+	ICE_PKG_TYPE_UNKNOWN,
+	ICE_PKG_TYPE_OS_DEFAULT,
+	ICE_PKG_TYPE_COMMS,
+};
+
 struct ice_adapter;
 
 /**
@@ -296,6 +303,7 @@ struct ice_adapter {
 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
 	bool is_safe_mode;
 	struct ice_devargs devargs;
+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
 };
 
 struct ice_vsi_vlan_pvid_info {
-- 
2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH v1] net/ice: support device-specific DDP package loading
  2019-08-29 13:17 [dpdk-dev] [PATCH v1] net/ice: support device-specific DDP package loading Ting Xu
@ 2019-08-29 18:08 ` Stillwell Jr, Paul M
  2019-08-29 22:05   ` Zhang, Qi Z
  2019-09-03 14:29 ` [dpdk-dev] [PATCH v3] " Ting Xu
  1 sibling, 1 reply; 16+ messages in thread
From: Stillwell Jr, Paul M @ 2019-08-29 18:08 UTC (permalink / raw)
  To: Xu, Ting, dev; +Cc: Lu, Wenzhuo, Yang, Qiming, Zhang, Qi Z

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Ting Xu
> Sent: Thursday, August 29, 2019 6:18 AM
> To: dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Yang, Qiming
> <qiming.yang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>
> Subject: [dpdk-dev] [PATCH v1] net/ice: support device-specific DDP package
> loading
> 
> This patch adds the feature that supports loading DDP package according to
> the device serial number. Prior to loading the default DDP package (ice.pkg),
> the driver will check for the presence of a device-specific DDP package with
> the name containing 64-bit PCIe Device Serial Number (ice-
> xxxxxxxxxxxxxxxx.pkg) during initialization. Users can use "lspci -vs" to get
> the device serial number.
> The pkg search path are /lib/firmware/intel/ice/ddp/ and
> /lib/firmware/updates/intel/ice/ddp/. If the package exists, the driver will
> download it to the device instead of the default one. The loaded package
> type (OS default and COMMS) will be stored in ice_adapter-
> >active_pkg_type. The package version is stored in ice_hw->active_pkg_ver.
> 
> Signed-off-by: Ting Xu <ting.xu@intel.com>
> ---
>  drivers/net/ice/ice_ethdev.c | 132
> ++++++++++++++++++++++++++++++++++-
>  drivers/net/ice/ice_ethdev.h |   8 +++
>  2 files changed, 139 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
> index 686d6f00f..92eafdd1f 100644
> --- a/drivers/net/ice/ice_ethdev.c
> +++ b/drivers/net/ice/ice_ethdev.c
> @@ -28,7 +28,15 @@ static const char * const ice_valid_args[] = {  };
> 
>  #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
> +
> +/* DDP package search path */
>  #define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
> +#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT
> "/lib/firmware/intel/ice/ddp/"
> +#define ICE_PKG_FILE_SEARCH_PATH_UPDATES
> "/lib/firmware/updates/intel/ice/ddp/"
> +
> +#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default
> Package"
> +#define ICE_COMMS_PKG_NAME			"ICE COMMS
> Package"
> +#define ICE_MAX_PKG_FILENAME_SIZE   256
> 
>  int ice_logtype_init;
>  int ice_logtype_driver;
> @@ -1265,15 +1273,134 @@ ice_pf_setup(struct ice_pf *pf)
>  	return 0;
>  }
> 
> +/* PCIe configuration space setting */
> +#define PCI_CFG_SPACE_SIZE          256
> +#define PCI_CFG_SPACE_EXP_SIZE      4096
> +#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
> +#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
> +#define PCI_EXT_CAP_ID_DSN          0x03
> +
> +static int
> +ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap) {
> +	uint32_t header;
> +	int ttl;
> +	int pos = PCI_CFG_SPACE_SIZE;
> +
> +	/* minimum 8 bytes per capability */
> +	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
> +
> +	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
> +		PMD_INIT_LOG(ERR, "ice error reading extended
> capabilities\n");
> +		return -1;
> +	}
> +
> +	/*
> +	 * If we have no capabilities, this is indicated by cap ID,
> +	 * cap version and next pointer all being 0.
> +	 */
> +	if (header == 0)
> +		return 0;
> +
> +	while (ttl-- > 0) {
> +		if (PCI_EXT_CAP_ID(header) == cap)
> +			return pos;
> +
> +		pos = PCI_EXT_CAP_NEXT(header);
> +
> +		if (pos < PCI_CFG_SPACE_SIZE)
> +			break;
> +
> +		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
> +			PMD_INIT_LOG(ERR, "ice error reading extended
> capabilities\n");
> +			return -1;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/* Extract device serial number from PCIe Configuration Space and
> + * determine the pkg file path according to the DSN.
> + */
> +static int
> +ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char
> +*pkg_file) {
> +	int pos;
> +	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
> +	uint32_t dword;
> +	uint32_t dsn_low, dsn_high;
> +
> +	pos = ice_pci_find_next_ext_capability(pci_dev,
> PCI_EXT_CAP_ID_DSN);
> +
> +	if (pos) {
> +		rte_pci_read_config(pci_dev, &dword, 4, pos + 4);
> +		dsn_low = dword;
> +		rte_pci_read_config(pci_dev, &dword, 4, pos + 8);
> +		dsn_high = dword;
> +		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
> +			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
> +	} else {
> +		PMD_INIT_LOG(INFO, "Failed to read device serial
> number\n");
> +		strncpy(pkg_file, ICE_DFLT_PKG_FILE,
> ICE_MAX_PKG_FILENAME_SIZE);
> +
> +		return 0;
> +	}
> +
> +	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
> +		ICE_MAX_PKG_FILENAME_SIZE);
> +	if (!access(strncat(pkg_file, opt_ddp_filename,
> +		ICE_MAX_PKG_FILENAME_SIZE), 0))
> +		return 0;
> +
> +	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
> +		ICE_MAX_PKG_FILENAME_SIZE);
> +	if (!access(strncat(pkg_file, opt_ddp_filename,
> +		ICE_MAX_PKG_FILENAME_SIZE), 0))
> +		return 0;
> +

The above search order is not correct. You should search the updates path first and then the default path. That is the order that the kernel interfaces search them.

> +	strncpy(pkg_file, ICE_DFLT_PKG_FILE,
> ICE_MAX_PKG_FILENAME_SIZE);
> +
> +	return 0;
> +}
> +
> +static enum ice_pkg_type
> +ice_get_pkg_type(struct ice_hw *hw)
> +{
> +	enum ice_pkg_type package_type;
> +
> +	/* store the activated package type (OS default or Comms) */
> +	if (!strncmp((char *)hw->active_pkg_name,
> ICE_OS_DEFAULT_PKG_NAME,
> +		ICE_PKG_NAME_SIZE))
> +		package_type = ICE_PKG_TYPE_OS_DEFAULT;
> +	else if (!strncmp((char *)hw->active_pkg_name,
> ICE_COMMS_PKG_NAME,
> +		ICE_PKG_NAME_SIZE))
> +		package_type = ICE_PKG_TYPE_COMMS;
> +	else
> +		package_type = ICE_PKG_TYPE_UNKNOWN;
> +
> +	PMD_INIT_LOG(INFO, "Activated package is: %d.%d.%d.%d, %s\n",

Activated => Active

> +		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
> +		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
> +		hw->active_pkg_name);
> +
> +	return package_type;
> +}
> +
>  static int ice_load_pkg(struct rte_eth_dev *dev)  {
>  	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
> -	const char *pkg_file = ICE_DFLT_PKG_FILE;
> +	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
>  	int err;
>  	uint8_t *buf;
>  	int buf_len;
>  	FILE *file;
>  	struct stat fstat;
> +	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
> +	struct ice_adapter *ad =
> +		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> +
> +	ice_pkg_file_search_path(pci_dev, pkg_file);
> 
>  	file = fopen(pkg_file, "rb");
>  	if (!file)  {
> @@ -1313,6 +1440,9 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
>  		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n",
> err);
>  		goto fail_exit;
>  	}
> +
> +	ad->active_pkg_type = ice_get_pkg_type(hw);
> +

How does active_pkg_type get used? What is the purpose?

>  	err = ice_init_hw_tbls(hw);
>  	if (err) {
>  		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
> diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
> index 5063960a8..d1d07641d 100644
> --- a/drivers/net/ice/ice_ethdev.h
> +++ b/drivers/net/ice/ice_ethdev.h
> @@ -124,6 +124,13 @@
>  #define ICE_ETH_OVERHEAD \
>  	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN +
> ICE_VLAN_TAG_SIZE * 2)
> 
> +/* DDP package type */
> +enum ice_pkg_type {
> +	ICE_PKG_TYPE_UNKNOWN,
> +	ICE_PKG_TYPE_OS_DEFAULT,
> +	ICE_PKG_TYPE_COMMS,
> +};
> +
>  struct ice_adapter;
> 
>  /**
> @@ -296,6 +303,7 @@ struct ice_adapter {
>  	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
>  	bool is_safe_mode;
>  	struct ice_devargs devargs;
> +	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
>  };
> 
>  struct ice_vsi_vlan_pvid_info {
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH v1] net/ice: support device-specific DDP package loading
  2019-08-29 18:08 ` Stillwell Jr, Paul M
@ 2019-08-29 22:05   ` Zhang, Qi Z
  0 siblings, 0 replies; 16+ messages in thread
From: Zhang, Qi Z @ 2019-08-29 22:05 UTC (permalink / raw)
  To: Stillwell Jr, Paul M, Xu, Ting, dev; +Cc: Lu, Wenzhuo, Yang, Qiming



> -----Original Message-----
> From: Stillwell Jr, Paul M
> Sent: Friday, August 30, 2019 2:08 AM
> To: Xu, Ting <ting.xu@intel.com>; dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Yang, Qiming
> <qiming.yang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v1] net/ice: support device-specific DDP
> package loading
> 
> > -----Original Message-----
> > From: dev <dev-bounces@dpdk.org> On Behalf Of Ting Xu
> > Sent: Thursday, August 29, 2019 6:18 AM
> > To: dev@dpdk.org
> > Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Yang, Qiming
> > <qiming.yang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>
> > Subject: [dpdk-dev] [PATCH v1] net/ice: support device-specific DDP
> > package loading
> >
> > This patch adds the feature that supports loading DDP package
> > according to the device serial number. Prior to loading the default
> > DDP package (ice.pkg), the driver will check for the presence of a
> > device-specific DDP package with the name containing 64-bit PCIe
> > Device Serial Number (ice-
> > xxxxxxxxxxxxxxxx.pkg) during initialization. Users can use "lspci -vs"
> > to get the device serial number.
> > The pkg search path are /lib/firmware/intel/ice/ddp/ and
> > /lib/firmware/updates/intel/ice/ddp/. If the package exists, the
> > driver will download it to the device instead of the default one. The
> > loaded package type (OS default and COMMS) will be stored in
> > ice_adapter-
> > >active_pkg_type. The package version is stored in
> ice_hw->active_pkg_ver.
> >
> > Signed-off-by: Ting Xu <ting.xu@intel.com>
> > ---
> >  drivers/net/ice/ice_ethdev.c | 132
> > ++++++++++++++++++++++++++++++++++-
> >  drivers/net/ice/ice_ethdev.h |   8 +++
> >  2 files changed, 139 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/ice/ice_ethdev.c
> > b/drivers/net/ice/ice_ethdev.c index 686d6f00f..92eafdd1f 100644
> > --- a/drivers/net/ice/ice_ethdev.c
> > +++ b/drivers/net/ice/ice_ethdev.c
> > @@ -28,7 +28,15 @@ static const char * const ice_valid_args[] = {  };
> >
> >  #define ICE_DFLT_OUTER_TAG_TYPE
> ICE_AQ_VSI_OUTER_TAG_VLAN_9100
> > +
> > +/* DDP package search path */
> >  #define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
> > +#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT
> > "/lib/firmware/intel/ice/ddp/"
> > +#define ICE_PKG_FILE_SEARCH_PATH_UPDATES
> > "/lib/firmware/updates/intel/ice/ddp/"
> > +
> > +#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default
> > Package"
> > +#define ICE_COMMS_PKG_NAME			"ICE COMMS
> > Package"
> > +#define ICE_MAX_PKG_FILENAME_SIZE   256
> >
> >  int ice_logtype_init;
> >  int ice_logtype_driver;
> > @@ -1265,15 +1273,134 @@ ice_pf_setup(struct ice_pf *pf)
> >  	return 0;
> >  }
> >
> > +/* PCIe configuration space setting */
> > +#define PCI_CFG_SPACE_SIZE          256
> > +#define PCI_CFG_SPACE_EXP_SIZE      4096
> > +#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
> > +#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
> > +#define PCI_EXT_CAP_ID_DSN          0x03
> > +
> > +static int
> > +ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap) {
> > +	uint32_t header;
> > +	int ttl;
> > +	int pos = PCI_CFG_SPACE_SIZE;
> > +
> > +	/* minimum 8 bytes per capability */
> > +	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
> > +
> > +	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
> > +		PMD_INIT_LOG(ERR, "ice error reading extended
> > capabilities\n");
> > +		return -1;
> > +	}
> > +
> > +	/*
> > +	 * If we have no capabilities, this is indicated by cap ID,
> > +	 * cap version and next pointer all being 0.
> > +	 */
> > +	if (header == 0)
> > +		return 0;
> > +
> > +	while (ttl-- > 0) {
> > +		if (PCI_EXT_CAP_ID(header) == cap)
> > +			return pos;
> > +
> > +		pos = PCI_EXT_CAP_NEXT(header);
> > +
> > +		if (pos < PCI_CFG_SPACE_SIZE)
> > +			break;
> > +
> > +		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
> > +			PMD_INIT_LOG(ERR, "ice error reading extended
> > capabilities\n");
> > +			return -1;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +/* Extract device serial number from PCIe Configuration Space and
> > + * determine the pkg file path according to the DSN.
> > + */
> > +static int
> > +ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char
> > +*pkg_file) {
> > +	int pos;
> > +	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
> > +	uint32_t dword;
> > +	uint32_t dsn_low, dsn_high;
> > +
> > +	pos = ice_pci_find_next_ext_capability(pci_dev,
> > PCI_EXT_CAP_ID_DSN);
> > +
> > +	if (pos) {
> > +		rte_pci_read_config(pci_dev, &dword, 4, pos + 4);
> > +		dsn_low = dword;
> > +		rte_pci_read_config(pci_dev, &dword, 4, pos + 8);
> > +		dsn_high = dword;
> > +		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
> > +			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
> > +	} else {
> > +		PMD_INIT_LOG(INFO, "Failed to read device serial
> > number\n");
> > +		strncpy(pkg_file, ICE_DFLT_PKG_FILE,
> > ICE_MAX_PKG_FILENAME_SIZE);
> > +
> > +		return 0;
> > +	}
> > +
> > +	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
> > +		ICE_MAX_PKG_FILENAME_SIZE);
> > +	if (!access(strncat(pkg_file, opt_ddp_filename,
> > +		ICE_MAX_PKG_FILENAME_SIZE), 0))
> > +		return 0;
> > +
> > +	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
> > +		ICE_MAX_PKG_FILENAME_SIZE);
> > +	if (!access(strncat(pkg_file, opt_ddp_filename,
> > +		ICE_MAX_PKG_FILENAME_SIZE), 0))
> > +		return 0;
> > +
> 
> The above search order is not correct. You should search the updates path
> first and then the default path. That is the order that the kernel interfaces
> search them.
> 
> > +	strncpy(pkg_file, ICE_DFLT_PKG_FILE,
> > ICE_MAX_PKG_FILENAME_SIZE);
> > +
> > +	return 0;
> > +}
> > +
> > +static enum ice_pkg_type
> > +ice_get_pkg_type(struct ice_hw *hw)
> > +{
> > +	enum ice_pkg_type package_type;
> > +
> > +	/* store the activated package type (OS default or Comms) */
> > +	if (!strncmp((char *)hw->active_pkg_name,
> > ICE_OS_DEFAULT_PKG_NAME,
> > +		ICE_PKG_NAME_SIZE))
> > +		package_type = ICE_PKG_TYPE_OS_DEFAULT;
> > +	else if (!strncmp((char *)hw->active_pkg_name,
> > ICE_COMMS_PKG_NAME,
> > +		ICE_PKG_NAME_SIZE))
> > +		package_type = ICE_PKG_TYPE_COMMS;
> > +	else
> > +		package_type = ICE_PKG_TYPE_UNKNOWN;
> > +
> > +	PMD_INIT_LOG(INFO, "Activated package is: %d.%d.%d.%d, %s\n",
> 
> Activated => Active
> 
> > +		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
> > +		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
> > +		hw->active_pkg_name);
> > +
> > +	return package_type;
> > +}
> > +
> >  static int ice_load_pkg(struct rte_eth_dev *dev)  {
> >  	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data-
> > >dev_private);
> > -	const char *pkg_file = ICE_DFLT_PKG_FILE;
> > +	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
> >  	int err;
> >  	uint8_t *buf;
> >  	int buf_len;
> >  	FILE *file;
> >  	struct stat fstat;
> > +	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
> > +	struct ice_adapter *ad =
> > +		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> > +
> > +	ice_pkg_file_search_path(pci_dev, pkg_file);
> >
> >  	file = fopen(pkg_file, "rb");
> >  	if (!file)  {
> > @@ -1313,6 +1440,9 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
> >  		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
> >  		goto fail_exit;
> >  	}
> > +
> > +	ad->active_pkg_type = ice_get_pkg_type(hw);
> > +
> 
> How does active_pkg_type get used? What is the purpose?

It will be used in following patches.
Basically we need this flag to expose package corresponding device capability at runtime for example rte_flow, supported ptype ...

> 
> >  	err = ice_init_hw_tbls(hw);
> >  	if (err) {
> >  		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err); diff --git
> > a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h index
> > 5063960a8..d1d07641d 100644
> > --- a/drivers/net/ice/ice_ethdev.h
> > +++ b/drivers/net/ice/ice_ethdev.h
> > @@ -124,6 +124,13 @@
> >  #define ICE_ETH_OVERHEAD \
> >  	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE *
> 2)
> >
> > +/* DDP package type */
> > +enum ice_pkg_type {
> > +	ICE_PKG_TYPE_UNKNOWN,
> > +	ICE_PKG_TYPE_OS_DEFAULT,
> > +	ICE_PKG_TYPE_COMMS,
> > +};
> > +
> >  struct ice_adapter;
> >
> >  /**
> > @@ -296,6 +303,7 @@ struct ice_adapter {
> >  	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
> >  	bool is_safe_mode;
> >  	struct ice_devargs devargs;
> > +	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
> >  };
> >
> >  struct ice_vsi_vlan_pvid_info {
> > --
> > 2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH v3] net/ice: support device-specific DDP package loading
  2019-09-03 14:29 ` [dpdk-dev] [PATCH v3] " Ting Xu
@ 2019-09-03  9:43   ` Ye Xiaolong
  2019-09-04  2:40     ` Xu, Ting
  2019-09-05 12:59   ` [dpdk-dev] [PATCH v4] " Ting Xu
  1 sibling, 1 reply; 16+ messages in thread
From: Ye Xiaolong @ 2019-09-03  9:43 UTC (permalink / raw)
  To: Ting Xu; +Cc: dev, wenzhuo.lu, qiming.yang, qi.z.zhang

Hi, Ting

On 09/03, Ting Xu wrote:
>This patch adds the feature that supports loading DDP package
>according to the device serial number. Prior to loading the
>default DDP package (ice.pkg), the driver will check for the
>presence of a device-specific DDP package with the name containing
>64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
>during initialization. Users can use "lspci -vs" to get the device
>serial number.
>The pkg search path are /lib/firmware/updates/intel/ice/ddp/
>and /lib/firmware/intel/ice/ddp/. If the package exists,
>the driver will download it to the device instead of the default
>one. The loaded package type (OS default and COMMS) will be
>stored in ice_adapter->active_pkg_type. The package version is
>stored in ice_hw->active_pkg_ver.
>
>Signed-off-by: Ting Xu <ting.xu@intel.com>
>
>-------------------------------------------------------------------
>
>v3: try to fix compile error; modify to change the pkg loading
>order.
>
>v2: modify codes according to the comments.
>---

You should put your change log after '---' marker, then it will be ignored 
when applying by `git am`, other separator like '----------------------...' 
you used will still show in the commit log.

> drivers/net/ice/ice_ethdev.c | 138 ++++++++++++++++++++++++++++++++++-
> drivers/net/ice/ice_ethdev.h |   8 ++
> 2 files changed, 144 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
>index 686d6f00f..922b71ac6 100644
>--- a/drivers/net/ice/ice_ethdev.c
>+++ b/drivers/net/ice/ice_ethdev.c
>@@ -28,7 +28,16 @@ static const char * const ice_valid_args[] = {
> };
> 
> #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
>-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
>+
>+/* DDP package search path */
>+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
>+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
>+
>+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
>+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
>+#define ICE_MAX_PKG_FILENAME_SIZE   256
> 
> int ice_logtype_init;
> int ice_logtype_driver;
>@@ -1265,15 +1274,137 @@ ice_pf_setup(struct ice_pf *pf)
> 	return 0;
> }
> 
>+/* PCIe configuration space setting */
>+#define PCI_CFG_SPACE_SIZE          256
>+#define PCI_CFG_SPACE_EXP_SIZE      4096
>+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
>+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
>+#define PCI_EXT_CAP_ID_DSN          0x03
>+
>+static int
>+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
>+{
>+	uint32_t header;
>+	int ttl;
>+	int pos = PCI_CFG_SPACE_SIZE;
>+
>+	/* minimum 8 bytes per capability */
>+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
>+
>+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+		return -1;
>+	}
>+
>+	/*
>+	 * If we have no capabilities, this is indicated by cap ID,
>+	 * cap version and next pointer all being 0.
>+	 */
>+	if (header == 0)
>+		return 0;
>+
>+	while (ttl-- > 0) {
>+		if (PCI_EXT_CAP_ID(header) == cap)
>+			return pos;
>+
>+		pos = PCI_EXT_CAP_NEXT(header);
>+
>+		if (pos < PCI_CFG_SPACE_SIZE)
>+			break;
>+
>+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+			return -1;
>+		}
>+	}
>+
>+	return 0;
>+}
>+
>+/* Extract device serial number from PCIe Configuration Space and
>+ * determine the pkg file path according to the DSN.
>+ */
>+static int
>+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
>+{
>+	int pos;
>+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
>+	uint32_t dword;
>+	uint32_t dsn_low, dsn_high;
>+
>+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
>+
>+	if (pos) {
>+		rte_pci_read_config(pci_dev, &dword, 4, pos + 4);
>+		dsn_low = dword;
>+		rte_pci_read_config(pci_dev, &dword, 4, pos + 8);
>+		dsn_high = dword;
>+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
>+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
>+	} else {
>+		PMD_INIT_LOG(INFO, "Failed to read device serial number\n");
>+		strncpy(pkg_file, ICE_PKG_FILE_DEFAULT,
>+			ICE_MAX_PKG_FILENAME_SIZE);
>+
>+		return 0;
>+	}
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(pkg_file, 0))
>+		return 0;
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);

Do we need to check access for the pkg_file here too? What if the file doesn't
exist or user doesn't have access to it?

Thanks,
Xiaolong

>+
>+	return 0;
>+}
>+
>+static enum ice_pkg_type
>+ice_get_pkg_type(struct ice_hw *hw)
>+{
>+	enum ice_pkg_type package_type;
>+
>+	/* store the activated package type (OS default or Comms) */
>+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
>+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_COMMS;
>+	else
>+		package_type = ICE_PKG_TYPE_UNKNOWN;
>+
>+	PMD_INIT_LOG(INFO, "Active package is: %d.%d.%d.%d, %s\n",
>+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
>+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
>+		hw->active_pkg_name);
>+
>+	return package_type;
>+}
>+
> static int ice_load_pkg(struct rte_eth_dev *dev)
> {
> 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>-	const char *pkg_file = ICE_DFLT_PKG_FILE;
>+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
> 	int err;
> 	uint8_t *buf;
> 	int buf_len;
> 	FILE *file;
> 	struct stat fstat;
>+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
>+	struct ice_adapter *ad =
>+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
>+
>+	ice_pkg_file_search_path(pci_dev, pkg_file);
> 
> 	file = fopen(pkg_file, "rb");
> 	if (!file)  {
>@@ -1313,6 +1444,9 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
> 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
> 		goto fail_exit;
> 	}
>+
>+	ad->active_pkg_type = ice_get_pkg_type(hw);
>+
> 	err = ice_init_hw_tbls(hw);
> 	if (err) {
> 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
>diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
>index 5063960a8..d1d07641d 100644
>--- a/drivers/net/ice/ice_ethdev.h
>+++ b/drivers/net/ice/ice_ethdev.h
>@@ -124,6 +124,13 @@
> #define ICE_ETH_OVERHEAD \
> 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
> 
>+/* DDP package type */
>+enum ice_pkg_type {
>+	ICE_PKG_TYPE_UNKNOWN,
>+	ICE_PKG_TYPE_OS_DEFAULT,
>+	ICE_PKG_TYPE_COMMS,
>+};
>+
> struct ice_adapter;
> 
> /**
>@@ -296,6 +303,7 @@ struct ice_adapter {
> 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
> 	bool is_safe_mode;
> 	struct ice_devargs devargs;
>+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
> };
> 
> struct ice_vsi_vlan_pvid_info {
>-- 
>2.17.1
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v3] net/ice: support device-specific DDP package loading
  2019-08-29 13:17 [dpdk-dev] [PATCH v1] net/ice: support device-specific DDP package loading Ting Xu
  2019-08-29 18:08 ` Stillwell Jr, Paul M
@ 2019-09-03 14:29 ` " Ting Xu
  2019-09-03  9:43   ` Ye Xiaolong
  2019-09-05 12:59   ` [dpdk-dev] [PATCH v4] " Ting Xu
  1 sibling, 2 replies; 16+ messages in thread
From: Ting Xu @ 2019-09-03 14:29 UTC (permalink / raw)
  To: dev; +Cc: wenzhuo.lu, qiming.yang, qi.z.zhang

This patch adds the feature that supports loading DDP package
according to the device serial number. Prior to loading the
default DDP package (ice.pkg), the driver will check for the
presence of a device-specific DDP package with the name containing
64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
during initialization. Users can use "lspci -vs" to get the device
serial number.
The pkg search path are /lib/firmware/updates/intel/ice/ddp/
and /lib/firmware/intel/ice/ddp/. If the package exists,
the driver will download it to the device instead of the default
one. The loaded package type (OS default and COMMS) will be
stored in ice_adapter->active_pkg_type. The package version is
stored in ice_hw->active_pkg_ver.

Signed-off-by: Ting Xu <ting.xu@intel.com>

-------------------------------------------------------------------

v3: try to fix compile error; modify to change the pkg loading
order.

v2: modify codes according to the comments.
---
 drivers/net/ice/ice_ethdev.c | 138 ++++++++++++++++++++++++++++++++++-
 drivers/net/ice/ice_ethdev.h |   8 ++
 2 files changed, 144 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 686d6f00f..922b71ac6 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -28,7 +28,16 @@ static const char * const ice_valid_args[] = {
 };
 
 #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
+
+/* DDP package search path */
+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
+
+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
+#define ICE_MAX_PKG_FILENAME_SIZE   256
 
 int ice_logtype_init;
 int ice_logtype_driver;
@@ -1265,15 +1274,137 @@ ice_pf_setup(struct ice_pf *pf)
 	return 0;
 }
 
+/* PCIe configuration space setting */
+#define PCI_CFG_SPACE_SIZE          256
+#define PCI_CFG_SPACE_EXP_SIZE      4096
+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
+#define PCI_EXT_CAP_ID_DSN          0x03
+
+static int
+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = PCI_CFG_SPACE_SIZE;
+
+	/* minimum 8 bytes per capability */
+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+		return -1;
+	}
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (PCI_EXT_CAP_ID(header) == cap)
+			return pos;
+
+		pos = PCI_EXT_CAP_NEXT(header);
+
+		if (pos < PCI_CFG_SPACE_SIZE)
+			break;
+
+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/* Extract device serial number from PCIe Configuration Space and
+ * determine the pkg file path according to the DSN.
+ */
+static int
+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
+{
+	int pos;
+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
+	uint32_t dword;
+	uint32_t dsn_low, dsn_high;
+
+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
+
+	if (pos) {
+		rte_pci_read_config(pci_dev, &dword, 4, pos + 4);
+		dsn_low = dword;
+		rte_pci_read_config(pci_dev, &dword, 4, pos + 8);
+		dsn_high = dword;
+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
+	} else {
+		PMD_INIT_LOG(INFO, "Failed to read device serial number\n");
+		strncpy(pkg_file, ICE_PKG_FILE_DEFAULT,
+			ICE_MAX_PKG_FILENAME_SIZE);
+
+		return 0;
+	}
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(pkg_file, 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
+
+	return 0;
+}
+
+static enum ice_pkg_type
+ice_get_pkg_type(struct ice_hw *hw)
+{
+	enum ice_pkg_type package_type;
+
+	/* store the activated package type (OS default or Comms) */
+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_COMMS;
+	else
+		package_type = ICE_PKG_TYPE_UNKNOWN;
+
+	PMD_INIT_LOG(INFO, "Active package is: %d.%d.%d.%d, %s\n",
+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
+		hw->active_pkg_name);
+
+	return package_type;
+}
+
 static int ice_load_pkg(struct rte_eth_dev *dev)
 {
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	const char *pkg_file = ICE_DFLT_PKG_FILE;
+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
 	int err;
 	uint8_t *buf;
 	int buf_len;
 	FILE *file;
 	struct stat fstat;
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct ice_adapter *ad =
+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	ice_pkg_file_search_path(pci_dev, pkg_file);
 
 	file = fopen(pkg_file, "rb");
 	if (!file)  {
@@ -1313,6 +1444,9 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
 		goto fail_exit;
 	}
+
+	ad->active_pkg_type = ice_get_pkg_type(hw);
+
 	err = ice_init_hw_tbls(hw);
 	if (err) {
 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 5063960a8..d1d07641d 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -124,6 +124,13 @@
 #define ICE_ETH_OVERHEAD \
 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
 
+/* DDP package type */
+enum ice_pkg_type {
+	ICE_PKG_TYPE_UNKNOWN,
+	ICE_PKG_TYPE_OS_DEFAULT,
+	ICE_PKG_TYPE_COMMS,
+};
+
 struct ice_adapter;
 
 /**
@@ -296,6 +303,7 @@ struct ice_adapter {
 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
 	bool is_safe_mode;
 	struct ice_devargs devargs;
+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
 };
 
 struct ice_vsi_vlan_pvid_info {
-- 
2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH v3] net/ice: support device-specific DDP package loading
  2019-09-03  9:43   ` Ye Xiaolong
@ 2019-09-04  2:40     ` Xu, Ting
  0 siblings, 0 replies; 16+ messages in thread
From: Xu, Ting @ 2019-09-04  2:40 UTC (permalink / raw)
  To: Ye, Xiaolong; +Cc: dev, Lu, Wenzhuo, Yang, Qiming, Zhang, Qi Z

Hi, Xiaolong,

As for the pkg_file, we first determine the pkg file path according to the search order. And then it will be given to the original pkg loading function, ice_load_pkg, to check if the pkg is available. If not, an error is returned. 
I do not check the access because it will be checked in the next step, so I  want to reduce some operations. 

Thanks!
------------------
Best Regards,
Xu Ting


-----Original Message-----
From: Ye, Xiaolong 
Sent: Tuesday, September 3, 2019 5:44 PM
To: Xu, Ting <ting.xu@intel.com>
Cc: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Yang, Qiming <qiming.yang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>
Subject: Re: [dpdk-dev] [PATCH v3] net/ice: support device-specific DDP package loading

Hi, Ting

On 09/03, Ting Xu wrote:
>This patch adds the feature that supports loading DDP package according 
>to the device serial number. Prior to loading the default DDP package 
>(ice.pkg), the driver will check for the presence of a device-specific 
>DDP package with the name containing 64-bit PCIe Device Serial Number 
>(ice-xxxxxxxxxxxxxxxx.pkg) during initialization. Users can use "lspci 
>-vs" to get the device serial number.
>The pkg search path are /lib/firmware/updates/intel/ice/ddp/
>and /lib/firmware/intel/ice/ddp/. If the package exists, the driver 
>will download it to the device instead of the default one. The loaded 
>package type (OS default and COMMS) will be stored in 
>ice_adapter->active_pkg_type. The package version is stored in 
>ice_hw->active_pkg_ver.
>
>Signed-off-by: Ting Xu <ting.xu@intel.com>
>
>-------------------------------------------------------------------
>
>v3: try to fix compile error; modify to change the pkg loading order.
>
>v2: modify codes according to the comments.
>---

You should put your change log after '---' marker, then it will be ignored when applying by `git am`, other separator like '----------------------...' 
you used will still show in the commit log.

> drivers/net/ice/ice_ethdev.c | 138 ++++++++++++++++++++++++++++++++++-
> drivers/net/ice/ice_ethdev.h |   8 ++
> 2 files changed, 144 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/net/ice/ice_ethdev.c 
>b/drivers/net/ice/ice_ethdev.c index 686d6f00f..922b71ac6 100644
>--- a/drivers/net/ice/ice_ethdev.c
>+++ b/drivers/net/ice/ice_ethdev.c
>@@ -28,7 +28,16 @@ static const char * const ice_valid_args[] = {  };
> 
> #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100 
>-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
>+
>+/* DDP package search path */
>+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
>+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
>+
>+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
>+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
>+#define ICE_MAX_PKG_FILENAME_SIZE   256
> 
> int ice_logtype_init;
> int ice_logtype_driver;
>@@ -1265,15 +1274,137 @@ ice_pf_setup(struct ice_pf *pf)
> 	return 0;
> }
> 
>+/* PCIe configuration space setting */
>+#define PCI_CFG_SPACE_SIZE          256
>+#define PCI_CFG_SPACE_EXP_SIZE      4096
>+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
>+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
>+#define PCI_EXT_CAP_ID_DSN          0x03
>+
>+static int
>+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap) 
>+{
>+	uint32_t header;
>+	int ttl;
>+	int pos = PCI_CFG_SPACE_SIZE;
>+
>+	/* minimum 8 bytes per capability */
>+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
>+
>+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+		return -1;
>+	}
>+
>+	/*
>+	 * If we have no capabilities, this is indicated by cap ID,
>+	 * cap version and next pointer all being 0.
>+	 */
>+	if (header == 0)
>+		return 0;
>+
>+	while (ttl-- > 0) {
>+		if (PCI_EXT_CAP_ID(header) == cap)
>+			return pos;
>+
>+		pos = PCI_EXT_CAP_NEXT(header);
>+
>+		if (pos < PCI_CFG_SPACE_SIZE)
>+			break;
>+
>+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+			return -1;
>+		}
>+	}
>+
>+	return 0;
>+}
>+
>+/* Extract device serial number from PCIe Configuration Space and
>+ * determine the pkg file path according to the DSN.
>+ */
>+static int
>+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char 
>+*pkg_file) {
>+	int pos;
>+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
>+	uint32_t dword;
>+	uint32_t dsn_low, dsn_high;
>+
>+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
>+
>+	if (pos) {
>+		rte_pci_read_config(pci_dev, &dword, 4, pos + 4);
>+		dsn_low = dword;
>+		rte_pci_read_config(pci_dev, &dword, 4, pos + 8);
>+		dsn_high = dword;
>+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
>+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
>+	} else {
>+		PMD_INIT_LOG(INFO, "Failed to read device serial number\n");
>+		strncpy(pkg_file, ICE_PKG_FILE_DEFAULT,
>+			ICE_MAX_PKG_FILENAME_SIZE);
>+
>+		return 0;
>+	}
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(pkg_file, 0))
>+		return 0;
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);

Do we need to check access for the pkg_file here too? What if the file doesn't exist or user doesn't have access to it?

Thanks,
Xiaolong

>+
>+	return 0;
>+}
>+
>+static enum ice_pkg_type
>+ice_get_pkg_type(struct ice_hw *hw)
>+{
>+	enum ice_pkg_type package_type;
>+
>+	/* store the activated package type (OS default or Comms) */
>+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
>+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_COMMS;
>+	else
>+		package_type = ICE_PKG_TYPE_UNKNOWN;
>+
>+	PMD_INIT_LOG(INFO, "Active package is: %d.%d.%d.%d, %s\n",
>+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
>+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
>+		hw->active_pkg_name);
>+
>+	return package_type;
>+}
>+
> static int ice_load_pkg(struct rte_eth_dev *dev)  {
> 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>-	const char *pkg_file = ICE_DFLT_PKG_FILE;
>+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
> 	int err;
> 	uint8_t *buf;
> 	int buf_len;
> 	FILE *file;
> 	struct stat fstat;
>+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
>+	struct ice_adapter *ad =
>+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
>+
>+	ice_pkg_file_search_path(pci_dev, pkg_file);
> 
> 	file = fopen(pkg_file, "rb");
> 	if (!file)  {
>@@ -1313,6 +1444,9 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
> 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
> 		goto fail_exit;
> 	}
>+
>+	ad->active_pkg_type = ice_get_pkg_type(hw);
>+
> 	err = ice_init_hw_tbls(hw);
> 	if (err) {
> 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err); diff --git 
>a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h index 
>5063960a8..d1d07641d 100644
>--- a/drivers/net/ice/ice_ethdev.h
>+++ b/drivers/net/ice/ice_ethdev.h
>@@ -124,6 +124,13 @@
> #define ICE_ETH_OVERHEAD \
> 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
> 
>+/* DDP package type */
>+enum ice_pkg_type {
>+	ICE_PKG_TYPE_UNKNOWN,
>+	ICE_PKG_TYPE_OS_DEFAULT,
>+	ICE_PKG_TYPE_COMMS,
>+};
>+
> struct ice_adapter;
> 
> /**
>@@ -296,6 +303,7 @@ struct ice_adapter {
> 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
> 	bool is_safe_mode;
> 	struct ice_devargs devargs;
>+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
> };
> 
> struct ice_vsi_vlan_pvid_info {
>--
>2.17.1
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v4] net/ice: support device-specific DDP package loading
  2019-09-03 14:29 ` [dpdk-dev] [PATCH v3] " Ting Xu
  2019-09-03  9:43   ` Ye Xiaolong
@ 2019-09-05 12:59   ` " Ting Xu
  2019-09-06 14:51     ` [dpdk-dev] [PATCH v5] " Ting Xu
  1 sibling, 1 reply; 16+ messages in thread
From: Ting Xu @ 2019-09-05 12:59 UTC (permalink / raw)
  To: dev; +Cc: xiaolong.ye, qi.z.zhang, wenzhuo.lu, qiming.yang

This patch adds the feature that supports loading DDP package
according to the device serial number. Prior to loading the
default DDP package (ice.pkg), the driver will check for the
presence of a device-specific DDP package with the name containing
64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
during initialization. Users can use "lspci -vs" to get the device
serial number.
The pkg search path are /lib/firmware/updates/intel/ice/ddp/
and /lib/firmware/intel/ice/ddp/. If the package exists,
the driver will download it to the device instead of the default
one. The loaded package type (OS default and COMMS) will be
stored in ice_adapter->active_pkg_type. The package version is
stored in ice_hw->active_pkg_ver.

Signed-off-by: Ting Xu <ting.xu@intel.com>

---
v4: correct the commit message format.
v3: fix compile error; modify to change the pkg loading order.
v2: modify codes according to the comments.
---
 drivers/net/ice/ice_ethdev.c | 140 ++++++++++++++++++++++++++++++++++-
 drivers/net/ice/ice_ethdev.h |   8 ++
 2 files changed, 146 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 686d6f00f..ce6fbd5df 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -28,7 +28,16 @@ static const char * const ice_valid_args[] = {
 };
 
 #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
+
+/* DDP package search path */
+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
+
+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
+#define ICE_MAX_PKG_FILENAME_SIZE   256
 
 int ice_logtype_init;
 int ice_logtype_driver;
@@ -1265,15 +1274,138 @@ ice_pf_setup(struct ice_pf *pf)
 	return 0;
 }
 
+/* PCIe configuration space setting */
+#define PCI_CFG_SPACE_SIZE          256
+#define PCI_CFG_SPACE_EXP_SIZE      4096
+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
+#define PCI_EXT_CAP_ID_DSN          0x03
+
+static int
+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = PCI_CFG_SPACE_SIZE;
+
+	/* minimum 8 bytes per capability */
+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+		return -1;
+	}
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (PCI_EXT_CAP_ID(header) == cap)
+			return pos;
+
+		pos = PCI_EXT_CAP_NEXT(header);
+
+		if (pos < PCI_CFG_SPACE_SIZE)
+			break;
+
+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/* Extract device serial number from PCIe Configuration Space and
+ * determine the pkg file path according to the DSN.
+ */
+static int
+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
+{
+	int pos;
+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
+	uint32_t dword;
+	uint32_t dsn_low, dsn_high;
+	memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
+
+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
+
+	if (pos) {
+		rte_pci_read_config(pci_dev, &dword, 4, pos + 4);
+		dsn_low = dword;
+		rte_pci_read_config(pci_dev, &dword, 4, pos + 8);
+		dsn_high = dword;
+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
+	} else {
+		PMD_INIT_LOG(INFO, "Failed to read device serial number\n");
+		strncpy(pkg_file, ICE_PKG_FILE_DEFAULT,
+			ICE_MAX_PKG_FILENAME_SIZE);
+
+		return 0;
+	}
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(pkg_file, 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
+
+	return 0;
+}
+
+static enum ice_pkg_type
+ice_get_pkg_type(struct ice_hw *hw)
+{
+	enum ice_pkg_type package_type;
+
+	/* store the activated package type (OS default or Comms) */
+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_COMMS;
+	else
+		package_type = ICE_PKG_TYPE_UNKNOWN;
+
+	PMD_INIT_LOG(INFO, "Active package is: %d.%d.%d.%d, %s\n",
+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
+		hw->active_pkg_name);
+
+	return package_type;
+}
+
 static int ice_load_pkg(struct rte_eth_dev *dev)
 {
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	const char *pkg_file = ICE_DFLT_PKG_FILE;
+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
 	int err;
 	uint8_t *buf;
 	int buf_len;
 	FILE *file;
 	struct stat fstat;
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct ice_adapter *ad =
+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	ice_pkg_file_search_path(pci_dev, pkg_file);
 
 	file = fopen(pkg_file, "rb");
 	if (!file)  {
@@ -1313,6 +1445,10 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
 		goto fail_exit;
 	}
+
+	/* store the loaded pkg type info */
+	ad->active_pkg_type = ice_get_pkg_type(hw);
+
 	err = ice_init_hw_tbls(hw);
 	if (err) {
 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 5063960a8..d1d07641d 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -124,6 +124,13 @@
 #define ICE_ETH_OVERHEAD \
 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
 
+/* DDP package type */
+enum ice_pkg_type {
+	ICE_PKG_TYPE_UNKNOWN,
+	ICE_PKG_TYPE_OS_DEFAULT,
+	ICE_PKG_TYPE_COMMS,
+};
+
 struct ice_adapter;
 
 /**
@@ -296,6 +303,7 @@ struct ice_adapter {
 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
 	bool is_safe_mode;
 	struct ice_devargs devargs;
+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
 };
 
 struct ice_vsi_vlan_pvid_info {
-- 
2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH v5] net/ice: support device-specific DDP package loading
  2019-09-06 14:51     ` [dpdk-dev] [PATCH v5] " Ting Xu
@ 2019-09-06 13:53       ` Ye Xiaolong
  2019-09-06 14:16       ` Ye Xiaolong
  2019-09-11 12:35       ` [dpdk-dev] [PATCH v6] " Ting Xu
  2 siblings, 0 replies; 16+ messages in thread
From: Ye Xiaolong @ 2019-09-06 13:53 UTC (permalink / raw)
  To: Ting Xu; +Cc: dev, qi.z.zhang

On 09/06, Ting Xu wrote:
>This patch adds the feature that supports loading DDP package
>according to the device serial number. Prior to loading the
>default DDP package (ice.pkg), the driver will check for the
>presence of a device-specific DDP package with the name containing
>64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
>during initialization. Users can use "lspci -vs" to get the device
>serial number.
>The pkg search path are /lib/firmware/updates/intel/ice/ddp/
>and /lib/firmware/intel/ice/ddp/. If the package exists,
>the driver will download it to the device instead of the default
>one. The loaded package type (OS default and COMMS) will be
>stored in ice_adapter->active_pkg_type. The package version is
>stored in ice_hw->active_pkg_ver.
>
>Signed-off-by: Ting Xu <ting.xu@intel.com>
>
>---
>v5: optimize the operation when dsn is not found.
>v4: correct the commit message format.
>v3: fix compile error; modify to change the pkg loading order.
>v2: modify codes according to the comments.
>---
> drivers/net/ice/ice_ethdev.c | 136 ++++++++++++++++++++++++++++++++++-
> drivers/net/ice/ice_ethdev.h |   8 +++

Please also update the document and release note.

> 2 files changed, 142 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
>index 686d6f00f..2de3b6450 100644
>--- a/drivers/net/ice/ice_ethdev.c
>+++ b/drivers/net/ice/ice_ethdev.c
>@@ -28,7 +28,16 @@ static const char * const ice_valid_args[] = {
> };
> 
> #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
>-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
>+
>+/* DDP package search path */
>+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
>+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
>+
>+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
>+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
>+#define ICE_MAX_PKG_FILENAME_SIZE   256
> 
> int ice_logtype_init;
> int ice_logtype_driver;
>@@ -1265,15 +1274,134 @@ ice_pf_setup(struct ice_pf *pf)
> 	return 0;
> }
> 
>+/* PCIe configuration space setting */
>+#define PCI_CFG_SPACE_SIZE          256
>+#define PCI_CFG_SPACE_EXP_SIZE      4096
>+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
>+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
>+#define PCI_EXT_CAP_ID_DSN          0x03
>+
>+static int
>+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
>+{
>+	uint32_t header;
>+	int ttl;
>+	int pos = PCI_CFG_SPACE_SIZE;
>+
>+	/* minimum 8 bytes per capability */
>+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
>+
>+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+		return -1;
>+	}
>+
>+	/*
>+	 * If we have no capabilities, this is indicated by cap ID,
>+	 * cap version and next pointer all being 0.
>+	 */
>+	if (header == 0)
>+		return 0;
>+
>+	while (ttl-- > 0) {
>+		if (PCI_EXT_CAP_ID(header) == cap)
>+			return pos;
>+
>+		pos = PCI_EXT_CAP_NEXT(header);
>+
>+		if (pos < PCI_CFG_SPACE_SIZE)
>+			break;
>+
>+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+			return -1;
>+		}
>+	}
>+
>+	return 0;
>+}
>+
>+/* Extract device serial number from PCIe Configuration Space and
>+ * determine the pkg file path according to the DSN.
>+ */
>+static int
>+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
>+{
>+	int pos;
>+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
>+	uint32_t dword;
>+	uint32_t dsn_low, dsn_high;
>+	memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
>+
>+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
>+
>+	if (pos) {
>+		rte_pci_read_config(pci_dev, &dword, 4, pos + 4);
>+		dsn_low = dword;
>+		rte_pci_read_config(pci_dev, &dword, 4, pos + 8);
>+		dsn_high = dword;

why not just

		rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4);
		rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8);

Seems dword variable is unnecessary here.

Thanks,
Xiaolong

>+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
>+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
>+	} else {
>+		PMD_INIT_LOG(INFO, "Failed to read device serial number\n");
>+		goto fail_dsn;
>+	}
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+fail_dsn:
>+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(pkg_file, 0))
>+		return 0;
>+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
>+	return 0;
>+}
>+
>+static enum ice_pkg_type
>+ice_get_pkg_type(struct ice_hw *hw)
>+{
>+	enum ice_pkg_type package_type;
>+
>+	/* store the activated package type (OS default or Comms) */
>+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
>+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_COMMS;
>+	else
>+		package_type = ICE_PKG_TYPE_UNKNOWN;
>+
>+	PMD_INIT_LOG(INFO, "Active package is: %d.%d.%d.%d, %s\n",
>+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
>+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
>+		hw->active_pkg_name);
>+
>+	return package_type;
>+}
>+
> static int ice_load_pkg(struct rte_eth_dev *dev)
> {
> 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>-	const char *pkg_file = ICE_DFLT_PKG_FILE;
>+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
> 	int err;
> 	uint8_t *buf;
> 	int buf_len;
> 	FILE *file;
> 	struct stat fstat;
>+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
>+	struct ice_adapter *ad =
>+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
>+
>+	ice_pkg_file_search_path(pci_dev, pkg_file);
> 
> 	file = fopen(pkg_file, "rb");
> 	if (!file)  {
>@@ -1313,6 +1441,10 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
> 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
> 		goto fail_exit;
> 	}
>+
>+	/* store the loaded pkg type info */
>+	ad->active_pkg_type = ice_get_pkg_type(hw);
>+
> 	err = ice_init_hw_tbls(hw);
> 	if (err) {
> 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
>diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
>index 5063960a8..d1d07641d 100644
>--- a/drivers/net/ice/ice_ethdev.h
>+++ b/drivers/net/ice/ice_ethdev.h
>@@ -124,6 +124,13 @@
> #define ICE_ETH_OVERHEAD \
> 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
> 
>+/* DDP package type */
>+enum ice_pkg_type {
>+	ICE_PKG_TYPE_UNKNOWN,
>+	ICE_PKG_TYPE_OS_DEFAULT,
>+	ICE_PKG_TYPE_COMMS,
>+};
>+
> struct ice_adapter;
> 
> /**
>@@ -296,6 +303,7 @@ struct ice_adapter {
> 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
> 	bool is_safe_mode;
> 	struct ice_devargs devargs;
>+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
> };
> 
> struct ice_vsi_vlan_pvid_info {
>-- 
>2.17.1
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH v5] net/ice: support device-specific DDP package loading
  2019-09-06 14:51     ` [dpdk-dev] [PATCH v5] " Ting Xu
  2019-09-06 13:53       ` Ye Xiaolong
@ 2019-09-06 14:16       ` Ye Xiaolong
  2019-09-11 12:35       ` [dpdk-dev] [PATCH v6] " Ting Xu
  2 siblings, 0 replies; 16+ messages in thread
From: Ye Xiaolong @ 2019-09-06 14:16 UTC (permalink / raw)
  To: Ting Xu; +Cc: dev, qi.z.zhang

On 09/06, Ting Xu wrote:
>This patch adds the feature that supports loading DDP package
>according to the device serial number. Prior to loading the
>default DDP package (ice.pkg), the driver will check for the
>presence of a device-specific DDP package with the name containing
>64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
>during initialization. Users can use "lspci -vs" to get the device
>serial number.
>The pkg search path are /lib/firmware/updates/intel/ice/ddp/
>and /lib/firmware/intel/ice/ddp/. If the package exists,
>the driver will download it to the device instead of the default
>one. The loaded package type (OS default and COMMS) will be
>stored in ice_adapter->active_pkg_type. The package version is
>stored in ice_hw->active_pkg_ver.
>
>Signed-off-by: Ting Xu <ting.xu@intel.com>
>
>---
>v5: optimize the operation when dsn is not found.
>v4: correct the commit message format.
>v3: fix compile error; modify to change the pkg loading order.
>v2: modify codes according to the comments.
>---
> drivers/net/ice/ice_ethdev.c | 136 ++++++++++++++++++++++++++++++++++-
> drivers/net/ice/ice_ethdev.h |   8 +++
> 2 files changed, 142 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
>index 686d6f00f..2de3b6450 100644
>--- a/drivers/net/ice/ice_ethdev.c
>+++ b/drivers/net/ice/ice_ethdev.c
>@@ -28,7 +28,16 @@ static const char * const ice_valid_args[] = {
> };
> 
> #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
>-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
>+
>+/* DDP package search path */
>+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
>+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
>+
>+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
>+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
>+#define ICE_MAX_PKG_FILENAME_SIZE   256
> 
> int ice_logtype_init;
> int ice_logtype_driver;
>@@ -1265,15 +1274,134 @@ ice_pf_setup(struct ice_pf *pf)
> 	return 0;
> }
> 
>+/* PCIe configuration space setting */
>+#define PCI_CFG_SPACE_SIZE          256
>+#define PCI_CFG_SPACE_EXP_SIZE      4096
>+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
>+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
>+#define PCI_EXT_CAP_ID_DSN          0x03
>+
>+static int
>+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
>+{
>+	uint32_t header;
>+	int ttl;
>+	int pos = PCI_CFG_SPACE_SIZE;
>+
>+	/* minimum 8 bytes per capability */
>+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
>+
>+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+		return -1;
>+	}
>+
>+	/*
>+	 * If we have no capabilities, this is indicated by cap ID,
>+	 * cap version and next pointer all being 0.
>+	 */
>+	if (header == 0)
>+		return 0;
>+
>+	while (ttl-- > 0) {
>+		if (PCI_EXT_CAP_ID(header) == cap)
>+			return pos;
>+
>+		pos = PCI_EXT_CAP_NEXT(header);
>+
>+		if (pos < PCI_CFG_SPACE_SIZE)
>+			break;
>+
>+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+			return -1;
>+		}
>+	}
>+
>+	return 0;
>+}
>+
>+/* Extract device serial number from PCIe Configuration Space and
>+ * determine the pkg file path according to the DSN.
>+ */

DPDK prefers multi-line comments format like:

 /*
  * Multi-line comments look like this.  Make them real sentences. Fill
  * them so they look like real paragraphs.
  */


>+static int
>+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
>+{
>+	int pos;
>+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
>+	uint32_t dword;
>+	uint32_t dsn_low, dsn_high;
>+	memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
>+
>+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
>+
>+	if (pos) {
>+		rte_pci_read_config(pci_dev, &dword, 4, pos + 4);
>+		dsn_low = dword;
>+		rte_pci_read_config(pci_dev, &dword, 4, pos + 8);
>+		dsn_high = dword;
>+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
>+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
>+	} else {
>+		PMD_INIT_LOG(INFO, "Failed to read device serial number\n");
>+		goto fail_dsn;
>+	}
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+fail_dsn:
>+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(pkg_file, 0))
>+		return 0;
>+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
>+	return 0;
>+}
>+
>+static enum ice_pkg_type
>+ice_get_pkg_type(struct ice_hw *hw)
>+{
>+	enum ice_pkg_type package_type;
>+
>+	/* store the activated package type (OS default or Comms) */
>+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
>+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_COMMS;
>+	else
>+		package_type = ICE_PKG_TYPE_UNKNOWN;
>+
>+	PMD_INIT_LOG(INFO, "Active package is: %d.%d.%d.%d, %s\n",
>+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
>+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
>+		hw->active_pkg_name);
>+
>+	return package_type;
>+}
>+
> static int ice_load_pkg(struct rte_eth_dev *dev)
> {
> 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>-	const char *pkg_file = ICE_DFLT_PKG_FILE;
>+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
> 	int err;
> 	uint8_t *buf;
> 	int buf_len;
> 	FILE *file;
> 	struct stat fstat;
>+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
>+	struct ice_adapter *ad =
>+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
>+
>+	ice_pkg_file_search_path(pci_dev, pkg_file);
> 
> 	file = fopen(pkg_file, "rb");
> 	if (!file)  {
>@@ -1313,6 +1441,10 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
> 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
> 		goto fail_exit;
> 	}
>+
>+	/* store the loaded pkg type info */
>+	ad->active_pkg_type = ice_get_pkg_type(hw);
>+
> 	err = ice_init_hw_tbls(hw);
> 	if (err) {
> 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
>diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
>index 5063960a8..d1d07641d 100644
>--- a/drivers/net/ice/ice_ethdev.h
>+++ b/drivers/net/ice/ice_ethdev.h
>@@ -124,6 +124,13 @@
> #define ICE_ETH_OVERHEAD \
> 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
> 
>+/* DDP package type */
>+enum ice_pkg_type {
>+	ICE_PKG_TYPE_UNKNOWN,
>+	ICE_PKG_TYPE_OS_DEFAULT,
>+	ICE_PKG_TYPE_COMMS,
>+};
>+
> struct ice_adapter;
> 
> /**
>@@ -296,6 +303,7 @@ struct ice_adapter {
> 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
> 	bool is_safe_mode;
> 	struct ice_devargs devargs;
>+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
> };
> 
> struct ice_vsi_vlan_pvid_info {
>-- 
>2.17.1
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v5] net/ice: support device-specific DDP package loading
  2019-09-05 12:59   ` [dpdk-dev] [PATCH v4] " Ting Xu
@ 2019-09-06 14:51     ` " Ting Xu
  2019-09-06 13:53       ` Ye Xiaolong
                         ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Ting Xu @ 2019-09-06 14:51 UTC (permalink / raw)
  To: dev; +Cc: xiaolong.ye, qi.z.zhang

This patch adds the feature that supports loading DDP package
according to the device serial number. Prior to loading the
default DDP package (ice.pkg), the driver will check for the
presence of a device-specific DDP package with the name containing
64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
during initialization. Users can use "lspci -vs" to get the device
serial number.
The pkg search path are /lib/firmware/updates/intel/ice/ddp/
and /lib/firmware/intel/ice/ddp/. If the package exists,
the driver will download it to the device instead of the default
one. The loaded package type (OS default and COMMS) will be
stored in ice_adapter->active_pkg_type. The package version is
stored in ice_hw->active_pkg_ver.

Signed-off-by: Ting Xu <ting.xu@intel.com>

---
v5: optimize the operation when dsn is not found.
v4: correct the commit message format.
v3: fix compile error; modify to change the pkg loading order.
v2: modify codes according to the comments.
---
 drivers/net/ice/ice_ethdev.c | 136 ++++++++++++++++++++++++++++++++++-
 drivers/net/ice/ice_ethdev.h |   8 +++
 2 files changed, 142 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 686d6f00f..2de3b6450 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -28,7 +28,16 @@ static const char * const ice_valid_args[] = {
 };
 
 #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
+
+/* DDP package search path */
+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
+
+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
+#define ICE_MAX_PKG_FILENAME_SIZE   256
 
 int ice_logtype_init;
 int ice_logtype_driver;
@@ -1265,15 +1274,134 @@ ice_pf_setup(struct ice_pf *pf)
 	return 0;
 }
 
+/* PCIe configuration space setting */
+#define PCI_CFG_SPACE_SIZE          256
+#define PCI_CFG_SPACE_EXP_SIZE      4096
+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
+#define PCI_EXT_CAP_ID_DSN          0x03
+
+static int
+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = PCI_CFG_SPACE_SIZE;
+
+	/* minimum 8 bytes per capability */
+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+		return -1;
+	}
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (PCI_EXT_CAP_ID(header) == cap)
+			return pos;
+
+		pos = PCI_EXT_CAP_NEXT(header);
+
+		if (pos < PCI_CFG_SPACE_SIZE)
+			break;
+
+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/* Extract device serial number from PCIe Configuration Space and
+ * determine the pkg file path according to the DSN.
+ */
+static int
+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
+{
+	int pos;
+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
+	uint32_t dword;
+	uint32_t dsn_low, dsn_high;
+	memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
+
+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
+
+	if (pos) {
+		rte_pci_read_config(pci_dev, &dword, 4, pos + 4);
+		dsn_low = dword;
+		rte_pci_read_config(pci_dev, &dword, 4, pos + 8);
+		dsn_high = dword;
+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
+	} else {
+		PMD_INIT_LOG(INFO, "Failed to read device serial number\n");
+		goto fail_dsn;
+	}
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+fail_dsn:
+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(pkg_file, 0))
+		return 0;
+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
+	return 0;
+}
+
+static enum ice_pkg_type
+ice_get_pkg_type(struct ice_hw *hw)
+{
+	enum ice_pkg_type package_type;
+
+	/* store the activated package type (OS default or Comms) */
+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_COMMS;
+	else
+		package_type = ICE_PKG_TYPE_UNKNOWN;
+
+	PMD_INIT_LOG(INFO, "Active package is: %d.%d.%d.%d, %s\n",
+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
+		hw->active_pkg_name);
+
+	return package_type;
+}
+
 static int ice_load_pkg(struct rte_eth_dev *dev)
 {
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	const char *pkg_file = ICE_DFLT_PKG_FILE;
+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
 	int err;
 	uint8_t *buf;
 	int buf_len;
 	FILE *file;
 	struct stat fstat;
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct ice_adapter *ad =
+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	ice_pkg_file_search_path(pci_dev, pkg_file);
 
 	file = fopen(pkg_file, "rb");
 	if (!file)  {
@@ -1313,6 +1441,10 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
 		goto fail_exit;
 	}
+
+	/* store the loaded pkg type info */
+	ad->active_pkg_type = ice_get_pkg_type(hw);
+
 	err = ice_init_hw_tbls(hw);
 	if (err) {
 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 5063960a8..d1d07641d 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -124,6 +124,13 @@
 #define ICE_ETH_OVERHEAD \
 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
 
+/* DDP package type */
+enum ice_pkg_type {
+	ICE_PKG_TYPE_UNKNOWN,
+	ICE_PKG_TYPE_OS_DEFAULT,
+	ICE_PKG_TYPE_COMMS,
+};
+
 struct ice_adapter;
 
 /**
@@ -296,6 +303,7 @@ struct ice_adapter {
 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
 	bool is_safe_mode;
 	struct ice_devargs devargs;
+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
 };
 
 struct ice_vsi_vlan_pvid_info {
-- 
2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v6] net/ice: support device-specific DDP package loading
  2019-09-06 14:51     ` [dpdk-dev] [PATCH v5] " Ting Xu
  2019-09-06 13:53       ` Ye Xiaolong
  2019-09-06 14:16       ` Ye Xiaolong
@ 2019-09-11 12:35       ` " Ting Xu
  2019-09-13 10:51         ` Ye Xiaolong
  2019-09-17  8:44         ` [dpdk-dev] [PATCH v7] " Ting Xu
  2 siblings, 2 replies; 16+ messages in thread
From: Ting Xu @ 2019-09-11 12:35 UTC (permalink / raw)
  To: dev; +Cc: xiaolong.ye, qi.z.zhang, john.mcnamara, marko.kovacevic

This patch adds the feature that supports loading DDP package
according to the device serial number. Prior to loading the
default DDP package (ice.pkg), the driver will check for the
presence of a device-specific DDP package with the name containing
64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
during initialization. Users can use "lspci -vs" to get the device
serial number.
The pkg search path are /lib/firmware/updates/intel/ice/ddp/
and /lib/firmware/intel/ice/ddp/. If the package exists,
the driver will download it to the device instead of the default
one. The loaded package type (OS default and COMMS) will be
stored in ice_adapter->active_pkg_type. The package version is
stored in ice_hw->active_pkg_ver.

Signed-off-by: Ting Xu <ting.xu@intel.com>

---
v6: update doc and release note; reduce redundant variables;
change some log levels.
v5: optimize the operation when dsn is not found.
v4: correct the commit message format.
v3: fix compile error; modify to change the pkg loading order.
v2: modify codes according to the comments.
---
 doc/guides/nics/ice.rst                |  20 +++-
 doc/guides/rel_notes/release_19_11.rst |   5 +
 drivers/net/ice/ice_ethdev.c           | 134 ++++++++++++++++++++++++-
 drivers/net/ice/ice_ethdev.h           |   8 ++
 4 files changed, 161 insertions(+), 6 deletions(-)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 45b6749a1..161e1452c 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -125,10 +125,22 @@ The Intel E810 requires a programmable pipeline package be downloaded
 by the driver to support normal operations. The E810 has a limited
 functionality built in to allow PXE boot and other use cases, but the
 driver must download a package file during the driver initialization
-stage. The file must be in the /lib/firmware/intel/ice/ddp directory
-and it must be named ice.pkg. A symbolic link to this file is also ok.
-The same package file is used by both the kernel driver and the DPDK PMD.
-
+stage.
+
+The default DDP package file name is ice.pkg. For a specific NIC, the
+DDP package supposed to be loaded can have a filename: ice-xxxxxx.pkg,
+where 'xxxxxx' is the 64-bit PCIe Device Serial Number of the NIC. For
+example, if the NIC's device serial number is 00-CC-BB-FF-FF-AA-05-68,
+the device-specific DDP package filename is ice-00ccbbffffaa0568.pkg
+(in hex and all low case). During initialization, the driver searches
+in the following paths in order: /lib/firmware/updates/intel/ice/ddp
+and /lib/firmware/intel/ice/ddp. The correponding device-specific DDP
+package will be downloaded first if the file exists. If not, then the
+driver tries to load the default package. The type of loaded package
+is stored in ``ice_adapter->active_pkg_type``.
+
+A symbolic link to the DDP package file is also ok. The same package
+file is used by both the kernel driver and the DPDK PMD.
 
 19.02 limitation
 ~~~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 8490d897c..ef5048829 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -56,6 +56,11 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
+* **Support device-specific DDP package loading.**
+
+  Added support to load device-specific DDP package. The package file
+  with name including NIC's device serial number would be searched and
+  loaded (if existed) prior to the default package (ice.pkg).
 
 Removed Items
 -------------
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 686d6f00f..0811d8053 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -28,7 +28,16 @@ static const char * const ice_valid_args[] = {
 };
 
 #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
+
+/* DDP package search path */
+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
+
+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
+#define ICE_MAX_PKG_FILENAME_SIZE   256
 
 int ice_logtype_init;
 int ice_logtype_driver;
@@ -1265,15 +1274,132 @@ ice_pf_setup(struct ice_pf *pf)
 	return 0;
 }
 
+/* PCIe configuration space setting */
+#define PCI_CFG_SPACE_SIZE          256
+#define PCI_CFG_SPACE_EXP_SIZE      4096
+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
+#define PCI_EXT_CAP_ID_DSN          0x03
+
+static int
+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = PCI_CFG_SPACE_SIZE;
+
+	/* minimum 8 bytes per capability */
+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+		return -1;
+	}
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (PCI_EXT_CAP_ID(header) == cap)
+			return pos;
+
+		pos = PCI_EXT_CAP_NEXT(header);
+
+		if (pos < PCI_CFG_SPACE_SIZE)
+			break;
+
+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Extract device serial number from PCIe Configuration Space and
+ * determine the pkg file path according to the DSN.
+ */
+static int
+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
+{
+	int pos;
+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
+	uint32_t dsn_low, dsn_high;
+	memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
+
+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
+
+	if (pos) {
+		rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4);
+		rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8);
+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
+	} else {
+		PMD_INIT_LOG(ERR, "Failed to read device serial number\n");
+		goto fail_dsn;
+	}
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+fail_dsn:
+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(pkg_file, 0))
+		return 0;
+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
+	return 0;
+}
+
+static enum ice_pkg_type
+ice_load_pkg_type(struct ice_hw *hw)
+{
+	enum ice_pkg_type package_type;
+
+	/* store the activated package type (OS default or Comms) */
+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_COMMS;
+	else
+		package_type = ICE_PKG_TYPE_UNKNOWN;
+
+	PMD_INIT_LOG(NOTICE, "Active package is: %d.%d.%d.%d, %s",
+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
+		hw->active_pkg_name);
+
+	return package_type;
+}
+
 static int ice_load_pkg(struct rte_eth_dev *dev)
 {
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	const char *pkg_file = ICE_DFLT_PKG_FILE;
+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
 	int err;
 	uint8_t *buf;
 	int buf_len;
 	FILE *file;
 	struct stat fstat;
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct ice_adapter *ad =
+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	ice_pkg_file_search_path(pci_dev, pkg_file);
 
 	file = fopen(pkg_file, "rb");
 	if (!file)  {
@@ -1313,6 +1439,10 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
 		goto fail_exit;
 	}
+
+	/* store the loaded pkg type info */
+	ad->active_pkg_type = ice_load_pkg_type(hw);
+
 	err = ice_init_hw_tbls(hw);
 	if (err) {
 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 5063960a8..d1d07641d 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -124,6 +124,13 @@
 #define ICE_ETH_OVERHEAD \
 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
 
+/* DDP package type */
+enum ice_pkg_type {
+	ICE_PKG_TYPE_UNKNOWN,
+	ICE_PKG_TYPE_OS_DEFAULT,
+	ICE_PKG_TYPE_COMMS,
+};
+
 struct ice_adapter;
 
 /**
@@ -296,6 +303,7 @@ struct ice_adapter {
 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
 	bool is_safe_mode;
 	struct ice_devargs devargs;
+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
 };
 
 struct ice_vsi_vlan_pvid_info {
-- 
2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH v6] net/ice: support device-specific DDP package loading
  2019-09-11 12:35       ` [dpdk-dev] [PATCH v6] " Ting Xu
@ 2019-09-13 10:51         ` Ye Xiaolong
  2019-09-17  8:44         ` [dpdk-dev] [PATCH v7] " Ting Xu
  1 sibling, 0 replies; 16+ messages in thread
From: Ye Xiaolong @ 2019-09-13 10:51 UTC (permalink / raw)
  To: Ting Xu; +Cc: dev, qi.z.zhang, john.mcnamara, marko.kovacevic

Hi, Ting

On 09/11, Ting Xu wrote:
>This patch adds the feature that supports loading DDP package
>according to the device serial number. Prior to loading the
>default DDP package (ice.pkg), the driver will check for the
>presence of a device-specific DDP package with the name containing
>64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
>during initialization. Users can use "lspci -vs" to get the device
>serial number.
>The pkg search path are /lib/firmware/updates/intel/ice/ddp/
>and /lib/firmware/intel/ice/ddp/. If the package exists,
>the driver will download it to the device instead of the default
>one. The loaded package type (OS default and COMMS) will be
>stored in ice_adapter->active_pkg_type. The package version is
>stored in ice_hw->active_pkg_ver.
>
>Signed-off-by: Ting Xu <ting.xu@intel.com>
>
>---
>v6: update doc and release note; reduce redundant variables;
>change some log levels.
>v5: optimize the operation when dsn is not found.
>v4: correct the commit message format.
>v3: fix compile error; modify to change the pkg loading order.
>v2: modify codes according to the comments.
>---
> doc/guides/nics/ice.rst                |  20 +++-
> doc/guides/rel_notes/release_19_11.rst |   5 +
> drivers/net/ice/ice_ethdev.c           | 134 ++++++++++++++++++++++++-
> drivers/net/ice/ice_ethdev.h           |   8 ++
> 4 files changed, 161 insertions(+), 6 deletions(-)
>
>diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
>index 45b6749a1..161e1452c 100644
>--- a/doc/guides/nics/ice.rst
>+++ b/doc/guides/nics/ice.rst
>@@ -125,10 +125,22 @@ The Intel E810 requires a programmable pipeline package be downloaded
> by the driver to support normal operations. The E810 has a limited
> functionality built in to allow PXE boot and other use cases, but the
> driver must download a package file during the driver initialization
>-stage. The file must be in the /lib/firmware/intel/ice/ddp directory
>-and it must be named ice.pkg. A symbolic link to this file is also ok.
>-The same package file is used by both the kernel driver and the DPDK PMD.
>-
>+stage.
>+
>+The default DDP package file name is ice.pkg. For a specific NIC, the
>+DDP package supposed to be loaded can have a filename: ice-xxxxxx.pkg,
>+where 'xxxxxx' is the 64-bit PCIe Device Serial Number of the NIC. For
>+example, if the NIC's device serial number is 00-CC-BB-FF-FF-AA-05-68,
>+the device-specific DDP package filename is ice-00ccbbffffaa0568.pkg
>+(in hex and all low case). During initialization, the driver searches
>+in the following paths in order: /lib/firmware/updates/intel/ice/ddp
>+and /lib/firmware/intel/ice/ddp. The correponding device-specific DDP
>+package will be downloaded first if the file exists. If not, then the
>+driver tries to load the default package. The type of loaded package
>+is stored in ``ice_adapter->active_pkg_type``.
>+
>+A symbolic link to the DDP package file is also ok. The same package
>+file is used by both the kernel driver and the DPDK PMD.
> 
> 19.02 limitation
> ~~~~~~~~~~~~~~~~
>diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
>index 8490d897c..ef5048829 100644
>--- a/doc/guides/rel_notes/release_19_11.rst
>+++ b/doc/guides/rel_notes/release_19_11.rst
>@@ -56,6 +56,11 @@ New Features
>      Also, make sure to start the actual text at the margin.
>      =========================================================
> 
>+* **Support device-specific DDP package loading.**
>+
>+  Added support to load device-specific DDP package. The package file
>+  with name including NIC's device serial number would be searched and
>+  loaded (if existed) prior to the default package (ice.pkg).
> 
> Removed Items
> -------------
>diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
>index 686d6f00f..0811d8053 100644
>--- a/drivers/net/ice/ice_ethdev.c
>+++ b/drivers/net/ice/ice_ethdev.c
>@@ -28,7 +28,16 @@ static const char * const ice_valid_args[] = {
> };
> 
> #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
>-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
>+
>+/* DDP package search path */
>+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
>+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
>+
>+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
>+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
>+#define ICE_MAX_PKG_FILENAME_SIZE   256
> 
> int ice_logtype_init;
> int ice_logtype_driver;
>@@ -1265,15 +1274,132 @@ ice_pf_setup(struct ice_pf *pf)
> 	return 0;
> }
> 
>+/* PCIe configuration space setting */
>+#define PCI_CFG_SPACE_SIZE          256
>+#define PCI_CFG_SPACE_EXP_SIZE      4096
>+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
>+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
>+#define PCI_EXT_CAP_ID_DSN          0x03
>+
>+static int
>+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
>+{
>+	uint32_t header;
>+	int ttl;
>+	int pos = PCI_CFG_SPACE_SIZE;
>+
>+	/* minimum 8 bytes per capability */
>+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
>+
>+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+		return -1;
>+	}
>+
>+	/*
>+	 * If we have no capabilities, this is indicated by cap ID,
>+	 * cap version and next pointer all being 0.
>+	 */
>+	if (header == 0)
>+		return 0;
>+
>+	while (ttl-- > 0) {
>+		if (PCI_EXT_CAP_ID(header) == cap)
>+			return pos;
>+
>+		pos = PCI_EXT_CAP_NEXT(header);
>+
>+		if (pos < PCI_CFG_SPACE_SIZE)
>+			break;
>+
>+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+			return -1;
>+		}
>+	}
>+
>+	return 0;
>+}

Above code is common pci helper function, and it shares the same code in nfp pmd,
could you try to move them into lib/librte_ethdev/rte_ethdev_pci.h?

Thanks,
Xiaolong

>+
>+/*
>+ * Extract device serial number from PCIe Configuration Space and
>+ * determine the pkg file path according to the DSN.
>+ */
>+static int
>+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
>+{
>+	int pos;
>+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
>+	uint32_t dsn_low, dsn_high;
>+	memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
>+
>+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
>+
>+	if (pos) {
>+		rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4);
>+		rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8);
>+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
>+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
>+	} else {
>+		PMD_INIT_LOG(ERR, "Failed to read device serial number\n");
>+		goto fail_dsn;
>+	}
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+fail_dsn:
>+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(pkg_file, 0))
>+		return 0;
>+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
>+	return 0;
>+}
>+
>+static enum ice_pkg_type
>+ice_load_pkg_type(struct ice_hw *hw)
>+{
>+	enum ice_pkg_type package_type;
>+
>+	/* store the activated package type (OS default or Comms) */
>+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
>+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_COMMS;
>+	else
>+		package_type = ICE_PKG_TYPE_UNKNOWN;
>+
>+	PMD_INIT_LOG(NOTICE, "Active package is: %d.%d.%d.%d, %s",
>+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
>+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
>+		hw->active_pkg_name);
>+
>+	return package_type;
>+}
>+
> static int ice_load_pkg(struct rte_eth_dev *dev)
> {
> 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>-	const char *pkg_file = ICE_DFLT_PKG_FILE;
>+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
> 	int err;
> 	uint8_t *buf;
> 	int buf_len;
> 	FILE *file;
> 	struct stat fstat;
>+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
>+	struct ice_adapter *ad =
>+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
>+
>+	ice_pkg_file_search_path(pci_dev, pkg_file);
> 
> 	file = fopen(pkg_file, "rb");
> 	if (!file)  {
>@@ -1313,6 +1439,10 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
> 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
> 		goto fail_exit;
> 	}
>+
>+	/* store the loaded pkg type info */
>+	ad->active_pkg_type = ice_load_pkg_type(hw);
>+
> 	err = ice_init_hw_tbls(hw);
> 	if (err) {
> 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
>diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
>index 5063960a8..d1d07641d 100644
>--- a/drivers/net/ice/ice_ethdev.h
>+++ b/drivers/net/ice/ice_ethdev.h
>@@ -124,6 +124,13 @@
> #define ICE_ETH_OVERHEAD \
> 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
> 
>+/* DDP package type */
>+enum ice_pkg_type {
>+	ICE_PKG_TYPE_UNKNOWN,
>+	ICE_PKG_TYPE_OS_DEFAULT,
>+	ICE_PKG_TYPE_COMMS,
>+};
>+
> struct ice_adapter;
> 
> /**
>@@ -296,6 +303,7 @@ struct ice_adapter {
> 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
> 	bool is_safe_mode;
> 	struct ice_devargs devargs;
>+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
> };
> 
> struct ice_vsi_vlan_pvid_info {
>-- 
>2.17.1
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v7] net/ice: support device-specific DDP package loading
  2019-09-11 12:35       ` [dpdk-dev] [PATCH v6] " Ting Xu
  2019-09-13 10:51         ` Ye Xiaolong
@ 2019-09-17  8:44         ` " Ting Xu
  2019-09-17 13:02           ` [dpdk-dev] [PATCH v8] " Ting Xu
  1 sibling, 1 reply; 16+ messages in thread
From: Ting Xu @ 2019-09-17  8:44 UTC (permalink / raw)
  To: dev
  Cc: wenzhuo.lu, qiming.yang, john.mcnamara, marko.kovacevic,
	alejandro.lucero, thomas, ferruh.yigit, arybchenko, xiaolong.ye

This patch adds the feature that supports loading DDP package
according to the device serial number. Prior to loading the
default DDP package (ice.pkg), the driver will check for the
presence of a device-specific DDP package with the name containing
64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
during initialization. Users can use "lspci -vs" to get the device
serial number.
The pkg search path are /lib/firmware/updates/intel/ice/ddp/
and /lib/firmware/intel/ice/ddp/. If the package exists,
the driver will download it to the device instead of the default
one. The loaded package type (OS default and COMMS) will be
stored in ice_adapter->active_pkg_type. The package version is
stored in ice_hw->active_pkg_ver.

Signed-off-by: Ting Xu <ting.xu@intel.com>

---
v7: fix coding style error; move function to rte_ethdev_pci.h.
v6: update doc and release note; reduce redundant variables;
change some log levels.
v5: optimize the operation when dsn is not found.
v4: correct the commit message format.
v3: fix compile error; modify to change the pkg loading order.
v2: modify codes according to the comments.
---
 doc/guides/nics/ice.rst                    | 20 ++++-
 doc/guides/rel_notes/release_19_11.rst     |  5 ++
 drivers/net/ice/ice_ethdev.c               | 88 +++++++++++++++++++++-
 drivers/net/ice/ice_ethdev.h               |  8 ++
 drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c | 46 +----------
 lib/librte_ethdev/rte_ethdev_pci.h         | 59 +++++++++++++++
 6 files changed, 175 insertions(+), 51 deletions(-)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 03819d29f..59a222e28 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -118,10 +118,22 @@ The Intel E810 requires a programmable pipeline package be downloaded
 by the driver to support normal operations. The E810 has a limited
 functionality built in to allow PXE boot and other use cases, but the
 driver must download a package file during the driver initialization
-stage. The file must be in the /lib/firmware/intel/ice/ddp directory
-and it must be named ice.pkg. A symbolic link to this file is also ok.
-The same package file is used by both the kernel driver and the DPDK PMD.
-
+stage.
+
+The default DDP package file name is ice.pkg. For a specific NIC, the
+DDP package supposed to be loaded can have a filename: ice-xxxxxx.pkg,
+where 'xxxxxx' is the 64-bit PCIe Device Serial Number of the NIC. For
+example, if the NIC's device serial number is 00-CC-BB-FF-FF-AA-05-68,
+the device-specific DDP package filename is ice-00ccbbffffaa0568.pkg
+(in hex and all low case). During initialization, the driver searches
+in the following paths in order: /lib/firmware/updates/intel/ice/ddp
+and /lib/firmware/intel/ice/ddp. The corresponding device-specific DDP
+package will be downloaded first if the file exists. If not, then the
+driver tries to load the default package. The type of loaded package
+is stored in ``ice_adapter->active_pkg_type``.
+
+A symbolic link to the DDP package file is also ok. The same package
+file is used by both the kernel driver and the DPDK PMD.
 
 19.02 limitation
 ~~~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 8490d897c..ef5048829 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -56,6 +56,11 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
+* **Support device-specific DDP package loading.**
+
+  Added support to load device-specific DDP package. The package file
+  with name including NIC's device serial number would be searched and
+  loaded (if existed) prior to the default package (ice.pkg).
 
 Removed Items
 -------------
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 44a14cb8a..8d9f04134 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -26,7 +26,16 @@ static const char * const ice_valid_args[] = {
 };
 
 #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
+
+/* DDP package search path */
+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
+
+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
+#define ICE_MAX_PKG_FILENAME_SIZE   256
 
 int ice_logtype_init;
 int ice_logtype_driver;
@@ -1263,15 +1272,86 @@ ice_pf_setup(struct ice_pf *pf)
 	return 0;
 }
 
+/*
+ * Extract device serial number from PCIe Configuration Space and
+ * determine the pkg file path according to the DSN.
+ */
+static int
+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
+{
+	int pos;
+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
+	uint32_t dsn_low, dsn_high;
+	memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
+
+	pos = rte_eth_dev_pci_find_next_ext_capability(pci_dev,
+		PCI_EXT_CAP_ID_DSN);
+
+	if (pos) {
+		rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4);
+		rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8);
+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
+	} else {
+		PMD_INIT_LOG(ERR, "Failed to read device serial number\n");
+		goto fail_dsn;
+	}
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+fail_dsn:
+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(pkg_file, 0))
+		return 0;
+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
+	return 0;
+}
+
+static enum ice_pkg_type
+ice_load_pkg_type(struct ice_hw *hw)
+{
+	enum ice_pkg_type package_type;
+
+	/* store the activated package type (OS default or Comms) */
+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_COMMS;
+	else
+		package_type = ICE_PKG_TYPE_UNKNOWN;
+
+	PMD_INIT_LOG(NOTICE, "Active package is: %d.%d.%d.%d, %s",
+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
+		hw->active_pkg_name);
+
+	return package_type;
+}
+
 static int ice_load_pkg(struct rte_eth_dev *dev)
 {
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	const char *pkg_file = ICE_DFLT_PKG_FILE;
+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
 	int err;
 	uint8_t *buf;
 	int buf_len;
 	FILE *file;
 	struct stat fstat;
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct ice_adapter *ad =
+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	ice_pkg_file_search_path(pci_dev, pkg_file);
 
 	file = fopen(pkg_file, "rb");
 	if (!file)  {
@@ -1311,6 +1391,10 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
 		goto fail_exit;
 	}
+
+	/* store the loaded pkg type info */
+	ad->active_pkg_type = ice_load_pkg_type(hw);
+
 	err = ice_init_hw_tbls(hw);
 	if (err) {
 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index f569da833..926db23d2 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -124,6 +124,13 @@
 #define ICE_ETH_OVERHEAD \
 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
 
+/* DDP package type */
+enum ice_pkg_type {
+	ICE_PKG_TYPE_UNKNOWN,
+	ICE_PKG_TYPE_OS_DEFAULT,
+	ICE_PKG_TYPE_COMMS,
+};
+
 struct ice_adapter;
 
 /**
@@ -294,6 +301,7 @@ struct ice_adapter {
 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
 	bool is_safe_mode;
 	struct ice_devargs devargs;
+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
 };
 
 struct ice_vsi_vlan_pvid_info {
diff --git a/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c b/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c
index 0b9db974e..f16a3c86e 100644
--- a/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c
+++ b/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c
@@ -746,50 +746,6 @@ nfp6000_set_interface(struct rte_pci_device *dev, struct nfp_cpp *cpp)
 	return 0;
 }
 
-#define PCI_CFG_SPACE_SIZE	256
-#define PCI_CFG_SPACE_EXP_SIZE	4096
-#define PCI_EXT_CAP_ID(header)		(int)(header & 0x0000ffff)
-#define PCI_EXT_CAP_NEXT(header)	((header >> 20) & 0xffc)
-#define PCI_EXT_CAP_ID_DSN	0x03
-static int
-nfp_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
-{
-	uint32_t header;
-	int ttl;
-	int pos = PCI_CFG_SPACE_SIZE;
-
-	/* minimum 8 bytes per capability */
-	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
-
-	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
-		printf("nfp error reading extended capabilities\n");
-		return -1;
-	}
-
-	/*
-	 * If we have no capabilities, this is indicated by cap ID,
-	 * cap version and next pointer all being 0.
-	 */
-	if (header == 0)
-		return 0;
-
-	while (ttl-- > 0) {
-		if (PCI_EXT_CAP_ID(header) == cap)
-			return pos;
-
-		pos = PCI_EXT_CAP_NEXT(header);
-		if (pos < PCI_CFG_SPACE_SIZE)
-			break;
-
-		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
-			printf("nfp error reading extended capabilities\n");
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
 static int
 nfp6000_set_serial(struct rte_pci_device *dev, struct nfp_cpp *cpp)
 {
@@ -798,7 +754,7 @@ nfp6000_set_serial(struct rte_pci_device *dev, struct nfp_cpp *cpp)
 	int serial_len = 6;
 	int pos;
 
-	pos = nfp_pci_find_next_ext_capability(dev, PCI_EXT_CAP_ID_DSN);
+	pos = rte_eth_dev_pci_find_next_ext_capability(dev, PCI_EXT_CAP_ID_DSN);
 	if (pos <= 0) {
 		printf("PCI_EXT_CAP_ID_DSN not found. nfp set serial failed\n");
 		return -1;
diff --git a/lib/librte_ethdev/rte_ethdev_pci.h b/lib/librte_ethdev/rte_ethdev_pci.h
index ccdbb46ec..1445f74ef 100644
--- a/lib/librte_ethdev/rte_ethdev_pci.h
+++ b/lib/librte_ethdev/rte_ethdev_pci.h
@@ -196,4 +196,63 @@ rte_eth_dev_pci_generic_remove(struct rte_pci_device *pci_dev,
 	return 0;
 }
 
+ /**
+  * Returns the address of the next matching extended capability structure
+  * within the device's PCI configuration space or 0 if the device does
+  * not support it.  Some capabilities can occur several times, e.g., the
+  * vendor-specific capability, and this provides a way to find them all.
+  *
+  * @param dev
+  *  PCI device to query
+  *
+  * @cap
+  *  Capability code
+  */
+
+#define PCI_CFG_SPACE_SIZE          256
+#define PCI_CFG_SPACE_EXP_SIZE      4096
+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
+#define PCI_EXT_CAP_ID_DSN          0x03
+
+static inline int
+rte_eth_dev_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = PCI_CFG_SPACE_SIZE;
+
+	/* minimum 8 bytes per capability */
+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+		RTE_LOG(ERR, EAL, "Error reading extended capabilities\n");
+		return -1;
+	}
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (PCI_EXT_CAP_ID(header) == cap)
+			return pos;
+
+		pos = PCI_EXT_CAP_NEXT(header);
+
+		if (pos < PCI_CFG_SPACE_SIZE)
+			break;
+
+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+			RTE_LOG(ERR, EAL, "Error reading extended capabilities\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
 #endif /* _RTE_ETHDEV_PCI_H_ */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v8] net/ice: support device-specific DDP package loading
  2019-09-17  8:44         ` [dpdk-dev] [PATCH v7] " Ting Xu
@ 2019-09-17 13:02           ` " Ting Xu
  2019-09-19  6:32             ` Zhang, Qi Z
  2019-09-19 22:08             ` Ye Xiaolong
  0 siblings, 2 replies; 16+ messages in thread
From: Ting Xu @ 2019-09-17 13:02 UTC (permalink / raw)
  To: dev
  Cc: wenzhuo.lu, qiming.yang, qi.z.zhang, xiaolong.ye, john.mcnamara,
	marko.kovacevic

This patch adds the feature that supports loading DDP package
according to the device serial number. Prior to loading the
default DDP package (ice.pkg), the driver will check for the
presence of a device-specific DDP package with the name containing
64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
during initialization. Users can use "lspci -vs" to get the device
serial number.
The pkg search path are /lib/firmware/updates/intel/ice/ddp/
and /lib/firmware/intel/ice/ddp/. If the package exists,
the driver will download it to the device instead of the default
one. The loaded package type (OS default and COMMS) will be
stored in ice_adapter->active_pkg_type. The package version is
stored in ice_hw->active_pkg_ver.

Signed-off-by: Ting Xu <ting.xu@intel.com>

---
v8: separate the contents in v7 into two patches: The modification
about rte_ethdev_pci.h can be found in another patch. In this
v8 patch, just fix coding style error based on v6.

v7: fix coding style error; move function to rte_ethdev_pci.h.

v6: update doc and release note; reduce redundant variables;
change some log levels.

v5: optimize the operation when dsn is not found.

v4: correct the commit message format.

v3: fix compile error; modify to change the pkg loading order.

v2: modify codes according to the comments.
---
 doc/guides/nics/ice.rst                |  20 +++-
 doc/guides/rel_notes/release_19_11.rst |   5 +
 drivers/net/ice/ice_ethdev.c           | 134 ++++++++++++++++++++++++-
 drivers/net/ice/ice_ethdev.h           |   8 ++
 4 files changed, 161 insertions(+), 6 deletions(-)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 03819d29f..59a222e28 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -118,10 +118,22 @@ The Intel E810 requires a programmable pipeline package be downloaded
 by the driver to support normal operations. The E810 has a limited
 functionality built in to allow PXE boot and other use cases, but the
 driver must download a package file during the driver initialization
-stage. The file must be in the /lib/firmware/intel/ice/ddp directory
-and it must be named ice.pkg. A symbolic link to this file is also ok.
-The same package file is used by both the kernel driver and the DPDK PMD.
-
+stage.
+
+The default DDP package file name is ice.pkg. For a specific NIC, the
+DDP package supposed to be loaded can have a filename: ice-xxxxxx.pkg,
+where 'xxxxxx' is the 64-bit PCIe Device Serial Number of the NIC. For
+example, if the NIC's device serial number is 00-CC-BB-FF-FF-AA-05-68,
+the device-specific DDP package filename is ice-00ccbbffffaa0568.pkg
+(in hex and all low case). During initialization, the driver searches
+in the following paths in order: /lib/firmware/updates/intel/ice/ddp
+and /lib/firmware/intel/ice/ddp. The corresponding device-specific DDP
+package will be downloaded first if the file exists. If not, then the
+driver tries to load the default package. The type of loaded package
+is stored in ``ice_adapter->active_pkg_type``.
+
+A symbolic link to the DDP package file is also ok. The same package
+file is used by both the kernel driver and the DPDK PMD.
 
 19.02 limitation
 ~~~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 8490d897c..91c31a611 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -56,6 +56,11 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
+* **Updated the Intel ice driver.**
+
+  Updated the Intel ice driver with new features and improvements, including:
+
+  * Supported device-specific DDP package loading.
 
 Removed Items
 -------------
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 44a14cb8a..e60cc1943 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -26,7 +26,16 @@ static const char * const ice_valid_args[] = {
 };
 
 #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
+
+/* DDP package search path */
+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
+
+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
+#define ICE_MAX_PKG_FILENAME_SIZE   256
 
 int ice_logtype_init;
 int ice_logtype_driver;
@@ -1263,15 +1272,132 @@ ice_pf_setup(struct ice_pf *pf)
 	return 0;
 }
 
+/* PCIe configuration space setting */
+#define PCI_CFG_SPACE_SIZE          256
+#define PCI_CFG_SPACE_EXP_SIZE      4096
+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
+#define PCI_EXT_CAP_ID_DSN          0x03
+
+static int
+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = PCI_CFG_SPACE_SIZE;
+
+	/* minimum 8 bytes per capability */
+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+		return -1;
+	}
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (PCI_EXT_CAP_ID(header) == cap)
+			return pos;
+
+		pos = PCI_EXT_CAP_NEXT(header);
+
+		if (pos < PCI_CFG_SPACE_SIZE)
+			break;
+
+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Extract device serial number from PCIe Configuration Space and
+ * determine the pkg file path according to the DSN.
+ */
+static int
+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
+{
+	int pos;
+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
+	uint32_t dsn_low, dsn_high;
+	memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
+
+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
+
+	if (pos) {
+		rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4);
+		rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8);
+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
+	} else {
+		PMD_INIT_LOG(ERR, "Failed to read device serial number\n");
+		goto fail_dsn;
+	}
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
+		ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
+		return 0;
+
+fail_dsn:
+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
+	if (!access(pkg_file, 0))
+		return 0;
+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
+	return 0;
+}
+
+static enum ice_pkg_type
+ice_load_pkg_type(struct ice_hw *hw)
+{
+	enum ice_pkg_type package_type;
+
+	/* store the activated package type (OS default or Comms) */
+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
+		ICE_PKG_NAME_SIZE))
+		package_type = ICE_PKG_TYPE_COMMS;
+	else
+		package_type = ICE_PKG_TYPE_UNKNOWN;
+
+	PMD_INIT_LOG(NOTICE, "Active package is: %d.%d.%d.%d, %s",
+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
+		hw->active_pkg_name);
+
+	return package_type;
+}
+
 static int ice_load_pkg(struct rte_eth_dev *dev)
 {
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	const char *pkg_file = ICE_DFLT_PKG_FILE;
+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
 	int err;
 	uint8_t *buf;
 	int buf_len;
 	FILE *file;
 	struct stat fstat;
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct ice_adapter *ad =
+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	ice_pkg_file_search_path(pci_dev, pkg_file);
 
 	file = fopen(pkg_file, "rb");
 	if (!file)  {
@@ -1311,6 +1437,10 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
 		goto fail_exit;
 	}
+
+	/* store the loaded pkg type info */
+	ad->active_pkg_type = ice_load_pkg_type(hw);
+
 	err = ice_init_hw_tbls(hw);
 	if (err) {
 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index f569da833..926db23d2 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -124,6 +124,13 @@
 #define ICE_ETH_OVERHEAD \
 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
 
+/* DDP package type */
+enum ice_pkg_type {
+	ICE_PKG_TYPE_UNKNOWN,
+	ICE_PKG_TYPE_OS_DEFAULT,
+	ICE_PKG_TYPE_COMMS,
+};
+
 struct ice_adapter;
 
 /**
@@ -294,6 +301,7 @@ struct ice_adapter {
 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
 	bool is_safe_mode;
 	struct ice_devargs devargs;
+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
 };
 
 struct ice_vsi_vlan_pvid_info {
-- 
2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH v8] net/ice: support device-specific DDP package loading
  2019-09-17 13:02           ` [dpdk-dev] [PATCH v8] " Ting Xu
@ 2019-09-19  6:32             ` Zhang, Qi Z
  2019-09-19 22:08             ` Ye Xiaolong
  1 sibling, 0 replies; 16+ messages in thread
From: Zhang, Qi Z @ 2019-09-19  6:32 UTC (permalink / raw)
  To: Xu, Ting, dev
  Cc: Lu, Wenzhuo, Yang, Qiming, Ye, Xiaolong, Mcnamara, John,
	Kovacevic, Marko



> -----Original Message-----
> From: Xu, Ting
> Sent: Tuesday, September 17, 2019 9:02 PM
> To: dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Yang, Qiming
> <qiming.yang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Ye, Xiaolong
> <xiaolong.ye@intel.com>; Mcnamara, John <john.mcnamara@intel.com>;
> Kovacevic, Marko <marko.kovacevic@intel.com>
> Subject: [PATCH v8] net/ice: support device-specific DDP package loading
> 
> This patch adds the feature that supports loading DDP package according to
> the device serial number. Prior to loading the default DDP package (ice.pkg),
> the driver will check for the presence of a device-specific DDP package with the
> name containing 64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
> during initialization. Users can use "lspci -vs" to get the device serial number.
> The pkg search path are /lib/firmware/updates/intel/ice/ddp/
> and /lib/firmware/intel/ice/ddp/. If the package exists, the driver will
> download it to the device instead of the default one. The loaded package type
> (OS default and COMMS) will be stored in ice_adapter->active_pkg_type. The
> package version is stored in ice_hw->active_pkg_ver.
> 
> Signed-off-by: Ting Xu <ting.xu@intel.com>

Acked-by: Qi Zhang <qi.z.zhang@intel.com>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH v8] net/ice: support device-specific DDP package loading
  2019-09-17 13:02           ` [dpdk-dev] [PATCH v8] " Ting Xu
  2019-09-19  6:32             ` Zhang, Qi Z
@ 2019-09-19 22:08             ` Ye Xiaolong
  1 sibling, 0 replies; 16+ messages in thread
From: Ye Xiaolong @ 2019-09-19 22:08 UTC (permalink / raw)
  To: Ting Xu
  Cc: dev, wenzhuo.lu, qiming.yang, qi.z.zhang, john.mcnamara, marko.kovacevic

On 09/17, Ting Xu wrote:
>This patch adds the feature that supports loading DDP package
>according to the device serial number. Prior to loading the
>default DDP package (ice.pkg), the driver will check for the
>presence of a device-specific DDP package with the name containing
>64-bit PCIe Device Serial Number (ice-xxxxxxxxxxxxxxxx.pkg)
>during initialization. Users can use "lspci -vs" to get the device
>serial number.
>The pkg search path are /lib/firmware/updates/intel/ice/ddp/
>and /lib/firmware/intel/ice/ddp/. If the package exists,
>the driver will download it to the device instead of the default
>one. The loaded package type (OS default and COMMS) will be
>stored in ice_adapter->active_pkg_type. The package version is
>stored in ice_hw->active_pkg_ver.
>
>Signed-off-by: Ting Xu <ting.xu@intel.com>
>
>---
>v8: separate the contents in v7 into two patches: The modification
>about rte_ethdev_pci.h can be found in another patch. In this
>v8 patch, just fix coding style error based on v6.
>
>v7: fix coding style error; move function to rte_ethdev_pci.h.
>
>v6: update doc and release note; reduce redundant variables;
>change some log levels.
>
>v5: optimize the operation when dsn is not found.
>
>v4: correct the commit message format.
>
>v3: fix compile error; modify to change the pkg loading order.
>
>v2: modify codes according to the comments.
>---
> doc/guides/nics/ice.rst                |  20 +++-
> doc/guides/rel_notes/release_19_11.rst |   5 +
> drivers/net/ice/ice_ethdev.c           | 134 ++++++++++++++++++++++++-
> drivers/net/ice/ice_ethdev.h           |   8 ++
> 4 files changed, 161 insertions(+), 6 deletions(-)
>
>diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
>index 03819d29f..59a222e28 100644
>--- a/doc/guides/nics/ice.rst
>+++ b/doc/guides/nics/ice.rst
>@@ -118,10 +118,22 @@ The Intel E810 requires a programmable pipeline package be downloaded
> by the driver to support normal operations. The E810 has a limited
> functionality built in to allow PXE boot and other use cases, but the
> driver must download a package file during the driver initialization
>-stage. The file must be in the /lib/firmware/intel/ice/ddp directory
>-and it must be named ice.pkg. A symbolic link to this file is also ok.
>-The same package file is used by both the kernel driver and the DPDK PMD.
>-
>+stage.
>+
>+The default DDP package file name is ice.pkg. For a specific NIC, the
>+DDP package supposed to be loaded can have a filename: ice-xxxxxx.pkg,
>+where 'xxxxxx' is the 64-bit PCIe Device Serial Number of the NIC. For
>+example, if the NIC's device serial number is 00-CC-BB-FF-FF-AA-05-68,
>+the device-specific DDP package filename is ice-00ccbbffffaa0568.pkg
>+(in hex and all low case). During initialization, the driver searches
>+in the following paths in order: /lib/firmware/updates/intel/ice/ddp
>+and /lib/firmware/intel/ice/ddp. The corresponding device-specific DDP
>+package will be downloaded first if the file exists. If not, then the
>+driver tries to load the default package. The type of loaded package
>+is stored in ``ice_adapter->active_pkg_type``.
>+
>+A symbolic link to the DDP package file is also ok. The same package
>+file is used by both the kernel driver and the DPDK PMD.
> 
> 19.02 limitation
> ~~~~~~~~~~~~~~~~
>diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
>index 8490d897c..91c31a611 100644
>--- a/doc/guides/rel_notes/release_19_11.rst
>+++ b/doc/guides/rel_notes/release_19_11.rst
>@@ -56,6 +56,11 @@ New Features
>      Also, make sure to start the actual text at the margin.
>      =========================================================
> 
>+* **Updated the Intel ice driver.**
>+
>+  Updated the Intel ice driver with new features and improvements, including:
>+
>+  * Supported device-specific DDP package loading.
> 
> Removed Items
> -------------
>diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
>index 44a14cb8a..e60cc1943 100644
>--- a/drivers/net/ice/ice_ethdev.c
>+++ b/drivers/net/ice/ice_ethdev.c
>@@ -26,7 +26,16 @@ static const char * const ice_valid_args[] = {
> };
> 
> #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
>-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
>+
>+/* DDP package search path */
>+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
>+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
>+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
>+
>+#define ICE_OS_DEFAULT_PKG_NAME		"ICE OS Default Package"
>+#define ICE_COMMS_PKG_NAME			"ICE COMMS Package"
>+#define ICE_MAX_PKG_FILENAME_SIZE   256
> 
> int ice_logtype_init;
> int ice_logtype_driver;
>@@ -1263,15 +1272,132 @@ ice_pf_setup(struct ice_pf *pf)
> 	return 0;
> }
> 
>+/* PCIe configuration space setting */
>+#define PCI_CFG_SPACE_SIZE          256
>+#define PCI_CFG_SPACE_EXP_SIZE      4096
>+#define PCI_EXT_CAP_ID(header)      (int)((header) & 0x0000ffff)
>+#define PCI_EXT_CAP_NEXT(header)    (((header) >> 20) & 0xffc)
>+#define PCI_EXT_CAP_ID_DSN          0x03
>+
>+static int
>+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
>+{
>+	uint32_t header;
>+	int ttl;
>+	int pos = PCI_CFG_SPACE_SIZE;
>+
>+	/* minimum 8 bytes per capability */
>+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
>+
>+	if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+		PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+		return -1;
>+	}
>+
>+	/*
>+	 * If we have no capabilities, this is indicated by cap ID,
>+	 * cap version and next pointer all being 0.
>+	 */
>+	if (header == 0)
>+		return 0;
>+
>+	while (ttl-- > 0) {
>+		if (PCI_EXT_CAP_ID(header) == cap)
>+			return pos;
>+
>+		pos = PCI_EXT_CAP_NEXT(header);
>+
>+		if (pos < PCI_CFG_SPACE_SIZE)
>+			break;
>+
>+		if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
>+			PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
>+			return -1;
>+		}
>+	}
>+
>+	return 0;
>+}
>+
>+/*
>+ * Extract device serial number from PCIe Configuration Space and
>+ * determine the pkg file path according to the DSN.
>+ */
>+static int
>+ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
>+{
>+	int pos;
>+	char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
>+	uint32_t dsn_low, dsn_high;
>+	memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
>+
>+	pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN);
>+
>+	if (pos) {
>+		rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4);
>+		rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8);
>+		snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
>+			 "ice-%08x%08x.pkg", dsn_high, dsn_low);
>+	} else {
>+		PMD_INIT_LOG(ERR, "Failed to read device serial number\n");
>+		goto fail_dsn;
>+	}
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+	strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
>+		ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(strcat(pkg_file, opt_ddp_filename), 0))
>+		return 0;
>+
>+fail_dsn:
>+	strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
>+	if (!access(pkg_file, 0))
>+		return 0;
>+	strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
>+	return 0;
>+}
>+
>+static enum ice_pkg_type
>+ice_load_pkg_type(struct ice_hw *hw)
>+{
>+	enum ice_pkg_type package_type;
>+
>+	/* store the activated package type (OS default or Comms) */
>+	if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_OS_DEFAULT;
>+	else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
>+		ICE_PKG_NAME_SIZE))
>+		package_type = ICE_PKG_TYPE_COMMS;
>+	else
>+		package_type = ICE_PKG_TYPE_UNKNOWN;
>+
>+	PMD_INIT_LOG(NOTICE, "Active package is: %d.%d.%d.%d, %s",
>+		hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
>+		hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
>+		hw->active_pkg_name);
>+
>+	return package_type;
>+}
>+
> static int ice_load_pkg(struct rte_eth_dev *dev)
> {
> 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>-	const char *pkg_file = ICE_DFLT_PKG_FILE;
>+	char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
> 	int err;
> 	uint8_t *buf;
> 	int buf_len;
> 	FILE *file;
> 	struct stat fstat;
>+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
>+	struct ice_adapter *ad =
>+		ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
>+
>+	ice_pkg_file_search_path(pci_dev, pkg_file);
> 
> 	file = fopen(pkg_file, "rb");
> 	if (!file)  {
>@@ -1311,6 +1437,10 @@ static int ice_load_pkg(struct rte_eth_dev *dev)
> 		PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
> 		goto fail_exit;
> 	}
>+
>+	/* store the loaded pkg type info */
>+	ad->active_pkg_type = ice_load_pkg_type(hw);
>+
> 	err = ice_init_hw_tbls(hw);
> 	if (err) {
> 		PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
>diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
>index f569da833..926db23d2 100644
>--- a/drivers/net/ice/ice_ethdev.h
>+++ b/drivers/net/ice/ice_ethdev.h
>@@ -124,6 +124,13 @@
> #define ICE_ETH_OVERHEAD \
> 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE * 2)
> 
>+/* DDP package type */
>+enum ice_pkg_type {
>+	ICE_PKG_TYPE_UNKNOWN,
>+	ICE_PKG_TYPE_OS_DEFAULT,
>+	ICE_PKG_TYPE_COMMS,
>+};
>+
> struct ice_adapter;
> 
> /**
>@@ -294,6 +301,7 @@ struct ice_adapter {
> 	uint32_t ptype_tbl[ICE_MAX_PKT_TYPE] __rte_cache_min_aligned;
> 	bool is_safe_mode;
> 	struct ice_devargs devargs;
>+	enum ice_pkg_type active_pkg_type; /* loaded ddp package type */
> };
> 
> struct ice_vsi_vlan_pvid_info {
>-- 
>2.17.1
>

Reviewed-by: Xiaolong Ye <xiaolong.ye@intel.com>

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, back to index

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-29 13:17 [dpdk-dev] [PATCH v1] net/ice: support device-specific DDP package loading Ting Xu
2019-08-29 18:08 ` Stillwell Jr, Paul M
2019-08-29 22:05   ` Zhang, Qi Z
2019-09-03 14:29 ` [dpdk-dev] [PATCH v3] " Ting Xu
2019-09-03  9:43   ` Ye Xiaolong
2019-09-04  2:40     ` Xu, Ting
2019-09-05 12:59   ` [dpdk-dev] [PATCH v4] " Ting Xu
2019-09-06 14:51     ` [dpdk-dev] [PATCH v5] " Ting Xu
2019-09-06 13:53       ` Ye Xiaolong
2019-09-06 14:16       ` Ye Xiaolong
2019-09-11 12:35       ` [dpdk-dev] [PATCH v6] " Ting Xu
2019-09-13 10:51         ` Ye Xiaolong
2019-09-17  8:44         ` [dpdk-dev] [PATCH v7] " Ting Xu
2019-09-17 13:02           ` [dpdk-dev] [PATCH v8] " Ting Xu
2019-09-19  6:32             ` Zhang, Qi Z
2019-09-19 22:08             ` Ye Xiaolong

DPDK-dev Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/dpdk-dev/0 dpdk-dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dpdk-dev dpdk-dev/ https://lore.kernel.org/dpdk-dev \
		dev@dpdk.org dpdk-dev@archiver.kernel.org
	public-inbox-index dpdk-dev


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/ public-inbox