162306a36Sopenharmony_ci.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci.. _devlink_flash:
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci=============
662306a36Sopenharmony_ciDevlink Flash
762306a36Sopenharmony_ci=============
862306a36Sopenharmony_ci
962306a36Sopenharmony_ciThe ``devlink-flash`` API allows updating device firmware. It replaces the
1062306a36Sopenharmony_ciolder ``ethtool-flash`` mechanism, and doesn't require taking any
1162306a36Sopenharmony_cinetworking locks in the kernel to perform the flash update. Example use::
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci  $ devlink dev flash pci/0000:05:00.0 file flash-boot.bin
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ciNote that the file name is a path relative to the firmware loading path
1662306a36Sopenharmony_ci(usually ``/lib/firmware/``). Drivers may send status updates to inform
1762306a36Sopenharmony_ciuser space about the progress of the update operation.
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciOverwrite Mask
2062306a36Sopenharmony_ci==============
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ciThe ``devlink-flash`` command allows optionally specifying a mask indicating
2362306a36Sopenharmony_cihow the device should handle subsections of flash components when updating.
2462306a36Sopenharmony_ciThis mask indicates the set of sections which are allowed to be overwritten.
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci.. list-table:: List of overwrite mask bits
2762306a36Sopenharmony_ci   :widths: 5 95
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci   * - Name
3062306a36Sopenharmony_ci     - Description
3162306a36Sopenharmony_ci   * - ``DEVLINK_FLASH_OVERWRITE_SETTINGS``
3262306a36Sopenharmony_ci     - Indicates that the device should overwrite settings in the components
3362306a36Sopenharmony_ci       being updated with the settings found in the provided image.
3462306a36Sopenharmony_ci   * - ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS``
3562306a36Sopenharmony_ci     - Indicates that the device should overwrite identifiers in the
3662306a36Sopenharmony_ci       components being updated with the identifiers found in the provided
3762306a36Sopenharmony_ci       image. This includes MAC addresses, serial IDs, and similar device
3862306a36Sopenharmony_ci       identifiers.
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ciMultiple overwrite bits may be combined and requested together. If no bits
4162306a36Sopenharmony_ciare provided, it is expected that the device only update firmware binaries
4262306a36Sopenharmony_ciin the components being updated. Settings and identifiers are expected to be
4362306a36Sopenharmony_cipreserved across the update. A device may not support every combination and
4462306a36Sopenharmony_cithe driver for such a device must reject any combination which cannot be
4562306a36Sopenharmony_cifaithfully implemented.
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ciFirmware Loading
4862306a36Sopenharmony_ci================
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ciDevices which require firmware to operate usually store it in non-volatile
5162306a36Sopenharmony_cimemory on the board, e.g. flash. Some devices store only basic firmware on
5262306a36Sopenharmony_cithe board, and the driver loads the rest from disk during probing.
5362306a36Sopenharmony_ci``devlink-info`` allows users to query firmware information (loaded
5462306a36Sopenharmony_cicomponents and versions).
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ciIn other cases the device can both store the image on the board, load from
5762306a36Sopenharmony_cidisk, or automatically flash a new image from disk. The ``fw_load_policy``
5862306a36Sopenharmony_cidevlink parameter can be used to control this behavior
5962306a36Sopenharmony_ci(:ref:`Documentation/networking/devlink/devlink-params.rst <devlink_params_generic>`).
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ciOn-disk firmware files are usually stored in ``/lib/firmware/``.
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ciFirmware Version Management
6462306a36Sopenharmony_ci===========================
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ciDrivers are expected to implement ``devlink-flash`` and ``devlink-info``
6762306a36Sopenharmony_cifunctionality, which together allow for implementing vendor-independent
6862306a36Sopenharmony_ciautomated firmware update facilities.
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci``devlink-info`` exposes the ``driver`` name and three version groups
7162306a36Sopenharmony_ci(``fixed``, ``running``, ``stored``).
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ciThe ``driver`` attribute and ``fixed`` group identify the specific device
7462306a36Sopenharmony_cidesign, e.g. for looking up applicable firmware updates. This is why
7562306a36Sopenharmony_ci``serial_number`` is not part of the ``fixed`` versions (even though it
7662306a36Sopenharmony_ciis fixed) - ``fixed`` versions should identify the design, not a single
7762306a36Sopenharmony_cidevice.
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci``running`` and ``stored`` firmware versions identify the firmware running
8062306a36Sopenharmony_cion the device, and firmware which will be activated after reboot or device
8162306a36Sopenharmony_cireset.
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ciThe firmware update agent is supposed to be able to follow this simple
8462306a36Sopenharmony_cialgorithm to update firmware contents, regardless of the device vendor:
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci.. code-block:: sh
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci  # Get unique HW design identifier
8962306a36Sopenharmony_ci  $hw_id = devlink-dev-info['fixed']
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci  # Find out which FW flash we want to use for this NIC
9262306a36Sopenharmony_ci  $want_flash_vers = some-db-backed.lookup($hw_id, 'flash')
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci  # Update flash if necessary
9562306a36Sopenharmony_ci  if $want_flash_vers != devlink-dev-info['stored']:
9662306a36Sopenharmony_ci      $file = some-db-backed.download($hw_id, 'flash')
9762306a36Sopenharmony_ci      devlink-dev-flash($file)
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci  # Find out the expected overall firmware versions
10062306a36Sopenharmony_ci  $want_fw_vers = some-db-backed.lookup($hw_id, 'all')
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci  # Update on-disk file if necessary
10362306a36Sopenharmony_ci  if $want_fw_vers != devlink-dev-info['running']:
10462306a36Sopenharmony_ci      $file = some-db-backed.download($hw_id, 'disk')
10562306a36Sopenharmony_ci      write($file, '/lib/firmware/')
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci  # Try device reset, if available
10862306a36Sopenharmony_ci  if $want_fw_vers != devlink-dev-info['running']:
10962306a36Sopenharmony_ci     devlink-reset()
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci  # Reboot, if reset wasn't enough
11262306a36Sopenharmony_ci  if $want_fw_vers != devlink-dev-info['running']:
11362306a36Sopenharmony_ci     reboot()
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ciNote that each reference to ``devlink-dev-info`` in this pseudo-code
11662306a36Sopenharmony_ciis expected to fetch up-to-date information from the kernel.
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ciFor the convenience of identifying firmware files some vendors add
11962306a36Sopenharmony_ci``bundle_id`` information to the firmware versions. This meta-version covers
12062306a36Sopenharmony_cimultiple per-component versions and can be used e.g. in firmware file names
12162306a36Sopenharmony_ci(all component versions could get rather long.)
122