Commit cc5776fe authored by Michal Wilczynski's avatar Michal Wilczynski Committed by Tony Nguyen

ice: Enable switching default Tx scheduler topology

Introduce support for Tx scheduler topology change, based on user
selection, from default 9-layer to 5-layer.
Change requires NVM (version 3.20 or newer) and DDP package (OS Package
1.3.30 or newer - available for over a year in linux-firmware, since
commit aed71f296637 in linux-firmware ("ice: Update package to 1.3.30.0"))
https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/commit/?id=aed71f296637

Enable 5-layer topology switch in init path of the driver. To accomplish
that upload of the DDP package needs to be delayed, until change in Tx
topology is finished. To trigger the Tx change user selection should be
changed in NVM using devlink. Then the platform should be rebooted.
Signed-off-by: default avatarMichal Wilczynski <michal.wilczynski@intel.com>
Co-developed-by: default avatarMateusz Polchlopek <mateusz.polchlopek@intel.com>
Signed-off-by: default avatarMateusz Polchlopek <mateusz.polchlopek@intel.com>
Tested-by: default avatarPucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 927127cd
...@@ -4453,11 +4453,13 @@ static char *ice_get_opt_fw_name(struct ice_pf *pf) ...@@ -4453,11 +4453,13 @@ static char *ice_get_opt_fw_name(struct ice_pf *pf)
/** /**
* ice_request_fw - Device initialization routine * ice_request_fw - Device initialization routine
* @pf: pointer to the PF instance * @pf: pointer to the PF instance
* @firmware: double pointer to firmware struct
*
* Return: zero when successful, negative values otherwise.
*/ */
static void ice_request_fw(struct ice_pf *pf) static int ice_request_fw(struct ice_pf *pf, const struct firmware **firmware)
{ {
char *opt_fw_filename = ice_get_opt_fw_name(pf); char *opt_fw_filename = ice_get_opt_fw_name(pf);
const struct firmware *firmware = NULL;
struct device *dev = ice_pf_to_dev(pf); struct device *dev = ice_pf_to_dev(pf);
int err = 0; int err = 0;
...@@ -4466,29 +4468,95 @@ static void ice_request_fw(struct ice_pf *pf) ...@@ -4466,29 +4468,95 @@ static void ice_request_fw(struct ice_pf *pf)
* and warning messages for other errors. * and warning messages for other errors.
*/ */
if (opt_fw_filename) { if (opt_fw_filename) {
err = firmware_request_nowarn(&firmware, opt_fw_filename, dev); err = firmware_request_nowarn(firmware, opt_fw_filename, dev);
if (err) {
kfree(opt_fw_filename); kfree(opt_fw_filename);
goto dflt_pkg_load; if (!err)
return err;
} }
err = request_firmware(firmware, ICE_DDP_PKG_FILE, dev);
if (err)
dev_err(dev, "The DDP package file was not found or could not be read. Entering Safe Mode\n");
/* request for firmware was successful. Download to device */ return err;
ice_load_pkg(firmware, pf); }
kfree(opt_fw_filename);
release_firmware(firmware); /**
return; * ice_init_tx_topology - performs Tx topology initialization
* @hw: pointer to the hardware structure
* @firmware: pointer to firmware structure
*
* Return: zero when init was successful, negative values otherwise.
*/
static int
ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware)
{
u8 num_tx_sched_layers = hw->num_tx_sched_layers;
struct ice_pf *pf = hw->back;
struct device *dev;
u8 *buf_copy;
int err;
dev = ice_pf_to_dev(pf);
/* ice_cfg_tx_topo buf argument is not a constant,
* so we have to make a copy
*/
buf_copy = kmemdup(firmware->data, firmware->size, GFP_KERNEL);
err = ice_cfg_tx_topo(hw, buf_copy, firmware->size);
if (!err) {
if (hw->num_tx_sched_layers > num_tx_sched_layers)
dev_info(dev, "Tx scheduling layers switching feature disabled\n");
else
dev_info(dev, "Tx scheduling layers switching feature enabled\n");
/* if there was a change in topology ice_cfg_tx_topo triggered
* a CORER and we need to re-init hw
*/
ice_deinit_hw(hw);
err = ice_init_hw(hw);
return err;
} else if (err == -EIO) {
dev_info(dev, "DDP package does not support Tx scheduling layers switching feature - please update to the latest DDP package and try again\n");
} }
dflt_pkg_load: return 0;
err = request_firmware(&firmware, ICE_DDP_PKG_FILE, dev); }
/**
* ice_init_ddp_config - DDP related configuration
* @hw: pointer to the hardware structure
* @pf: pointer to pf structure
*
* This function loads DDP file from the disk, then initializes Tx
* topology. At the end DDP package is loaded on the card.
*
* Return: zero when init was successful, negative values otherwise.
*/
static int ice_init_ddp_config(struct ice_hw *hw, struct ice_pf *pf)
{
struct device *dev = ice_pf_to_dev(pf);
const struct firmware *firmware = NULL;
int err;
err = ice_request_fw(pf, &firmware);
if (err) { if (err) {
dev_err(dev, "The DDP package file was not found or could not be read. Entering Safe Mode\n"); dev_err(dev, "Fail during requesting FW: %d\n", err);
return; return err;
}
err = ice_init_tx_topology(hw, firmware);
if (err) {
dev_err(dev, "Fail during initialization of Tx topology: %d\n",
err);
release_firmware(firmware);
return err;
} }
/* request for firmware was successful. Download to device */ /* Download firmware to device */
ice_load_pkg(firmware, pf); ice_load_pkg(firmware, pf);
release_firmware(firmware); release_firmware(firmware);
return 0;
} }
/** /**
...@@ -4661,9 +4729,11 @@ int ice_init_dev(struct ice_pf *pf) ...@@ -4661,9 +4729,11 @@ int ice_init_dev(struct ice_pf *pf)
ice_init_feature_support(pf); ice_init_feature_support(pf);
ice_request_fw(pf); err = ice_init_ddp_config(hw, pf);
if (err)
return err;
/* if ice_request_fw fails, ICE_FLAG_ADV_FEATURES bit won't be /* if ice_init_ddp_config fails, ICE_FLAG_ADV_FEATURES bit won't be
* set in pf->state, which will cause ice_is_safe_mode to return * set in pf->state, which will cause ice_is_safe_mode to return
* true * true
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment