mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
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:
committed by
David S. Miller
parent
e19b0a3474
commit
e109d2b204
@@ -1770,6 +1770,49 @@ static int mlx5e_get_module_eeprom(struct net_device *netdev,
|
|||||||
return 0;
|
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,
|
int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
|
||||||
struct ethtool_flash *flash)
|
struct ethtool_flash *flash)
|
||||||
{
|
{
|
||||||
@@ -2159,6 +2202,7 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
|
|||||||
.set_wol = mlx5e_set_wol,
|
.set_wol = mlx5e_set_wol,
|
||||||
.get_module_info = mlx5e_get_module_info,
|
.get_module_info = mlx5e_get_module_info,
|
||||||
.get_module_eeprom = mlx5e_get_module_eeprom,
|
.get_module_eeprom = mlx5e_get_module_eeprom,
|
||||||
|
.get_module_eeprom_by_page = mlx5e_get_module_eeprom_by_page,
|
||||||
.flash_device = mlx5e_flash_device,
|
.flash_device = mlx5e_flash_device,
|
||||||
.get_priv_flags = mlx5e_get_priv_flags,
|
.get_priv_flags = mlx5e_get_priv_flags,
|
||||||
.set_priv_flags = mlx5e_set_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);
|
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,
|
static int mlx5_query_port_pvlc(struct mlx5_core_dev *dev, u32 *pvlc,
|
||||||
int pvlc_size, u8 local_port)
|
int pvlc_size, u8 local_port)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -209,6 +209,8 @@ void mlx5_query_port_fcs(struct mlx5_core_dev *mdev, bool *supported,
|
|||||||
bool *enabled);
|
bool *enabled);
|
||||||
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 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_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out);
|
||||||
int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in);
|
int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in);
|
||||||
|
|||||||
Reference in New Issue
Block a user