5d5b4128c4
Sections of device flash may contain settings or device identifying information. When performing a flash update, it is generally expected that these settings and identifiers are not overwritten. However, it may sometimes be useful to allow overwriting these fields when performing a flash update. Some examples include, 1) customizing the initial device config on first programming, such as overwriting default device identifying information, or 2) reverting a device configuration to known good state provided in the new firmware image, or 3) in case it is suspected that current firmware logic for managing the preservation of fields during an update is broken. Although some devices are able to completely separate these types of settings and fields into separate components, this is not true for all hardware. To support controlling this behavior, a new DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK is defined. This is an nla_bitfield32 which will define what subset of fields in a component should be overwritten during an update. If no bits are specified, or of the overwrite mask is not provided, then an update should not overwrite anything, and should maintain the settings and identifiers as they are in the previous image. If the overwrite mask has the DEVLINK_FLASH_OVERWRITE_SETTINGS bit set, then the device should be configured to overwrite any of the settings in the requested component with settings found in the provided image. Similarly, if the DEVLINK_FLASH_OVERWRITE_IDENTIFIERS bit is set, the device should be configured to overwrite any device identifiers in the requested component with the identifiers from the image. Multiple overwrite modes may be combined to indicate that a combination of the set of fields that should be overwritten. Drivers which support the new overwrite mask must set the DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK in the supported_flash_update_params field of their devlink_ops. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Reviewed-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
122 lines
4.6 KiB
ReStructuredText
122 lines
4.6 KiB
ReStructuredText
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
|
|
|
.. _devlink_flash:
|
|
|
|
=============
|
|
Devlink Flash
|
|
=============
|
|
|
|
The ``devlink-flash`` API allows updating device firmware. It replaces the
|
|
older ``ethtool-flash`` mechanism, and doesn't require taking any
|
|
networking locks in the kernel to perform the flash update. Example use::
|
|
|
|
$ devlink dev flash pci/0000:05:00.0 file flash-boot.bin
|
|
|
|
Note that the file name is a path relative to the firmware loading path
|
|
(usually ``/lib/firmware/``). Drivers may send status updates to inform
|
|
user space about the progress of the update operation.
|
|
|
|
Overwrite Mask
|
|
==============
|
|
|
|
The ``devlink-flash`` command allows optionally specifying a mask indicating
|
|
how the device should handle subsections of flash components when updating.
|
|
This mask indicates the set of sections which are allowed to be overwritten.
|
|
|
|
.. list-table:: List of overwrite mask bits
|
|
:widths: 5 95
|
|
|
|
* - Name
|
|
- Description
|
|
* - ``DEVLINK_FLASH_OVERWRITE_SETTINGS``
|
|
- Indicates that the device should overwrite settings in the components
|
|
being updated with the settings found in the provided image.
|
|
* - ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS``
|
|
- Indicates that the device should overwrite identifiers in the
|
|
components being updated with the identifiers found in the provided
|
|
image. This includes MAC addresses, serial IDs, and similar device
|
|
identifiers.
|
|
|
|
Multiple overwrite bits may be combined and requested together. If no bits
|
|
are provided, it is expected that the device only update firmware binaries
|
|
in the components being updated. Settings and identifiers are expected to be
|
|
preserved across the update. A device may not support every combination and
|
|
the driver for such a device must reject any combination which cannot be
|
|
faithfully implemented.
|
|
|
|
Firmware Loading
|
|
================
|
|
|
|
Devices which require firmware to operate usually store it in non-volatile
|
|
memory on the board, e.g. flash. Some devices store only basic firmware on
|
|
the board, and the driver loads the rest from disk during probing.
|
|
``devlink-info`` allows users to query firmware information (loaded
|
|
components and versions).
|
|
|
|
In other cases the device can both store the image on the board, load from
|
|
disk, or automatically flash a new image from disk. The ``fw_load_policy``
|
|
devlink parameter can be used to control this behavior
|
|
(:ref:`Documentation/networking/devlink/devlink-params.rst <devlink_params_generic>`).
|
|
|
|
On-disk firmware files are usually stored in ``/lib/firmware/``.
|
|
|
|
Firmware Version Management
|
|
===========================
|
|
|
|
Drivers are expected to implement ``devlink-flash`` and ``devlink-info``
|
|
functionality, which together allow for implementing vendor-independent
|
|
automated firmware update facilities.
|
|
|
|
``devlink-info`` exposes the ``driver`` name and three version groups
|
|
(``fixed``, ``running``, ``stored``).
|
|
|
|
The ``driver`` attribute and ``fixed`` group identify the specific device
|
|
design, e.g. for looking up applicable firmware updates. This is why
|
|
``serial_number`` is not part of the ``fixed`` versions (even though it
|
|
is fixed) - ``fixed`` versions should identify the design, not a single
|
|
device.
|
|
|
|
``running`` and ``stored`` firmware versions identify the firmware running
|
|
on the device, and firmware which will be activated after reboot or device
|
|
reset.
|
|
|
|
The firmware update agent is supposed to be able to follow this simple
|
|
algorithm to update firmware contents, regardless of the device vendor:
|
|
|
|
.. code-block:: sh
|
|
|
|
# Get unique HW design identifier
|
|
$hw_id = devlink-dev-info['fixed']
|
|
|
|
# Find out which FW flash we want to use for this NIC
|
|
$want_flash_vers = some-db-backed.lookup($hw_id, 'flash')
|
|
|
|
# Update flash if necessary
|
|
if $want_flash_vers != devlink-dev-info['stored']:
|
|
$file = some-db-backed.download($hw_id, 'flash')
|
|
devlink-dev-flash($file)
|
|
|
|
# Find out the expected overall firmware versions
|
|
$want_fw_vers = some-db-backed.lookup($hw_id, 'all')
|
|
|
|
# Update on-disk file if necessary
|
|
if $want_fw_vers != devlink-dev-info['running']:
|
|
$file = some-db-backed.download($hw_id, 'disk')
|
|
write($file, '/lib/firmware/')
|
|
|
|
# Try device reset, if available
|
|
if $want_fw_vers != devlink-dev-info['running']:
|
|
devlink-reset()
|
|
|
|
# Reboot, if reset wasn't enough
|
|
if $want_fw_vers != devlink-dev-info['running']:
|
|
reboot()
|
|
|
|
Note that each reference to ``devlink-dev-info`` in this pseudo-code
|
|
is expected to fetch up-to-date information from the kernel.
|
|
|
|
For the convenience of identifying firmware files some vendors add
|
|
``bundle_id`` information to the firmware versions. This meta-version covers
|
|
multiple per-component versions and can be used e.g. in firmware file names
|
|
(all component versions could get rather long.)
|