root/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ionic_get_stats_strings
  2. ionic_get_stats
  3. ionic_get_stats_count
  4. ionic_get_sset_count
  5. ionic_get_strings
  6. ionic_get_drvinfo
  7. ionic_get_regs_len
  8. ionic_get_regs
  9. ionic_get_link_ksettings
  10. ionic_set_link_ksettings
  11. ionic_get_pauseparam
  12. ionic_set_pauseparam
  13. ionic_get_coalesce
  14. ionic_set_coalesce
  15. ionic_get_ringparam
  16. ionic_set_ringparam
  17. ionic_get_channels
  18. ionic_set_channels
  19. ionic_get_priv_flags
  20. ionic_set_priv_flags
  21. ionic_get_rxnfc
  22. ionic_get_rxfh_indir_size
  23. ionic_get_rxfh_key_size
  24. ionic_get_rxfh
  25. ionic_set_rxfh
  26. ionic_set_tunable
  27. ionic_get_tunable
  28. ionic_get_module_info
  29. ionic_get_module_eeprom
  30. ionic_nway_reset
  31. ionic_ethtool_set_ops

   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 
   7 #include "ionic.h"
   8 #include "ionic_bus.h"
   9 #include "ionic_lif.h"
  10 #include "ionic_ethtool.h"
  11 #include "ionic_stats.h"
  12 
  13 static const char ionic_priv_flags_strings[][ETH_GSTRING_LEN] = {
  14 #define PRIV_F_SW_DBG_STATS             BIT(0)
  15         "sw-dbg-stats",
  16 };
  17 #define PRIV_FLAGS_COUNT ARRAY_SIZE(ionic_priv_flags_strings)
  18 
  19 static void ionic_get_stats_strings(struct ionic_lif *lif, u8 *buf)
  20 {
  21         u32 i;
  22 
  23         for (i = 0; i < ionic_num_stats_grps; i++)
  24                 ionic_stats_groups[i].get_strings(lif, &buf);
  25 }
  26 
  27 static void ionic_get_stats(struct net_device *netdev,
  28                             struct ethtool_stats *stats, u64 *buf)
  29 {
  30         struct ionic_lif *lif;
  31         u32 i;
  32 
  33         lif = netdev_priv(netdev);
  34 
  35         memset(buf, 0, stats->n_stats * sizeof(*buf));
  36         for (i = 0; i < ionic_num_stats_grps; i++)
  37                 ionic_stats_groups[i].get_values(lif, &buf);
  38 }
  39 
  40 static int ionic_get_stats_count(struct ionic_lif *lif)
  41 {
  42         int i, num_stats = 0;
  43 
  44         for (i = 0; i < ionic_num_stats_grps; i++)
  45                 num_stats += ionic_stats_groups[i].get_count(lif);
  46 
  47         return num_stats;
  48 }
  49 
  50 static int ionic_get_sset_count(struct net_device *netdev, int sset)
  51 {
  52         struct ionic_lif *lif = netdev_priv(netdev);
  53         int count = 0;
  54 
  55         switch (sset) {
  56         case ETH_SS_STATS:
  57                 count = ionic_get_stats_count(lif);
  58                 break;
  59         case ETH_SS_PRIV_FLAGS:
  60                 count = PRIV_FLAGS_COUNT;
  61                 break;
  62         }
  63         return count;
  64 }
  65 
  66 static void ionic_get_strings(struct net_device *netdev,
  67                               u32 sset, u8 *buf)
  68 {
  69         struct ionic_lif *lif = netdev_priv(netdev);
  70 
  71         switch (sset) {
  72         case ETH_SS_STATS:
  73                 ionic_get_stats_strings(lif, buf);
  74                 break;
  75         case ETH_SS_PRIV_FLAGS:
  76                 memcpy(buf, ionic_priv_flags_strings,
  77                        PRIV_FLAGS_COUNT * ETH_GSTRING_LEN);
  78                 break;
  79         }
  80 }
  81 
  82 static void ionic_get_drvinfo(struct net_device *netdev,
  83                               struct ethtool_drvinfo *drvinfo)
  84 {
  85         struct ionic_lif *lif = netdev_priv(netdev);
  86         struct ionic *ionic = lif->ionic;
  87 
  88         strlcpy(drvinfo->driver, IONIC_DRV_NAME, sizeof(drvinfo->driver));
  89         strlcpy(drvinfo->version, IONIC_DRV_VERSION, sizeof(drvinfo->version));
  90         strlcpy(drvinfo->fw_version, ionic->idev.dev_info.fw_version,
  91                 sizeof(drvinfo->fw_version));
  92         strlcpy(drvinfo->bus_info, ionic_bus_info(ionic),
  93                 sizeof(drvinfo->bus_info));
  94 }
  95 
  96 static int ionic_get_regs_len(struct net_device *netdev)
  97 {
  98         return (IONIC_DEV_INFO_REG_COUNT + IONIC_DEV_CMD_REG_COUNT) * sizeof(u32);
  99 }
 100 
 101 static void ionic_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
 102                            void *p)
 103 {
 104         struct ionic_lif *lif = netdev_priv(netdev);
 105         unsigned int size;
 106 
 107         regs->version = IONIC_DEV_CMD_REG_VERSION;
 108 
 109         size = IONIC_DEV_INFO_REG_COUNT * sizeof(u32);
 110         memcpy_fromio(p, lif->ionic->idev.dev_info_regs->words, size);
 111 
 112         size = IONIC_DEV_CMD_REG_COUNT * sizeof(u32);
 113         memcpy_fromio(p, lif->ionic->idev.dev_cmd_regs->words, size);
 114 }
 115 
 116 static int ionic_get_link_ksettings(struct net_device *netdev,
 117                                     struct ethtool_link_ksettings *ks)
 118 {
 119         struct ionic_lif *lif = netdev_priv(netdev);
 120         struct ionic_dev *idev = &lif->ionic->idev;
 121         int copper_seen = 0;
 122 
 123         ethtool_link_ksettings_zero_link_mode(ks, supported);
 124 
 125         /* The port_info data is found in a DMA space that the NIC keeps
 126          * up-to-date, so there's no need to request the data from the
 127          * NIC, we already have it in our memory space.
 128          */
 129 
 130         switch (le16_to_cpu(idev->port_info->status.xcvr.pid)) {
 131                 /* Copper */
 132         case IONIC_XCVR_PID_QSFP_100G_CR4:
 133                 ethtool_link_ksettings_add_link_mode(ks, supported,
 134                                                      100000baseCR4_Full);
 135                 copper_seen++;
 136                 break;
 137         case IONIC_XCVR_PID_QSFP_40GBASE_CR4:
 138                 ethtool_link_ksettings_add_link_mode(ks, supported,
 139                                                      40000baseCR4_Full);
 140                 copper_seen++;
 141                 break;
 142         case IONIC_XCVR_PID_SFP_25GBASE_CR_S:
 143         case IONIC_XCVR_PID_SFP_25GBASE_CR_L:
 144         case IONIC_XCVR_PID_SFP_25GBASE_CR_N:
 145                 ethtool_link_ksettings_add_link_mode(ks, supported,
 146                                                      25000baseCR_Full);
 147                 copper_seen++;
 148                 break;
 149         case IONIC_XCVR_PID_SFP_10GBASE_AOC:
 150         case IONIC_XCVR_PID_SFP_10GBASE_CU:
 151                 ethtool_link_ksettings_add_link_mode(ks, supported,
 152                                                      10000baseCR_Full);
 153                 copper_seen++;
 154                 break;
 155 
 156                 /* Fibre */
 157         case IONIC_XCVR_PID_QSFP_100G_SR4:
 158         case IONIC_XCVR_PID_QSFP_100G_AOC:
 159                 ethtool_link_ksettings_add_link_mode(ks, supported,
 160                                                      100000baseSR4_Full);
 161                 break;
 162         case IONIC_XCVR_PID_QSFP_100G_LR4:
 163                 ethtool_link_ksettings_add_link_mode(ks, supported,
 164                                                      100000baseLR4_ER4_Full);
 165                 break;
 166         case IONIC_XCVR_PID_QSFP_100G_ER4:
 167                 ethtool_link_ksettings_add_link_mode(ks, supported,
 168                                                      100000baseLR4_ER4_Full);
 169                 break;
 170         case IONIC_XCVR_PID_QSFP_40GBASE_SR4:
 171         case IONIC_XCVR_PID_QSFP_40GBASE_AOC:
 172                 ethtool_link_ksettings_add_link_mode(ks, supported,
 173                                                      40000baseSR4_Full);
 174                 break;
 175         case IONIC_XCVR_PID_QSFP_40GBASE_LR4:
 176                 ethtool_link_ksettings_add_link_mode(ks, supported,
 177                                                      40000baseLR4_Full);
 178                 break;
 179         case IONIC_XCVR_PID_SFP_25GBASE_SR:
 180         case IONIC_XCVR_PID_SFP_25GBASE_AOC:
 181                 ethtool_link_ksettings_add_link_mode(ks, supported,
 182                                                      25000baseSR_Full);
 183                 break;
 184         case IONIC_XCVR_PID_SFP_10GBASE_SR:
 185                 ethtool_link_ksettings_add_link_mode(ks, supported,
 186                                                      10000baseSR_Full);
 187                 break;
 188         case IONIC_XCVR_PID_SFP_10GBASE_LR:
 189                 ethtool_link_ksettings_add_link_mode(ks, supported,
 190                                                      10000baseLR_Full);
 191                 break;
 192         case IONIC_XCVR_PID_SFP_10GBASE_LRM:
 193                 ethtool_link_ksettings_add_link_mode(ks, supported,
 194                                                      10000baseLRM_Full);
 195                 break;
 196         case IONIC_XCVR_PID_SFP_10GBASE_ER:
 197                 ethtool_link_ksettings_add_link_mode(ks, supported,
 198                                                      10000baseER_Full);
 199                 break;
 200         case IONIC_XCVR_PID_UNKNOWN:
 201                 /* This means there's no module plugged in */
 202                 break;
 203         default:
 204                 dev_info(lif->ionic->dev, "unknown xcvr type pid=%d / 0x%x\n",
 205                          idev->port_info->status.xcvr.pid,
 206                          idev->port_info->status.xcvr.pid);
 207                 break;
 208         }
 209 
 210         bitmap_copy(ks->link_modes.advertising, ks->link_modes.supported,
 211                     __ETHTOOL_LINK_MODE_MASK_NBITS);
 212 
 213         ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
 214         ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
 215         if (idev->port_info->config.fec_type == IONIC_PORT_FEC_TYPE_FC)
 216                 ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_BASER);
 217         else if (idev->port_info->config.fec_type == IONIC_PORT_FEC_TYPE_RS)
 218                 ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
 219 
 220         ethtool_link_ksettings_add_link_mode(ks, supported, FIBRE);
 221         ethtool_link_ksettings_add_link_mode(ks, supported, Pause);
 222 
 223         if (idev->port_info->status.xcvr.phy == IONIC_PHY_TYPE_COPPER ||
 224             copper_seen)
 225                 ks->base.port = PORT_DA;
 226         else if (idev->port_info->status.xcvr.phy == IONIC_PHY_TYPE_FIBER)
 227                 ks->base.port = PORT_FIBRE;
 228         else
 229                 ks->base.port = PORT_NONE;
 230 
 231         if (ks->base.port != PORT_NONE) {
 232                 ks->base.speed = le32_to_cpu(lif->info->status.link_speed);
 233 
 234                 if (le16_to_cpu(lif->info->status.link_status))
 235                         ks->base.duplex = DUPLEX_FULL;
 236                 else
 237                         ks->base.duplex = DUPLEX_UNKNOWN;
 238 
 239                 ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
 240 
 241                 if (idev->port_info->config.an_enable) {
 242                         ethtool_link_ksettings_add_link_mode(ks, advertising,
 243                                                              Autoneg);
 244                         ks->base.autoneg = AUTONEG_ENABLE;
 245                 }
 246         }
 247 
 248         return 0;
 249 }
 250 
 251 static int ionic_set_link_ksettings(struct net_device *netdev,
 252                                     const struct ethtool_link_ksettings *ks)
 253 {
 254         struct ionic_lif *lif = netdev_priv(netdev);
 255         struct ionic *ionic = lif->ionic;
 256         struct ionic_dev *idev;
 257         u32 req_rs, req_fc;
 258         u8 fec_type;
 259         int err = 0;
 260 
 261         idev = &lif->ionic->idev;
 262         fec_type = IONIC_PORT_FEC_TYPE_NONE;
 263 
 264         /* set autoneg */
 265         if (ks->base.autoneg != idev->port_info->config.an_enable) {
 266                 mutex_lock(&ionic->dev_cmd_lock);
 267                 ionic_dev_cmd_port_autoneg(idev, ks->base.autoneg);
 268                 err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 269                 mutex_unlock(&ionic->dev_cmd_lock);
 270                 if (err)
 271                         return err;
 272         }
 273 
 274         /* set speed */
 275         if (ks->base.speed != le32_to_cpu(idev->port_info->config.speed)) {
 276                 mutex_lock(&ionic->dev_cmd_lock);
 277                 ionic_dev_cmd_port_speed(idev, ks->base.speed);
 278                 err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 279                 mutex_unlock(&ionic->dev_cmd_lock);
 280                 if (err)
 281                         return err;
 282         }
 283 
 284         /* set FEC */
 285         req_rs = ethtool_link_ksettings_test_link_mode(ks, advertising, FEC_RS);
 286         req_fc = ethtool_link_ksettings_test_link_mode(ks, advertising, FEC_BASER);
 287         if (req_rs && req_fc) {
 288                 netdev_info(netdev, "Only select one FEC mode at a time\n");
 289                 return -EINVAL;
 290         } else if (req_fc) {
 291                 fec_type = IONIC_PORT_FEC_TYPE_FC;
 292         } else if (req_rs) {
 293                 fec_type = IONIC_PORT_FEC_TYPE_RS;
 294         } else if (!(req_rs | req_fc)) {
 295                 fec_type = IONIC_PORT_FEC_TYPE_NONE;
 296         }
 297 
 298         if (fec_type != idev->port_info->config.fec_type) {
 299                 mutex_lock(&ionic->dev_cmd_lock);
 300                 ionic_dev_cmd_port_fec(idev, fec_type);
 301                 err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 302                 mutex_unlock(&ionic->dev_cmd_lock);
 303                 if (err)
 304                         return err;
 305         }
 306 
 307         return 0;
 308 }
 309 
 310 static void ionic_get_pauseparam(struct net_device *netdev,
 311                                  struct ethtool_pauseparam *pause)
 312 {
 313         struct ionic_lif *lif = netdev_priv(netdev);
 314         u8 pause_type;
 315 
 316         pause->autoneg = 0;
 317 
 318         pause_type = lif->ionic->idev.port_info->config.pause_type;
 319         if (pause_type) {
 320                 pause->rx_pause = pause_type & IONIC_PAUSE_F_RX ? 1 : 0;
 321                 pause->tx_pause = pause_type & IONIC_PAUSE_F_TX ? 1 : 0;
 322         }
 323 }
 324 
 325 static int ionic_set_pauseparam(struct net_device *netdev,
 326                                 struct ethtool_pauseparam *pause)
 327 {
 328         struct ionic_lif *lif = netdev_priv(netdev);
 329         struct ionic *ionic = lif->ionic;
 330         u32 requested_pause;
 331         int err;
 332 
 333         if (pause->autoneg)
 334                 return -EOPNOTSUPP;
 335 
 336         /* change both at the same time */
 337         requested_pause = IONIC_PORT_PAUSE_TYPE_LINK;
 338         if (pause->rx_pause)
 339                 requested_pause |= IONIC_PAUSE_F_RX;
 340         if (pause->tx_pause)
 341                 requested_pause |= IONIC_PAUSE_F_TX;
 342 
 343         if (requested_pause == lif->ionic->idev.port_info->config.pause_type)
 344                 return 0;
 345 
 346         mutex_lock(&ionic->dev_cmd_lock);
 347         ionic_dev_cmd_port_pause(&lif->ionic->idev, requested_pause);
 348         err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 349         mutex_unlock(&ionic->dev_cmd_lock);
 350         if (err)
 351                 return err;
 352 
 353         return 0;
 354 }
 355 
 356 static int ionic_get_coalesce(struct net_device *netdev,
 357                               struct ethtool_coalesce *coalesce)
 358 {
 359         struct ionic_lif *lif = netdev_priv(netdev);
 360 
 361         /* Tx uses Rx interrupt */
 362         coalesce->tx_coalesce_usecs = lif->rx_coalesce_usecs;
 363         coalesce->rx_coalesce_usecs = lif->rx_coalesce_usecs;
 364 
 365         return 0;
 366 }
 367 
 368 static int ionic_set_coalesce(struct net_device *netdev,
 369                               struct ethtool_coalesce *coalesce)
 370 {
 371         struct ionic_lif *lif = netdev_priv(netdev);
 372         struct ionic_identity *ident;
 373         struct ionic_qcq *qcq;
 374         unsigned int i;
 375         u32 usecs;
 376         u32 coal;
 377 
 378         if (coalesce->rx_max_coalesced_frames ||
 379             coalesce->rx_coalesce_usecs_irq ||
 380             coalesce->rx_max_coalesced_frames_irq ||
 381             coalesce->tx_max_coalesced_frames ||
 382             coalesce->tx_coalesce_usecs_irq ||
 383             coalesce->tx_max_coalesced_frames_irq ||
 384             coalesce->stats_block_coalesce_usecs ||
 385             coalesce->use_adaptive_rx_coalesce ||
 386             coalesce->use_adaptive_tx_coalesce ||
 387             coalesce->pkt_rate_low ||
 388             coalesce->rx_coalesce_usecs_low ||
 389             coalesce->rx_max_coalesced_frames_low ||
 390             coalesce->tx_coalesce_usecs_low ||
 391             coalesce->tx_max_coalesced_frames_low ||
 392             coalesce->pkt_rate_high ||
 393             coalesce->rx_coalesce_usecs_high ||
 394             coalesce->rx_max_coalesced_frames_high ||
 395             coalesce->tx_coalesce_usecs_high ||
 396             coalesce->tx_max_coalesced_frames_high ||
 397             coalesce->rate_sample_interval)
 398                 return -EINVAL;
 399 
 400         ident = &lif->ionic->ident;
 401         if (ident->dev.intr_coal_div == 0) {
 402                 netdev_warn(netdev, "bad HW value in dev.intr_coal_div = %d\n",
 403                             ident->dev.intr_coal_div);
 404                 return -EIO;
 405         }
 406 
 407         /* Tx uses Rx interrupt, so only change Rx */
 408         if (coalesce->tx_coalesce_usecs != lif->rx_coalesce_usecs) {
 409                 netdev_warn(netdev, "only the rx-usecs can be changed\n");
 410                 return -EINVAL;
 411         }
 412 
 413         coal = ionic_coal_usec_to_hw(lif->ionic, coalesce->rx_coalesce_usecs);
 414 
 415         if (coal > IONIC_INTR_CTRL_COAL_MAX)
 416                 return -ERANGE;
 417 
 418         /* If they asked for non-zero and it resolved to zero, bump it up */
 419         if (!coal && coalesce->rx_coalesce_usecs)
 420                 coal = 1;
 421 
 422         /* Convert it back to get device resolution */
 423         usecs = ionic_coal_hw_to_usec(lif->ionic, coal);
 424 
 425         if (usecs != lif->rx_coalesce_usecs) {
 426                 lif->rx_coalesce_usecs = usecs;
 427 
 428                 if (test_bit(IONIC_LIF_UP, lif->state)) {
 429                         for (i = 0; i < lif->nxqs; i++) {
 430                                 qcq = lif->rxqcqs[i].qcq;
 431                                 ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
 432                                                      qcq->intr.index, coal);
 433                         }
 434                 }
 435         }
 436 
 437         return 0;
 438 }
 439 
 440 static void ionic_get_ringparam(struct net_device *netdev,
 441                                 struct ethtool_ringparam *ring)
 442 {
 443         struct ionic_lif *lif = netdev_priv(netdev);
 444 
 445         ring->tx_max_pending = IONIC_MAX_TXRX_DESC;
 446         ring->tx_pending = lif->ntxq_descs;
 447         ring->rx_max_pending = IONIC_MAX_TXRX_DESC;
 448         ring->rx_pending = lif->nrxq_descs;
 449 }
 450 
 451 static int ionic_set_ringparam(struct net_device *netdev,
 452                                struct ethtool_ringparam *ring)
 453 {
 454         struct ionic_lif *lif = netdev_priv(netdev);
 455         bool running;
 456 
 457         if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
 458                 netdev_info(netdev, "Changing jumbo or mini descriptors not supported\n");
 459                 return -EINVAL;
 460         }
 461 
 462         if (!is_power_of_2(ring->tx_pending) ||
 463             !is_power_of_2(ring->rx_pending)) {
 464                 netdev_info(netdev, "Descriptor count must be a power of 2\n");
 465                 return -EINVAL;
 466         }
 467 
 468         /* if nothing to do return success */
 469         if (ring->tx_pending == lif->ntxq_descs &&
 470             ring->rx_pending == lif->nrxq_descs)
 471                 return 0;
 472 
 473         if (!ionic_wait_for_bit(lif, IONIC_LIF_QUEUE_RESET))
 474                 return -EBUSY;
 475 
 476         running = test_bit(IONIC_LIF_UP, lif->state);
 477         if (running)
 478                 ionic_stop(netdev);
 479 
 480         lif->ntxq_descs = ring->tx_pending;
 481         lif->nrxq_descs = ring->rx_pending;
 482 
 483         if (running)
 484                 ionic_open(netdev);
 485         clear_bit(IONIC_LIF_QUEUE_RESET, lif->state);
 486 
 487         return 0;
 488 }
 489 
 490 static void ionic_get_channels(struct net_device *netdev,
 491                                struct ethtool_channels *ch)
 492 {
 493         struct ionic_lif *lif = netdev_priv(netdev);
 494 
 495         /* report maximum channels */
 496         ch->max_combined = lif->ionic->ntxqs_per_lif;
 497 
 498         /* report current channels */
 499         ch->combined_count = lif->nxqs;
 500 }
 501 
 502 static int ionic_set_channels(struct net_device *netdev,
 503                               struct ethtool_channels *ch)
 504 {
 505         struct ionic_lif *lif = netdev_priv(netdev);
 506         bool running;
 507 
 508         if (!ch->combined_count || ch->other_count ||
 509             ch->rx_count || ch->tx_count)
 510                 return -EINVAL;
 511 
 512         if (ch->combined_count == lif->nxqs)
 513                 return 0;
 514 
 515         if (!ionic_wait_for_bit(lif, IONIC_LIF_QUEUE_RESET))
 516                 return -EBUSY;
 517 
 518         running = test_bit(IONIC_LIF_UP, lif->state);
 519         if (running)
 520                 ionic_stop(netdev);
 521 
 522         lif->nxqs = ch->combined_count;
 523 
 524         if (running)
 525                 ionic_open(netdev);
 526         clear_bit(IONIC_LIF_QUEUE_RESET, lif->state);
 527 
 528         return 0;
 529 }
 530 
 531 static u32 ionic_get_priv_flags(struct net_device *netdev)
 532 {
 533         struct ionic_lif *lif = netdev_priv(netdev);
 534         u32 priv_flags = 0;
 535 
 536         if (test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state))
 537                 priv_flags |= PRIV_F_SW_DBG_STATS;
 538 
 539         return priv_flags;
 540 }
 541 
 542 static int ionic_set_priv_flags(struct net_device *netdev, u32 priv_flags)
 543 {
 544         struct ionic_lif *lif = netdev_priv(netdev);
 545         u32 flags = lif->flags;
 546 
 547         clear_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state);
 548         if (priv_flags & PRIV_F_SW_DBG_STATS)
 549                 set_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state);
 550 
 551         if (flags != lif->flags)
 552                 lif->flags = flags;
 553 
 554         return 0;
 555 }
 556 
 557 static int ionic_get_rxnfc(struct net_device *netdev,
 558                            struct ethtool_rxnfc *info, u32 *rules)
 559 {
 560         struct ionic_lif *lif = netdev_priv(netdev);
 561         int err = 0;
 562 
 563         switch (info->cmd) {
 564         case ETHTOOL_GRXRINGS:
 565                 info->data = lif->nxqs;
 566                 break;
 567         default:
 568                 netdev_err(netdev, "Command parameter %d is not supported\n",
 569                            info->cmd);
 570                 err = -EOPNOTSUPP;
 571         }
 572 
 573         return err;
 574 }
 575 
 576 static u32 ionic_get_rxfh_indir_size(struct net_device *netdev)
 577 {
 578         struct ionic_lif *lif = netdev_priv(netdev);
 579 
 580         return le16_to_cpu(lif->ionic->ident.lif.eth.rss_ind_tbl_sz);
 581 }
 582 
 583 static u32 ionic_get_rxfh_key_size(struct net_device *netdev)
 584 {
 585         return IONIC_RSS_HASH_KEY_SIZE;
 586 }
 587 
 588 static int ionic_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
 589                           u8 *hfunc)
 590 {
 591         struct ionic_lif *lif = netdev_priv(netdev);
 592         unsigned int i, tbl_sz;
 593 
 594         if (indir) {
 595                 tbl_sz = le16_to_cpu(lif->ionic->ident.lif.eth.rss_ind_tbl_sz);
 596                 for (i = 0; i < tbl_sz; i++)
 597                         indir[i] = lif->rss_ind_tbl[i];
 598         }
 599 
 600         if (key)
 601                 memcpy(key, lif->rss_hash_key, IONIC_RSS_HASH_KEY_SIZE);
 602 
 603         if (hfunc)
 604                 *hfunc = ETH_RSS_HASH_TOP;
 605 
 606         return 0;
 607 }
 608 
 609 static int ionic_set_rxfh(struct net_device *netdev, const u32 *indir,
 610                           const u8 *key, const u8 hfunc)
 611 {
 612         struct ionic_lif *lif = netdev_priv(netdev);
 613         int err;
 614 
 615         if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
 616                 return -EOPNOTSUPP;
 617 
 618         err = ionic_lif_rss_config(lif, lif->rss_types, key, indir);
 619         if (err)
 620                 return err;
 621 
 622         return 0;
 623 }
 624 
 625 static int ionic_set_tunable(struct net_device *dev,
 626                              const struct ethtool_tunable *tuna,
 627                              const void *data)
 628 {
 629         struct ionic_lif *lif = netdev_priv(dev);
 630 
 631         switch (tuna->id) {
 632         case ETHTOOL_RX_COPYBREAK:
 633                 lif->rx_copybreak = *(u32 *)data;
 634                 break;
 635         default:
 636                 return -EOPNOTSUPP;
 637         }
 638 
 639         return 0;
 640 }
 641 
 642 static int ionic_get_tunable(struct net_device *netdev,
 643                              const struct ethtool_tunable *tuna, void *data)
 644 {
 645         struct ionic_lif *lif = netdev_priv(netdev);
 646 
 647         switch (tuna->id) {
 648         case ETHTOOL_RX_COPYBREAK:
 649                 *(u32 *)data = lif->rx_copybreak;
 650                 break;
 651         default:
 652                 return -EOPNOTSUPP;
 653         }
 654 
 655         return 0;
 656 }
 657 
 658 static int ionic_get_module_info(struct net_device *netdev,
 659                                  struct ethtool_modinfo *modinfo)
 660 
 661 {
 662         struct ionic_lif *lif = netdev_priv(netdev);
 663         struct ionic_dev *idev = &lif->ionic->idev;
 664         struct ionic_xcvr_status *xcvr;
 665 
 666         xcvr = &idev->port_info->status.xcvr;
 667 
 668         /* report the module data type and length */
 669         switch (xcvr->sprom[0]) {
 670         case 0x03: /* SFP */
 671                 modinfo->type = ETH_MODULE_SFF_8079;
 672                 modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
 673                 break;
 674         case 0x0D: /* QSFP */
 675         case 0x11: /* QSFP28 */
 676                 modinfo->type = ETH_MODULE_SFF_8436;
 677                 modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
 678                 break;
 679         default:
 680                 netdev_info(netdev, "unknown xcvr type 0x%02x\n",
 681                             xcvr->sprom[0]);
 682                 break;
 683         }
 684 
 685         return 0;
 686 }
 687 
 688 static int ionic_get_module_eeprom(struct net_device *netdev,
 689                                    struct ethtool_eeprom *ee,
 690                                    u8 *data)
 691 {
 692         struct ionic_lif *lif = netdev_priv(netdev);
 693         struct ionic_dev *idev = &lif->ionic->idev;
 694         struct ionic_xcvr_status *xcvr;
 695         char tbuf[sizeof(xcvr->sprom)];
 696         int count = 10;
 697         u32 len;
 698 
 699         /* The NIC keeps the module prom up-to-date in the DMA space
 700          * so we can simply copy the module bytes into the data buffer.
 701          */
 702         xcvr = &idev->port_info->status.xcvr;
 703         len = min_t(u32, sizeof(xcvr->sprom), ee->len);
 704 
 705         do {
 706                 memcpy(data, xcvr->sprom, len);
 707                 memcpy(tbuf, xcvr->sprom, len);
 708 
 709                 /* Let's make sure we got a consistent copy */
 710                 if (!memcmp(data, tbuf, len))
 711                         break;
 712 
 713         } while (--count);
 714 
 715         if (!count)
 716                 return -ETIMEDOUT;
 717 
 718         return 0;
 719 }
 720 
 721 static int ionic_nway_reset(struct net_device *netdev)
 722 {
 723         struct ionic_lif *lif = netdev_priv(netdev);
 724         struct ionic *ionic = lif->ionic;
 725         int err = 0;
 726 
 727         /* flap the link to force auto-negotiation */
 728 
 729         mutex_lock(&ionic->dev_cmd_lock);
 730 
 731         ionic_dev_cmd_port_state(&ionic->idev, IONIC_PORT_ADMIN_STATE_DOWN);
 732         err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 733 
 734         if (!err) {
 735                 ionic_dev_cmd_port_state(&ionic->idev, IONIC_PORT_ADMIN_STATE_UP);
 736                 err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 737         }
 738 
 739         mutex_unlock(&ionic->dev_cmd_lock);
 740 
 741         return err;
 742 }
 743 
 744 static const struct ethtool_ops ionic_ethtool_ops = {
 745         .get_drvinfo            = ionic_get_drvinfo,
 746         .get_regs_len           = ionic_get_regs_len,
 747         .get_regs               = ionic_get_regs,
 748         .get_link               = ethtool_op_get_link,
 749         .get_link_ksettings     = ionic_get_link_ksettings,
 750         .get_coalesce           = ionic_get_coalesce,
 751         .set_coalesce           = ionic_set_coalesce,
 752         .get_ringparam          = ionic_get_ringparam,
 753         .set_ringparam          = ionic_set_ringparam,
 754         .get_channels           = ionic_get_channels,
 755         .set_channels           = ionic_set_channels,
 756         .get_strings            = ionic_get_strings,
 757         .get_ethtool_stats      = ionic_get_stats,
 758         .get_sset_count         = ionic_get_sset_count,
 759         .get_priv_flags         = ionic_get_priv_flags,
 760         .set_priv_flags         = ionic_set_priv_flags,
 761         .get_rxnfc              = ionic_get_rxnfc,
 762         .get_rxfh_indir_size    = ionic_get_rxfh_indir_size,
 763         .get_rxfh_key_size      = ionic_get_rxfh_key_size,
 764         .get_rxfh               = ionic_get_rxfh,
 765         .set_rxfh               = ionic_set_rxfh,
 766         .get_tunable            = ionic_get_tunable,
 767         .set_tunable            = ionic_set_tunable,
 768         .get_module_info        = ionic_get_module_info,
 769         .get_module_eeprom      = ionic_get_module_eeprom,
 770         .get_pauseparam         = ionic_get_pauseparam,
 771         .set_pauseparam         = ionic_set_pauseparam,
 772         .set_link_ksettings     = ionic_set_link_ksettings,
 773         .nway_reset             = ionic_nway_reset,
 774 };
 775 
 776 void ionic_ethtool_set_ops(struct net_device *netdev)
 777 {
 778         netdev->ethtool_ops = &ionic_ethtool_ops;
 779 }

/* [<][>][^][v][top][bottom][index][help] */