* [PATCH net-next v2 0/2] ethtool: Add support for writing firmware
@ 2024-09-10 9:02 Danielle Ratson
2024-09-10 9:02 ` [PATCH net-next v2 1/2] net: ethtool: Add new parameters and a function to support EPL Danielle Ratson
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Danielle Ratson @ 2024-09-10 9:02 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, yuehaibing, linux-kernel, petrm,
danieller
In the CMIS specification for pluggable modules, LPL (Local Payload) and
EPL (Extended Payload) are two types of data payloads used for managing
various functions and features of the module.
EPL payloads are used for more complex and extensive management functions
that require a larger amount of data, so writing firmware blocks using EPL
is much more efficient.
Currently, only LPL payload is supported for writing firmware blocks to
the module.
Add support for writing firmware block using EPL payload, both to support
modules that support only EPL write mechanism, and to optimize the flashing
process of modules that support LPL and EPL.
Running the flashing command on the same sample module using EPL vs. LPL
showed an improvement of 84%.
Patchset overview:
Patch #1: preparations
Patch #2: Add EPL support
v2:
* Fix the commit meassges to align the cover letter about the
right meaning of LPL and EPL.
Patch #2:
* Initialize the variable 'bytes_written' before the first
iteration.
Danielle Ratson (2):
net: ethtool: Add new parameters and a function to support EPL
net: ethtool: Add support for writing firmware blocks using EPL
payload
net/ethtool/cmis.h | 16 ++++--
net/ethtool/cmis_cdb.c | 94 +++++++++++++++++++++++++-----
net/ethtool/cmis_fw_update.c | 108 +++++++++++++++++++++++++++++------
3 files changed, 184 insertions(+), 34 deletions(-)
--
2.45.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next v2 1/2] net: ethtool: Add new parameters and a function to support EPL
2024-09-10 9:02 [PATCH net-next v2 0/2] ethtool: Add support for writing firmware Danielle Ratson
@ 2024-09-10 9:02 ` Danielle Ratson
2024-09-11 7:32 ` Simon Horman
2024-09-10 9:02 ` [PATCH net-next v2 2/2] net: ethtool: Add support for writing firmware blocks using EPL payload Danielle Ratson
2024-09-15 17:17 ` [PATCH net-next v2 0/2] ethtool: Add support for writing firmware Jakub Kicinski
2 siblings, 1 reply; 10+ messages in thread
From: Danielle Ratson @ 2024-09-10 9:02 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, yuehaibing, linux-kernel, petrm,
danieller
In the CMIS specification for pluggable modules, LPL (Local Payload) and
EPL (Extended Payload) are two types of data payloads used for managing
various functions and features of the module.
EPL payloads are used for more complex and extensive management
functions that require a larger amount of data, so writing firmware
blocks using EPL is much more efficient.
Currently, only LPL payload is supported for writing firmware blocks to
the module.
Add EPL related parameters to the function ethtool_cmis_cdb_compose_args()
and add a specific function for calculating the maximum allowable length
extension for EPL. Both will be used in the next patch to add support for
writing firmware blocks using EPL.
Signed-off-by: Danielle Ratson <danieller@nvidia.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
net/ethtool/cmis.h | 12 +++++++-----
net/ethtool/cmis_cdb.c | 32 +++++++++++++++++++++-----------
net/ethtool/cmis_fw_update.c | 17 ++++++++++-------
3 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
index 3e7c293af78c..73a5060d0f4c 100644
--- a/net/ethtool/cmis.h
+++ b/net/ethtool/cmis.h
@@ -96,13 +96,15 @@ struct ethtool_cmis_cdb_rpl {
u8 payload[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH];
};
-u32 ethtool_cmis_get_max_payload_size(u8 num_of_byte_octs);
+u32 ethtool_cmis_get_max_lpl_size(u8 num_of_byte_octs);
+u32 ethtool_cmis_get_max_epl_size(u8 num_of_byte_octs);
void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
- enum ethtool_cmis_cdb_cmd_id cmd, u8 *pl,
- u8 lpl_len, u16 max_duration,
- u8 read_write_len_ext, u16 msleep_pre_rpl,
- u8 rpl_exp_len, u8 flags);
+ enum ethtool_cmis_cdb_cmd_id cmd, u8 *lpl,
+ u8 lpl_len, u8 *epl, u16 epl_len,
+ u16 max_duration, u8 read_write_len_ext,
+ u16 msleep_pre_rpl, u8 rpl_exp_len,
+ u8 flags);
void ethtool_cmis_cdb_check_completion_flag(u8 cmis_rev, u8 *flags);
diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
index 1bb08783b60d..f599b20479f6 100644
--- a/net/ethtool/cmis_cdb.c
+++ b/net/ethtool/cmis_cdb.c
@@ -11,25 +11,34 @@
* min(i, 15) byte octets where i specifies the allowable additional number of
* byte octets in a READ or a WRITE.
*/
-u32 ethtool_cmis_get_max_payload_size(u8 num_of_byte_octs)
+u32 ethtool_cmis_get_max_lpl_size(u8 num_of_byte_octs)
{
return 8 * (1 + min_t(u8, num_of_byte_octs, 15));
}
+/* For accessing the EPL field on page 9Fh, the allowable length extension is
+ * min(i, 255) byte octets where i specifies the allowable additional number of
+ * byte octets in a READ or a WRITE.
+ */
+u32 ethtool_cmis_get_max_epl_size(u8 num_of_byte_octs)
+{
+ return 8 * (1 + min_t(u8, num_of_byte_octs, 255));
+}
+
void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
- enum ethtool_cmis_cdb_cmd_id cmd, u8 *pl,
- u8 lpl_len, u16 max_duration,
- u8 read_write_len_ext, u16 msleep_pre_rpl,
- u8 rpl_exp_len, u8 flags)
+ enum ethtool_cmis_cdb_cmd_id cmd, u8 *lpl,
+ u8 lpl_len, u8 *epl, u16 epl_len,
+ u16 max_duration, u8 read_write_len_ext,
+ u16 msleep_pre_rpl, u8 rpl_exp_len, u8 flags)
{
args->req.id = cpu_to_be16(cmd);
args->req.lpl_len = lpl_len;
- if (pl)
- memcpy(args->req.payload, pl, args->req.lpl_len);
+ if (lpl)
+ memcpy(args->req.payload, lpl, args->req.lpl_len);
args->max_duration = max_duration;
args->read_write_len_ext =
- ethtool_cmis_get_max_payload_size(read_write_len_ext);
+ ethtool_cmis_get_max_lpl_size(read_write_len_ext);
args->msleep_pre_rpl = msleep_pre_rpl;
args->rpl_exp_len = rpl_exp_len;
args->flags = flags;
@@ -178,7 +187,7 @@ cmis_cdb_validate_password(struct ethtool_cmis_cdb *cdb,
}
ethtool_cmis_cdb_compose_args(&args, ETHTOOL_CMIS_CDB_CMD_QUERY_STATUS,
- (u8 *)&qs_pl, sizeof(qs_pl), 0,
+ (u8 *)&qs_pl, sizeof(qs_pl), NULL, 0, 0,
cdb->read_write_len_ext, 1000,
sizeof(*rpl),
CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
@@ -240,8 +249,9 @@ static int cmis_cdb_module_features_get(struct ethtool_cmis_cdb *cdb,
ethtool_cmis_cdb_check_completion_flag(cdb->cmis_rev, &flags);
ethtool_cmis_cdb_compose_args(&args,
ETHTOOL_CMIS_CDB_CMD_MODULE_FEATURES,
- NULL, 0, 0, cdb->read_write_len_ext,
- 1000, sizeof(*rpl), flags);
+ NULL, 0, NULL, 0, 0,
+ cdb->read_write_len_ext, 1000,
+ sizeof(*rpl), flags);
err = ethtool_cmis_cdb_execute_cmd(dev, &args);
if (err < 0) {
diff --git a/net/ethtool/cmis_fw_update.c b/net/ethtool/cmis_fw_update.c
index 655ff5224ffa..a514127985d4 100644
--- a/net/ethtool/cmis_fw_update.c
+++ b/net/ethtool/cmis_fw_update.c
@@ -54,7 +54,8 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
ethtool_cmis_cdb_check_completion_flag(cdb->cmis_rev, &flags);
ethtool_cmis_cdb_compose_args(&args,
ETHTOOL_CMIS_CDB_CMD_FW_MANAGMENT_FEATURES,
- NULL, 0, cdb->max_completion_time,
+ NULL, 0, NULL, 0,
+ cdb->max_completion_time,
cdb->read_write_len_ext, 1000,
sizeof(*rpl), flags);
@@ -122,7 +123,7 @@ cmis_fw_update_start_download(struct ethtool_cmis_cdb *cdb,
ethtool_cmis_cdb_compose_args(&args,
ETHTOOL_CMIS_CDB_CMD_START_FW_DOWNLOAD,
- (u8 *)&pl, lpl_len,
+ (u8 *)&pl, lpl_len, NULL, 0,
fw_mng->max_duration_start,
cdb->read_write_len_ext, 1000, 0,
CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
@@ -158,7 +159,7 @@ cmis_fw_update_write_image(struct ethtool_cmis_cdb *cdb,
int err;
max_lpl_len = min_t(u32,
- ethtool_cmis_get_max_payload_size(cdb->read_write_len_ext),
+ ethtool_cmis_get_max_lpl_size(cdb->read_write_len_ext),
ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH);
max_block_size =
max_lpl_len - sizeof_field(struct cmis_cdb_write_fw_block_lpl_pl,
@@ -183,7 +184,7 @@ cmis_fw_update_write_image(struct ethtool_cmis_cdb *cdb,
ethtool_cmis_cdb_compose_args(&args,
ETHTOOL_CMIS_CDB_CMD_WRITE_FW_BLOCK_LPL,
- (u8 *)&pl, lpl_len,
+ (u8 *)&pl, lpl_len, NULL, 0,
fw_mng->max_duration_write,
cdb->read_write_len_ext, 1, 0,
CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
@@ -212,7 +213,8 @@ cmis_fw_update_complete_download(struct ethtool_cmis_cdb *cdb,
ethtool_cmis_cdb_compose_args(&args,
ETHTOOL_CMIS_CDB_CMD_COMPLETE_FW_DOWNLOAD,
- NULL, 0, fw_mng->max_duration_complete,
+ NULL, 0, NULL, 0,
+ fw_mng->max_duration_complete,
cdb->read_write_len_ext, 1000, 0,
CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
@@ -294,7 +296,7 @@ cmis_fw_update_run_image(struct ethtool_cmis_cdb *cdb, struct net_device *dev,
int err;
ethtool_cmis_cdb_compose_args(&args, ETHTOOL_CMIS_CDB_CMD_RUN_FW_IMAGE,
- (u8 *)&pl, sizeof(pl),
+ (u8 *)&pl, sizeof(pl), NULL, 0,
cdb->max_completion_time,
cdb->read_write_len_ext, 1000, 0,
CDB_F_MODULE_STATE_VALID);
@@ -326,7 +328,8 @@ cmis_fw_update_commit_image(struct ethtool_cmis_cdb *cdb,
ethtool_cmis_cdb_compose_args(&args,
ETHTOOL_CMIS_CDB_CMD_COMMIT_FW_IMAGE,
- NULL, 0, cdb->max_completion_time,
+ NULL, 0, NULL, 0,
+ cdb->max_completion_time,
cdb->read_write_len_ext, 1000, 0,
CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
--
2.45.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next v2 2/2] net: ethtool: Add support for writing firmware blocks using EPL payload
2024-09-10 9:02 [PATCH net-next v2 0/2] ethtool: Add support for writing firmware Danielle Ratson
2024-09-10 9:02 ` [PATCH net-next v2 1/2] net: ethtool: Add new parameters and a function to support EPL Danielle Ratson
@ 2024-09-10 9:02 ` Danielle Ratson
2024-09-11 7:32 ` Simon Horman
2024-09-15 17:17 ` [PATCH net-next v2 0/2] ethtool: Add support for writing firmware Jakub Kicinski
2 siblings, 1 reply; 10+ messages in thread
From: Danielle Ratson @ 2024-09-10 9:02 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, yuehaibing, linux-kernel, petrm,
danieller
In the CMIS specification for pluggable modules, LPL (Local Payload) and
EPL (Extended Payload) are two types of data payloads used for managing
various functions and features of the module.
EPL payloads are used for more complex and extensive management
functions that require a larger amount of data, so writing firmware
blocks using EPL is much more efficient.
Currently, only LPL payload is supported for writing firmware blocks to
the module.
Add support for writing firmware block using EPL payload, both to
support modules that supports only EPL write mechanism, and to optimize
the flashing process of modules that support LPL and EPL.
Signed-off-by: Danielle Ratson <danieller@nvidia.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
Notes:
v2:
* Initialize the variable 'bytes_written' before the first
iteration.
net/ethtool/cmis.h | 4 ++
net/ethtool/cmis_cdb.c | 66 ++++++++++++++++++++++++--
net/ethtool/cmis_fw_update.c | 91 ++++++++++++++++++++++++++++++++----
3 files changed, 148 insertions(+), 13 deletions(-)
diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
index 73a5060d0f4c..1e790413db0e 100644
--- a/net/ethtool/cmis.h
+++ b/net/ethtool/cmis.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#define ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH 120
+#define ETHTOOL_CMIS_CDB_EPL_MAX_PL_LENGTH 2048
#define ETHTOOL_CMIS_CDB_CMD_PAGE 0x9F
#define ETHTOOL_CMIS_CDB_PAGE_I2C_ADDR 0x50
@@ -23,6 +24,7 @@ enum ethtool_cmis_cdb_cmd_id {
ETHTOOL_CMIS_CDB_CMD_FW_MANAGMENT_FEATURES = 0x0041,
ETHTOOL_CMIS_CDB_CMD_START_FW_DOWNLOAD = 0x0101,
ETHTOOL_CMIS_CDB_CMD_WRITE_FW_BLOCK_LPL = 0x0103,
+ ETHTOOL_CMIS_CDB_CMD_WRITE_FW_BLOCK_EPL = 0x0104,
ETHTOOL_CMIS_CDB_CMD_COMPLETE_FW_DOWNLOAD = 0x0107,
ETHTOOL_CMIS_CDB_CMD_RUN_FW_IMAGE = 0x0109,
ETHTOOL_CMIS_CDB_CMD_COMMIT_FW_IMAGE = 0x010A,
@@ -38,6 +40,7 @@ enum ethtool_cmis_cdb_cmd_id {
* @resv1: Added to match the CMIS standard request continuity.
* @resv2: Added to match the CMIS standard request continuity.
* @payload: Payload for the CDB commands.
+ * @epl: Extended payload for the CDB commands.
*/
struct ethtool_cmis_cdb_request {
__be16 id;
@@ -49,6 +52,7 @@ struct ethtool_cmis_cdb_request {
u8 resv2;
u8 payload[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH];
);
+ u8 *epl; /* Everything above this field checksummed. */
};
#define CDB_F_COMPLETION_VALID BIT(0)
diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
index f599b20479f6..e27cad17505e 100644
--- a/net/ethtool/cmis_cdb.c
+++ b/net/ethtool/cmis_cdb.c
@@ -33,12 +33,19 @@ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
{
args->req.id = cpu_to_be16(cmd);
args->req.lpl_len = lpl_len;
- if (lpl)
+ if (lpl) {
memcpy(args->req.payload, lpl, args->req.lpl_len);
+ args->read_write_len_ext =
+ ethtool_cmis_get_max_lpl_size(read_write_len_ext);
+ }
+ if (epl) {
+ args->req.epl_len = cpu_to_be16(epl_len);
+ args->req.epl = epl;
+ args->read_write_len_ext =
+ ethtool_cmis_get_max_epl_size(read_write_len_ext);
+ }
args->max_duration = max_duration;
- args->read_write_len_ext =
- ethtool_cmis_get_max_lpl_size(read_write_len_ext);
args->msleep_pre_rpl = msleep_pre_rpl;
args->rpl_exp_len = rpl_exp_len;
args->flags = flags;
@@ -548,6 +555,49 @@ __ethtool_cmis_cdb_execute_cmd(struct net_device *dev,
return err;
}
+#define CMIS_CDB_EPL_PAGE_START 0xA0
+#define CMIS_CDB_EPL_PAGE_END 0xAF
+#define CMIS_CDB_EPL_FW_BLOCK_OFFSET_START 128
+#define CMIS_CDB_EPL_FW_BLOCK_OFFSET_END 255
+
+static int
+ethtool_cmis_cdb_execute_epl_cmd(struct net_device *dev,
+ struct ethtool_cmis_cdb_cmd_args *args,
+ struct ethtool_module_eeprom *page_data)
+{
+ u16 epl_len = be16_to_cpu(args->req.epl_len);
+ u32 bytes_written = 0;
+ u8 page;
+ int err;
+
+ for (page = CMIS_CDB_EPL_PAGE_START;
+ page <= CMIS_CDB_EPL_PAGE_END && bytes_written < epl_len; page++) {
+ u16 offset = CMIS_CDB_EPL_FW_BLOCK_OFFSET_START;
+
+ while (offset <= CMIS_CDB_EPL_FW_BLOCK_OFFSET_END &&
+ bytes_written < epl_len) {
+ u32 bytes_left = epl_len - bytes_written;
+ u16 space_left, bytes_to_write;
+
+ space_left = CMIS_CDB_EPL_FW_BLOCK_OFFSET_END - offset + 1;
+ bytes_to_write = min_t(u16, bytes_left,
+ min_t(u16, space_left,
+ args->read_write_len_ext));
+
+ err = __ethtool_cmis_cdb_execute_cmd(dev, page_data,
+ page, offset,
+ bytes_to_write,
+ args->req.epl + bytes_written);
+ if (err < 0)
+ return err;
+
+ offset += bytes_to_write;
+ bytes_written += bytes_to_write;
+ }
+ }
+ return 0;
+}
+
static u8 cmis_cdb_calc_checksum(const void *data, size_t size)
{
const u8 *bytes = (const u8 *)data;
@@ -569,7 +619,9 @@ int ethtool_cmis_cdb_execute_cmd(struct net_device *dev,
int err;
args->req.chk_code =
- cmis_cdb_calc_checksum(&args->req, sizeof(args->req));
+ cmis_cdb_calc_checksum(&args->req,
+ offsetof(struct ethtool_cmis_cdb_request,
+ epl));
if (args->req.lpl_len > args->read_write_len_ext) {
args->err_msg = "LPL length is longer than CDB read write length extension allows";
@@ -591,6 +643,12 @@ int ethtool_cmis_cdb_execute_cmd(struct net_device *dev,
if (err < 0)
return err;
+ if (args->req.epl_len) {
+ err = ethtool_cmis_cdb_execute_epl_cmd(dev, args, &page_data);
+ if (err < 0)
+ return err;
+ }
+
offset = CMIS_CDB_CMD_ID_OFFSET +
offsetof(struct ethtool_cmis_cdb_request, id);
err = __ethtool_cmis_cdb_execute_cmd(dev, &page_data,
diff --git a/net/ethtool/cmis_fw_update.c b/net/ethtool/cmis_fw_update.c
index a514127985d4..48aef6220f00 100644
--- a/net/ethtool/cmis_fw_update.c
+++ b/net/ethtool/cmis_fw_update.c
@@ -9,6 +9,7 @@
struct cmis_fw_update_fw_mng_features {
u8 start_cmd_payload_size;
+ u8 write_mechanism;
u16 max_duration_start;
u16 max_duration_write;
u16 max_duration_complete;
@@ -36,7 +37,9 @@ struct cmis_cdb_fw_mng_features_rpl {
};
enum cmis_cdb_fw_write_mechanism {
+ CMIS_CDB_FW_WRITE_MECHANISM_NONE = 0x00,
CMIS_CDB_FW_WRITE_MECHANISM_LPL = 0x01,
+ CMIS_CDB_FW_WRITE_MECHANISM_EPL = 0x10,
CMIS_CDB_FW_WRITE_MECHANISM_BOTH = 0x11,
};
@@ -68,10 +71,9 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
}
rpl = (struct cmis_cdb_fw_mng_features_rpl *)args.req.payload;
- if (!(rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL ||
- rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_BOTH)) {
+ if (rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_NONE) {
ethnl_module_fw_flash_ntf_err(dev, ntf_params,
- "Write LPL is not supported",
+ "CDB write mechanism is not supported",
NULL);
return -EOPNOTSUPP;
}
@@ -83,6 +85,10 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
*/
cdb->read_write_len_ext = rpl->read_write_len_ext;
fw_mng->start_cmd_payload_size = rpl->start_cmd_payload_size;
+ fw_mng->write_mechanism =
+ rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL ?
+ CMIS_CDB_FW_WRITE_MECHANISM_LPL :
+ CMIS_CDB_FW_WRITE_MECHANISM_EPL;
fw_mng->max_duration_start = be16_to_cpu(rpl->max_duration_start);
fw_mng->max_duration_write = be16_to_cpu(rpl->max_duration_write);
fw_mng->max_duration_complete = be16_to_cpu(rpl->max_duration_complete);
@@ -149,9 +155,9 @@ struct cmis_cdb_write_fw_block_lpl_pl {
};
static int
-cmis_fw_update_write_image(struct ethtool_cmis_cdb *cdb,
- struct ethtool_cmis_fw_update_params *fw_update,
- struct cmis_fw_update_fw_mng_features *fw_mng)
+cmis_fw_update_write_image_lpl(struct ethtool_cmis_cdb *cdb,
+ struct ethtool_cmis_fw_update_params *fw_update,
+ struct cmis_fw_update_fw_mng_features *fw_mng)
{
u8 start = fw_mng->start_cmd_payload_size;
u32 offset, max_block_size, max_lpl_len;
@@ -202,6 +208,67 @@ cmis_fw_update_write_image(struct ethtool_cmis_cdb *cdb,
return 0;
}
+struct cmis_cdb_write_fw_block_epl_pl {
+ u8 fw_block[ETHTOOL_CMIS_CDB_EPL_MAX_PL_LENGTH];
+};
+
+static int
+cmis_fw_update_write_image_epl(struct ethtool_cmis_cdb *cdb,
+ struct ethtool_cmis_fw_update_params *fw_update,
+ struct cmis_fw_update_fw_mng_features *fw_mng)
+{
+ u8 start = fw_mng->start_cmd_payload_size;
+ u32 image_size = fw_update->fw->size;
+ u32 offset, lpl_len;
+ int err;
+
+ lpl_len = sizeof_field(struct cmis_cdb_write_fw_block_lpl_pl,
+ block_address);
+
+ for (offset = start; offset < image_size;
+ offset += ETHTOOL_CMIS_CDB_EPL_MAX_PL_LENGTH) {
+ struct cmis_cdb_write_fw_block_lpl_pl lpl = {
+ .block_address = cpu_to_be32(offset - start),
+ };
+ struct cmis_cdb_write_fw_block_epl_pl *epl;
+ struct ethtool_cmis_cdb_cmd_args args = {};
+ u32 epl_len;
+
+ ethnl_module_fw_flash_ntf_in_progress(fw_update->dev,
+ &fw_update->ntf_params,
+ offset - start,
+ image_size);
+
+ epl_len = min_t(u32, ETHTOOL_CMIS_CDB_EPL_MAX_PL_LENGTH,
+ image_size - offset);
+ epl = kmalloc_array(epl_len, sizeof(u8), GFP_KERNEL);
+ if (!epl)
+ return -ENOMEM;
+
+ memcpy(epl->fw_block, &fw_update->fw->data[offset], epl_len);
+
+ ethtool_cmis_cdb_compose_args(&args,
+ ETHTOOL_CMIS_CDB_CMD_WRITE_FW_BLOCK_EPL,
+ (u8 *)&lpl, lpl_len, (u8 *)epl,
+ epl_len,
+ fw_mng->max_duration_write,
+ cdb->read_write_len_ext, 1, 0,
+ CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
+
+ err = ethtool_cmis_cdb_execute_cmd(fw_update->dev, &args);
+ kfree(epl);
+ if (err < 0) {
+ ethnl_module_fw_flash_ntf_err(fw_update->dev,
+ &fw_update->ntf_params,
+ "Write FW block EPL command failed",
+ args.err_msg);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
static int
cmis_fw_update_complete_download(struct ethtool_cmis_cdb *cdb,
struct net_device *dev,
@@ -238,9 +305,15 @@ cmis_fw_update_download_image(struct ethtool_cmis_cdb *cdb,
if (err < 0)
return err;
- err = cmis_fw_update_write_image(cdb, fw_update, fw_mng);
- if (err < 0)
- return err;
+ if (fw_mng->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL) {
+ err = cmis_fw_update_write_image_lpl(cdb, fw_update, fw_mng);
+ if (err < 0)
+ return err;
+ } else {
+ err = cmis_fw_update_write_image_epl(cdb, fw_update, fw_mng);
+ if (err < 0)
+ return err;
+ }
err = cmis_fw_update_complete_download(cdb, fw_update->dev, fw_mng,
&fw_update->ntf_params);
--
2.45.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2 2/2] net: ethtool: Add support for writing firmware blocks using EPL payload
2024-09-10 9:02 ` [PATCH net-next v2 2/2] net: ethtool: Add support for writing firmware blocks using EPL payload Danielle Ratson
@ 2024-09-11 7:32 ` Simon Horman
2024-09-11 12:26 ` Andrew Lunn
0 siblings, 1 reply; 10+ messages in thread
From: Simon Horman @ 2024-09-11 7:32 UTC (permalink / raw)
To: Danielle Ratson
Cc: netdev, davem, edumazet, kuba, pabeni, yuehaibing, linux-kernel,
petrm, Andrew Lunn
+ Andrew Lunn
On Tue, Sep 10, 2024 at 12:02:17PM +0300, Danielle Ratson wrote:
> In the CMIS specification for pluggable modules, LPL (Local Payload) and
> EPL (Extended Payload) are two types of data payloads used for managing
> various functions and features of the module.
>
> EPL payloads are used for more complex and extensive management
> functions that require a larger amount of data, so writing firmware
> blocks using EPL is much more efficient.
>
> Currently, only LPL payload is supported for writing firmware blocks to
> the module.
>
> Add support for writing firmware block using EPL payload, both to
> support modules that supports only EPL write mechanism, and to optimize
> the flashing process of modules that support LPL and EPL.
>
> Signed-off-by: Danielle Ratson <danieller@nvidia.com>
> Reviewed-by: Petr Machata <petrm@nvidia.com>
> ---
>
> Notes:
> v2:
> * Initialize the variable 'bytes_written' before the first
> iteration.
Hi Danielle,
Thanks for the update. From a doing-what-it-says-on-the-wrapper
perspective, this looks good to me.
Reviewed-by: Simon Horman <horms@kernel.org>
I do note that there were some questions from Andrew Lunn (CCed) in v1
regarding the size of transfers over the bus. I see that you responded to
that. Thanks! But I do wonder if he has any further comments.
https://lore.kernel.org/all/DM6PR12MB45163C3543368036C03B6E05D8982@DM6PR12MB4516.namprd12.prod.outlook.com/
...
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2 1/2] net: ethtool: Add new parameters and a function to support EPL
2024-09-10 9:02 ` [PATCH net-next v2 1/2] net: ethtool: Add new parameters and a function to support EPL Danielle Ratson
@ 2024-09-11 7:32 ` Simon Horman
0 siblings, 0 replies; 10+ messages in thread
From: Simon Horman @ 2024-09-11 7:32 UTC (permalink / raw)
To: Danielle Ratson
Cc: netdev, davem, edumazet, kuba, pabeni, yuehaibing, linux-kernel,
petrm
On Tue, Sep 10, 2024 at 12:02:16PM +0300, Danielle Ratson wrote:
> In the CMIS specification for pluggable modules, LPL (Local Payload) and
> EPL (Extended Payload) are two types of data payloads used for managing
> various functions and features of the module.
>
> EPL payloads are used for more complex and extensive management
> functions that require a larger amount of data, so writing firmware
> blocks using EPL is much more efficient.
>
> Currently, only LPL payload is supported for writing firmware blocks to
> the module.
>
> Add EPL related parameters to the function ethtool_cmis_cdb_compose_args()
> and add a specific function for calculating the maximum allowable length
> extension for EPL. Both will be used in the next patch to add support for
> writing firmware blocks using EPL.
>
> Signed-off-by: Danielle Ratson <danieller@nvidia.com>
> Reviewed-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2 2/2] net: ethtool: Add support for writing firmware blocks using EPL payload
2024-09-11 7:32 ` Simon Horman
@ 2024-09-11 12:26 ` Andrew Lunn
2024-09-11 15:41 ` Danielle Ratson
0 siblings, 1 reply; 10+ messages in thread
From: Andrew Lunn @ 2024-09-11 12:26 UTC (permalink / raw)
To: Simon Horman
Cc: Danielle Ratson, netdev, davem, edumazet, kuba, pabeni,
yuehaibing, linux-kernel, petrm
On Wed, Sep 11, 2024 at 08:32:34AM +0100, Simon Horman wrote:
> + Andrew Lunn
>
> On Tue, Sep 10, 2024 at 12:02:17PM +0300, Danielle Ratson wrote:
> > In the CMIS specification for pluggable modules, LPL (Local Payload) and
> > EPL (Extended Payload) are two types of data payloads used for managing
> > various functions and features of the module.
> >
> > EPL payloads are used for more complex and extensive management
> > functions that require a larger amount of data, so writing firmware
> > blocks using EPL is much more efficient.
> >
> > Currently, only LPL payload is supported for writing firmware blocks to
> > the module.
> >
> > Add support for writing firmware block using EPL payload, both to
> > support modules that supports only EPL write mechanism, and to optimize
> > the flashing process of modules that support LPL and EPL.
> >
> > Signed-off-by: Danielle Ratson <danieller@nvidia.com>
> > Reviewed-by: Petr Machata <petrm@nvidia.com>
> > ---
> >
> > Notes:
> > v2:
> > * Initialize the variable 'bytes_written' before the first
> > iteration.
>
> Hi Danielle,
>
> Thanks for the update. From a doing-what-it-says-on-the-wrapper
> perspective, this looks good to me.
>
> Reviewed-by: Simon Horman <horms@kernel.org>
>
> I do note that there were some questions from Andrew Lunn (CCed) in v1
> regarding the size of transfers over the bus. I see that you responded to
> that. Thanks! But I do wonder if he has any further comments.
I do wounder where the speedup comes from.
> The LPL contains ap to 128 bytes, and the EPL up to 2048
Are 128 consecutive 16 byte transfers per block really faster than 8
consecutive transfers per block? If you have an efficient I2C master,
both should be doing 400Kbp. If the master is inefficient, you end up
with the same amount of dead time on the wire.
And does the standard really say you can fragment the block at the I2C
layer?
I suspect in the end we will have an API between the core and the
driver to ask it what size of block it actually supports. But we can
probably add that when we need it.
Andrew
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH net-next v2 2/2] net: ethtool: Add support for writing firmware blocks using EPL payload
2024-09-11 12:26 ` Andrew Lunn
@ 2024-09-11 15:41 ` Danielle Ratson
2024-09-11 17:38 ` Andrew Lunn
0 siblings, 1 reply; 10+ messages in thread
From: Danielle Ratson @ 2024-09-11 15:41 UTC (permalink / raw)
To: Andrew Lunn, Simon Horman
Cc: netdev@vger.kernel.org, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, yuehaibing@huawei.com,
linux-kernel@vger.kernel.org, Petr Machata
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Wednesday, 11 September 2024 15:26
> To: Simon Horman <horms@kernel.org>
> Cc: Danielle Ratson <danieller@nvidia.com>; netdev@vger.kernel.org;
> davem@davemloft.net; edumazet@google.com; kuba@kernel.org;
> pabeni@redhat.com; yuehaibing@huawei.com; linux-kernel@vger.kernel.org;
> Petr Machata <petrm@nvidia.com>
> Subject: Re: [PATCH net-next v2 2/2] net: ethtool: Add support for writing
> firmware blocks using EPL payload
>
> On Wed, Sep 11, 2024 at 08:32:34AM +0100, Simon Horman wrote:
> > + Andrew Lunn
> >
> > On Tue, Sep 10, 2024 at 12:02:17PM +0300, Danielle Ratson wrote:
> > > In the CMIS specification for pluggable modules, LPL (Local Payload)
> > > and EPL (Extended Payload) are two types of data payloads used for
> > > managing various functions and features of the module.
> > >
> > > EPL payloads are used for more complex and extensive management
> > > functions that require a larger amount of data, so writing firmware
> > > blocks using EPL is much more efficient.
> > >
> > > Currently, only LPL payload is supported for writing firmware blocks
> > > to the module.
> > >
> > > Add support for writing firmware block using EPL payload, both to
> > > support modules that supports only EPL write mechanism, and to
> > > optimize the flashing process of modules that support LPL and EPL.
> > >
> > > Signed-off-by: Danielle Ratson <danieller@nvidia.com>
> > > Reviewed-by: Petr Machata <petrm@nvidia.com>
> > > ---
> > >
> > > Notes:
> > > v2:
> > > * Initialize the variable 'bytes_written' before the first
> > > iteration.
> >
> > Hi Danielle,
> >
> > Thanks for the update. From a doing-what-it-says-on-the-wrapper
> > perspective, this looks good to me.
> >
> > Reviewed-by: Simon Horman <horms@kernel.org>
> >
> > I do note that there were some questions from Andrew Lunn (CCed) in v1
> > regarding the size of transfers over the bus. I see that you responded
> > to that. Thanks! But I do wonder if he has any further comments.
>
> I do wounder where the speedup comes from.
>
> > The LPL contains ap to 128 bytes, and the EPL up to 2048
>
> Are 128 consecutive 16 byte transfers per block really faster than 8
> consecutive transfers per block? If you have an efficient I2C master, both
> should be doing 400Kbp. If the master is inefficient, you end up with the same
> amount of dead time on the wire.
>
> And does the standard really say you can fragment the block at the I2C layer?
>
> I suspect in the end we will have an API between the core and the driver to ask
> it what size of block it actually supports. But we can probably add that when
> we need it.
>
> Andrew
Hi Andrew,
In both cases we transfer the same size of data, which corresponds to the size of the firmware image, to the module.
Moreover, in both cases the same size of data is passing on the wire, which depends on the wire obligations.
But, instead of running #n "0103h: Write FW Block LPL" commands (see section 9.7.4 in CMIS 5.2) with up to 128 bytes, we are running #n/16 "0104h: Write FW Block EPL" commands (see section 9.7.5 in CMIS 5.2) with up to 2048 bytes.
That means that instead of processing #n commands and sending back to the core the status for each one, we do it for only #n/16.
The standard does not say anything about the I2C layer, but the speedup doesn’t lie in that.
Thanks,
Danielle
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2 2/2] net: ethtool: Add support for writing firmware blocks using EPL payload
2024-09-11 15:41 ` Danielle Ratson
@ 2024-09-11 17:38 ` Andrew Lunn
2024-09-13 7:29 ` Danielle Ratson
0 siblings, 1 reply; 10+ messages in thread
From: Andrew Lunn @ 2024-09-11 17:38 UTC (permalink / raw)
To: Danielle Ratson
Cc: Simon Horman, netdev@vger.kernel.org, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
yuehaibing@huawei.com, linux-kernel@vger.kernel.org, Petr Machata
> Hi Andrew,
>
> In both cases we transfer the same size of data, which corresponds to the size of the firmware image, to the module.
> Moreover, in both cases the same size of data is passing on the wire, which depends on the wire obligations.
>
> But, instead of running #n "0103h: Write FW Block LPL" commands (see section 9.7.4 in CMIS 5.2) with up to 128 bytes, we are running #n/16 "0104h: Write FW Block EPL" commands (see section 9.7.5 in CMIS 5.2) with up to 2048 bytes.
> That means that instead of processing #n commands and sending back to the core the status for each one, we do it for only #n/16.
O.K, thanks.
> The standard does not say anything about the I2C layer, but the
> speedup doesn’t lie in that.
What does your hardware do? Can it do 2048 byte I2C bus transfers? Or
is it getting chopped up into smaller chunks?
Thanks
Andrew
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH net-next v2 2/2] net: ethtool: Add support for writing firmware blocks using EPL payload
2024-09-11 17:38 ` Andrew Lunn
@ 2024-09-13 7:29 ` Danielle Ratson
0 siblings, 0 replies; 10+ messages in thread
From: Danielle Ratson @ 2024-09-13 7:29 UTC (permalink / raw)
To: Andrew Lunn
Cc: Simon Horman, netdev@vger.kernel.org, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
yuehaibing@huawei.com, linux-kernel@vger.kernel.org, Petr Machata
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Wednesday, 11 September 2024 20:38
> To: Danielle Ratson <danieller@nvidia.com>
> Cc: Simon Horman <horms@kernel.org>; netdev@vger.kernel.org;
> davem@davemloft.net; edumazet@google.com; kuba@kernel.org;
> pabeni@redhat.com; yuehaibing@huawei.com; linux-kernel@vger.kernel.org;
> Petr Machata <petrm@nvidia.com>
> Subject: Re: [PATCH net-next v2 2/2] net: ethtool: Add support for writing
> firmware blocks using EPL payload
>
> > Hi Andrew,
> >
> > In both cases we transfer the same size of data, which corresponds to the
> size of the firmware image, to the module.
> > Moreover, in both cases the same size of data is passing on the wire, which
> depends on the wire obligations.
> >
> > But, instead of running #n "0103h: Write FW Block LPL" commands (see
> section 9.7.4 in CMIS 5.2) with up to 128 bytes, we are running #n/16
> "0104h: Write FW Block EPL" commands (see section 9.7.5 in CMIS 5.2) with
> up to 2048 bytes.
> > That means that instead of processing #n commands and sending back to
> the core the status for each one, we do it for only #n/16.
>
> O.K, thanks.
>
> > The standard does not say anything about the I2C layer, but the
> > speedup doesn’t lie in that.
>
> What does your hardware do? Can it do 2048 byte I2C bus transfers? Or is it
> getting chopped up into smaller chunks?
No, it can not transfer 2048 bytes in one chunks, it is getting chopped in the driver.
Thanks,
Danielle
>
> Thanks
> Andrew
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next v2 0/2] ethtool: Add support for writing firmware
2024-09-10 9:02 [PATCH net-next v2 0/2] ethtool: Add support for writing firmware Danielle Ratson
2024-09-10 9:02 ` [PATCH net-next v2 1/2] net: ethtool: Add new parameters and a function to support EPL Danielle Ratson
2024-09-10 9:02 ` [PATCH net-next v2 2/2] net: ethtool: Add support for writing firmware blocks using EPL payload Danielle Ratson
@ 2024-09-15 17:17 ` Jakub Kicinski
2 siblings, 0 replies; 10+ messages in thread
From: Jakub Kicinski @ 2024-09-15 17:17 UTC (permalink / raw)
To: Danielle Ratson
Cc: netdev, davem, edumazet, pabeni, yuehaibing, linux-kernel, petrm
On Tue, 10 Sep 2024 12:02:15 +0300 Danielle Ratson wrote:
> In the CMIS specification for pluggable modules, LPL (Local Payload) and
> EPL (Extended Payload) are two types of data payloads used for managing
> various functions and features of the module.
>
> EPL payloads are used for more complex and extensive management functions
> that require a larger amount of data, so writing firmware blocks using EPL
> is much more efficient.
>
> Currently, only LPL payload is supported for writing firmware blocks to
> the module.
>
> Add support for writing firmware block using EPL payload, both to support
> modules that support only EPL write mechanism, and to optimize the flashing
> process of modules that support LPL and EPL.
>
> Running the flashing command on the same sample module using EPL vs. LPL
> showed an improvement of 84%.
this missed 6.12, sorry, I didn't get a clear enough signal form
the discussion to merge it in time
--
pw-bot: defer
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2024-09-15 17:17 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-10 9:02 [PATCH net-next v2 0/2] ethtool: Add support for writing firmware Danielle Ratson
2024-09-10 9:02 ` [PATCH net-next v2 1/2] net: ethtool: Add new parameters and a function to support EPL Danielle Ratson
2024-09-11 7:32 ` Simon Horman
2024-09-10 9:02 ` [PATCH net-next v2 2/2] net: ethtool: Add support for writing firmware blocks using EPL payload Danielle Ratson
2024-09-11 7:32 ` Simon Horman
2024-09-11 12:26 ` Andrew Lunn
2024-09-11 15:41 ` Danielle Ratson
2024-09-11 17:38 ` Andrew Lunn
2024-09-13 7:29 ` Danielle Ratson
2024-09-15 17:17 ` [PATCH net-next v2 0/2] ethtool: Add support for writing firmware Jakub Kicinski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).