Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/mlx5e: ethtool, Add support for EEPROM high pages query

Add the support to read additional EEPROM information from high pages.
Information for modules such as SFF-8436 and SFF-8636:
1) Application select table
2) User writable EEPROM
3) Thresholds and alarms

Signed-off-by: Erez Alfasi <ereza@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>

authored by

Erez Alfasi and committed by
Saeed Mahameed
a708fb7b 0e1a2a3e

+39 -10
+4 -4
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
··· 1561 1561 struct mlx5e_priv *priv = netdev_priv(netdev); 1562 1562 struct mlx5_core_dev *dev = priv->mdev; 1563 1563 int size_read = 0; 1564 - u8 data[4]; 1564 + u8 data[4] = {0}; 1565 1565 1566 1566 size_read = mlx5_query_module_eeprom(dev, 0, 2, data); 1567 1567 if (size_read < 2) ··· 1571 1571 switch (data[0]) { 1572 1572 case MLX5_MODULE_ID_QSFP: 1573 1573 modinfo->type = ETH_MODULE_SFF_8436; 1574 - modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN; 1574 + modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN; 1575 1575 break; 1576 1576 case MLX5_MODULE_ID_QSFP_PLUS: 1577 1577 case MLX5_MODULE_ID_QSFP28: 1578 1578 /* data[1] = revision id */ 1579 1579 if (data[0] == MLX5_MODULE_ID_QSFP28 || data[1] >= 0x3) { 1580 1580 modinfo->type = ETH_MODULE_SFF_8636; 1581 - modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; 1581 + modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN; 1582 1582 } else { 1583 1583 modinfo->type = ETH_MODULE_SFF_8436; 1584 - modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN; 1584 + modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN; 1585 1585 } 1586 1586 break; 1587 1587 case MLX5_MODULE_ID_SFP:
+34 -6
drivers/net/ethernet/mellanox/mlx5/core/port.c
··· 293 293 return 0; 294 294 } 295 295 296 + static int mlx5_eeprom_page(int offset) 297 + { 298 + if (offset < MLX5_EEPROM_PAGE_LENGTH) 299 + /* Addresses between 0-255 - page 00 */ 300 + return 0; 301 + 302 + /* Addresses between 256 - 639 belongs to pages 01, 02 and 03 303 + * For example, offset = 400 belongs to page 02: 304 + * 1 + ((400 - 256)/128) = 2 305 + */ 306 + return 1 + ((offset - MLX5_EEPROM_PAGE_LENGTH) / 307 + MLX5_EEPROM_HIGH_PAGE_LENGTH); 308 + } 309 + 310 + static int mlx5_eeprom_high_page_offset(int page_num) 311 + { 312 + if (!page_num) /* Page 0 always start from low page */ 313 + return 0; 314 + 315 + /* High page */ 316 + return page_num * MLX5_EEPROM_HIGH_PAGE_LENGTH; 317 + } 318 + 296 319 int mlx5_query_module_eeprom(struct mlx5_core_dev *dev, 297 320 u16 offset, u16 size, u8 *data) 298 321 { 322 + int module_num, page_num, status, err; 299 323 u32 out[MLX5_ST_SZ_DW(mcia_reg)]; 300 324 u32 in[MLX5_ST_SZ_DW(mcia_reg)]; 301 - int module_num; 302 325 u16 i2c_addr; 303 - int status; 304 - int err; 305 326 void *ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); 306 327 307 328 err = mlx5_query_module_num(dev, &module_num); ··· 332 311 memset(in, 0, sizeof(in)); 333 312 size = min_t(int, size, MLX5_EEPROM_MAX_BYTES); 334 313 335 - if (offset < MLX5_EEPROM_PAGE_LENGTH && 336 - offset + size > MLX5_EEPROM_PAGE_LENGTH) 314 + /* Get the page number related to the given offset */ 315 + page_num = mlx5_eeprom_page(offset); 316 + 317 + /* Set the right offset according to the page number, 318 + * For page_num > 0, relative offset is always >= 128 (high page). 319 + */ 320 + offset -= mlx5_eeprom_high_page_offset(page_num); 321 + 322 + if (offset + size > MLX5_EEPROM_PAGE_LENGTH) 337 323 /* Cross pages read, read until offset 256 in low page */ 338 324 size -= offset + size - MLX5_EEPROM_PAGE_LENGTH; 339 325 ··· 349 321 MLX5_SET(mcia_reg, in, l, 0); 350 322 MLX5_SET(mcia_reg, in, module, module_num); 351 323 MLX5_SET(mcia_reg, in, i2c_device_address, i2c_addr); 352 - MLX5_SET(mcia_reg, in, page_number, 0); 324 + MLX5_SET(mcia_reg, in, page_number, page_num); 353 325 MLX5_SET(mcia_reg, in, device_address, offset); 354 326 MLX5_SET(mcia_reg, in, size, size); 355 327
+1
include/linux/mlx5/port.h
··· 60 60 #define MLX5_I2C_ADDR_LOW 0x50 61 61 #define MLX5_I2C_ADDR_HIGH 0x51 62 62 #define MLX5_EEPROM_PAGE_LENGTH 256 63 + #define MLX5_EEPROM_HIGH_PAGE_LENGTH 128 63 64 64 65 enum mlx5e_link_mode { 65 66 MLX5E_1000BASE_CX_SGMII = 0,