Skip to content

Commit 399e27d

Browse files
jacob-kelleranguy11
authored andcommitted
ice: support immediate firmware activation via devlink reload
The ice hardware contains an embedded chip with firmware which can be updated using devlink flash. The firmware which runs on this chip is referred to as the Embedded Management Processor firmware (EMP firmware). Activating the new firmware image currently requires that the system be rebooted. This is not ideal as rebooting the system can cause unwanted downtime. In practical terms, activating the firmware does not always require a full system reboot. In many cases it is possible to activate the EMP firmware immediately. There are a couple of different scenarios to cover. * The EMP firmware itself can be reloaded by issuing a special update to the device called an Embedded Management Processor reset (EMP reset). This reset causes the device to reset and reload the EMP firmware. * PCI configuration changes are only reloaded after a cold PCIe reset. Unfortunately there is no generic way to trigger this for a PCIe device without a system reboot. When performing a flash update, firmware is capable of responding with some information about the specific update requirements. The driver updates the flash by programming a secondary inactive bank with the contents of the new image, and then issuing a command to request to switch the active bank starting from the next load. The response to the final command for updating the inactive NVM flash bank includes an indication of the minimum reset required to fully update the device. This can be one of the following: * A full power on is required * A cold PCIe reset is required * An EMP reset is required The response to the command to switch flash banks includes an indication of whether or not the firmware will allow an EMP reset request. For most updates, an EMP reset is sufficient to load the new EMP firmware without issues. In some cases, this reset is not sufficient because the PCI configuration space has changed. When this could cause incompatibility with the new EMP image, the firmware is capable of rejecting the EMP reset request. Add logic to ice_fw_update.c to handle the response data flash update AdminQ commands. For the reset level, issue a devlink status notification informing the user of how to complete the update with a simple suggestion like "Activate new firmware by rebooting the system". Cache the status of whether or not firmware will restrict the EMP reset for use in implementing devlink reload. Implement support for devlink reload with the "fw_activate" flag. This allows user space to request the firmware be activated immediately. For the .reload_down handler, we will issue a request for the EMP reset using the appropriate firmware AdminQ command. If we know that the firmware will not allow an EMP reset, simply exit with a suitable netlink extended ACK message indicating that the EMP reset is not available. For the .reload_up handler, simply wait until the driver has finished resetting. Logic to handle processing of an EMP reset already exists in the driver as part of its reset and rebuild flows. Implement support for the devlink reload interface with the "fw_activate" action. This allows userspace to request activation of firmware without a reboot. Note that support for indicating the required reset and EMP reset restriction is not supported on old versions of firmware. The driver can determine if the two features are supported by checking the device capabilities report. I confirmed support has existed since at least version 5.5.2 as reported by the 'fw.mgmt' version. Support to issue the EMP reset request has existed in all version of the EMP firmware for the ice hardware. Check the device capabilities report to determine whether or not the indications are reported by the running firmware. If the reset requirement indication is not supported, always assume a full power on is necessary. If the reset restriction capability is not supported, always assume the EMP reset is available. Users can verify if the EMP reset has activated the firmware by using the devlink info report to check that the 'running' firmware version has updated. For example a user might do the following: # Check current version $ devlink dev info # Update the device $ devlink dev flash pci/0000:af:00.0 file firmware.bin # Confirm stored version updated $ devlink dev info # Reload to activate new firmware $ devlink dev reload pci/0000:af:00.0 action fw_activate # Confirm running version updated $ devlink dev info Finally, this change does *not* implement basic driver-only reload support. I did look into trying to do this. However, it requires significant refactor of how the ice driver probes and loads everything. The ice driver probe and allocation flows were not designed with such a reload in mind. Refactoring the flow to support this is beyond the scope of this change. Signed-off-by: Jacob Keller <[email protected]> Tested-by: Gurucharan G <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent af18d88 commit 399e27d

File tree

11 files changed

+330
-29
lines changed

11 files changed

+330
-29
lines changed

Documentation/networking/devlink/ice.rst

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ The ``ice`` driver reports the following versions
2626
* - ``fw.mgmt``
2727
- running
2828
- 2.1.7
29-
- 3-digit version number of the management firmware that controls the
30-
PHY, link, etc.
29+
- 3-digit version number of the management firmware running on the
30+
Embedded Management Processor of the device. It controls the PHY,
31+
link, access to device resources, etc. Intel documentation refers to
32+
this as the EMP firmware.
3133
* - ``fw.mgmt.api``
3234
- running
3335
- 1.5.1
@@ -119,6 +121,24 @@ preserving settings, and thus ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS`` on its
119121
own will be rejected. If no overwrite mask is provided, the firmware will be
120122
instructed to preserve all settings and identifying fields when updating.
121123

124+
Reload
125+
======
126+
127+
The ``ice`` driver supports activating new firmware after a flash update
128+
using ``DEVLINK_CMD_RELOAD`` with the ``DEVLINK_RELOAD_ACTION_FW_ACTIVATE``
129+
action.
130+
131+
.. code:: shell
132+
133+
$ devlink dev reload pci/0000:01:00.0 reload action fw_activate
134+
135+
The new firmware is activated by issuing a device specific Embedded
136+
Management Processor reset which requests the device to reset and reload the
137+
EMP firmware image.
138+
139+
The driver does not currently support reloading the driver via
140+
``DEVLINK_RELOAD_ACTION_DRIVER_REINIT``.
141+
122142
Regions
123143
=======
124144

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,7 @@ struct ice_pf {
553553
spinlock_t aq_wait_lock;
554554
struct hlist_head aq_wait_list;
555555
wait_queue_head_t aq_wait_queue;
556+
bool fw_emp_reset_disabled;
556557

557558
wait_queue_head_t reset_wait_queue;
558559

drivers/net/ethernet/intel/ice/ice_adminq_cmd.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ struct ice_aqc_list_caps_elem {
117117
#define ICE_AQC_CAPS_NET_VER 0x004C
118118
#define ICE_AQC_CAPS_PENDING_NET_VER 0x004D
119119
#define ICE_AQC_CAPS_RDMA 0x0051
120+
#define ICE_AQC_CAPS_PCIE_RESET_AVOIDANCE 0x0076
121+
#define ICE_AQC_CAPS_POST_UPDATE_RESET_RESTRICT 0x0077
120122
#define ICE_AQC_CAPS_NVM_MGMT 0x0080
121123

122124
u8 major_ver;
@@ -1408,6 +1410,11 @@ struct ice_aqc_nvm {
14081410
#define ICE_AQC_NVM_REVERT_LAST_ACTIV BIT(6) /* Write Activate only */
14091411
#define ICE_AQC_NVM_ACTIV_SEL_MASK ICE_M(0x7, 3)
14101412
#define ICE_AQC_NVM_FLASH_ONLY BIT(7)
1413+
#define ICE_AQC_NVM_RESET_LVL_M ICE_M(0x3, 0) /* Write reply only */
1414+
#define ICE_AQC_NVM_POR_FLAG 0
1415+
#define ICE_AQC_NVM_PERST_FLAG 1
1416+
#define ICE_AQC_NVM_EMPR_FLAG 2
1417+
#define ICE_AQC_NVM_EMPR_ENA BIT(0) /* Write Activate reply only */
14111418
__le16 module_typeid;
14121419
__le16 length;
14131420
#define ICE_AQC_NVM_ERASE_LEN 0xFFFF

drivers/net/ethernet/intel/ice/ice_common.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,18 @@ ice_parse_common_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps,
20682068
ice_debug(hw, ICE_DBG_INIT, "%s: max_mtu = %d\n",
20692069
prefix, caps->max_mtu);
20702070
break;
2071+
case ICE_AQC_CAPS_PCIE_RESET_AVOIDANCE:
2072+
caps->pcie_reset_avoidance = (number > 0);
2073+
ice_debug(hw, ICE_DBG_INIT,
2074+
"%s: pcie_reset_avoidance = %d\n", prefix,
2075+
caps->pcie_reset_avoidance);
2076+
break;
2077+
case ICE_AQC_CAPS_POST_UPDATE_RESET_RESTRICT:
2078+
caps->reset_restrict_support = (number == 1);
2079+
ice_debug(hw, ICE_DBG_INIT,
2080+
"%s: reset_restrict_support = %d\n", prefix,
2081+
caps->reset_restrict_support);
2082+
break;
20712083
default:
20722084
/* Not one of the recognized common capabilities */
20732085
found = false;

drivers/net/ethernet/intel/ice/ice_devlink.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,106 @@ static int ice_devlink_info_get(struct devlink *devlink,
370370
return err;
371371
}
372372

373+
/**
374+
* ice_devlink_reload_empr_start - Start EMP reset to activate new firmware
375+
* @devlink: pointer to the devlink instance to reload
376+
* @netns_change: if true, the network namespace is changing
377+
* @action: the action to perform. Must be DEVLINK_RELOAD_ACTION_FW_ACTIVATE
378+
* @limit: limits on what reload should do, such as not resetting
379+
* @extack: netlink extended ACK structure
380+
*
381+
* Allow user to activate new Embedded Management Processor firmware by
382+
* issuing device specific EMP reset. Called in response to
383+
* a DEVLINK_CMD_RELOAD with the DEVLINK_RELOAD_ACTION_FW_ACTIVATE.
384+
*
385+
* Note that teardown and rebuild of the driver state happens automatically as
386+
* part of an interrupt and watchdog task. This is because all physical
387+
* functions on the device must be able to reset when an EMP reset occurs from
388+
* any source.
389+
*/
390+
static int
391+
ice_devlink_reload_empr_start(struct devlink *devlink, bool netns_change,
392+
enum devlink_reload_action action,
393+
enum devlink_reload_limit limit,
394+
struct netlink_ext_ack *extack)
395+
{
396+
struct ice_pf *pf = devlink_priv(devlink);
397+
struct device *dev = ice_pf_to_dev(pf);
398+
struct ice_hw *hw = &pf->hw;
399+
u8 pending;
400+
int err;
401+
402+
err = ice_get_pending_updates(pf, &pending, extack);
403+
if (err)
404+
return err;
405+
406+
/* pending is a bitmask of which flash banks have a pending update,
407+
* including the main NVM bank, the Option ROM bank, and the netlist
408+
* bank. If any of these bits are set, then there is a pending update
409+
* waiting to be activated.
410+
*/
411+
if (!pending) {
412+
NL_SET_ERR_MSG_MOD(extack, "No pending firmware update");
413+
return -ECANCELED;
414+
}
415+
416+
if (pf->fw_emp_reset_disabled) {
417+
NL_SET_ERR_MSG_MOD(extack, "EMP reset is not available. To activate firmware, a reboot or power cycle is needed");
418+
return -ECANCELED;
419+
}
420+
421+
dev_dbg(dev, "Issuing device EMP reset to activate firmware\n");
422+
423+
err = ice_aq_nvm_update_empr(hw);
424+
if (err) {
425+
dev_err(dev, "Failed to trigger EMP device reset to reload firmware, err %d aq_err %s\n",
426+
err, ice_aq_str(hw->adminq.sq_last_status));
427+
NL_SET_ERR_MSG_MOD(extack, "Failed to trigger EMP device reset to reload firmware");
428+
return err;
429+
}
430+
431+
return 0;
432+
}
433+
434+
/**
435+
* ice_devlink_reload_empr_finish - Wait for EMP reset to finish
436+
* @devlink: pointer to the devlink instance reloading
437+
* @action: the action requested
438+
* @limit: limits imposed by userspace, such as not resetting
439+
* @actions_performed: on return, indicate what actions actually performed
440+
* @extack: netlink extended ACK structure
441+
*
442+
* Wait for driver to finish rebuilding after EMP reset is completed. This
443+
* includes time to wait for both the actual device reset as well as the time
444+
* for the driver's rebuild to complete.
445+
*/
446+
static int
447+
ice_devlink_reload_empr_finish(struct devlink *devlink,
448+
enum devlink_reload_action action,
449+
enum devlink_reload_limit limit,
450+
u32 *actions_performed,
451+
struct netlink_ext_ack *extack)
452+
{
453+
struct ice_pf *pf = devlink_priv(devlink);
454+
int err;
455+
456+
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
457+
458+
err = ice_wait_for_reset(pf, 60 * HZ);
459+
if (err) {
460+
NL_SET_ERR_MSG_MOD(extack, "Device still resetting after 1 minute");
461+
return err;
462+
}
463+
464+
return 0;
465+
}
466+
373467
static const struct devlink_ops ice_devlink_ops = {
374468
.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
469+
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
470+
/* The ice driver currently does not support driver reinit */
471+
.reload_down = ice_devlink_reload_empr_start,
472+
.reload_up = ice_devlink_reload_empr_finish,
375473
.eswitch_mode_get = ice_eswitch_mode_get,
376474
.eswitch_mode_set = ice_eswitch_mode_set,
377475
.info_get = ice_devlink_info_get,
@@ -532,6 +630,7 @@ void ice_devlink_register(struct ice_pf *pf)
532630
{
533631
struct devlink *devlink = priv_to_devlink(pf);
534632

633+
devlink_set_features(devlink, DEVLINK_F_RELOAD);
535634
devlink_register(devlink);
536635
}
537636

0 commit comments

Comments
 (0)