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