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>
Reviewed-by: Xiaolong Ye <xiaolong.ye@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
This commit is contained in:
Ting Xu 2019-09-17 13:02:28 +00:00 committed by Ferruh Yigit
parent 3ba381eb65
commit 03a05924da
4 changed files with 161 additions and 5 deletions

View File

@ -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
~~~~~~~~~~~~~~~~

View File

@ -56,6 +56,12 @@ 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:
* Added support for device-specific DDP package loading.
* **Added Marvell NITROX symmetric crypto PMD.**
Added a symmetric crypto PMD for Marvell NITROX V security processor.

View File

@ -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);

View File

@ -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 {