ethtool: Add an interface for flashing transceiver modules' firmware

CMIS compliant modules such as QSFP-DD might be running a firmware that
can be updated in a vendor-neutral way by exchanging messages between
the host and the module as described in section 7.3.1 of revision 5.2 of
the CMIS standard.

Add a pair of new ethtool messages that allow:

* User space to trigger firmware update of transceiver modules

* The kernel to notify user space about the progress of the process

The user interface is designed to be asynchronous in order to avoid
RTNL being held for too long and to allow several modules to be
updated simultaneously. The interface is designed with CMIS compliant
modules in mind, but kept generic enough to accommodate future use
cases, if these arise.

Signed-off-by: Danielle Ratson <danieller@nvidia.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Danielle Ratson 2024-06-27 17:08:50 +03:00 committed by David S. Miller
parent 1983a80070
commit 46fb3ba95b
5 changed files with 164 additions and 1 deletions

View File

@ -20,6 +20,10 @@ definitions:
name: header-flags
type: flags
entries: [ compact-bitsets, omit-reply, stats ]
-
name: module-fw-flash-status
type: enum
entries: [ started, in_progress, completed, error ]
attribute-sets:
-
@ -1004,6 +1008,32 @@ attribute-sets:
-
name: burst-tmr
type: u32
-
name: module-fw-flash
attributes:
-
name: header
type: nest
nested-attributes: header
-
name: file-name
type: string
-
name: password
type: u32
-
name: status
type: u32
enum: module-fw-flash-status
-
name: status-msg
type: string
-
name: done
type: uint
-
name: total
type: uint
operations:
enum-model: directional
@ -1764,3 +1794,28 @@ operations:
name: mm-ntf
doc: Notification for change in MAC Merge configuration.
notify: mm-get
-
name: module-fw-flash-act
doc: Flash transceiver module firmware.
attribute-set: module-fw-flash
do:
request:
attributes:
- header
- file-name
- password
-
name: module-fw-flash-ntf
doc: Notification for firmware flashing progress and status.
attribute-set: module-fw-flash
event:
attributes:
- header
- status
- status-msg
- done
- total

View File

@ -228,6 +228,7 @@ Userspace to kernel:
``ETHTOOL_MSG_PLCA_GET_STATUS`` get PLCA RS status
``ETHTOOL_MSG_MM_GET`` get MAC merge layer state
``ETHTOOL_MSG_MM_SET`` set MAC merge layer parameters
``ETHTOOL_MSG_MODULE_FW_FLASH_ACT`` flash transceiver module firmware
===================================== =================================
Kernel to userspace:
@ -274,6 +275,7 @@ Kernel to userspace:
``ETHTOOL_MSG_PLCA_GET_STATUS_REPLY`` PLCA RS status
``ETHTOOL_MSG_PLCA_NTF`` PLCA RS parameters
``ETHTOOL_MSG_MM_GET_REPLY`` MAC merge layer status
``ETHTOOL_MSG_MODULE_FW_FLASH_NTF`` transceiver module flash updates
======================================== =================================
``GET`` requests are sent by userspace applications to retrieve device
@ -2041,6 +2043,73 @@ The attributes are propagated to the driver through the following structure:
.. kernel-doc:: include/linux/ethtool.h
:identifiers: ethtool_mm_cfg
MODULE_FW_FLASH_ACT
===================
Flashes transceiver module firmware.
Request contents:
======================================= ====== ===========================
``ETHTOOL_A_MODULE_FW_FLASH_HEADER`` nested request header
``ETHTOOL_A_MODULE_FW_FLASH_FILE_NAME`` string firmware image file name
``ETHTOOL_A_MODULE_FW_FLASH_PASSWORD`` u32 transceiver module password
======================================= ====== ===========================
The firmware update process consists of three logical steps:
1. Downloading a firmware image to the transceiver module and validating it.
2. Running the firmware image.
3. Committing the firmware image so that it is run upon reset.
When flash command is given, those three steps are taken in that order.
This message merely schedules the update process and returns immediately
without blocking. The process then runs asynchronously.
Since it can take several minutes to complete, during the update process
notifications are emitted from the kernel to user space updating it about
the status and progress.
The ``ETHTOOL_A_MODULE_FW_FLASH_FILE_NAME`` attribute encodes the firmware
image file name. The firmware image is downloaded to the transceiver module,
validated, run and committed.
The optional ``ETHTOOL_A_MODULE_FW_FLASH_PASSWORD`` attribute encodes a password
that might be required as part of the transceiver module firmware update
process.
The firmware update process can take several minutes to complete. Therefore,
during the update process notifications are emitted from the kernel to user
space updating it about the status and progress.
Notification contents:
+---------------------------------------------------+--------+----------------+
| ``ETHTOOL_A_MODULE_FW_FLASH_HEADER`` | nested | reply header |
+---------------------------------------------------+--------+----------------+
| ``ETHTOOL_A_MODULE_FW_FLASH_STATUS`` | u32 | status |
+---------------------------------------------------+--------+----------------+
| ``ETHTOOL_A_MODULE_FW_FLASH_STATUS_MSG`` | string | status message |
+---------------------------------------------------+--------+----------------+
| ``ETHTOOL_A_MODULE_FW_FLASH_DONE`` | uint | progress |
+---------------------------------------------------+--------+----------------+
| ``ETHTOOL_A_MODULE_FW_FLASH_TOTAL`` | uint | total |
+---------------------------------------------------+--------+----------------+
The ``ETHTOOL_A_MODULE_FW_FLASH_STATUS`` attribute encodes the current status
of the firmware update process. Possible values are:
.. kernel-doc:: include/uapi/linux/ethtool.h
:identifiers: ethtool_module_fw_flash_status
The ``ETHTOOL_A_MODULE_FW_FLASH_STATUS_MSG`` attribute encodes a status message
string.
The ``ETHTOOL_A_MODULE_FW_FLASH_DONE`` and ``ETHTOOL_A_MODULE_FW_FLASH_TOTAL``
attributes encode the completed and total amount of work, respectively.
Request translation
===================
@ -2147,4 +2216,5 @@ are netlink only.
n/a ``ETHTOOL_MSG_PLCA_GET_STATUS``
n/a ``ETHTOOL_MSG_MM_GET``
n/a ``ETHTOOL_MSG_MM_SET``
n/a ``ETHTOOL_MSG_MODULE_FW_FLASH_ACT``
=================================== =====================================

View File

@ -877,6 +877,24 @@ enum ethtool_mm_verify_status {
ETHTOOL_MM_VERIFY_STATUS_DISABLED,
};
/**
* enum ethtool_module_fw_flash_status - plug-in module firmware flashing status
* @ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED: The firmware flashing process has
* started.
* @ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS: The firmware flashing process
* is in progress.
* @ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED: The firmware flashing process was
* completed successfully.
* @ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR: The firmware flashing process was
* stopped due to an error.
*/
enum ethtool_module_fw_flash_status {
ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED = 1,
ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS,
ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED,
ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR,
};
/**
* struct ethtool_gstrings - string set for data tagging
* @cmd: Command number = %ETHTOOL_GSTRINGS

View File

@ -57,6 +57,7 @@ enum {
ETHTOOL_MSG_PLCA_GET_STATUS,
ETHTOOL_MSG_MM_GET,
ETHTOOL_MSG_MM_SET,
ETHTOOL_MSG_MODULE_FW_FLASH_ACT,
/* add new constants above here */
__ETHTOOL_MSG_USER_CNT,
@ -109,6 +110,7 @@ enum {
ETHTOOL_MSG_PLCA_NTF,
ETHTOOL_MSG_MM_GET_REPLY,
ETHTOOL_MSG_MM_NTF,
ETHTOOL_MSG_MODULE_FW_FLASH_NTF,
/* add new constants above here */
__ETHTOOL_MSG_KERNEL_CNT,
@ -1018,6 +1020,23 @@ enum {
ETHTOOL_A_MM_MAX = (__ETHTOOL_A_MM_CNT - 1)
};
/* MODULE_FW_FLASH */
enum {
ETHTOOL_A_MODULE_FW_FLASH_UNSPEC,
ETHTOOL_A_MODULE_FW_FLASH_HEADER, /* nest - _A_HEADER_* */
ETHTOOL_A_MODULE_FW_FLASH_FILE_NAME, /* string */
ETHTOOL_A_MODULE_FW_FLASH_PASSWORD, /* u32 */
ETHTOOL_A_MODULE_FW_FLASH_STATUS, /* u32 */
ETHTOOL_A_MODULE_FW_FLASH_STATUS_MSG, /* string */
ETHTOOL_A_MODULE_FW_FLASH_DONE, /* uint */
ETHTOOL_A_MODULE_FW_FLASH_TOTAL, /* uint */
/* add new constants above here */
__ETHTOOL_A_MODULE_FW_FLASH_CNT,
ETHTOOL_A_MODULE_FW_FLASH_MAX = (__ETHTOOL_A_MODULE_FW_FLASH_CNT - 1)
};
/* generic netlink info */
#define ETHTOOL_GENL_NAME "ethtool"
#define ETHTOOL_GENL_VERSION 1

View File

@ -16,7 +16,8 @@ get_hdr_inc=-D$(1) -include $(UAPI_PATH)/linux/$(2)
CFLAGS_devlink:=$(call get_hdr_inc,_LINUX_DEVLINK_H_,devlink.h)
CFLAGS_dpll:=$(call get_hdr_inc,_LINUX_DPLL_H,dpll.h)
CFLAGS_ethtool:=$(call get_hdr_inc,_LINUX_ETHTOOL_NETLINK_H_,ethtool_netlink.h)
CFLAGS_ethtool:=$(call get_hdr_inc,_LINUX_ETHTOOL_H,ethtool.h) \
$(call get_hdr_inc,_LINUX_ETHTOOL_NETLINK_H_,ethtool_netlink.h)
CFLAGS_handshake:=$(call get_hdr_inc,_LINUX_HANDSHAKE_H,handshake.h)
CFLAGS_mptcp_pm:=$(call get_hdr_inc,_LINUX_MPTCP_PM_H,mptcp_pm.h)
CFLAGS_netdev:=$(call get_hdr_inc,_LINUX_NETDEV_H,netdev.h)