mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-06 07:34:03 -04:00
ionic: support ethtool get_module_eeprom_by_page
Add support for the newer get_module_eeprom_by_page interface. Only the upper half of the 256 byte page is available for reading, and the firmware puts the two sections into the extended sprom buffer, so a union is used over the extended sprom buffer to make clear which page is to be accessed. With get_module_eeprom_by_page implemented there is no need for the older get_module_info or git_module_eeprom interfaces, so remove them. Reviewed-by: Brett Creeley <brett.creeley@amd.com> Signed-off-by: Shannon Nelson <shannon.nelson@amd.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20250415231317.40616-3-shannon.nelson@amd.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
committed by
Paolo Abeni
parent
c51ab838f5
commit
9c2e17d30b
@@ -948,44 +948,6 @@ static int ionic_get_tunable(struct net_device *netdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ionic_get_module_info(struct net_device *netdev,
|
||||
struct ethtool_modinfo *modinfo)
|
||||
|
||||
{
|
||||
struct ionic_lif *lif = netdev_priv(netdev);
|
||||
struct ionic_dev *idev = &lif->ionic->idev;
|
||||
struct ionic_xcvr_status *xcvr;
|
||||
struct sfp_eeprom_base *sfp;
|
||||
|
||||
xcvr = &idev->port_info->status.xcvr;
|
||||
sfp = (struct sfp_eeprom_base *) xcvr->sprom;
|
||||
|
||||
/* report the module data type and length */
|
||||
switch (sfp->phys_id) {
|
||||
case SFF8024_ID_SFP:
|
||||
modinfo->type = ETH_MODULE_SFF_8079;
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
|
||||
break;
|
||||
case SFF8024_ID_QSFP_8436_8636:
|
||||
case SFF8024_ID_QSFP28_8636:
|
||||
modinfo->type = ETH_MODULE_SFF_8436;
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
|
||||
break;
|
||||
case SFF8024_ID_QSFP_PLUS_CMIS:
|
||||
modinfo->type = ETH_MODULE_SFF_8472;
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
|
||||
break;
|
||||
default:
|
||||
netdev_info(netdev, "unknown xcvr type 0x%02x\n",
|
||||
xcvr->sprom[0]);
|
||||
modinfo->type = 0;
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ionic_do_module_copy(u8 *dst, u8 *src, u32 len)
|
||||
{
|
||||
char tbuf[sizeof_field(struct ionic_xcvr_status, sprom)];
|
||||
@@ -1010,46 +972,43 @@ static int ionic_do_module_copy(u8 *dst, u8 *src, u32 len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ionic_get_module_eeprom(struct net_device *netdev,
|
||||
struct ethtool_eeprom *ee,
|
||||
u8 *data)
|
||||
static int ionic_get_module_eeprom_by_page(struct net_device *netdev,
|
||||
const struct ethtool_module_eeprom *page_data,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct ionic_lif *lif = netdev_priv(netdev);
|
||||
struct ionic_dev *idev = &lif->ionic->idev;
|
||||
u32 start = ee->offset;
|
||||
u32 err = -EINVAL;
|
||||
u32 size = 0;
|
||||
u8 *src;
|
||||
|
||||
if (start < ETH_MODULE_SFF_8079_LEN) {
|
||||
if (start + ee->len > ETH_MODULE_SFF_8079_LEN)
|
||||
size = ETH_MODULE_SFF_8079_LEN - start;
|
||||
else
|
||||
size = ee->len;
|
||||
if (!page_data->length)
|
||||
return -EINVAL;
|
||||
|
||||
src = &idev->port_info->status.xcvr.sprom[start];
|
||||
err = ionic_do_module_copy(data, src, size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
data += size;
|
||||
start += size;
|
||||
if (page_data->bank != 0) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Only bank 0 is supported");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (start >= ETH_MODULE_SFF_8079_LEN &&
|
||||
start < ETH_MODULE_SFF_8472_LEN) {
|
||||
size = ee->len - size;
|
||||
if (start + size > ETH_MODULE_SFF_8472_LEN)
|
||||
size = ETH_MODULE_SFF_8472_LEN - start;
|
||||
|
||||
start -= ETH_MODULE_SFF_8079_LEN;
|
||||
src = &idev->port_info->sprom_epage[start];
|
||||
err = ionic_do_module_copy(data, src, size);
|
||||
if (err)
|
||||
return err;
|
||||
switch (page_data->page) {
|
||||
case 0:
|
||||
src = &idev->port_info->status.xcvr.sprom[page_data->offset];
|
||||
break;
|
||||
case 1:
|
||||
src = &idev->port_info->sprom_page1[page_data->offset - 128];
|
||||
break;
|
||||
case 2:
|
||||
src = &idev->port_info->sprom_page2[page_data->offset - 128];
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return err;
|
||||
memset(page_data->data, 0, page_data->length);
|
||||
err = ionic_do_module_copy(page_data->data, src, page_data->length);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return page_data->length;
|
||||
}
|
||||
|
||||
static int ionic_get_ts_info(struct net_device *netdev,
|
||||
@@ -1197,8 +1156,7 @@ static const struct ethtool_ops ionic_ethtool_ops = {
|
||||
.set_rxfh = ionic_set_rxfh,
|
||||
.get_tunable = ionic_get_tunable,
|
||||
.set_tunable = ionic_set_tunable,
|
||||
.get_module_info = ionic_get_module_info,
|
||||
.get_module_eeprom = ionic_get_module_eeprom,
|
||||
.get_module_eeprom_by_page = ionic_get_module_eeprom_by_page,
|
||||
.get_pauseparam = ionic_get_pauseparam,
|
||||
.set_pauseparam = ionic_set_pauseparam,
|
||||
.get_fecparam = ionic_get_fecparam,
|
||||
|
||||
@@ -2839,7 +2839,9 @@ union ionic_port_identity {
|
||||
* @status: Port status data
|
||||
* @stats: Port statistics data
|
||||
* @mgmt_stats: Port management statistics data
|
||||
* @sprom_epage: Extended Transceiver sprom, high page 1 and 2
|
||||
* @sprom_epage: Extended Transceiver sprom
|
||||
* @sprom_page1: Extended Transceiver sprom, page 1
|
||||
* @sprom_page2: Extended Transceiver sprom, page 2
|
||||
* @rsvd: reserved byte(s)
|
||||
* @pb_stats: uplink pb drop stats
|
||||
*/
|
||||
@@ -2850,7 +2852,13 @@ struct ionic_port_info {
|
||||
struct ionic_port_stats stats;
|
||||
struct ionic_mgmt_port_stats mgmt_stats;
|
||||
};
|
||||
u8 sprom_epage[256];
|
||||
union {
|
||||
u8 sprom_epage[256];
|
||||
struct {
|
||||
u8 sprom_page1[128];
|
||||
u8 sprom_page2[128];
|
||||
};
|
||||
};
|
||||
u8 rsvd[504];
|
||||
|
||||
/* pb_stats must start at 2k offset */
|
||||
|
||||
Reference in New Issue
Block a user