1cd556e40SJakub Kicinski.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2cd556e40SJakub Kicinski
3cd556e40SJakub Kicinski.. _devlink_flash:
4cd556e40SJakub Kicinski
5cd556e40SJakub Kicinski=============
6cd556e40SJakub KicinskiDevlink Flash
7cd556e40SJakub Kicinski=============
8cd556e40SJakub Kicinski
9cd556e40SJakub KicinskiThe ``devlink-flash`` API allows updating device firmware. It replaces the
10cd556e40SJakub Kicinskiolder ``ethtool-flash`` mechanism, and doesn't require taking any
11cd556e40SJakub Kicinskinetworking locks in the kernel to perform the flash update. Example use::
12cd556e40SJakub Kicinski
13cd556e40SJakub Kicinski  $ devlink dev flash pci/0000:05:00.0 file flash-boot.bin
14cd556e40SJakub Kicinski
15cd556e40SJakub KicinskiNote that the file name is a path relative to the firmware loading path
16cd556e40SJakub Kicinski(usually ``/lib/firmware/``). Drivers may send status updates to inform
17cd556e40SJakub Kicinskiuser space about the progress of the update operation.
18cd556e40SJakub Kicinski
19*5d5b4128SJacob KellerOverwrite Mask
20*5d5b4128SJacob Keller==============
21*5d5b4128SJacob Keller
22*5d5b4128SJacob KellerThe ``devlink-flash`` command allows optionally specifying a mask indicating
23*5d5b4128SJacob Kellerhow the device should handle subsections of flash components when updating.
24*5d5b4128SJacob KellerThis mask indicates the set of sections which are allowed to be overwritten.
25*5d5b4128SJacob Keller
26*5d5b4128SJacob Keller.. list-table:: List of overwrite mask bits
27*5d5b4128SJacob Keller   :widths: 5 95
28*5d5b4128SJacob Keller
29*5d5b4128SJacob Keller   * - Name
30*5d5b4128SJacob Keller     - Description
31*5d5b4128SJacob Keller   * - ``DEVLINK_FLASH_OVERWRITE_SETTINGS``
32*5d5b4128SJacob Keller     - Indicates that the device should overwrite settings in the components
33*5d5b4128SJacob Keller       being updated with the settings found in the provided image.
34*5d5b4128SJacob Keller   * - ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS``
35*5d5b4128SJacob Keller     - Indicates that the device should overwrite identifiers in the
36*5d5b4128SJacob Keller       components being updated with the identifiers found in the provided
37*5d5b4128SJacob Keller       image. This includes MAC addresses, serial IDs, and similar device
38*5d5b4128SJacob Keller       identifiers.
39*5d5b4128SJacob Keller
40*5d5b4128SJacob KellerMultiple overwrite bits may be combined and requested together. If no bits
41*5d5b4128SJacob Kellerare provided, it is expected that the device only update firmware binaries
42*5d5b4128SJacob Kellerin the components being updated. Settings and identifiers are expected to be
43*5d5b4128SJacob Kellerpreserved across the update. A device may not support every combination and
44*5d5b4128SJacob Kellerthe driver for such a device must reject any combination which cannot be
45*5d5b4128SJacob Kellerfaithfully implemented.
46*5d5b4128SJacob Keller
47cd556e40SJakub KicinskiFirmware Loading
48cd556e40SJakub Kicinski================
49cd556e40SJakub Kicinski
50cd556e40SJakub KicinskiDevices which require firmware to operate usually store it in non-volatile
51cd556e40SJakub Kicinskimemory on the board, e.g. flash. Some devices store only basic firmware on
52cd556e40SJakub Kicinskithe board, and the driver loads the rest from disk during probing.
53cd556e40SJakub Kicinski``devlink-info`` allows users to query firmware information (loaded
54cd556e40SJakub Kicinskicomponents and versions).
55cd556e40SJakub Kicinski
56cd556e40SJakub KicinskiIn other cases the device can both store the image on the board, load from
57cd556e40SJakub Kicinskidisk, or automatically flash a new image from disk. The ``fw_load_policy``
58cd556e40SJakub Kicinskidevlink parameter can be used to control this behavior
59cd556e40SJakub Kicinski(:ref:`Documentation/networking/devlink/devlink-params.rst <devlink_params_generic>`).
60cd556e40SJakub Kicinski
61cd556e40SJakub KicinskiOn-disk firmware files are usually stored in ``/lib/firmware/``.
62cd556e40SJakub Kicinski
63cd556e40SJakub KicinskiFirmware Version Management
64cd556e40SJakub Kicinski===========================
65cd556e40SJakub Kicinski
66cd556e40SJakub KicinskiDrivers are expected to implement ``devlink-flash`` and ``devlink-info``
67cd556e40SJakub Kicinskifunctionality, which together allow for implementing vendor-independent
68cd556e40SJakub Kicinskiautomated firmware update facilities.
69cd556e40SJakub Kicinski
70cd556e40SJakub Kicinski``devlink-info`` exposes the ``driver`` name and three version groups
71cd556e40SJakub Kicinski(``fixed``, ``running``, ``stored``).
72cd556e40SJakub Kicinski
73cd556e40SJakub KicinskiThe ``driver`` attribute and ``fixed`` group identify the specific device
74cd556e40SJakub Kicinskidesign, e.g. for looking up applicable firmware updates. This is why
75cd556e40SJakub Kicinski``serial_number`` is not part of the ``fixed`` versions (even though it
76cd556e40SJakub Kicinskiis fixed) - ``fixed`` versions should identify the design, not a single
77cd556e40SJakub Kicinskidevice.
78cd556e40SJakub Kicinski
79cd556e40SJakub Kicinski``running`` and ``stored`` firmware versions identify the firmware running
80cd556e40SJakub Kicinskion the device, and firmware which will be activated after reboot or device
81cd556e40SJakub Kicinskireset.
82cd556e40SJakub Kicinski
83cd556e40SJakub KicinskiThe firmware update agent is supposed to be able to follow this simple
84cd556e40SJakub Kicinskialgorithm to update firmware contents, regardless of the device vendor:
85cd556e40SJakub Kicinski
86cd556e40SJakub Kicinski.. code-block:: sh
87cd556e40SJakub Kicinski
88cd556e40SJakub Kicinski  # Get unique HW design identifier
89cd556e40SJakub Kicinski  $hw_id = devlink-dev-info['fixed']
90cd556e40SJakub Kicinski
91cd556e40SJakub Kicinski  # Find out which FW flash we want to use for this NIC
92cd556e40SJakub Kicinski  $want_flash_vers = some-db-backed.lookup($hw_id, 'flash')
93cd556e40SJakub Kicinski
94cd556e40SJakub Kicinski  # Update flash if necessary
95cd556e40SJakub Kicinski  if $want_flash_vers != devlink-dev-info['stored']:
96cd556e40SJakub Kicinski      $file = some-db-backed.download($hw_id, 'flash')
97cd556e40SJakub Kicinski      devlink-dev-flash($file)
98cd556e40SJakub Kicinski
99cd556e40SJakub Kicinski  # Find out the expected overall firmware versions
100cd556e40SJakub Kicinski  $want_fw_vers = some-db-backed.lookup($hw_id, 'all')
101cd556e40SJakub Kicinski
102cd556e40SJakub Kicinski  # Update on-disk file if necessary
103cd556e40SJakub Kicinski  if $want_fw_vers != devlink-dev-info['running']:
104cd556e40SJakub Kicinski      $file = some-db-backed.download($hw_id, 'disk')
105cd556e40SJakub Kicinski      write($file, '/lib/firmware/')
106cd556e40SJakub Kicinski
107cd556e40SJakub Kicinski  # Try device reset, if available
108cd556e40SJakub Kicinski  if $want_fw_vers != devlink-dev-info['running']:
109cd556e40SJakub Kicinski     devlink-reset()
110cd556e40SJakub Kicinski
111cd556e40SJakub Kicinski  # Reboot, if reset wasn't enough
112cd556e40SJakub Kicinski  if $want_fw_vers != devlink-dev-info['running']:
113cd556e40SJakub Kicinski     reboot()
114cd556e40SJakub Kicinski
115cd556e40SJakub KicinskiNote that each reference to ``devlink-dev-info`` in this pseudo-code
116cd556e40SJakub Kicinskiis expected to fetch up-to-date information from the kernel.
117cd556e40SJakub Kicinski
118cd556e40SJakub KicinskiFor the convenience of identifying firmware files some vendors add
119cd556e40SJakub Kicinski``bundle_id`` information to the firmware versions. This meta-version covers
120cd556e40SJakub Kicinskimultiple per-component versions and can be used e.g. in firmware file names
121cd556e40SJakub Kicinski(all component versions could get rather long.)
122