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>
This commit is contained in:
Родитель
0e1a2a3e6e
Коммит
a708fb7b1f
|
@ -1561,7 +1561,7 @@ static int mlx5e_get_module_info(struct net_device *netdev,
|
||||||
struct mlx5e_priv *priv = netdev_priv(netdev);
|
struct mlx5e_priv *priv = netdev_priv(netdev);
|
||||||
struct mlx5_core_dev *dev = priv->mdev;
|
struct mlx5_core_dev *dev = priv->mdev;
|
||||||
int size_read = 0;
|
int size_read = 0;
|
||||||
u8 data[4];
|
u8 data[4] = {0};
|
||||||
|
|
||||||
size_read = mlx5_query_module_eeprom(dev, 0, 2, data);
|
size_read = mlx5_query_module_eeprom(dev, 0, 2, data);
|
||||||
if (size_read < 2)
|
if (size_read < 2)
|
||||||
|
@ -1571,17 +1571,17 @@ static int mlx5e_get_module_info(struct net_device *netdev,
|
||||||
switch (data[0]) {
|
switch (data[0]) {
|
||||||
case MLX5_MODULE_ID_QSFP:
|
case MLX5_MODULE_ID_QSFP:
|
||||||
modinfo->type = ETH_MODULE_SFF_8436;
|
modinfo->type = ETH_MODULE_SFF_8436;
|
||||||
modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
|
modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
|
||||||
break;
|
break;
|
||||||
case MLX5_MODULE_ID_QSFP_PLUS:
|
case MLX5_MODULE_ID_QSFP_PLUS:
|
||||||
case MLX5_MODULE_ID_QSFP28:
|
case MLX5_MODULE_ID_QSFP28:
|
||||||
/* data[1] = revision id */
|
/* data[1] = revision id */
|
||||||
if (data[0] == MLX5_MODULE_ID_QSFP28 || data[1] >= 0x3) {
|
if (data[0] == MLX5_MODULE_ID_QSFP28 || data[1] >= 0x3) {
|
||||||
modinfo->type = ETH_MODULE_SFF_8636;
|
modinfo->type = ETH_MODULE_SFF_8636;
|
||||||
modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
|
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
|
||||||
} else {
|
} else {
|
||||||
modinfo->type = ETH_MODULE_SFF_8436;
|
modinfo->type = ETH_MODULE_SFF_8436;
|
||||||
modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
|
modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MLX5_MODULE_ID_SFP:
|
case MLX5_MODULE_ID_SFP:
|
||||||
|
|
|
@ -293,15 +293,36 @@ static int mlx5_query_module_num(struct mlx5_core_dev *dev, int *module_num)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mlx5_eeprom_page(int offset)
|
||||||
|
{
|
||||||
|
if (offset < MLX5_EEPROM_PAGE_LENGTH)
|
||||||
|
/* Addresses between 0-255 - page 00 */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Addresses between 256 - 639 belongs to pages 01, 02 and 03
|
||||||
|
* For example, offset = 400 belongs to page 02:
|
||||||
|
* 1 + ((400 - 256)/128) = 2
|
||||||
|
*/
|
||||||
|
return 1 + ((offset - MLX5_EEPROM_PAGE_LENGTH) /
|
||||||
|
MLX5_EEPROM_HIGH_PAGE_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mlx5_eeprom_high_page_offset(int page_num)
|
||||||
|
{
|
||||||
|
if (!page_num) /* Page 0 always start from low page */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* High page */
|
||||||
|
return page_num * MLX5_EEPROM_HIGH_PAGE_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
|
int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
|
||||||
u16 offset, u16 size, u8 *data)
|
u16 offset, u16 size, u8 *data)
|
||||||
{
|
{
|
||||||
|
int module_num, page_num, status, err;
|
||||||
u32 out[MLX5_ST_SZ_DW(mcia_reg)];
|
u32 out[MLX5_ST_SZ_DW(mcia_reg)];
|
||||||
u32 in[MLX5_ST_SZ_DW(mcia_reg)];
|
u32 in[MLX5_ST_SZ_DW(mcia_reg)];
|
||||||
int module_num;
|
|
||||||
u16 i2c_addr;
|
u16 i2c_addr;
|
||||||
int status;
|
|
||||||
int err;
|
|
||||||
void *ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0);
|
void *ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0);
|
||||||
|
|
||||||
err = mlx5_query_module_num(dev, &module_num);
|
err = mlx5_query_module_num(dev, &module_num);
|
||||||
|
@ -311,8 +332,15 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
|
||||||
memset(in, 0, sizeof(in));
|
memset(in, 0, sizeof(in));
|
||||||
size = min_t(int, size, MLX5_EEPROM_MAX_BYTES);
|
size = min_t(int, size, MLX5_EEPROM_MAX_BYTES);
|
||||||
|
|
||||||
if (offset < MLX5_EEPROM_PAGE_LENGTH &&
|
/* Get the page number related to the given offset */
|
||||||
offset + size > MLX5_EEPROM_PAGE_LENGTH)
|
page_num = mlx5_eeprom_page(offset);
|
||||||
|
|
||||||
|
/* Set the right offset according to the page number,
|
||||||
|
* For page_num > 0, relative offset is always >= 128 (high page).
|
||||||
|
*/
|
||||||
|
offset -= mlx5_eeprom_high_page_offset(page_num);
|
||||||
|
|
||||||
|
if (offset + size > MLX5_EEPROM_PAGE_LENGTH)
|
||||||
/* Cross pages read, read until offset 256 in low page */
|
/* Cross pages read, read until offset 256 in low page */
|
||||||
size -= offset + size - MLX5_EEPROM_PAGE_LENGTH;
|
size -= offset + size - MLX5_EEPROM_PAGE_LENGTH;
|
||||||
|
|
||||||
|
@ -321,7 +349,7 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
|
||||||
MLX5_SET(mcia_reg, in, l, 0);
|
MLX5_SET(mcia_reg, in, l, 0);
|
||||||
MLX5_SET(mcia_reg, in, module, module_num);
|
MLX5_SET(mcia_reg, in, module, module_num);
|
||||||
MLX5_SET(mcia_reg, in, i2c_device_address, i2c_addr);
|
MLX5_SET(mcia_reg, in, i2c_device_address, i2c_addr);
|
||||||
MLX5_SET(mcia_reg, in, page_number, 0);
|
MLX5_SET(mcia_reg, in, page_number, page_num);
|
||||||
MLX5_SET(mcia_reg, in, device_address, offset);
|
MLX5_SET(mcia_reg, in, device_address, offset);
|
||||||
MLX5_SET(mcia_reg, in, size, size);
|
MLX5_SET(mcia_reg, in, size, size);
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ enum mlx5_an_status {
|
||||||
#define MLX5_I2C_ADDR_LOW 0x50
|
#define MLX5_I2C_ADDR_LOW 0x50
|
||||||
#define MLX5_I2C_ADDR_HIGH 0x51
|
#define MLX5_I2C_ADDR_HIGH 0x51
|
||||||
#define MLX5_EEPROM_PAGE_LENGTH 256
|
#define MLX5_EEPROM_PAGE_LENGTH 256
|
||||||
|
#define MLX5_EEPROM_HIGH_PAGE_LENGTH 128
|
||||||
|
|
||||||
enum mlx5e_link_mode {
|
enum mlx5e_link_mode {
|
||||||
MLX5E_1000BASE_CX_SGMII = 0,
|
MLX5E_1000BASE_CX_SGMII = 0,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче