Skip to content

Commit 1f4aea1

Browse files
idoschkuba-moo
authored andcommitted
mlxsw: core_env: Read transceiver module EEPROM in 128 bytes chunks
Old firmware versions could only read up to 48 bytes from a transceiver module's EEPROM in one go. Newer versions can read up to 128 bytes, resulting in fewer transactions. Query support for the new capability during driver initialization and if supported, read up to 128 bytes in one go. This is going to be especially useful for upcoming transceiver module firmware flashing support. Before: # perf stat -e devlink:devlink_hwmsg -- ethtool -m swp11 page 0x1 offset 128 length 128 i2c 0x50 [...] Performance counter stats for 'ethtool -m swp11 page 0x1 offset 128 length 128 i2c 0x50': 3 devlink:devlink_hwmsg After: # perf stat -e devlink:devlink_hwmsg -- ethtool -m swp11 page 0x1 offset 128 length 128 i2c 0x50 [...] Performance counter stats for 'ethtool -m swp11 page 0x1 offset 128 length 128 i2c 0x50': 1 devlink:devlink_hwmsg Signed-off-by: Ido Schimmel <[email protected]> Reviewed-by: Petr Machata <[email protected]> Signed-off-by: Petr Machata <[email protected]> Link: https://lore.kernel.org/r/99d1618e8cd5acefb2f795dfde1a5b41caa07dcb.1690281940.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent c8dbf67 commit 1f4aea1

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

drivers/net/ethernet/mellanox/mlxsw/core_env.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct mlxsw_env {
3232
const struct mlxsw_bus_info *bus_info;
3333
u8 max_module_count; /* Maximum number of modules per-slot. */
3434
u8 num_of_slots; /* Including the main board. */
35+
u8 max_eeprom_len; /* Maximum module EEPROM transaction length. */
3536
struct mutex line_cards_lock; /* Protects line cards. */
3637
struct mlxsw_env_line_card *line_cards[];
3738
};
@@ -146,18 +147,15 @@ mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, u8 slot_index,
146147
int module, u16 offset, u16 size, void *data,
147148
bool qsfp, unsigned int *p_read_size)
148149
{
150+
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
149151
char mcia_pl[MLXSW_REG_MCIA_LEN];
150152
char *eeprom_tmp;
151153
u16 i2c_addr;
152154
u8 page = 0;
153155
int status;
154156
int err;
155157

156-
/* MCIA register accepts buffer size <= 48. Page of size 128 should be
157-
* read by chunks of size 48, 48, 32. Align the size of the last chunk
158-
* to avoid reading after the end of the page.
159-
*/
160-
size = min_t(u16, size, MLXSW_REG_MCIA_EEPROM_SIZE);
158+
size = min_t(u16, size, mlxsw_env->max_eeprom_len);
161159

162160
if (offset < MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH &&
163161
offset + size > MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH)
@@ -489,7 +487,7 @@ mlxsw_env_get_module_eeprom_by_page(struct mlxsw_core *mlxsw_core,
489487
u8 size;
490488

491489
size = min_t(u8, page->length - bytes_read,
492-
MLXSW_REG_MCIA_EEPROM_SIZE);
490+
mlxsw_env->max_eeprom_len);
493491

494492
mlxsw_reg_mcia_pack(mcia_pl, slot_index, module, page->page,
495493
device_addr + bytes_read, size,
@@ -1359,6 +1357,26 @@ static struct mlxsw_linecards_event_ops mlxsw_env_event_ops = {
13591357
.got_inactive = mlxsw_env_got_inactive,
13601358
};
13611359

1360+
static int mlxsw_env_max_module_eeprom_len_query(struct mlxsw_env *mlxsw_env)
1361+
{
1362+
char mcam_pl[MLXSW_REG_MCAM_LEN];
1363+
bool mcia_128b_supported;
1364+
int err;
1365+
1366+
mlxsw_reg_mcam_pack(mcam_pl,
1367+
MLXSW_REG_MCAM_FEATURE_GROUP_ENHANCED_FEATURES);
1368+
err = mlxsw_reg_query(mlxsw_env->core, MLXSW_REG(mcam), mcam_pl);
1369+
if (err)
1370+
return err;
1371+
1372+
mlxsw_reg_mcam_unpack(mcam_pl, MLXSW_REG_MCAM_MCIA_128B,
1373+
&mcia_128b_supported);
1374+
1375+
mlxsw_env->max_eeprom_len = mcia_128b_supported ? 128 : 48;
1376+
1377+
return 0;
1378+
}
1379+
13621380
int mlxsw_env_init(struct mlxsw_core *mlxsw_core,
13631381
const struct mlxsw_bus_info *bus_info,
13641382
struct mlxsw_env **p_env)
@@ -1427,10 +1445,15 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core,
14271445
if (err)
14281446
goto err_type_set;
14291447

1448+
err = mlxsw_env_max_module_eeprom_len_query(env);
1449+
if (err)
1450+
goto err_eeprom_len_query;
1451+
14301452
env->line_cards[0]->active = true;
14311453

14321454
return 0;
14331455

1456+
err_eeprom_len_query:
14341457
err_type_set:
14351458
mlxsw_env_module_event_disable(env, 0);
14361459
err_mlxsw_env_module_event_enable:

drivers/net/ethernet/mellanox/mlxsw/reg.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9708,7 +9708,6 @@ MLXSW_ITEM32(reg, mcia, size, 0x08, 0, 16);
97089708

97099709
#define MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH 256
97109710
#define MLXSW_REG_MCIA_EEPROM_UP_PAGE_LENGTH 128
9711-
#define MLXSW_REG_MCIA_EEPROM_SIZE 48
97129711
#define MLXSW_REG_MCIA_I2C_ADDR_LOW 0x50
97139712
#define MLXSW_REG_MCIA_I2C_ADDR_HIGH 0x51
97149713
#define MLXSW_REG_MCIA_PAGE0_LO_OFF 0xa0
@@ -9745,7 +9744,7 @@ enum mlxsw_reg_mcia_eeprom_module_info {
97459744
* Bytes to read/write.
97469745
* Access: RW
97479746
*/
9748-
MLXSW_ITEM_BUF(reg, mcia, eeprom, 0x10, MLXSW_REG_MCIA_EEPROM_SIZE);
9747+
MLXSW_ITEM_BUF(reg, mcia, eeprom, 0x10, 128);
97499748

97509749
/* This is used to access the optional upper pages (1-3) in the QSFP+
97519750
* memory map. Page 1 is available on offset 256 through 383, page 2 -

0 commit comments

Comments
 (0)