Commit e109d2b2 authored by Vladyslav Tarasiuk's avatar Vladyslav Tarasiuk Committed by David S. Miller

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: default avatarVladyslav Tarasiuk <vladyslavt@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e19b0a34
......@@ -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, &params->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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment