Commit e95f922f authored by Shannon Nelson's avatar Shannon Nelson Committed by David S. Miller

ionic: implement ethtool set-fec

Wire up the --set-fec and --show-fec features in the ethtool
callbacks and pull the related code out of set_link_ksettings.
Signed-off-by: default avatarShannon Nelson <snelson@pensando.io>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 780eded3
...@@ -254,12 +254,9 @@ static int ionic_set_link_ksettings(struct net_device *netdev, ...@@ -254,12 +254,9 @@ static int ionic_set_link_ksettings(struct net_device *netdev,
struct ionic_lif *lif = netdev_priv(netdev); struct ionic_lif *lif = netdev_priv(netdev);
struct ionic *ionic = lif->ionic; struct ionic *ionic = lif->ionic;
struct ionic_dev *idev; struct ionic_dev *idev;
u32 req_rs, req_fc;
u8 fec_type;
int err = 0; int err = 0;
idev = &lif->ionic->idev; idev = &lif->ionic->idev;
fec_type = IONIC_PORT_FEC_TYPE_NONE;
/* set autoneg */ /* set autoneg */
if (ks->base.autoneg != idev->port_info->config.an_enable) { if (ks->base.autoneg != idev->port_info->config.an_enable) {
...@@ -281,29 +278,6 @@ static int ionic_set_link_ksettings(struct net_device *netdev, ...@@ -281,29 +278,6 @@ static int ionic_set_link_ksettings(struct net_device *netdev,
return err; return err;
} }
/* set FEC */
req_rs = ethtool_link_ksettings_test_link_mode(ks, advertising, FEC_RS);
req_fc = ethtool_link_ksettings_test_link_mode(ks, advertising, FEC_BASER);
if (req_rs && req_fc) {
netdev_info(netdev, "Only select one FEC mode at a time\n");
return -EINVAL;
} else if (req_fc) {
fec_type = IONIC_PORT_FEC_TYPE_FC;
} else if (req_rs) {
fec_type = IONIC_PORT_FEC_TYPE_RS;
} else if (!(req_rs | req_fc)) {
fec_type = IONIC_PORT_FEC_TYPE_NONE;
}
if (fec_type != idev->port_info->config.fec_type) {
mutex_lock(&ionic->dev_cmd_lock);
ionic_dev_cmd_port_fec(idev, fec_type);
err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
mutex_unlock(&ionic->dev_cmd_lock);
if (err)
return err;
}
return 0; return 0;
} }
...@@ -353,6 +327,70 @@ static int ionic_set_pauseparam(struct net_device *netdev, ...@@ -353,6 +327,70 @@ static int ionic_set_pauseparam(struct net_device *netdev,
return 0; return 0;
} }
static int ionic_get_fecparam(struct net_device *netdev,
struct ethtool_fecparam *fec)
{
struct ionic_lif *lif = netdev_priv(netdev);
switch (lif->ionic->idev.port_info->config.fec_type) {
case IONIC_PORT_FEC_TYPE_NONE:
fec->active_fec = ETHTOOL_FEC_OFF;
break;
case IONIC_PORT_FEC_TYPE_RS:
fec->active_fec = ETHTOOL_FEC_RS;
break;
case IONIC_PORT_FEC_TYPE_FC:
fec->active_fec = ETHTOOL_FEC_BASER;
break;
}
fec->fec = ETHTOOL_FEC_OFF | ETHTOOL_FEC_RS | ETHTOOL_FEC_BASER;
return 0;
}
static int ionic_set_fecparam(struct net_device *netdev,
struct ethtool_fecparam *fec)
{
struct ionic_lif *lif = netdev_priv(netdev);
u8 fec_type;
int ret = 0;
if (lif->ionic->idev.port_info->config.an_enable) {
netdev_err(netdev, "FEC request not allowed while autoneg is enabled\n");
return -EINVAL;
}
switch (fec->fec) {
case ETHTOOL_FEC_NONE:
fec_type = IONIC_PORT_FEC_TYPE_NONE;
break;
case ETHTOOL_FEC_OFF:
fec_type = IONIC_PORT_FEC_TYPE_NONE;
break;
case ETHTOOL_FEC_RS:
fec_type = IONIC_PORT_FEC_TYPE_RS;
break;
case ETHTOOL_FEC_BASER:
fec_type = IONIC_PORT_FEC_TYPE_FC;
break;
case ETHTOOL_FEC_AUTO:
default:
netdev_err(netdev, "FEC request 0x%04x not supported\n",
fec->fec);
return -EINVAL;
}
if (fec_type != lif->ionic->idev.port_info->config.fec_type) {
mutex_lock(&lif->ionic->dev_cmd_lock);
ionic_dev_cmd_port_fec(&lif->ionic->idev, fec_type);
ret = ionic_dev_cmd_wait(lif->ionic, DEVCMD_TIMEOUT);
mutex_unlock(&lif->ionic->dev_cmd_lock);
}
return ret;
}
static int ionic_get_coalesce(struct net_device *netdev, static int ionic_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coalesce) struct ethtool_coalesce *coalesce)
{ {
...@@ -751,6 +789,7 @@ static const struct ethtool_ops ionic_ethtool_ops = { ...@@ -751,6 +789,7 @@ static const struct ethtool_ops ionic_ethtool_ops = {
.get_regs = ionic_get_regs, .get_regs = ionic_get_regs,
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
.get_link_ksettings = ionic_get_link_ksettings, .get_link_ksettings = ionic_get_link_ksettings,
.set_link_ksettings = ionic_set_link_ksettings,
.get_coalesce = ionic_get_coalesce, .get_coalesce = ionic_get_coalesce,
.set_coalesce = ionic_set_coalesce, .set_coalesce = ionic_set_coalesce,
.get_ringparam = ionic_get_ringparam, .get_ringparam = ionic_get_ringparam,
...@@ -773,7 +812,8 @@ static const struct ethtool_ops ionic_ethtool_ops = { ...@@ -773,7 +812,8 @@ static const struct ethtool_ops ionic_ethtool_ops = {
.get_module_eeprom = ionic_get_module_eeprom, .get_module_eeprom = ionic_get_module_eeprom,
.get_pauseparam = ionic_get_pauseparam, .get_pauseparam = ionic_get_pauseparam,
.set_pauseparam = ionic_set_pauseparam, .set_pauseparam = ionic_set_pauseparam,
.set_link_ksettings = ionic_set_link_ksettings, .get_fecparam = ionic_get_fecparam,
.set_fecparam = ionic_set_fecparam,
.nway_reset = ionic_nway_reset, .nway_reset = ionic_nway_reset,
}; };
......
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