> +static int ionic_get_link_ksettings(struct net_device *netdev, > + struct ethtool_link_ksettings *ks) > +{ > + struct lif *lif = netdev_priv(netdev); > + struct ionic_dev *idev = &lif->ionic->idev; > + int copper_seen = 0; > + > + ethtool_link_ksettings_zero_link_mode(ks, supported); > + ethtool_link_ksettings_zero_link_mode(ks, advertising); > + > + switch (le16_to_cpu(idev->port_info->status.xcvr.pid)) { > + /* Copper */ > + case XCVR_PID_QSFP_100G_CR4: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 100000baseCR4_Full); > + copper_seen++; > + break; > + case XCVR_PID_QSFP_40GBASE_CR4: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 40000baseCR4_Full); > + copper_seen++; > + break; > + case XCVR_PID_SFP_25GBASE_CR_S: > + case XCVR_PID_SFP_25GBASE_CR_L: > + case XCVR_PID_SFP_25GBASE_CR_N: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 25000baseCR_Full); > + copper_seen++; > + break; > + case XCVR_PID_SFP_10GBASE_AOC: > + case XCVR_PID_SFP_10GBASE_CU: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 10000baseCR_Full); > + copper_seen++; > + break; > + > + /* Fibre */ > + case XCVR_PID_QSFP_100G_SR4: > + case XCVR_PID_QSFP_100G_AOC: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 100000baseSR4_Full); > + break; > + case XCVR_PID_QSFP_100G_LR4: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 100000baseLR4_ER4_Full); > + break; > + case XCVR_PID_QSFP_100G_ER4: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 100000baseLR4_ER4_Full); > + break; > + case XCVR_PID_QSFP_40GBASE_SR4: > + case XCVR_PID_QSFP_40GBASE_AOC: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 40000baseSR4_Full); > + break; > + case XCVR_PID_QSFP_40GBASE_LR4: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 40000baseLR4_Full); > + break; > + case XCVR_PID_SFP_25GBASE_SR: > + case XCVR_PID_SFP_25GBASE_AOC: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 25000baseSR_Full); > + break; > + case XCVR_PID_SFP_10GBASE_SR: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 10000baseSR_Full); > + break; > + case XCVR_PID_SFP_10GBASE_LR: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 10000baseLR_Full); > + break; > + case XCVR_PID_SFP_10GBASE_LRM: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 10000baseLRM_Full); > + break; > + case XCVR_PID_SFP_10GBASE_ER: > + ethtool_link_ksettings_add_link_mode(ks, supported, > + 10000baseER_Full); > + break;
I don't know these link modes too well. But only setting a single bit seems odd. What i do know is that an SFP which supports 2500BaseX should also be able to support 1000BaseX. So should a 100G SFP also support 40G, 25G, 10G etc? The SERDES just runs a slower bitstream over the basic bitpipe? > + case XCVR_PID_QSFP_100G_ACC: > + case XCVR_PID_QSFP_40GBASE_ER4: > + case XCVR_PID_SFP_25GBASE_LR: > + case XCVR_PID_SFP_25GBASE_ER: > + dev_info(lif->ionic->dev, "no decode bits for xcvr type pid=%d > / 0x%x\n", > + idev->port_info->status.xcvr.pid, > + idev->port_info->status.xcvr.pid); > + break; Why not add them? > + memcpy(ks->link_modes.advertising, ks->link_modes.supported, > + sizeof(ks->link_modes.advertising)); bitmap_copy() would be a better way to do this. You could consider adding a helper to ethtool.h. Andrew