mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 12:03:54 +02:00
Merge branch 'ionic-support-qsfp-cmis'
Shannon Nelson says: ==================== ionic: support QSFP CMIS This patchset sets up support for additional pages and better handling of the QSFP CMIS data. v1: https://lore.kernel.org/netdev/20250411182140.63158-1-shannon.nelson@amd.com/ ==================== Link: https://patch.msgid.link/20250415231317.40616-1-shannon.nelson@amd.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
a86aa9c247
|
|
@ -948,64 +948,20 @@ 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)
|
||||
|
||||
static int ionic_do_module_copy(u8 *dst, u8 *src, u32 len)
|
||||
{
|
||||
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:
|
||||
case SFF8024_ID_QSFP_PLUS_CMIS:
|
||||
modinfo->type = ETH_MODULE_SFF_8436;
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8436_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_get_module_eeprom(struct net_device *netdev,
|
||||
struct ethtool_eeprom *ee,
|
||||
u8 *data)
|
||||
{
|
||||
struct ionic_lif *lif = netdev_priv(netdev);
|
||||
struct ionic_dev *idev = &lif->ionic->idev;
|
||||
struct ionic_xcvr_status *xcvr;
|
||||
char tbuf[sizeof(xcvr->sprom)];
|
||||
char tbuf[sizeof_field(struct ionic_xcvr_status, sprom)];
|
||||
int count = 10;
|
||||
u32 len;
|
||||
|
||||
/* The NIC keeps the module prom up-to-date in the DMA space
|
||||
* so we can simply copy the module bytes into the data buffer.
|
||||
*/
|
||||
xcvr = &idev->port_info->status.xcvr;
|
||||
len = min_t(u32, sizeof(xcvr->sprom), ee->len);
|
||||
|
||||
do {
|
||||
memcpy(data, &xcvr->sprom[ee->offset], len);
|
||||
memcpy(tbuf, &xcvr->sprom[ee->offset], len);
|
||||
memcpy(dst, src, len);
|
||||
memcpy(tbuf, src, len);
|
||||
|
||||
/* Let's make sure we got a consistent copy */
|
||||
if (!memcmp(data, tbuf, len))
|
||||
if (!memcmp(dst, tbuf, len))
|
||||
break;
|
||||
|
||||
} while (--count);
|
||||
|
|
@ -1016,6 +972,48 @@ static int ionic_get_module_eeprom(struct net_device *netdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
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 err = -EINVAL;
|
||||
u8 *src;
|
||||
|
||||
if (!page_data->length)
|
||||
return -EINVAL;
|
||||
|
||||
if (page_data->bank != 0) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Only bank 0 is supported");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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;
|
||||
case 17:
|
||||
src = &idev->port_info->sprom_page17[page_data->offset - 128];
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
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,
|
||||
struct kernel_ethtool_ts_info *info)
|
||||
{
|
||||
|
|
@ -1161,8 +1159,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,6 +2839,10 @@ union ionic_port_identity {
|
|||
* @status: Port status data
|
||||
* @stats: Port statistics data
|
||||
* @mgmt_stats: Port management statistics data
|
||||
* @sprom_epage: Extended Transceiver sprom
|
||||
* @sprom_page1: Extended Transceiver sprom, page 1
|
||||
* @sprom_page2: Extended Transceiver sprom, page 2
|
||||
* @sprom_page17: Extended Transceiver sprom, page 17
|
||||
* @rsvd: reserved byte(s)
|
||||
* @pb_stats: uplink pb drop stats
|
||||
*/
|
||||
|
|
@ -2849,8 +2853,17 @@ struct ionic_port_info {
|
|||
struct ionic_port_stats stats;
|
||||
struct ionic_mgmt_port_stats mgmt_stats;
|
||||
};
|
||||
/* room for pb_stats to start at 2k offset */
|
||||
u8 rsvd[760];
|
||||
union {
|
||||
u8 sprom_epage[384];
|
||||
struct {
|
||||
u8 sprom_page1[128];
|
||||
u8 sprom_page2[128];
|
||||
u8 sprom_page17[128];
|
||||
};
|
||||
};
|
||||
u8 rsvd[376];
|
||||
|
||||
/* pb_stats must start at 2k offset */
|
||||
struct ionic_port_pb_stats pb_stats;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user