net/mlx5: Implement get_module_eeprom_by_page()
Implement ethtool_ops::get_module_eeprom_by_page() to enable support of new SFP standards. Signed-off-by: Vladyslav Tarasiuk <vladyslavt@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e19b0a3474
commit
e109d2b204
@ -1770,6 +1770,49 @@ static int mlx5e_get_module_eeprom(struct net_device *netdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlx5e_get_module_eeprom_by_page(struct net_device *netdev,
|
||||
const struct ethtool_module_eeprom *page_data,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(netdev);
|
||||
struct mlx5_module_eeprom_query_params query;
|
||||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
u8 *data = page_data->data;
|
||||
int size_read;
|
||||
int i = 0;
|
||||
|
||||
if (!page_data->length)
|
||||
return -EINVAL;
|
||||
|
||||
memset(data, 0, page_data->length);
|
||||
|
||||
query.offset = page_data->offset;
|
||||
query.i2c_address = page_data->i2c_address;
|
||||
query.bank = page_data->bank;
|
||||
query.page = page_data->page;
|
||||
while (i < page_data->length) {
|
||||
query.size = page_data->length - i;
|
||||
size_read = mlx5_query_module_eeprom_by_page(mdev, &query, data + i);
|
||||
|
||||
/* Done reading, return how many bytes was read */
|
||||
if (!size_read)
|
||||
return i;
|
||||
|
||||
if (size_read == -EINVAL)
|
||||
return -EINVAL;
|
||||
if (size_read < 0) {
|
||||
netdev_err(priv->netdev, "%s: mlx5_query_module_eeprom_by_page failed:0x%x\n",
|
||||
__func__, size_read);
|
||||
return i;
|
||||
}
|
||||
|
||||
i += size_read;
|
||||
query.offset += size_read;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
|
||||
struct ethtool_flash *flash)
|
||||
{
|
||||
@ -2159,6 +2202,7 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
|
||||
.set_wol = mlx5e_set_wol,
|
||||
.get_module_info = mlx5e_get_module_info,
|
||||
.get_module_eeprom = mlx5e_get_module_eeprom,
|
||||
.get_module_eeprom_by_page = mlx5e_get_module_eeprom_by_page,
|
||||
.flash_device = mlx5e_flash_device,
|
||||
.get_priv_flags = mlx5e_get_priv_flags,
|
||||
.set_priv_flags = mlx5e_set_priv_flags,
|
||||
|
@ -428,6 +428,47 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_query_module_eeprom);
|
||||
|
||||
int mlx5_query_module_eeprom_by_page(struct mlx5_core_dev *dev,
|
||||
struct mlx5_module_eeprom_query_params *params,
|
||||
u8 *data)
|
||||
{
|
||||
u8 module_id;
|
||||
int err;
|
||||
|
||||
err = mlx5_query_module_num(dev, ¶ms->module_number);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mlx5_query_module_id(dev, params->module_number, &module_id);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
switch (module_id) {
|
||||
case MLX5_MODULE_ID_SFP:
|
||||
if (params->page > 0)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case MLX5_MODULE_ID_QSFP:
|
||||
case MLX5_MODULE_ID_QSFP28:
|
||||
case MLX5_MODULE_ID_QSFP_PLUS:
|
||||
if (params->page > 3)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
mlx5_core_err(dev, "Module ID not recognized: 0x%x\n", module_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (params->i2c_address != MLX5_I2C_ADDR_HIGH &&
|
||||
params->i2c_address != MLX5_I2C_ADDR_LOW) {
|
||||
mlx5_core_err(dev, "I2C address not recognized: 0x%x\n", params->i2c_address);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return mlx5_query_mcia(dev, params, data);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_query_module_eeprom_by_page);
|
||||
|
||||
static int mlx5_query_port_pvlc(struct mlx5_core_dev *dev, u32 *pvlc,
|
||||
int pvlc_size, u8 local_port)
|
||||
{
|
||||
|
@ -209,6 +209,8 @@ void mlx5_query_port_fcs(struct mlx5_core_dev *mdev, bool *supported,
|
||||
bool *enabled);
|
||||
int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
|
||||
u16 offset, u16 size, u8 *data);
|
||||
int mlx5_query_module_eeprom_by_page(struct mlx5_core_dev *dev,
|
||||
struct mlx5_module_eeprom_query_params *params, u8 *data);
|
||||
|
||||
int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out);
|
||||
int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in);
|
||||
|
Loading…
Reference in New Issue
Block a user