cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ionic_ethtool.c (27970B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */
      3
      4#include <linux/module.h>
      5#include <linux/netdevice.h>
      6#include <linux/sfp.h>
      7
      8#include "ionic.h"
      9#include "ionic_bus.h"
     10#include "ionic_lif.h"
     11#include "ionic_ethtool.h"
     12#include "ionic_stats.h"
     13
     14static void ionic_get_stats_strings(struct ionic_lif *lif, u8 *buf)
     15{
     16	u32 i;
     17
     18	for (i = 0; i < ionic_num_stats_grps; i++)
     19		ionic_stats_groups[i].get_strings(lif, &buf);
     20}
     21
     22static void ionic_get_stats(struct net_device *netdev,
     23			    struct ethtool_stats *stats, u64 *buf)
     24{
     25	struct ionic_lif *lif = netdev_priv(netdev);
     26	u32 i;
     27
     28	if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
     29		return;
     30
     31	memset(buf, 0, stats->n_stats * sizeof(*buf));
     32	for (i = 0; i < ionic_num_stats_grps; i++)
     33		ionic_stats_groups[i].get_values(lif, &buf);
     34}
     35
     36static int ionic_get_stats_count(struct ionic_lif *lif)
     37{
     38	int i, num_stats = 0;
     39
     40	for (i = 0; i < ionic_num_stats_grps; i++)
     41		num_stats += ionic_stats_groups[i].get_count(lif);
     42
     43	return num_stats;
     44}
     45
     46static int ionic_get_sset_count(struct net_device *netdev, int sset)
     47{
     48	struct ionic_lif *lif = netdev_priv(netdev);
     49	int count = 0;
     50
     51	switch (sset) {
     52	case ETH_SS_STATS:
     53		count = ionic_get_stats_count(lif);
     54		break;
     55	}
     56	return count;
     57}
     58
     59static void ionic_get_strings(struct net_device *netdev,
     60			      u32 sset, u8 *buf)
     61{
     62	struct ionic_lif *lif = netdev_priv(netdev);
     63
     64	switch (sset) {
     65	case ETH_SS_STATS:
     66		ionic_get_stats_strings(lif, buf);
     67		break;
     68	}
     69}
     70
     71static void ionic_get_drvinfo(struct net_device *netdev,
     72			      struct ethtool_drvinfo *drvinfo)
     73{
     74	struct ionic_lif *lif = netdev_priv(netdev);
     75	struct ionic *ionic = lif->ionic;
     76
     77	strscpy(drvinfo->driver, IONIC_DRV_NAME, sizeof(drvinfo->driver));
     78	strscpy(drvinfo->fw_version, ionic->idev.dev_info.fw_version,
     79		sizeof(drvinfo->fw_version));
     80	strscpy(drvinfo->bus_info, ionic_bus_info(ionic),
     81		sizeof(drvinfo->bus_info));
     82}
     83
     84static int ionic_get_regs_len(struct net_device *netdev)
     85{
     86	return (IONIC_DEV_INFO_REG_COUNT + IONIC_DEV_CMD_REG_COUNT) * sizeof(u32);
     87}
     88
     89static void ionic_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
     90			   void *p)
     91{
     92	struct ionic_lif *lif = netdev_priv(netdev);
     93	unsigned int offset;
     94	unsigned int size;
     95
     96	regs->version = IONIC_DEV_CMD_REG_VERSION;
     97
     98	offset = 0;
     99	size = IONIC_DEV_INFO_REG_COUNT * sizeof(u32);
    100	memcpy_fromio(p + offset, lif->ionic->idev.dev_info_regs->words, size);
    101
    102	offset += size;
    103	size = IONIC_DEV_CMD_REG_COUNT * sizeof(u32);
    104	memcpy_fromio(p + offset, lif->ionic->idev.dev_cmd_regs->words, size);
    105}
    106
    107static int ionic_get_link_ksettings(struct net_device *netdev,
    108				    struct ethtool_link_ksettings *ks)
    109{
    110	struct ionic_lif *lif = netdev_priv(netdev);
    111	struct ionic_dev *idev = &lif->ionic->idev;
    112	int copper_seen = 0;
    113
    114	ethtool_link_ksettings_zero_link_mode(ks, supported);
    115
    116	if (!idev->port_info) {
    117		netdev_err(netdev, "port_info not initialized\n");
    118		return -EOPNOTSUPP;
    119	}
    120
    121	/* The port_info data is found in a DMA space that the NIC keeps
    122	 * up-to-date, so there's no need to request the data from the
    123	 * NIC, we already have it in our memory space.
    124	 */
    125
    126	switch (le16_to_cpu(idev->port_info->status.xcvr.pid)) {
    127		/* Copper */
    128	case IONIC_XCVR_PID_QSFP_100G_CR4:
    129		ethtool_link_ksettings_add_link_mode(ks, supported,
    130						     100000baseCR4_Full);
    131		copper_seen++;
    132		break;
    133	case IONIC_XCVR_PID_QSFP_40GBASE_CR4:
    134		ethtool_link_ksettings_add_link_mode(ks, supported,
    135						     40000baseCR4_Full);
    136		copper_seen++;
    137		break;
    138	case IONIC_XCVR_PID_SFP_25GBASE_CR_S:
    139	case IONIC_XCVR_PID_SFP_25GBASE_CR_L:
    140	case IONIC_XCVR_PID_SFP_25GBASE_CR_N:
    141		ethtool_link_ksettings_add_link_mode(ks, supported,
    142						     25000baseCR_Full);
    143		copper_seen++;
    144		break;
    145	case IONIC_XCVR_PID_SFP_10GBASE_AOC:
    146	case IONIC_XCVR_PID_SFP_10GBASE_CU:
    147		ethtool_link_ksettings_add_link_mode(ks, supported,
    148						     10000baseCR_Full);
    149		copper_seen++;
    150		break;
    151
    152		/* Fibre */
    153	case IONIC_XCVR_PID_QSFP_100G_SR4:
    154	case IONIC_XCVR_PID_QSFP_100G_AOC:
    155		ethtool_link_ksettings_add_link_mode(ks, supported,
    156						     100000baseSR4_Full);
    157		break;
    158	case IONIC_XCVR_PID_QSFP_100G_CWDM4:
    159	case IONIC_XCVR_PID_QSFP_100G_PSM4:
    160	case IONIC_XCVR_PID_QSFP_100G_LR4:
    161		ethtool_link_ksettings_add_link_mode(ks, supported,
    162						     100000baseLR4_ER4_Full);
    163		break;
    164	case IONIC_XCVR_PID_QSFP_100G_ER4:
    165		ethtool_link_ksettings_add_link_mode(ks, supported,
    166						     100000baseLR4_ER4_Full);
    167		break;
    168	case IONIC_XCVR_PID_QSFP_40GBASE_SR4:
    169	case IONIC_XCVR_PID_QSFP_40GBASE_AOC:
    170		ethtool_link_ksettings_add_link_mode(ks, supported,
    171						     40000baseSR4_Full);
    172		break;
    173	case IONIC_XCVR_PID_QSFP_40GBASE_LR4:
    174		ethtool_link_ksettings_add_link_mode(ks, supported,
    175						     40000baseLR4_Full);
    176		break;
    177	case IONIC_XCVR_PID_SFP_25GBASE_SR:
    178	case IONIC_XCVR_PID_SFP_25GBASE_AOC:
    179	case IONIC_XCVR_PID_SFP_25GBASE_ACC:
    180		ethtool_link_ksettings_add_link_mode(ks, supported,
    181						     25000baseSR_Full);
    182		break;
    183	case IONIC_XCVR_PID_SFP_10GBASE_SR:
    184		ethtool_link_ksettings_add_link_mode(ks, supported,
    185						     10000baseSR_Full);
    186		break;
    187	case IONIC_XCVR_PID_SFP_10GBASE_LR:
    188		ethtool_link_ksettings_add_link_mode(ks, supported,
    189						     10000baseLR_Full);
    190		break;
    191	case IONIC_XCVR_PID_SFP_10GBASE_LRM:
    192		ethtool_link_ksettings_add_link_mode(ks, supported,
    193						     10000baseLRM_Full);
    194		break;
    195	case IONIC_XCVR_PID_SFP_10GBASE_ER:
    196		ethtool_link_ksettings_add_link_mode(ks, supported,
    197						     10000baseER_Full);
    198		break;
    199	case IONIC_XCVR_PID_SFP_10GBASE_T:
    200		ethtool_link_ksettings_add_link_mode(ks, supported,
    201						     10000baseT_Full);
    202		break;
    203	case IONIC_XCVR_PID_SFP_1000BASE_T:
    204		ethtool_link_ksettings_add_link_mode(ks, supported,
    205						     1000baseT_Full);
    206		break;
    207	case IONIC_XCVR_PID_UNKNOWN:
    208		/* This means there's no module plugged in */
    209		break;
    210	default:
    211		dev_info(lif->ionic->dev, "unknown xcvr type pid=%d / 0x%x\n",
    212			 idev->port_info->status.xcvr.pid,
    213			 idev->port_info->status.xcvr.pid);
    214		break;
    215	}
    216
    217	linkmode_copy(ks->link_modes.advertising, ks->link_modes.supported);
    218
    219	ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
    220	ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
    221	if (idev->port_info->config.fec_type == IONIC_PORT_FEC_TYPE_FC)
    222		ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_BASER);
    223	else if (idev->port_info->config.fec_type == IONIC_PORT_FEC_TYPE_RS)
    224		ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
    225
    226	ethtool_link_ksettings_add_link_mode(ks, supported, FIBRE);
    227	ethtool_link_ksettings_add_link_mode(ks, supported, Pause);
    228
    229	if (idev->port_info->status.xcvr.phy == IONIC_PHY_TYPE_COPPER ||
    230	    copper_seen)
    231		ks->base.port = PORT_DA;
    232	else if (idev->port_info->status.xcvr.phy == IONIC_PHY_TYPE_FIBER)
    233		ks->base.port = PORT_FIBRE;
    234	else
    235		ks->base.port = PORT_NONE;
    236
    237	if (ks->base.port != PORT_NONE) {
    238		ks->base.speed = le32_to_cpu(lif->info->status.link_speed);
    239
    240		if (le16_to_cpu(lif->info->status.link_status))
    241			ks->base.duplex = DUPLEX_FULL;
    242		else
    243			ks->base.duplex = DUPLEX_UNKNOWN;
    244
    245		ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
    246
    247		if (idev->port_info->config.an_enable) {
    248			ethtool_link_ksettings_add_link_mode(ks, advertising,
    249							     Autoneg);
    250			ks->base.autoneg = AUTONEG_ENABLE;
    251		}
    252	}
    253
    254	return 0;
    255}
    256
    257static int ionic_set_link_ksettings(struct net_device *netdev,
    258				    const struct ethtool_link_ksettings *ks)
    259{
    260	struct ionic_lif *lif = netdev_priv(netdev);
    261	struct ionic_dev *idev = &lif->ionic->idev;
    262	struct ionic *ionic = lif->ionic;
    263	int err = 0;
    264
    265	if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
    266		return -EBUSY;
    267
    268	/* set autoneg */
    269	if (ks->base.autoneg != idev->port_info->config.an_enable) {
    270		mutex_lock(&ionic->dev_cmd_lock);
    271		ionic_dev_cmd_port_autoneg(idev, ks->base.autoneg);
    272		err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
    273		mutex_unlock(&ionic->dev_cmd_lock);
    274		if (err)
    275			return err;
    276	}
    277
    278	/* set speed */
    279	if (ks->base.speed != le32_to_cpu(idev->port_info->config.speed)) {
    280		mutex_lock(&ionic->dev_cmd_lock);
    281		ionic_dev_cmd_port_speed(idev, ks->base.speed);
    282		err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
    283		mutex_unlock(&ionic->dev_cmd_lock);
    284		if (err)
    285			return err;
    286	}
    287
    288	return 0;
    289}
    290
    291static void ionic_get_pauseparam(struct net_device *netdev,
    292				 struct ethtool_pauseparam *pause)
    293{
    294	struct ionic_lif *lif = netdev_priv(netdev);
    295	u8 pause_type;
    296
    297	pause->autoneg = 0;
    298
    299	pause_type = lif->ionic->idev.port_info->config.pause_type;
    300	if (pause_type) {
    301		pause->rx_pause = (pause_type & IONIC_PAUSE_F_RX) ? 1 : 0;
    302		pause->tx_pause = (pause_type & IONIC_PAUSE_F_TX) ? 1 : 0;
    303	}
    304}
    305
    306static int ionic_set_pauseparam(struct net_device *netdev,
    307				struct ethtool_pauseparam *pause)
    308{
    309	struct ionic_lif *lif = netdev_priv(netdev);
    310	struct ionic *ionic = lif->ionic;
    311	u32 requested_pause;
    312	int err;
    313
    314	if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
    315		return -EBUSY;
    316
    317	if (pause->autoneg)
    318		return -EOPNOTSUPP;
    319
    320	/* change both at the same time */
    321	requested_pause = IONIC_PORT_PAUSE_TYPE_LINK;
    322	if (pause->rx_pause)
    323		requested_pause |= IONIC_PAUSE_F_RX;
    324	if (pause->tx_pause)
    325		requested_pause |= IONIC_PAUSE_F_TX;
    326
    327	if (requested_pause == lif->ionic->idev.port_info->config.pause_type)
    328		return 0;
    329
    330	mutex_lock(&ionic->dev_cmd_lock);
    331	ionic_dev_cmd_port_pause(&lif->ionic->idev, requested_pause);
    332	err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
    333	mutex_unlock(&ionic->dev_cmd_lock);
    334	if (err)
    335		return err;
    336
    337	return 0;
    338}
    339
    340static int ionic_get_fecparam(struct net_device *netdev,
    341			      struct ethtool_fecparam *fec)
    342{
    343	struct ionic_lif *lif = netdev_priv(netdev);
    344
    345	switch (lif->ionic->idev.port_info->config.fec_type) {
    346	case IONIC_PORT_FEC_TYPE_NONE:
    347		fec->active_fec = ETHTOOL_FEC_OFF;
    348		break;
    349	case IONIC_PORT_FEC_TYPE_RS:
    350		fec->active_fec = ETHTOOL_FEC_RS;
    351		break;
    352	case IONIC_PORT_FEC_TYPE_FC:
    353		fec->active_fec = ETHTOOL_FEC_BASER;
    354		break;
    355	}
    356
    357	fec->fec = ETHTOOL_FEC_OFF | ETHTOOL_FEC_RS | ETHTOOL_FEC_BASER;
    358
    359	return 0;
    360}
    361
    362static int ionic_set_fecparam(struct net_device *netdev,
    363			      struct ethtool_fecparam *fec)
    364{
    365	struct ionic_lif *lif = netdev_priv(netdev);
    366	u8 fec_type;
    367	int ret = 0;
    368
    369	if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
    370		return -EBUSY;
    371
    372	if (lif->ionic->idev.port_info->config.an_enable) {
    373		netdev_err(netdev, "FEC request not allowed while autoneg is enabled\n");
    374		return -EINVAL;
    375	}
    376
    377	switch (fec->fec) {
    378	case ETHTOOL_FEC_NONE:
    379		fec_type = IONIC_PORT_FEC_TYPE_NONE;
    380		break;
    381	case ETHTOOL_FEC_OFF:
    382		fec_type = IONIC_PORT_FEC_TYPE_NONE;
    383		break;
    384	case ETHTOOL_FEC_RS:
    385		fec_type = IONIC_PORT_FEC_TYPE_RS;
    386		break;
    387	case ETHTOOL_FEC_BASER:
    388		fec_type = IONIC_PORT_FEC_TYPE_FC;
    389		break;
    390	case ETHTOOL_FEC_AUTO:
    391	default:
    392		netdev_err(netdev, "FEC request 0x%04x not supported\n",
    393			   fec->fec);
    394		return -EINVAL;
    395	}
    396
    397	if (fec_type != lif->ionic->idev.port_info->config.fec_type) {
    398		mutex_lock(&lif->ionic->dev_cmd_lock);
    399		ionic_dev_cmd_port_fec(&lif->ionic->idev, fec_type);
    400		ret = ionic_dev_cmd_wait(lif->ionic, DEVCMD_TIMEOUT);
    401		mutex_unlock(&lif->ionic->dev_cmd_lock);
    402	}
    403
    404	return ret;
    405}
    406
    407static int ionic_get_coalesce(struct net_device *netdev,
    408			      struct ethtool_coalesce *coalesce,
    409			      struct kernel_ethtool_coalesce *kernel_coal,
    410			      struct netlink_ext_ack *extack)
    411{
    412	struct ionic_lif *lif = netdev_priv(netdev);
    413
    414	coalesce->tx_coalesce_usecs = lif->tx_coalesce_usecs;
    415	coalesce->rx_coalesce_usecs = lif->rx_coalesce_usecs;
    416
    417	if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
    418		coalesce->use_adaptive_tx_coalesce = test_bit(IONIC_LIF_F_TX_DIM_INTR, lif->state);
    419	else
    420		coalesce->use_adaptive_tx_coalesce = 0;
    421
    422	coalesce->use_adaptive_rx_coalesce = test_bit(IONIC_LIF_F_RX_DIM_INTR, lif->state);
    423
    424	return 0;
    425}
    426
    427static int ionic_set_coalesce(struct net_device *netdev,
    428			      struct ethtool_coalesce *coalesce,
    429			      struct kernel_ethtool_coalesce *kernel_coal,
    430			      struct netlink_ext_ack *extack)
    431{
    432	struct ionic_lif *lif = netdev_priv(netdev);
    433	struct ionic_identity *ident;
    434	u32 rx_coal, rx_dim;
    435	u32 tx_coal, tx_dim;
    436	unsigned int i;
    437
    438	ident = &lif->ionic->ident;
    439	if (ident->dev.intr_coal_div == 0) {
    440		netdev_warn(netdev, "bad HW value in dev.intr_coal_div = %d\n",
    441			    ident->dev.intr_coal_div);
    442		return -EIO;
    443	}
    444
    445	/* Tx normally shares Rx interrupt, so only change Rx if not split */
    446	if (!test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state) &&
    447	    (coalesce->tx_coalesce_usecs != lif->rx_coalesce_usecs ||
    448	     coalesce->use_adaptive_tx_coalesce)) {
    449		netdev_warn(netdev, "only rx parameters can be changed\n");
    450		return -EINVAL;
    451	}
    452
    453	/* Convert the usec request to a HW usable value.  If they asked
    454	 * for non-zero and it resolved to zero, bump it up
    455	 */
    456	rx_coal = ionic_coal_usec_to_hw(lif->ionic, coalesce->rx_coalesce_usecs);
    457	if (!rx_coal && coalesce->rx_coalesce_usecs)
    458		rx_coal = 1;
    459	tx_coal = ionic_coal_usec_to_hw(lif->ionic, coalesce->tx_coalesce_usecs);
    460	if (!tx_coal && coalesce->tx_coalesce_usecs)
    461		tx_coal = 1;
    462
    463	if (rx_coal > IONIC_INTR_CTRL_COAL_MAX ||
    464	    tx_coal > IONIC_INTR_CTRL_COAL_MAX)
    465		return -ERANGE;
    466
    467	/* Save the new values */
    468	lif->rx_coalesce_usecs = coalesce->rx_coalesce_usecs;
    469	lif->rx_coalesce_hw = rx_coal;
    470
    471	if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
    472		lif->tx_coalesce_usecs = coalesce->tx_coalesce_usecs;
    473	else
    474		lif->tx_coalesce_usecs = coalesce->rx_coalesce_usecs;
    475	lif->tx_coalesce_hw = tx_coal;
    476
    477	if (coalesce->use_adaptive_rx_coalesce) {
    478		set_bit(IONIC_LIF_F_RX_DIM_INTR, lif->state);
    479		rx_dim = rx_coal;
    480	} else {
    481		clear_bit(IONIC_LIF_F_RX_DIM_INTR, lif->state);
    482		rx_dim = 0;
    483	}
    484
    485	if (coalesce->use_adaptive_tx_coalesce) {
    486		set_bit(IONIC_LIF_F_TX_DIM_INTR, lif->state);
    487		tx_dim = tx_coal;
    488	} else {
    489		clear_bit(IONIC_LIF_F_TX_DIM_INTR, lif->state);
    490		tx_dim = 0;
    491	}
    492
    493	if (test_bit(IONIC_LIF_F_UP, lif->state)) {
    494		for (i = 0; i < lif->nxqs; i++) {
    495			if (lif->rxqcqs[i]->flags & IONIC_QCQ_F_INTR) {
    496				ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
    497						     lif->rxqcqs[i]->intr.index,
    498						     lif->rx_coalesce_hw);
    499				lif->rxqcqs[i]->intr.dim_coal_hw = rx_dim;
    500			}
    501
    502			if (lif->txqcqs[i]->flags & IONIC_QCQ_F_INTR) {
    503				ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
    504						     lif->txqcqs[i]->intr.index,
    505						     lif->tx_coalesce_hw);
    506				lif->txqcqs[i]->intr.dim_coal_hw = tx_dim;
    507			}
    508		}
    509	}
    510
    511	return 0;
    512}
    513
    514static void ionic_get_ringparam(struct net_device *netdev,
    515				struct ethtool_ringparam *ring,
    516				struct kernel_ethtool_ringparam *kernel_ring,
    517				struct netlink_ext_ack *extack)
    518{
    519	struct ionic_lif *lif = netdev_priv(netdev);
    520
    521	ring->tx_max_pending = IONIC_MAX_TX_DESC;
    522	ring->tx_pending = lif->ntxq_descs;
    523	ring->rx_max_pending = IONIC_MAX_RX_DESC;
    524	ring->rx_pending = lif->nrxq_descs;
    525}
    526
    527static int ionic_set_ringparam(struct net_device *netdev,
    528			       struct ethtool_ringparam *ring,
    529			       struct kernel_ethtool_ringparam *kernel_ring,
    530			       struct netlink_ext_ack *extack)
    531{
    532	struct ionic_lif *lif = netdev_priv(netdev);
    533	struct ionic_queue_params qparam;
    534	int err;
    535
    536	if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
    537		return -EBUSY;
    538
    539	ionic_init_queue_params(lif, &qparam);
    540
    541	if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
    542		netdev_info(netdev, "Changing jumbo or mini descriptors not supported\n");
    543		return -EINVAL;
    544	}
    545
    546	if (!is_power_of_2(ring->tx_pending) ||
    547	    !is_power_of_2(ring->rx_pending)) {
    548		netdev_info(netdev, "Descriptor count must be a power of 2\n");
    549		return -EINVAL;
    550	}
    551
    552	/* if nothing to do return success */
    553	if (ring->tx_pending == lif->ntxq_descs &&
    554	    ring->rx_pending == lif->nrxq_descs)
    555		return 0;
    556
    557	if (ring->tx_pending != lif->ntxq_descs)
    558		netdev_info(netdev, "Changing Tx ring size from %d to %d\n",
    559			    lif->ntxq_descs, ring->tx_pending);
    560
    561	if (ring->rx_pending != lif->nrxq_descs)
    562		netdev_info(netdev, "Changing Rx ring size from %d to %d\n",
    563			    lif->nrxq_descs, ring->rx_pending);
    564
    565	/* if we're not running, just set the values and return */
    566	if (!netif_running(lif->netdev)) {
    567		lif->ntxq_descs = ring->tx_pending;
    568		lif->nrxq_descs = ring->rx_pending;
    569		return 0;
    570	}
    571
    572	qparam.ntxq_descs = ring->tx_pending;
    573	qparam.nrxq_descs = ring->rx_pending;
    574
    575	mutex_lock(&lif->queue_lock);
    576	err = ionic_reconfigure_queues(lif, &qparam);
    577	mutex_unlock(&lif->queue_lock);
    578	if (err)
    579		netdev_info(netdev, "Ring reconfiguration failed, changes canceled: %d\n", err);
    580
    581	return err;
    582}
    583
    584static void ionic_get_channels(struct net_device *netdev,
    585			       struct ethtool_channels *ch)
    586{
    587	struct ionic_lif *lif = netdev_priv(netdev);
    588
    589	/* report maximum channels */
    590	ch->max_combined = lif->ionic->ntxqs_per_lif;
    591	ch->max_rx = lif->ionic->ntxqs_per_lif / 2;
    592	ch->max_tx = lif->ionic->ntxqs_per_lif / 2;
    593
    594	/* report current channels */
    595	if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) {
    596		ch->rx_count = lif->nxqs;
    597		ch->tx_count = lif->nxqs;
    598	} else {
    599		ch->combined_count = lif->nxqs;
    600	}
    601}
    602
    603static int ionic_set_channels(struct net_device *netdev,
    604			      struct ethtool_channels *ch)
    605{
    606	struct ionic_lif *lif = netdev_priv(netdev);
    607	struct ionic_queue_params qparam;
    608	int max_cnt;
    609	int err;
    610
    611	if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
    612		return -EBUSY;
    613
    614	ionic_init_queue_params(lif, &qparam);
    615
    616	if (ch->rx_count != ch->tx_count) {
    617		netdev_info(netdev, "The rx and tx count must be equal\n");
    618		return -EINVAL;
    619	}
    620
    621	if (ch->combined_count && ch->rx_count) {
    622		netdev_info(netdev, "Use either combined or rx and tx, not both\n");
    623		return -EINVAL;
    624	}
    625
    626	max_cnt = lif->ionic->ntxqs_per_lif;
    627	if (ch->combined_count) {
    628		if (ch->combined_count > max_cnt)
    629			return -EINVAL;
    630
    631		if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
    632			netdev_info(lif->netdev, "Sharing queue interrupts\n");
    633		else if (ch->combined_count == lif->nxqs)
    634			return 0;
    635
    636		if (lif->nxqs != ch->combined_count)
    637			netdev_info(netdev, "Changing queue count from %d to %d\n",
    638				    lif->nxqs, ch->combined_count);
    639
    640		qparam.nxqs = ch->combined_count;
    641		qparam.intr_split = 0;
    642	} else {
    643		max_cnt /= 2;
    644		if (ch->rx_count > max_cnt)
    645			return -EINVAL;
    646
    647		if (!test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
    648			netdev_info(lif->netdev, "Splitting queue interrupts\n");
    649		else if (ch->rx_count == lif->nxqs)
    650			return 0;
    651
    652		if (lif->nxqs != ch->rx_count)
    653			netdev_info(netdev, "Changing queue count from %d to %d\n",
    654				    lif->nxqs, ch->rx_count);
    655
    656		qparam.nxqs = ch->rx_count;
    657		qparam.intr_split = 1;
    658	}
    659
    660	/* if we're not running, just set the values and return */
    661	if (!netif_running(lif->netdev)) {
    662		lif->nxqs = qparam.nxqs;
    663
    664		if (qparam.intr_split) {
    665			set_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
    666		} else {
    667			clear_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
    668			lif->tx_coalesce_usecs = lif->rx_coalesce_usecs;
    669			lif->tx_coalesce_hw = lif->rx_coalesce_hw;
    670		}
    671		return 0;
    672	}
    673
    674	mutex_lock(&lif->queue_lock);
    675	err = ionic_reconfigure_queues(lif, &qparam);
    676	mutex_unlock(&lif->queue_lock);
    677	if (err)
    678		netdev_info(netdev, "Queue reconfiguration failed, changes canceled: %d\n", err);
    679
    680	return err;
    681}
    682
    683static int ionic_get_rxnfc(struct net_device *netdev,
    684			   struct ethtool_rxnfc *info, u32 *rules)
    685{
    686	struct ionic_lif *lif = netdev_priv(netdev);
    687	int err = 0;
    688
    689	switch (info->cmd) {
    690	case ETHTOOL_GRXRINGS:
    691		info->data = lif->nxqs;
    692		break;
    693	default:
    694		netdev_err(netdev, "Command parameter %d is not supported\n",
    695			   info->cmd);
    696		err = -EOPNOTSUPP;
    697	}
    698
    699	return err;
    700}
    701
    702static u32 ionic_get_rxfh_indir_size(struct net_device *netdev)
    703{
    704	struct ionic_lif *lif = netdev_priv(netdev);
    705
    706	return le16_to_cpu(lif->ionic->ident.lif.eth.rss_ind_tbl_sz);
    707}
    708
    709static u32 ionic_get_rxfh_key_size(struct net_device *netdev)
    710{
    711	return IONIC_RSS_HASH_KEY_SIZE;
    712}
    713
    714static int ionic_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
    715			  u8 *hfunc)
    716{
    717	struct ionic_lif *lif = netdev_priv(netdev);
    718	unsigned int i, tbl_sz;
    719
    720	if (indir) {
    721		tbl_sz = le16_to_cpu(lif->ionic->ident.lif.eth.rss_ind_tbl_sz);
    722		for (i = 0; i < tbl_sz; i++)
    723			indir[i] = lif->rss_ind_tbl[i];
    724	}
    725
    726	if (key)
    727		memcpy(key, lif->rss_hash_key, IONIC_RSS_HASH_KEY_SIZE);
    728
    729	if (hfunc)
    730		*hfunc = ETH_RSS_HASH_TOP;
    731
    732	return 0;
    733}
    734
    735static int ionic_set_rxfh(struct net_device *netdev, const u32 *indir,
    736			  const u8 *key, const u8 hfunc)
    737{
    738	struct ionic_lif *lif = netdev_priv(netdev);
    739
    740	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
    741		return -EOPNOTSUPP;
    742
    743	return ionic_lif_rss_config(lif, lif->rss_types, key, indir);
    744}
    745
    746static int ionic_set_tunable(struct net_device *dev,
    747			     const struct ethtool_tunable *tuna,
    748			     const void *data)
    749{
    750	struct ionic_lif *lif = netdev_priv(dev);
    751
    752	switch (tuna->id) {
    753	case ETHTOOL_RX_COPYBREAK:
    754		lif->rx_copybreak = *(u32 *)data;
    755		break;
    756	default:
    757		return -EOPNOTSUPP;
    758	}
    759
    760	return 0;
    761}
    762
    763static int ionic_get_tunable(struct net_device *netdev,
    764			     const struct ethtool_tunable *tuna, void *data)
    765{
    766	struct ionic_lif *lif = netdev_priv(netdev);
    767
    768	switch (tuna->id) {
    769	case ETHTOOL_RX_COPYBREAK:
    770		*(u32 *)data = lif->rx_copybreak;
    771		break;
    772	default:
    773		return -EOPNOTSUPP;
    774	}
    775
    776	return 0;
    777}
    778
    779static int ionic_get_module_info(struct net_device *netdev,
    780				 struct ethtool_modinfo *modinfo)
    781
    782{
    783	struct ionic_lif *lif = netdev_priv(netdev);
    784	struct ionic_dev *idev = &lif->ionic->idev;
    785	struct ionic_xcvr_status *xcvr;
    786	struct sfp_eeprom_base *sfp;
    787
    788	xcvr = &idev->port_info->status.xcvr;
    789	sfp = (struct sfp_eeprom_base *) xcvr->sprom;
    790
    791	/* report the module data type and length */
    792	switch (sfp->phys_id) {
    793	case SFF8024_ID_SFP:
    794		modinfo->type = ETH_MODULE_SFF_8079;
    795		modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
    796		break;
    797	case SFF8024_ID_QSFP_8436_8636:
    798	case SFF8024_ID_QSFP28_8636:
    799		modinfo->type = ETH_MODULE_SFF_8436;
    800		modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
    801		break;
    802	default:
    803		netdev_info(netdev, "unknown xcvr type 0x%02x\n",
    804			    xcvr->sprom[0]);
    805		modinfo->type = 0;
    806		modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
    807		break;
    808	}
    809
    810	return 0;
    811}
    812
    813static int ionic_get_module_eeprom(struct net_device *netdev,
    814				   struct ethtool_eeprom *ee,
    815				   u8 *data)
    816{
    817	struct ionic_lif *lif = netdev_priv(netdev);
    818	struct ionic_dev *idev = &lif->ionic->idev;
    819	struct ionic_xcvr_status *xcvr;
    820	char tbuf[sizeof(xcvr->sprom)];
    821	int count = 10;
    822	u32 len;
    823
    824	/* The NIC keeps the module prom up-to-date in the DMA space
    825	 * so we can simply copy the module bytes into the data buffer.
    826	 */
    827	xcvr = &idev->port_info->status.xcvr;
    828	len = min_t(u32, sizeof(xcvr->sprom), ee->len);
    829
    830	do {
    831		memcpy(data, xcvr->sprom, len);
    832		memcpy(tbuf, xcvr->sprom, len);
    833
    834		/* Let's make sure we got a consistent copy */
    835		if (!memcmp(data, tbuf, len))
    836			break;
    837
    838	} while (--count);
    839
    840	if (!count)
    841		return -ETIMEDOUT;
    842
    843	return 0;
    844}
    845
    846static int ionic_get_ts_info(struct net_device *netdev,
    847			     struct ethtool_ts_info *info)
    848{
    849	struct ionic_lif *lif = netdev_priv(netdev);
    850	struct ionic *ionic = lif->ionic;
    851	__le64 mask;
    852
    853	if (!lif->phc || !lif->phc->ptp)
    854		return ethtool_op_get_ts_info(netdev, info);
    855
    856	info->phc_index = ptp_clock_index(lif->phc->ptp);
    857
    858	info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
    859				SOF_TIMESTAMPING_RX_SOFTWARE |
    860				SOF_TIMESTAMPING_SOFTWARE |
    861				SOF_TIMESTAMPING_TX_HARDWARE |
    862				SOF_TIMESTAMPING_RX_HARDWARE |
    863				SOF_TIMESTAMPING_RAW_HARDWARE;
    864
    865	/* tx modes */
    866
    867	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
    868			 BIT(HWTSTAMP_TX_ON);
    869
    870	mask = cpu_to_le64(BIT_ULL(IONIC_TXSTAMP_ONESTEP_SYNC));
    871	if (ionic->ident.lif.eth.hwstamp_tx_modes & mask)
    872		info->tx_types |= BIT(HWTSTAMP_TX_ONESTEP_SYNC);
    873
    874	mask = cpu_to_le64(BIT_ULL(IONIC_TXSTAMP_ONESTEP_P2P));
    875	if (ionic->ident.lif.eth.hwstamp_tx_modes & mask)
    876		info->tx_types |= BIT(HWTSTAMP_TX_ONESTEP_P2P);
    877
    878	/* rx filters */
    879
    880	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
    881			   BIT(HWTSTAMP_FILTER_ALL);
    882
    883	mask = cpu_to_le64(IONIC_PKT_CLS_NTP_ALL);
    884	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    885		info->rx_filters |= BIT(HWTSTAMP_FILTER_NTP_ALL);
    886
    887	mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_SYNC);
    888	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    889		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC);
    890
    891	mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_DREQ);
    892	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    893		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ);
    894
    895	mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_ALL);
    896	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    897		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_EVENT);
    898
    899	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_SYNC);
    900	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    901		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC);
    902
    903	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_DREQ);
    904	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    905		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
    906
    907	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_ALL);
    908	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    909		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
    910
    911	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_SYNC);
    912	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    913		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L2_SYNC);
    914
    915	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_DREQ);
    916	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    917		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ);
    918
    919	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_ALL);
    920	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    921		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT);
    922
    923	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_SYNC);
    924	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    925		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_SYNC);
    926
    927	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_DREQ);
    928	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    929		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ);
    930
    931	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_ALL);
    932	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
    933		info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
    934
    935	return 0;
    936}
    937
    938static int ionic_nway_reset(struct net_device *netdev)
    939{
    940	struct ionic_lif *lif = netdev_priv(netdev);
    941	struct ionic *ionic = lif->ionic;
    942	int err = 0;
    943
    944	if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
    945		return -EBUSY;
    946
    947	/* flap the link to force auto-negotiation */
    948
    949	mutex_lock(&ionic->dev_cmd_lock);
    950
    951	ionic_dev_cmd_port_state(&ionic->idev, IONIC_PORT_ADMIN_STATE_DOWN);
    952	err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
    953
    954	if (!err) {
    955		ionic_dev_cmd_port_state(&ionic->idev, IONIC_PORT_ADMIN_STATE_UP);
    956		err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
    957	}
    958
    959	mutex_unlock(&ionic->dev_cmd_lock);
    960
    961	return err;
    962}
    963
    964static const struct ethtool_ops ionic_ethtool_ops = {
    965	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
    966				     ETHTOOL_COALESCE_USE_ADAPTIVE_RX |
    967				     ETHTOOL_COALESCE_USE_ADAPTIVE_TX,
    968	.get_drvinfo		= ionic_get_drvinfo,
    969	.get_regs_len		= ionic_get_regs_len,
    970	.get_regs		= ionic_get_regs,
    971	.get_link		= ethtool_op_get_link,
    972	.get_link_ksettings	= ionic_get_link_ksettings,
    973	.set_link_ksettings	= ionic_set_link_ksettings,
    974	.get_coalesce		= ionic_get_coalesce,
    975	.set_coalesce		= ionic_set_coalesce,
    976	.get_ringparam		= ionic_get_ringparam,
    977	.set_ringparam		= ionic_set_ringparam,
    978	.get_channels		= ionic_get_channels,
    979	.set_channels		= ionic_set_channels,
    980	.get_strings		= ionic_get_strings,
    981	.get_ethtool_stats	= ionic_get_stats,
    982	.get_sset_count		= ionic_get_sset_count,
    983	.get_rxnfc		= ionic_get_rxnfc,
    984	.get_rxfh_indir_size	= ionic_get_rxfh_indir_size,
    985	.get_rxfh_key_size	= ionic_get_rxfh_key_size,
    986	.get_rxfh		= ionic_get_rxfh,
    987	.set_rxfh		= ionic_set_rxfh,
    988	.get_tunable		= ionic_get_tunable,
    989	.set_tunable		= ionic_set_tunable,
    990	.get_module_info	= ionic_get_module_info,
    991	.get_module_eeprom	= ionic_get_module_eeprom,
    992	.get_pauseparam		= ionic_get_pauseparam,
    993	.set_pauseparam		= ionic_set_pauseparam,
    994	.get_fecparam		= ionic_get_fecparam,
    995	.set_fecparam		= ionic_set_fecparam,
    996	.get_ts_info		= ionic_get_ts_info,
    997	.nway_reset		= ionic_nway_reset,
    998};
    999
   1000void ionic_ethtool_set_ops(struct net_device *netdev)
   1001{
   1002	netdev->ethtool_ops = &ionic_ethtool_ops;
   1003}