diff mbox series

[net,2/2] ethtool: cmis: use u16 for calculated read_write_len_ext

Message ID 20250402183123.321036-3-michael.chan@broadcom.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series ethtool: cmis fixes | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers fail 1 blamed authors not CCed: petrm@nvidia.com; 1 maintainers not CCed: petrm@nvidia.com
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes fail Problems with Fixes tag: 1
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch warning WARNING: Please use correct Fixes: style 'Fixes: <12+ chars of sha1> ("<title line>")' - ie: 'Fixes: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands")' WARNING: line length of 85 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2025-04-04--00-00 (tests: 911)

Commit Message

Michael Chan April 2, 2025, 6:31 p.m. UTC
From: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>

For EPL (Extended Payload), the maximum calculated size returned by
ethtool_cmis_get_max_epl_size() is 2048, so the read_write_len_ext
field in struct ethtool_cmis_cdb_cmd_args needs to be changed to u16
to hold the value.

To avoid confusion with other u8 read_write_len_ext fields defined
by the CMIS spec, change the field name to calc_read_write_len_ext.

Without this change, module flashing can fail:

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: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands)
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Signed-off-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 net/ethtool/cmis.h     | 7 ++++---
 net/ethtool/cmis_cdb.c | 8 ++++----
 2 files changed, 8 insertions(+), 7 deletions(-)

Comments

Simon Horman April 3, 2025, 9:04 a.m. UTC | #1
On Wed, Apr 02, 2025 at 11:31:23AM -0700, Michael Chan wrote:
> From: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
> 
> For EPL (Extended Payload), the maximum calculated size returned by
> ethtool_cmis_get_max_epl_size() is 2048, so the read_write_len_ext
> field in struct ethtool_cmis_cdb_cmd_args needs to be changed to u16
> to hold the value.
> 
> To avoid confusion with other u8 read_write_len_ext fields defined
> by the CMIS spec, change the field name to calc_read_write_len_ext.
> 
> Without this change, module flashing can fail:
> 
> 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: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands)

Hi Damodharam, all,

As per my comment on patch 1/2: I don't think there is any need to resend
for this, but I think there is a '"' missing towards the end of the Fixes
tag above. That is, I think it should look like this.

Fixes: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands")

> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Signed-off-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>

Other than the nit above this looks good to me.

Reviewed-by: Simon Horman <horms@kernel.org>
Ido Schimmel April 3, 2025, 3:03 p.m. UTC | #2
Adding Petr given Danielle is away

On Wed, Apr 02, 2025 at 11:31:23AM -0700, Michael Chan wrote:
> From: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
> 
> For EPL (Extended Payload), the maximum calculated size returned by
> ethtool_cmis_get_max_epl_size() is 2048, so the read_write_len_ext
> field in struct ethtool_cmis_cdb_cmd_args needs to be changed to u16
> to hold the value.
> 
> To avoid confusion with other u8 read_write_len_ext fields defined
> by the CMIS spec, change the field name to calc_read_write_len_ext.
> 
> Without this change, module flashing can fail:
> 
> 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: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands)
> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Signed-off-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>
> ---
>  net/ethtool/cmis.h     | 7 ++++---
>  net/ethtool/cmis_cdb.c | 8 ++++----
>  2 files changed, 8 insertions(+), 7 deletions(-)
> 
> diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
> index 1e790413db0e..51f5d5439e2a 100644
> --- a/net/ethtool/cmis.h
> +++ b/net/ethtool/cmis.h
> @@ -63,8 +63,9 @@ struct ethtool_cmis_cdb_request {
>   * struct ethtool_cmis_cdb_cmd_args - CDB commands execution arguments
>   * @req: CDB command fields as described in the CMIS standard.
>   * @max_duration: Maximum duration time for command completion in msec.
> - * @read_write_len_ext: Allowable additional number of byte octets to the LPL
> - *			in a READ or a WRITE commands.
> + * @calc_read_write_len_ext: Calculated allowable additional number of byte
> + *			     octets to the LPL or EPL in a READ or WRITE CDB
> + *			     command.
>   * @msleep_pre_rpl: Waiting time before checking reply in msec.
>   * @rpl_exp_len: Expected reply length in bytes.
>   * @flags: Validation flags for CDB commands.
> @@ -73,7 +74,7 @@ struct ethtool_cmis_cdb_request {
>  struct ethtool_cmis_cdb_cmd_args {
>  	struct ethtool_cmis_cdb_request req;
>  	u16				max_duration;
> -	u8				read_write_len_ext;
> +	u16				calc_read_write_len_ext;
>  	u8				msleep_pre_rpl;
>  	u8                              rpl_exp_len;
>  	u8				flags;
> diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
> index dba3aa909a95..1f487e1a6347 100644
> --- a/net/ethtool/cmis_cdb.c
> +++ b/net/ethtool/cmis_cdb.c
> @@ -35,13 +35,13 @@ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
>  	args->req.lpl_len = lpl_len;
>  	if (lpl) {
>  		memcpy(args->req.payload, lpl, args->req.lpl_len);
> -		args->read_write_len_ext =
> +		args->calc_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 =
> +		args->calc_read_write_len_ext =
>  			ethtool_cmis_get_max_epl_size(read_write_len_ext);

AFAIU, a size larger than a page (128 bytes) is only useful when auto
paging is supported which is something the kernel doesn't currently
support. Therefore, I think it's misleading to initialize this field to
a value larger than 128.

How about deleting ethtool_cmis_get_max_epl_size() and moving the
initialization of 'args->read_write_len_ext' outside of the if block as
it was before 9a3b0d078bd82?

>  	}
>  
> @@ -590,7 +590,7 @@ ethtool_cmis_cdb_execute_epl_cmd(struct net_device *dev,
>  			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));
> +						     args->calc_read_write_len_ext));
>  
>  			err = __ethtool_cmis_cdb_execute_cmd(dev, page_data,
>  							     page, offset,
> @@ -631,7 +631,7 @@ int ethtool_cmis_cdb_execute_cmd(struct net_device *dev,
>  				       offsetof(struct ethtool_cmis_cdb_request,
>  						epl));
>  
> -	if (args->req.lpl_len > args->read_write_len_ext) {
> +	if (args->req.lpl_len > args->calc_read_write_len_ext) {
>  		args->err_msg = "LPL length is longer than CDB read write length extension allows";
>  		return -EINVAL;
>  	}
> -- 
> 2.30.1
> 
>
Ido Schimmel April 7, 2025, 4:23 p.m. UTC | #3
On Mon, Apr 07, 2025 at 08:09:56AM -0700, Damodharam Ammepalli wrote:
> From: Ido Schimmel <idosch@idosch.org>
> 
> Adding Petr given Danielle is away
> 
> On Wed, Apr 02, 2025 at 11:31:23AM -0700, Michael Chan wrote:
> > From: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
> > 
> > For EPL (Extended Payload), the maximum calculated size returned by
> > ethtool_cmis_get_max_epl_size() is 2048, so the read_write_len_ext
> > field in struct ethtool_cmis_cdb_cmd_args needs to be changed to u16
> > to hold the value.
> > 
> > To avoid confusion with other u8 read_write_len_ext fields defined
> > by the CMIS spec, change the field name to calc_read_write_len_ext.
> > 
> > Without this change, module flashing can fail:
> > 
> > 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: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands)
> > Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> > Signed-off-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
> > Signed-off-by: Michael Chan <michael.chan@broadcom.com>
> > ---
> >  net/ethtool/cmis.h     | 7 ++++---
> >  net/ethtool/cmis_cdb.c | 8 ++++----
> >  2 files changed, 8 insertions(+), 7 deletions(-)
> > 
> > diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
> > index 1e790413db0e..51f5d5439e2a 100644
> > --- a/net/ethtool/cmis.h
> > +++ b/net/ethtool/cmis.h
> > @@ -63,8 +63,9 @@ struct ethtool_cmis_cdb_request {
> >   * struct ethtool_cmis_cdb_cmd_args - CDB commands execution arguments
> >   * @req: CDB command fields as described in the CMIS standard.
> >   * @max_duration: Maximum duration time for command completion in msec.
> > - * @read_write_len_ext: Allowable additional number of byte octets to the LPL
> > - *			in a READ or a WRITE commands.
> > + * @calc_read_write_len_ext: Calculated allowable additional number of byte
> > + *			     octets to the LPL or EPL in a READ or WRITE CDB
> > + *			     command.
> >   * @msleep_pre_rpl: Waiting time before checking reply in msec.
> >   * @rpl_exp_len: Expected reply length in bytes.
> >   * @flags: Validation flags for CDB commands.
> > @@ -73,7 +74,7 @@ struct ethtool_cmis_cdb_request {
> >  struct ethtool_cmis_cdb_cmd_args {
> >  	struct ethtool_cmis_cdb_request req;
> >  	u16				max_duration;
> > -	u8				read_write_len_ext;
> > +	u16				calc_read_write_len_ext;
> >  	u8				msleep_pre_rpl;
> >  	u8                              rpl_exp_len;
> >  	u8				flags;
> > diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
> > index dba3aa909a95..1f487e1a6347 100644
> > --- a/net/ethtool/cmis_cdb.c
> > +++ b/net/ethtool/cmis_cdb.c
> > @@ -35,13 +35,13 @@ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
> >  	args->req.lpl_len = lpl_len;
> >  	if (lpl) {
> >  		memcpy(args->req.payload, lpl, args->req.lpl_len);
> > -		args->read_write_len_ext =
> > +		args->calc_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 =
> > +		args->calc_read_write_len_ext =
> >  			ethtool_cmis_get_max_epl_size(read_write_len_ext);
> 
> AFAIU, a size larger than a page (128 bytes) is only useful when auto
> paging is supported which is something the kernel doesn't currently
> support. Therefore, I think it's misleading to initialize this field to
> a value larger than 128.
> 
> How about deleting ethtool_cmis_get_max_epl_size() and moving the
> initialization of 'args->read_write_len_ext' outside of the if block as
> it was before 9a3b0d078bd82?
> 
> >  	}
> >  
> > @@ -590,7 +590,7 @@ ethtool_cmis_cdb_execute_epl_cmd(struct net_device *dev,
> >  			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));
> > +						     args->calc_read_write_len_ext));
> >  
> >  			err = __ethtool_cmis_cdb_execute_cmd(dev, page_data,
> >  							     page, offset,
> > @@ -631,7 +631,7 @@ int ethtool_cmis_cdb_execute_cmd(struct net_device *dev,
> >  				       offsetof(struct ethtool_cmis_cdb_request,
> >  						epl));
> >  
> > -	if (args->req.lpl_len > args->read_write_len_ext) {
> > +	if (args->req.lpl_len > args->calc_read_write_len_ext) {
> >  		args->err_msg = "LPL length is longer than CDB read write length extension allows";
> >  		return -EINVAL;
> >  	}
> > -- 
> > 2.30.1
> > 
> > 
> 
> This module supports AutoPaging, 255 read_write_len_ext and EPL write mechanism.
> This advertised 0xff (byte2) calculates the args->read_write_len_ext
> to 2048B, which needs u16.
> Hexdump: cmis_cdb_advert_rpl
> Off 0x00 :77 ff 1f 80
> 
> With your suggested change, ethtool_cmis_cdb_execute_epl_cmd() is skipped
> since args->req.epl_len is set to zero and download fails.

To be clear, this is what I'm suggesting [1] and it doesn't involve
setting args->req.epl_len to zero, so I'm not sure what was tested.

Basically, setting maximum length of read or write to 128 bytes as the
kernel does not currently support auto paging (even if the transceiver
module does) and will not try to perform cross-page reads or writes.

[1]
diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
index 1e790413db0e..4a9a946cabf0 100644
--- a/net/ethtool/cmis.h
+++ b/net/ethtool/cmis.h
@@ -101,7 +101,6 @@ struct ethtool_cmis_cdb_rpl {
 };
 
 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 *lpl,
diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
index d159dc121bde..0e2691ccb0df 100644
--- a/net/ethtool/cmis_cdb.c
+++ b/net/ethtool/cmis_cdb.c
@@ -16,15 +16,6 @@ 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 *lpl,
 				   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,
 {
 	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;
Damodharam Ammepalli April 7, 2025, 6:03 p.m. UTC | #4
On Mon, Apr 7, 2025 at 9:23 AM Ido Schimmel <idosch@idosch.org> wrote:
>
> On Mon, Apr 07, 2025 at 08:09:56AM -0700, Damodharam Ammepalli wrote:
> > From: Ido Schimmel <idosch@idosch.org>
> >
> > Adding Petr given Danielle is away
> >
> > On Wed, Apr 02, 2025 at 11:31:23AM -0700, Michael Chan wrote:
> > > From: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
> > >
> > > For EPL (Extended Payload), the maximum calculated size returned by
> > > ethtool_cmis_get_max_epl_size() is 2048, so the read_write_len_ext
> > > field in struct ethtool_cmis_cdb_cmd_args needs to be changed to u16
> > > to hold the value.
> > >
> > > To avoid confusion with other u8 read_write_len_ext fields defined
> > > by the CMIS spec, change the field name to calc_read_write_len_ext.
> > >
> > > Without this change, module flashing can fail:
> > >
> > > 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: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands)
> > > Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> > > Signed-off-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
> > > Signed-off-by: Michael Chan <michael.chan@broadcom.com>
> > > ---
> > >  net/ethtool/cmis.h     | 7 ++++---
> > >  net/ethtool/cmis_cdb.c | 8 ++++----
> > >  2 files changed, 8 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
> > > index 1e790413db0e..51f5d5439e2a 100644
> > > --- a/net/ethtool/cmis.h
> > > +++ b/net/ethtool/cmis.h
> > > @@ -63,8 +63,9 @@ struct ethtool_cmis_cdb_request {
> > >   * struct ethtool_cmis_cdb_cmd_args - CDB commands execution arguments
> > >   * @req: CDB command fields as described in the CMIS standard.
> > >   * @max_duration: Maximum duration time for command completion in msec.
> > > - * @read_write_len_ext: Allowable additional number of byte octets to the LPL
> > > - *                 in a READ or a WRITE commands.
> > > + * @calc_read_write_len_ext: Calculated allowable additional number of byte
> > > + *                      octets to the LPL or EPL in a READ or WRITE CDB
> > > + *                      command.
> > >   * @msleep_pre_rpl: Waiting time before checking reply in msec.
> > >   * @rpl_exp_len: Expected reply length in bytes.
> > >   * @flags: Validation flags for CDB commands.
> > > @@ -73,7 +74,7 @@ struct ethtool_cmis_cdb_request {
> > >  struct ethtool_cmis_cdb_cmd_args {
> > >     struct ethtool_cmis_cdb_request req;
> > >     u16                             max_duration;
> > > -   u8                              read_write_len_ext;
> > > +   u16                             calc_read_write_len_ext;
> > >     u8                              msleep_pre_rpl;
> > >     u8                              rpl_exp_len;
> > >     u8                              flags;
> > > diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
> > > index dba3aa909a95..1f487e1a6347 100644
> > > --- a/net/ethtool/cmis_cdb.c
> > > +++ b/net/ethtool/cmis_cdb.c
> > > @@ -35,13 +35,13 @@ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
> > >     args->req.lpl_len = lpl_len;
> > >     if (lpl) {
> > >             memcpy(args->req.payload, lpl, args->req.lpl_len);
> > > -           args->read_write_len_ext =
> > > +           args->calc_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 =
> > > +           args->calc_read_write_len_ext =
> > >                     ethtool_cmis_get_max_epl_size(read_write_len_ext);
> >
> > AFAIU, a size larger than a page (128 bytes) is only useful when auto
> > paging is supported which is something the kernel doesn't currently
> > support. Therefore, I think it's misleading to initialize this field to
> > a value larger than 128.
> >
> > How about deleting ethtool_cmis_get_max_epl_size() and moving the
> > initialization of 'args->read_write_len_ext' outside of the if block as
> > it was before 9a3b0d078bd82?
> >
> > >     }
> > >
> > > @@ -590,7 +590,7 @@ ethtool_cmis_cdb_execute_epl_cmd(struct net_device *dev,
> > >                     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));
> > > +                                                args->calc_read_write_len_ext));
> > >
> > >                     err = __ethtool_cmis_cdb_execute_cmd(dev, page_data,
> > >                                                          page, offset,
> > > @@ -631,7 +631,7 @@ int ethtool_cmis_cdb_execute_cmd(struct net_device *dev,
> > >                                    offsetof(struct ethtool_cmis_cdb_request,
> > >                                             epl));
> > >
> > > -   if (args->req.lpl_len > args->read_write_len_ext) {
> > > +   if (args->req.lpl_len > args->calc_read_write_len_ext) {
> > >             args->err_msg = "LPL length is longer than CDB read write length extension allows";
> > >             return -EINVAL;
> > >     }
> > > --
> > > 2.30.1
> > >
> > >
> >
> > This module supports AutoPaging, 255 read_write_len_ext and EPL write mechanism.
> > This advertised 0xff (byte2) calculates the args->read_write_len_ext
> > to 2048B, which needs u16.
> > Hexdump: cmis_cdb_advert_rpl
> > Off 0x00 :77 ff 1f 80
> >
> > With your suggested change, ethtool_cmis_cdb_execute_epl_cmd() is skipped
> > since args->req.epl_len is set to zero and download fails.
>
> To be clear, this is what I'm suggesting [1] and it doesn't involve
> setting args->req.epl_len to zero, so I'm not sure what was tested.
>
> Basically, setting maximum length of read or write to 128 bytes as the
> kernel does not currently support auto paging (even if the transceiver
> module does) and will not try to perform cross-page reads or writes.
>
> [1]
> diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
> index 1e790413db0e..4a9a946cabf0 100644
> --- a/net/ethtool/cmis.h
> +++ b/net/ethtool/cmis.h
> @@ -101,7 +101,6 @@ struct ethtool_cmis_cdb_rpl {
>  };
>
>  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 *lpl,
> diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
> index d159dc121bde..0e2691ccb0df 100644
> --- a/net/ethtool/cmis_cdb.c
> +++ b/net/ethtool/cmis_cdb.c
> @@ -16,15 +16,6 @@ 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 *lpl,
>                                    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,
>  {
>         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;

Yes, your change works and here is the diff.
From the comment "before 9a3b0d078bd82", I tried
updating your comments on top of edc344568922. I should
have asked you for clarification.


diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
index 54916c16d13f..4f5ad34af3ea 100644
--- a/net/ethtool/cmis.h
+++ b/net/ethtool/cmis.h
@@ -75,7 +75,7 @@ struct ethtool_cmis_cdb_request {
 struct ethtool_cmis_cdb_cmd_args {
        struct ethtool_cmis_cdb_request req;
        u16                             max_duration;
-       u16                             calc_read_write_len_ext;
+       u8                              read_write_len_ext;
        u8                              msleep_pre_rpl;
        u8                              rpl_exp_len;
        u8                              flags;
diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
index 1f487e1a6347..56c6130fe010 100644
--- a/net/ethtool/cmis_cdb.c
+++ b/net/ethtool/cmis_cdb.c
@@ -16,15 +16,6 @@ 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 *lpl,
                                   u8 lpl_len, u8 *epl, u16 epl_len,
@@ -35,16 +26,13 @@ void ethtool_cmis_cdb_compose_args(struct
ethtool_cmis_cdb_cmd_args *args,
        args->req.lpl_len = lpl_len;
        if (lpl) {
                memcpy(args->req.payload, lpl, args->req.lpl_len);
-               args->calc_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->calc_read_write_len_ext =
-                       ethtool_cmis_get_max_epl_size(read_write_len_ext);
        }
-
+       args->read_write_len_ext =
+                       ethtool_cmis_get_max_lpl_size(read_write_len_ext);
        args->max_duration = max_duration;
        args->msleep_pre_rpl = msleep_pre_rpl;
        args->rpl_exp_len = rpl_exp_len;
@@ -590,7 +578,7 @@ ethtool_cmis_cdb_execute_epl_cmd(struct net_device *dev,
                        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->calc_read_write_len_ext));
+                                                    args->read_write_len_ext));

                        err = __ethtool_cmis_cdb_execute_cmd(dev, page_data,
                                                             page, offset,
@@ -631,7 +619,7 @@ int ethtool_cmis_cdb_execute_cmd(struct net_device *dev,
                                       offsetof(struct ethtool_cmis_cdb_request,
                                                epl));

-       if (args->req.lpl_len > args->calc_read_write_len_ext) {
+       if (args->req.lpl_len > args->read_write_len_ext) {
                args->err_msg = "LPL length is longer than CDB read
write length extension allows";
                return -EINVAL;
        }
diff mbox series

Patch

diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
index 1e790413db0e..51f5d5439e2a 100644
--- a/net/ethtool/cmis.h
+++ b/net/ethtool/cmis.h
@@ -63,8 +63,9 @@  struct ethtool_cmis_cdb_request {
  * struct ethtool_cmis_cdb_cmd_args - CDB commands execution arguments
  * @req: CDB command fields as described in the CMIS standard.
  * @max_duration: Maximum duration time for command completion in msec.
- * @read_write_len_ext: Allowable additional number of byte octets to the LPL
- *			in a READ or a WRITE commands.
+ * @calc_read_write_len_ext: Calculated allowable additional number of byte
+ *			     octets to the LPL or EPL in a READ or WRITE CDB
+ *			     command.
  * @msleep_pre_rpl: Waiting time before checking reply in msec.
  * @rpl_exp_len: Expected reply length in bytes.
  * @flags: Validation flags for CDB commands.
@@ -73,7 +74,7 @@  struct ethtool_cmis_cdb_request {
 struct ethtool_cmis_cdb_cmd_args {
 	struct ethtool_cmis_cdb_request req;
 	u16				max_duration;
-	u8				read_write_len_ext;
+	u16				calc_read_write_len_ext;
 	u8				msleep_pre_rpl;
 	u8                              rpl_exp_len;
 	u8				flags;
diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
index dba3aa909a95..1f487e1a6347 100644
--- a/net/ethtool/cmis_cdb.c
+++ b/net/ethtool/cmis_cdb.c
@@ -35,13 +35,13 @@  void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
 	args->req.lpl_len = lpl_len;
 	if (lpl) {
 		memcpy(args->req.payload, lpl, args->req.lpl_len);
-		args->read_write_len_ext =
+		args->calc_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 =
+		args->calc_read_write_len_ext =
 			ethtool_cmis_get_max_epl_size(read_write_len_ext);
 	}
 
@@ -590,7 +590,7 @@  ethtool_cmis_cdb_execute_epl_cmd(struct net_device *dev,
 			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));
+						     args->calc_read_write_len_ext));
 
 			err = __ethtool_cmis_cdb_execute_cmd(dev, page_data,
 							     page, offset,
@@ -631,7 +631,7 @@  int ethtool_cmis_cdb_execute_cmd(struct net_device *dev,
 				       offsetof(struct ethtool_cmis_cdb_request,
 						epl));
 
-	if (args->req.lpl_len > args->read_write_len_ext) {
+	if (args->req.lpl_len > args->calc_read_write_len_ext) {
 		args->err_msg = "LPL length is longer than CDB read write length extension allows";
 		return -EINVAL;
 	}