Skip to content

Commit eaa517b

Browse files
idoschPaolo Abeni
authored andcommitted
ethtool: cmis_cdb: Fix incorrect read / write length extension
The 'read_write_len_ext' field in 'struct ethtool_cmis_cdb_cmd_args' stores the maximum number of bytes that can be read from or written to the Local Payload (LPL) page in a single multi-byte access. Cited commit started overwriting this field with the maximum number of bytes that can be read from or written to the Extended Payload (LPL) pages in a single multi-byte access. Transceiver modules that support auto paging can advertise a number larger than 255 which is problematic as 'read_write_len_ext' is a 'u8', resulting in the number getting truncated and firmware flashing failing [1]. Fix by ignoring the maximum EPL access size as the kernel does not currently support auto paging (even if the transceiver module does) and will not try to read / write more than 128 bytes at once. [1] Transceiver module firmware flashing started for device enp177s0np0 Transceiver module firmware flashing in progress for device enp177s0np0 Progress: 0% Transceiver module firmware flashing encountered an error for device enp177s0np0 Status message: Write FW block EPL command failed, LPL length is longer than CDB read write length extension allows. Fixes: 9a3b0d0 ("net: ethtool: Add support for writing firmware blocks using EPL payload") Reported-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com> Closes: https://lore.kernel.org/netdev/20250402183123.321036-3-michael.chan@broadcom.com/ Tested-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com> Reviewed-by: Petr Machata <petrm@nvidia.com> Link: https://patch.msgid.link/20250409112440.365672-1-idosch@nvidia.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 69ddc65 commit eaa517b

File tree

2 files changed

+3
-16
lines changed

2 files changed

+3
-16
lines changed

net/ethtool/cmis.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ struct ethtool_cmis_cdb_rpl {
101101
};
102102

103103
u32 ethtool_cmis_get_max_lpl_size(u8 num_of_byte_octs);
104-
u32 ethtool_cmis_get_max_epl_size(u8 num_of_byte_octs);
105104

106105
void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
107106
enum ethtool_cmis_cdb_cmd_id cmd, u8 *lpl,

net/ethtool/cmis_cdb.c

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,6 @@ u32 ethtool_cmis_get_max_lpl_size(u8 num_of_byte_octs)
1616
return 8 * (1 + min_t(u8, num_of_byte_octs, 15));
1717
}
1818

19-
/* For accessing the EPL field on page 9Fh, the allowable length extension is
20-
* min(i, 255) byte octets where i specifies the allowable additional number of
21-
* byte octets in a READ or a WRITE.
22-
*/
23-
u32 ethtool_cmis_get_max_epl_size(u8 num_of_byte_octs)
24-
{
25-
return 8 * (1 + min_t(u8, num_of_byte_octs, 255));
26-
}
27-
2819
void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
2920
enum ethtool_cmis_cdb_cmd_id cmd, u8 *lpl,
3021
u8 lpl_len, u8 *epl, u16 epl_len,
@@ -33,19 +24,16 @@ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
3324
{
3425
args->req.id = cpu_to_be16(cmd);
3526
args->req.lpl_len = lpl_len;
36-
if (lpl) {
27+
if (lpl)
3728
memcpy(args->req.payload, lpl, args->req.lpl_len);
38-
args->read_write_len_ext =
39-
ethtool_cmis_get_max_lpl_size(read_write_len_ext);
40-
}
4129
if (epl) {
4230
args->req.epl_len = cpu_to_be16(epl_len);
4331
args->req.epl = epl;
44-
args->read_write_len_ext =
45-
ethtool_cmis_get_max_epl_size(read_write_len_ext);
4632
}
4733

4834
args->max_duration = max_duration;
35+
args->read_write_len_ext =
36+
ethtool_cmis_get_max_lpl_size(read_write_len_ext);
4937
args->msleep_pre_rpl = msleep_pre_rpl;
5038
args->rpl_exp_len = rpl_exp_len;
5139
args->flags = flags;

0 commit comments

Comments
 (0)