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

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
Loading
Loading
Loading
Loading
+67 −27
Original line number Diff line number Diff line
@@ -254,12 +254,9 @@ static int ionic_set_link_ksettings(struct net_device *netdev,
	struct ionic_lif *lif = netdev_priv(netdev);
	struct ionic *ionic = lif->ionic;
	struct ionic_dev *idev;
	u32 req_rs, req_fc;
	u8 fec_type;
	int err = 0;

	idev = &lif->ionic->idev;
	fec_type = IONIC_PORT_FEC_TYPE_NONE;

	/* set autoneg */
	if (ks->base.autoneg != idev->port_info->config.an_enable) {
@@ -281,29 +278,6 @@ static int ionic_set_link_ksettings(struct net_device *netdev,
			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;
}

@@ -353,6 +327,70 @@ static int ionic_set_pauseparam(struct net_device *netdev,
	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,
			      struct ethtool_coalesce *coalesce)
{
@@ -751,6 +789,7 @@ static const struct ethtool_ops ionic_ethtool_ops = {
	.get_regs		= ionic_get_regs,
	.get_link		= ethtool_op_get_link,
	.get_link_ksettings	= ionic_get_link_ksettings,
	.set_link_ksettings	= ionic_set_link_ksettings,
	.get_coalesce		= ionic_get_coalesce,
	.set_coalesce		= ionic_set_coalesce,
	.get_ringparam		= ionic_get_ringparam,
@@ -773,7 +812,8 @@ static const struct ethtool_ops ionic_ethtool_ops = {
	.get_module_eeprom	= ionic_get_module_eeprom,
	.get_pauseparam		= ionic_get_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,
};