提交 2ea10903 编写于 作者: A Arkadi Sharshevsky 提交者: David S. Miller

mlxsw: spectrum: Add support for access cable info via ethtool

Add support for access cable info via ethtool.
Signed-off-by: NArkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: NJiri Pirko <jiri@mellanox.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 7ca36994
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -2519,6 +2519,135 @@ static int mlxsw_sp_flash_device(struct net_device *dev,
return err;
}
#define MLXSW_SP_QSFP_I2C_ADDR 0x50
static int mlxsw_sp_query_module_eeprom(struct mlxsw_sp_port *mlxsw_sp_port,
u16 offset, u16 size, void *data,
unsigned int *p_read_size)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
char eeprom_tmp[MLXSW_SP_REG_MCIA_EEPROM_SIZE];
char mcia_pl[MLXSW_REG_MCIA_LEN];
int status;
int err;
size = min_t(u16, size, MLXSW_SP_REG_MCIA_EEPROM_SIZE);
mlxsw_reg_mcia_pack(mcia_pl, mlxsw_sp_port->mapping.module,
0, 0, offset, size, MLXSW_SP_QSFP_I2C_ADDR);
err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mcia), mcia_pl);
if (err)
return err;
status = mlxsw_reg_mcia_status_get(mcia_pl);
if (status)
return -EIO;
mlxsw_reg_mcia_eeprom_memcpy_from(mcia_pl, eeprom_tmp);
memcpy(data, eeprom_tmp, size);
*p_read_size = size;
return 0;
}
enum mlxsw_sp_eeprom_module_info_rev_id {
MLXSW_SP_EEPROM_MODULE_INFO_REV_ID_UNSPC = 0x00,
MLXSW_SP_EEPROM_MODULE_INFO_REV_ID_8436 = 0x01,
MLXSW_SP_EEPROM_MODULE_INFO_REV_ID_8636 = 0x03,
};
enum mlxsw_sp_eeprom_module_info_id {
MLXSW_SP_EEPROM_MODULE_INFO_ID_SFP = 0x03,
MLXSW_SP_EEPROM_MODULE_INFO_ID_QSFP = 0x0C,
MLXSW_SP_EEPROM_MODULE_INFO_ID_QSFP_PLUS = 0x0D,
MLXSW_SP_EEPROM_MODULE_INFO_ID_QSFP28 = 0x11,
};
enum mlxsw_sp_eeprom_module_info {
MLXSW_SP_EEPROM_MODULE_INFO_ID,
MLXSW_SP_EEPROM_MODULE_INFO_REV_ID,
MLXSW_SP_EEPROM_MODULE_INFO_SIZE,
};
static int mlxsw_sp_get_module_info(struct net_device *netdev,
struct ethtool_modinfo *modinfo)
{
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
u8 module_info[MLXSW_SP_EEPROM_MODULE_INFO_SIZE];
u8 module_rev_id, module_id;
unsigned int read_size;
int err;
err = mlxsw_sp_query_module_eeprom(mlxsw_sp_port, 0,
MLXSW_SP_EEPROM_MODULE_INFO_SIZE,
module_info, &read_size);
if (err)
return err;
if (read_size < MLXSW_SP_EEPROM_MODULE_INFO_SIZE)
return -EIO;
module_rev_id = module_info[MLXSW_SP_EEPROM_MODULE_INFO_REV_ID];
module_id = module_info[MLXSW_SP_EEPROM_MODULE_INFO_ID];
switch (module_id) {
case MLXSW_SP_EEPROM_MODULE_INFO_ID_QSFP:
modinfo->type = ETH_MODULE_SFF_8436;
modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
break;
case MLXSW_SP_EEPROM_MODULE_INFO_ID_QSFP_PLUS:
case MLXSW_SP_EEPROM_MODULE_INFO_ID_QSFP28:
if (module_id == MLXSW_SP_EEPROM_MODULE_INFO_ID_QSFP28 ||
module_rev_id >= MLXSW_SP_EEPROM_MODULE_INFO_REV_ID_8636) {
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
} else {
modinfo->type = ETH_MODULE_SFF_8436;
modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
}
break;
case MLXSW_SP_EEPROM_MODULE_INFO_ID_SFP:
modinfo->type = ETH_MODULE_SFF_8472;
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
break;
default:
return -EINVAL;
}
return 0;
}
static int mlxsw_sp_get_module_eeprom(struct net_device *netdev,
struct ethtool_eeprom *ee,
u8 *data)
{
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
int offset = ee->offset;
unsigned int read_size;
int i = 0;
int err;
if (!ee->len)
return -EINVAL;
memset(data, 0, ee->len);
while (i < ee->len) {
err = mlxsw_sp_query_module_eeprom(mlxsw_sp_port, offset,
ee->len - i, data + i,
&read_size);
if (err) {
netdev_err(mlxsw_sp_port->dev, "Eeprom query failed\n");
return err;
}
i += read_size;
offset += read_size;
}
return 0;
}
static const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {
.get_drvinfo = mlxsw_sp_port_get_drvinfo,
.get_link = ethtool_op_get_link,
......@@ -2531,6 +2660,8 @@ static const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {
.get_link_ksettings = mlxsw_sp_port_get_link_ksettings,
.set_link_ksettings = mlxsw_sp_port_set_link_ksettings,
.flash_device = mlxsw_sp_flash_device,
.get_module_info = mlxsw_sp_get_module_info,
.get_module_eeprom = mlxsw_sp_get_module_eeprom,
};
static int
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部