linux/drivers/net/vmxnet3/vmxnet3_ethtool.c
<<
>>
Prefs
   1/*
   2 * Linux driver for VMware's vmxnet3 ethernet NIC.
   3 *
   4 * Copyright (C) 2008-2016, VMware, Inc. All Rights Reserved.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms of the GNU General Public License as published by the
   8 * Free Software Foundation; version 2 of the License and no later version.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  13 * NON INFRINGEMENT.  See the GNU General Public License for more
  14 * details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19 *
  20 * The full GNU General Public License is included in this distribution in
  21 * the file called "COPYING".
  22 *
  23 * Maintained by: pv-drivers@vmware.com
  24 *
  25 */
  26
  27
  28#include "vmxnet3_int.h"
  29
  30struct vmxnet3_stat_desc {
  31        char desc[ETH_GSTRING_LEN];
  32        int  offset;
  33};
  34
  35
  36/* per tq stats maintained by the device */
  37static const struct vmxnet3_stat_desc
  38vmxnet3_tq_dev_stats[] = {
  39        /* description,         offset */
  40        { "Tx Queue#",        0 },
  41        { "  TSO pkts tx",      offsetof(struct UPT1_TxStats, TSOPktsTxOK) },
  42        { "  TSO bytes tx",     offsetof(struct UPT1_TxStats, TSOBytesTxOK) },
  43        { "  ucast pkts tx",    offsetof(struct UPT1_TxStats, ucastPktsTxOK) },
  44        { "  ucast bytes tx",   offsetof(struct UPT1_TxStats, ucastBytesTxOK) },
  45        { "  mcast pkts tx",    offsetof(struct UPT1_TxStats, mcastPktsTxOK) },
  46        { "  mcast bytes tx",   offsetof(struct UPT1_TxStats, mcastBytesTxOK) },
  47        { "  bcast pkts tx",    offsetof(struct UPT1_TxStats, bcastPktsTxOK) },
  48        { "  bcast bytes tx",   offsetof(struct UPT1_TxStats, bcastBytesTxOK) },
  49        { "  pkts tx err",      offsetof(struct UPT1_TxStats, pktsTxError) },
  50        { "  pkts tx discard",  offsetof(struct UPT1_TxStats, pktsTxDiscard) },
  51};
  52
  53/* per tq stats maintained by the driver */
  54static const struct vmxnet3_stat_desc
  55vmxnet3_tq_driver_stats[] = {
  56        /* description,         offset */
  57        {"  drv dropped tx total",      offsetof(struct vmxnet3_tq_driver_stats,
  58                                                 drop_total) },
  59        { "     too many frags", offsetof(struct vmxnet3_tq_driver_stats,
  60                                          drop_too_many_frags) },
  61        { "     giant hdr",     offsetof(struct vmxnet3_tq_driver_stats,
  62                                         drop_oversized_hdr) },
  63        { "     hdr err",       offsetof(struct vmxnet3_tq_driver_stats,
  64                                         drop_hdr_inspect_err) },
  65        { "     tso",           offsetof(struct vmxnet3_tq_driver_stats,
  66                                         drop_tso) },
  67        { "  ring full",        offsetof(struct vmxnet3_tq_driver_stats,
  68                                         tx_ring_full) },
  69        { "  pkts linearized",  offsetof(struct vmxnet3_tq_driver_stats,
  70                                         linearized) },
  71        { "  hdr cloned",       offsetof(struct vmxnet3_tq_driver_stats,
  72                                         copy_skb_header) },
  73        { "  giant hdr",        offsetof(struct vmxnet3_tq_driver_stats,
  74                                         oversized_hdr) },
  75};
  76
  77/* per rq stats maintained by the device */
  78static const struct vmxnet3_stat_desc
  79vmxnet3_rq_dev_stats[] = {
  80        { "Rx Queue#",        0 },
  81        { "  LRO pkts rx",      offsetof(struct UPT1_RxStats, LROPktsRxOK) },
  82        { "  LRO byte rx",      offsetof(struct UPT1_RxStats, LROBytesRxOK) },
  83        { "  ucast pkts rx",    offsetof(struct UPT1_RxStats, ucastPktsRxOK) },
  84        { "  ucast bytes rx",   offsetof(struct UPT1_RxStats, ucastBytesRxOK) },
  85        { "  mcast pkts rx",    offsetof(struct UPT1_RxStats, mcastPktsRxOK) },
  86        { "  mcast bytes rx",   offsetof(struct UPT1_RxStats, mcastBytesRxOK) },
  87        { "  bcast pkts rx",    offsetof(struct UPT1_RxStats, bcastPktsRxOK) },
  88        { "  bcast bytes rx",   offsetof(struct UPT1_RxStats, bcastBytesRxOK) },
  89        { "  pkts rx OOB",      offsetof(struct UPT1_RxStats, pktsRxOutOfBuf) },
  90        { "  pkts rx err",      offsetof(struct UPT1_RxStats, pktsRxError) },
  91};
  92
  93/* per rq stats maintained by the driver */
  94static const struct vmxnet3_stat_desc
  95vmxnet3_rq_driver_stats[] = {
  96        /* description,         offset */
  97        { "  drv dropped rx total", offsetof(struct vmxnet3_rq_driver_stats,
  98                                             drop_total) },
  99        { "     err",           offsetof(struct vmxnet3_rq_driver_stats,
 100                                         drop_err) },
 101        { "     fcs",           offsetof(struct vmxnet3_rq_driver_stats,
 102                                         drop_fcs) },
 103        { "  rx buf alloc fail", offsetof(struct vmxnet3_rq_driver_stats,
 104                                          rx_buf_alloc_failure) },
 105};
 106
 107/* global stats maintained by the driver */
 108static const struct vmxnet3_stat_desc
 109vmxnet3_global_stats[] = {
 110        /* description,         offset */
 111        { "tx timeout count",   offsetof(struct vmxnet3_adapter,
 112                                         tx_timeout_count) }
 113};
 114
 115
 116void
 117vmxnet3_get_stats64(struct net_device *netdev,
 118                   struct rtnl_link_stats64 *stats)
 119{
 120        struct vmxnet3_adapter *adapter;
 121        struct vmxnet3_tq_driver_stats *drvTxStats;
 122        struct vmxnet3_rq_driver_stats *drvRxStats;
 123        struct UPT1_TxStats *devTxStats;
 124        struct UPT1_RxStats *devRxStats;
 125        unsigned long flags;
 126        int i;
 127
 128        adapter = netdev_priv(netdev);
 129
 130        /* Collect the dev stats into the shared area */
 131        spin_lock_irqsave(&adapter->cmd_lock, flags);
 132        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
 133        spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 134
 135        for (i = 0; i < adapter->num_tx_queues; i++) {
 136                devTxStats = &adapter->tqd_start[i].stats;
 137                drvTxStats = &adapter->tx_queue[i].stats;
 138                stats->tx_packets += devTxStats->ucastPktsTxOK +
 139                                     devTxStats->mcastPktsTxOK +
 140                                     devTxStats->bcastPktsTxOK;
 141                stats->tx_bytes += devTxStats->ucastBytesTxOK +
 142                                   devTxStats->mcastBytesTxOK +
 143                                   devTxStats->bcastBytesTxOK;
 144                stats->tx_errors += devTxStats->pktsTxError;
 145                stats->tx_dropped += drvTxStats->drop_total;
 146        }
 147
 148        for (i = 0; i < adapter->num_rx_queues; i++) {
 149                devRxStats = &adapter->rqd_start[i].stats;
 150                drvRxStats = &adapter->rx_queue[i].stats;
 151                stats->rx_packets += devRxStats->ucastPktsRxOK +
 152                                     devRxStats->mcastPktsRxOK +
 153                                     devRxStats->bcastPktsRxOK;
 154
 155                stats->rx_bytes += devRxStats->ucastBytesRxOK +
 156                                   devRxStats->mcastBytesRxOK +
 157                                   devRxStats->bcastBytesRxOK;
 158
 159                stats->rx_errors += devRxStats->pktsRxError;
 160                stats->rx_dropped += drvRxStats->drop_total;
 161                stats->multicast +=  devRxStats->mcastPktsRxOK;
 162        }
 163}
 164
 165static int
 166vmxnet3_get_sset_count(struct net_device *netdev, int sset)
 167{
 168        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 169        switch (sset) {
 170        case ETH_SS_STATS:
 171                return (ARRAY_SIZE(vmxnet3_tq_dev_stats) +
 172                        ARRAY_SIZE(vmxnet3_tq_driver_stats)) *
 173                       adapter->num_tx_queues +
 174                       (ARRAY_SIZE(vmxnet3_rq_dev_stats) +
 175                        ARRAY_SIZE(vmxnet3_rq_driver_stats)) *
 176                       adapter->num_rx_queues +
 177                        ARRAY_SIZE(vmxnet3_global_stats);
 178        default:
 179                return -EOPNOTSUPP;
 180        }
 181}
 182
 183
 184/* This is a version 2 of the vmxnet3 ethtool_regs which goes hand in hand with
 185 * the version 2 of the vmxnet3 support for ethtool(8) --register-dump.
 186 * Therefore, if any registers are added, removed or modified, then a version
 187 * bump and a corresponding change in the vmxnet3 support for ethtool(8)
 188 * --register-dump would be required.
 189 */
 190static int
 191vmxnet3_get_regs_len(struct net_device *netdev)
 192{
 193        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 194
 195        return ((9 /* BAR1 registers */ +
 196                (1 + adapter->intr.num_intrs) +
 197                (1 + adapter->num_tx_queues * 17 /* Tx queue registers */) +
 198                (1 + adapter->num_rx_queues * 23 /* Rx queue registers */)) *
 199                sizeof(u32));
 200}
 201
 202
 203static void
 204vmxnet3_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
 205{
 206        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 207
 208        strlcpy(drvinfo->driver, vmxnet3_driver_name, sizeof(drvinfo->driver));
 209
 210        strlcpy(drvinfo->version, VMXNET3_DRIVER_VERSION_REPORT,
 211                sizeof(drvinfo->version));
 212
 213        strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
 214                sizeof(drvinfo->bus_info));
 215}
 216
 217
 218static void
 219vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
 220{
 221         struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 222        if (stringset == ETH_SS_STATS) {
 223                int i, j;
 224                for (j = 0; j < adapter->num_tx_queues; j++) {
 225                        for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++) {
 226                                memcpy(buf, vmxnet3_tq_dev_stats[i].desc,
 227                                       ETH_GSTRING_LEN);
 228                                buf += ETH_GSTRING_LEN;
 229                        }
 230                        for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats);
 231                             i++) {
 232                                memcpy(buf, vmxnet3_tq_driver_stats[i].desc,
 233                                       ETH_GSTRING_LEN);
 234                                buf += ETH_GSTRING_LEN;
 235                        }
 236                }
 237
 238                for (j = 0; j < adapter->num_rx_queues; j++) {
 239                        for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++) {
 240                                memcpy(buf, vmxnet3_rq_dev_stats[i].desc,
 241                                       ETH_GSTRING_LEN);
 242                                buf += ETH_GSTRING_LEN;
 243                        }
 244                        for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats);
 245                             i++) {
 246                                memcpy(buf, vmxnet3_rq_driver_stats[i].desc,
 247                                       ETH_GSTRING_LEN);
 248                                buf += ETH_GSTRING_LEN;
 249                        }
 250                }
 251
 252                for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++) {
 253                        memcpy(buf, vmxnet3_global_stats[i].desc,
 254                                ETH_GSTRING_LEN);
 255                        buf += ETH_GSTRING_LEN;
 256                }
 257        }
 258}
 259
 260int vmxnet3_set_features(struct net_device *netdev, netdev_features_t features)
 261{
 262        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 263        unsigned long flags;
 264        netdev_features_t changed = features ^ netdev->features;
 265
 266        if (changed & (NETIF_F_RXCSUM | NETIF_F_LRO |
 267                       NETIF_F_HW_VLAN_CTAG_RX)) {
 268                if (features & NETIF_F_RXCSUM)
 269                        adapter->shared->devRead.misc.uptFeatures |=
 270                        UPT1_F_RXCSUM;
 271                else
 272                        adapter->shared->devRead.misc.uptFeatures &=
 273                        ~UPT1_F_RXCSUM;
 274
 275                /* update hardware LRO capability accordingly */
 276                if (features & NETIF_F_LRO)
 277                        adapter->shared->devRead.misc.uptFeatures |=
 278                                                        UPT1_F_LRO;
 279                else
 280                        adapter->shared->devRead.misc.uptFeatures &=
 281                                                        ~UPT1_F_LRO;
 282
 283                if (features & NETIF_F_HW_VLAN_CTAG_RX)
 284                        adapter->shared->devRead.misc.uptFeatures |=
 285                        UPT1_F_RXVLAN;
 286                else
 287                        adapter->shared->devRead.misc.uptFeatures &=
 288                        ~UPT1_F_RXVLAN;
 289
 290                spin_lock_irqsave(&adapter->cmd_lock, flags);
 291                VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
 292                                       VMXNET3_CMD_UPDATE_FEATURE);
 293                spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 294        }
 295        return 0;
 296}
 297
 298static void
 299vmxnet3_get_ethtool_stats(struct net_device *netdev,
 300                          struct ethtool_stats *stats, u64  *buf)
 301{
 302        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 303        unsigned long flags;
 304        u8 *base;
 305        int i;
 306        int j = 0;
 307
 308        spin_lock_irqsave(&adapter->cmd_lock, flags);
 309        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
 310        spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 311
 312        /* this does assume each counter is 64-bit wide */
 313        for (j = 0; j < adapter->num_tx_queues; j++) {
 314                base = (u8 *)&adapter->tqd_start[j].stats;
 315                *buf++ = (u64)j;
 316                for (i = 1; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++)
 317                        *buf++ = *(u64 *)(base +
 318                                          vmxnet3_tq_dev_stats[i].offset);
 319
 320                base = (u8 *)&adapter->tx_queue[j].stats;
 321                for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++)
 322                        *buf++ = *(u64 *)(base +
 323                                          vmxnet3_tq_driver_stats[i].offset);
 324        }
 325
 326        for (j = 0; j < adapter->num_rx_queues; j++) {
 327                base = (u8 *)&adapter->rqd_start[j].stats;
 328                *buf++ = (u64) j;
 329                for (i = 1; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++)
 330                        *buf++ = *(u64 *)(base +
 331                                          vmxnet3_rq_dev_stats[i].offset);
 332
 333                base = (u8 *)&adapter->rx_queue[j].stats;
 334                for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++)
 335                        *buf++ = *(u64 *)(base +
 336                                          vmxnet3_rq_driver_stats[i].offset);
 337        }
 338
 339        base = (u8 *)adapter;
 340        for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++)
 341                *buf++ = *(u64 *)(base + vmxnet3_global_stats[i].offset);
 342}
 343
 344
 345/* This is a version 2 of the vmxnet3 ethtool_regs which goes hand in hand with
 346 * the version 2 of the vmxnet3 support for ethtool(8) --register-dump.
 347 * Therefore, if any registers are added, removed or modified, then a version
 348 * bump and a corresponding change in the vmxnet3 support for ethtool(8)
 349 * --register-dump would be required.
 350 */
 351static void
 352vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
 353{
 354        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 355        u32 *buf = p;
 356        int i = 0, j = 0;
 357
 358        memset(p, 0, vmxnet3_get_regs_len(netdev));
 359
 360        regs->version = 2;
 361
 362        /* Update vmxnet3_get_regs_len if we want to dump more registers */
 363
 364        buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_VRRS);
 365        buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_UVRS);
 366        buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_DSAL);
 367        buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_DSAH);
 368        buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
 369        buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_MACL);
 370        buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_MACH);
 371        buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_ICR);
 372        buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_ECR);
 373
 374        buf[j++] = adapter->intr.num_intrs;
 375        for (i = 0; i < adapter->intr.num_intrs; i++) {
 376                buf[j++] = VMXNET3_READ_BAR0_REG(adapter, VMXNET3_REG_IMR
 377                                                 + i * VMXNET3_REG_ALIGN);
 378        }
 379
 380        buf[j++] = adapter->num_tx_queues;
 381        for (i = 0; i < adapter->num_tx_queues; i++) {
 382                struct vmxnet3_tx_queue *tq = &adapter->tx_queue[i];
 383
 384                buf[j++] = VMXNET3_READ_BAR0_REG(adapter, VMXNET3_REG_TXPROD +
 385                                                 i * VMXNET3_REG_ALIGN);
 386
 387                buf[j++] = VMXNET3_GET_ADDR_LO(tq->tx_ring.basePA);
 388                buf[j++] = VMXNET3_GET_ADDR_HI(tq->tx_ring.basePA);
 389                buf[j++] = tq->tx_ring.size;
 390                buf[j++] = tq->tx_ring.next2fill;
 391                buf[j++] = tq->tx_ring.next2comp;
 392                buf[j++] = tq->tx_ring.gen;
 393
 394                buf[j++] = VMXNET3_GET_ADDR_LO(tq->data_ring.basePA);
 395                buf[j++] = VMXNET3_GET_ADDR_HI(tq->data_ring.basePA);
 396                buf[j++] = tq->data_ring.size;
 397                buf[j++] = tq->txdata_desc_size;
 398
 399                buf[j++] = VMXNET3_GET_ADDR_LO(tq->comp_ring.basePA);
 400                buf[j++] = VMXNET3_GET_ADDR_HI(tq->comp_ring.basePA);
 401                buf[j++] = tq->comp_ring.size;
 402                buf[j++] = tq->comp_ring.next2proc;
 403                buf[j++] = tq->comp_ring.gen;
 404
 405                buf[j++] = tq->stopped;
 406        }
 407
 408        buf[j++] = adapter->num_rx_queues;
 409        for (i = 0; i < adapter->num_rx_queues; i++) {
 410                struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i];
 411
 412                buf[j++] =  VMXNET3_READ_BAR0_REG(adapter, VMXNET3_REG_RXPROD +
 413                                                  i * VMXNET3_REG_ALIGN);
 414                buf[j++] =  VMXNET3_READ_BAR0_REG(adapter, VMXNET3_REG_RXPROD2 +
 415                                                  i * VMXNET3_REG_ALIGN);
 416
 417                buf[j++] = VMXNET3_GET_ADDR_LO(rq->rx_ring[0].basePA);
 418                buf[j++] = VMXNET3_GET_ADDR_HI(rq->rx_ring[0].basePA);
 419                buf[j++] = rq->rx_ring[0].size;
 420                buf[j++] = rq->rx_ring[0].next2fill;
 421                buf[j++] = rq->rx_ring[0].next2comp;
 422                buf[j++] = rq->rx_ring[0].gen;
 423
 424                buf[j++] = VMXNET3_GET_ADDR_LO(rq->rx_ring[1].basePA);
 425                buf[j++] = VMXNET3_GET_ADDR_HI(rq->rx_ring[1].basePA);
 426                buf[j++] = rq->rx_ring[1].size;
 427                buf[j++] = rq->rx_ring[1].next2fill;
 428                buf[j++] = rq->rx_ring[1].next2comp;
 429                buf[j++] = rq->rx_ring[1].gen;
 430
 431                buf[j++] = VMXNET3_GET_ADDR_LO(rq->data_ring.basePA);
 432                buf[j++] = VMXNET3_GET_ADDR_HI(rq->data_ring.basePA);
 433                buf[j++] = rq->rx_ring[0].size;
 434                buf[j++] = rq->data_ring.desc_size;
 435
 436                buf[j++] = VMXNET3_GET_ADDR_LO(rq->comp_ring.basePA);
 437                buf[j++] = VMXNET3_GET_ADDR_HI(rq->comp_ring.basePA);
 438                buf[j++] = rq->comp_ring.size;
 439                buf[j++] = rq->comp_ring.next2proc;
 440                buf[j++] = rq->comp_ring.gen;
 441        }
 442}
 443
 444
 445static void
 446vmxnet3_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 447{
 448        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 449
 450        wol->supported = WAKE_UCAST | WAKE_ARP | WAKE_MAGIC;
 451        wol->wolopts = adapter->wol;
 452}
 453
 454
 455static int
 456vmxnet3_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 457{
 458        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 459
 460        if (wol->wolopts & (WAKE_PHY | WAKE_MCAST | WAKE_BCAST |
 461                            WAKE_MAGICSECURE)) {
 462                return -EOPNOTSUPP;
 463        }
 464
 465        adapter->wol = wol->wolopts;
 466
 467        device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
 468
 469        return 0;
 470}
 471
 472
 473static int
 474vmxnet3_get_link_ksettings(struct net_device *netdev,
 475                           struct ethtool_link_ksettings *ecmd)
 476{
 477        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 478
 479        ethtool_link_ksettings_zero_link_mode(ecmd, supported);
 480        ethtool_link_ksettings_add_link_mode(ecmd, supported, 10000baseT_Full);
 481        ethtool_link_ksettings_add_link_mode(ecmd, supported, 1000baseT_Full);
 482        ethtool_link_ksettings_add_link_mode(ecmd, supported, TP);
 483        ethtool_link_ksettings_zero_link_mode(ecmd, advertising);
 484        ethtool_link_ksettings_add_link_mode(ecmd, advertising, TP);
 485        ecmd->base.port = PORT_TP;
 486
 487        if (adapter->link_speed) {
 488                ecmd->base.speed = adapter->link_speed;
 489                ecmd->base.duplex = DUPLEX_FULL;
 490        } else {
 491                ecmd->base.speed = SPEED_UNKNOWN;
 492                ecmd->base.duplex = DUPLEX_UNKNOWN;
 493        }
 494        return 0;
 495}
 496
 497
 498static void
 499vmxnet3_get_ringparam(struct net_device *netdev,
 500                      struct ethtool_ringparam *param)
 501{
 502        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 503
 504        param->rx_max_pending = VMXNET3_RX_RING_MAX_SIZE;
 505        param->tx_max_pending = VMXNET3_TX_RING_MAX_SIZE;
 506        param->rx_mini_max_pending = VMXNET3_VERSION_GE_3(adapter) ?
 507                VMXNET3_RXDATA_DESC_MAX_SIZE : 0;
 508        param->rx_jumbo_max_pending = VMXNET3_RX_RING2_MAX_SIZE;
 509
 510        param->rx_pending = adapter->rx_ring_size;
 511        param->tx_pending = adapter->tx_ring_size;
 512        param->rx_mini_pending = VMXNET3_VERSION_GE_3(adapter) ?
 513                adapter->rxdata_desc_size : 0;
 514        param->rx_jumbo_pending = adapter->rx_ring2_size;
 515}
 516
 517
 518static int
 519vmxnet3_set_ringparam(struct net_device *netdev,
 520                      struct ethtool_ringparam *param)
 521{
 522        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 523        u32 new_tx_ring_size, new_rx_ring_size, new_rx_ring2_size;
 524        u16 new_rxdata_desc_size;
 525        u32 sz;
 526        int err = 0;
 527
 528        if (param->tx_pending == 0 || param->tx_pending >
 529                                                VMXNET3_TX_RING_MAX_SIZE)
 530                return -EINVAL;
 531
 532        if (param->rx_pending == 0 || param->rx_pending >
 533                                                VMXNET3_RX_RING_MAX_SIZE)
 534                return -EINVAL;
 535
 536        if (param->rx_jumbo_pending == 0 ||
 537            param->rx_jumbo_pending > VMXNET3_RX_RING2_MAX_SIZE)
 538                return -EINVAL;
 539
 540        /* if adapter not yet initialized, do nothing */
 541        if (adapter->rx_buf_per_pkt == 0) {
 542                netdev_err(netdev, "adapter not completely initialized, "
 543                           "ring size cannot be changed yet\n");
 544                return -EOPNOTSUPP;
 545        }
 546
 547        if (VMXNET3_VERSION_GE_3(adapter)) {
 548                if (param->rx_mini_pending < 0 ||
 549                    param->rx_mini_pending > VMXNET3_RXDATA_DESC_MAX_SIZE) {
 550                        return -EINVAL;
 551                }
 552        } else if (param->rx_mini_pending != 0) {
 553                return -EINVAL;
 554        }
 555
 556        /* round it up to a multiple of VMXNET3_RING_SIZE_ALIGN */
 557        new_tx_ring_size = (param->tx_pending + VMXNET3_RING_SIZE_MASK) &
 558                                                        ~VMXNET3_RING_SIZE_MASK;
 559        new_tx_ring_size = min_t(u32, new_tx_ring_size,
 560                                 VMXNET3_TX_RING_MAX_SIZE);
 561        if (new_tx_ring_size > VMXNET3_TX_RING_MAX_SIZE || (new_tx_ring_size %
 562                                                VMXNET3_RING_SIZE_ALIGN) != 0)
 563                return -EINVAL;
 564
 565        /* ring0 has to be a multiple of
 566         * rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN
 567         */
 568        sz = adapter->rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN;
 569        new_rx_ring_size = (param->rx_pending + sz - 1) / sz * sz;
 570        new_rx_ring_size = min_t(u32, new_rx_ring_size,
 571                                 VMXNET3_RX_RING_MAX_SIZE / sz * sz);
 572        if (new_rx_ring_size > VMXNET3_RX_RING_MAX_SIZE || (new_rx_ring_size %
 573                                                           sz) != 0)
 574                return -EINVAL;
 575
 576        /* ring2 has to be a multiple of VMXNET3_RING_SIZE_ALIGN */
 577        new_rx_ring2_size = (param->rx_jumbo_pending + VMXNET3_RING_SIZE_MASK) &
 578                                ~VMXNET3_RING_SIZE_MASK;
 579        new_rx_ring2_size = min_t(u32, new_rx_ring2_size,
 580                                  VMXNET3_RX_RING2_MAX_SIZE);
 581
 582        /* rx data ring buffer size has to be a multiple of
 583         * VMXNET3_RXDATA_DESC_SIZE_ALIGN
 584         */
 585        new_rxdata_desc_size =
 586                (param->rx_mini_pending + VMXNET3_RXDATA_DESC_SIZE_MASK) &
 587                ~VMXNET3_RXDATA_DESC_SIZE_MASK;
 588        new_rxdata_desc_size = min_t(u16, new_rxdata_desc_size,
 589                                     VMXNET3_RXDATA_DESC_MAX_SIZE);
 590
 591        if (new_tx_ring_size == adapter->tx_ring_size &&
 592            new_rx_ring_size == adapter->rx_ring_size &&
 593            new_rx_ring2_size == adapter->rx_ring2_size &&
 594            new_rxdata_desc_size == adapter->rxdata_desc_size) {
 595                return 0;
 596        }
 597
 598        /*
 599         * Reset_work may be in the middle of resetting the device, wait for its
 600         * completion.
 601         */
 602        while (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
 603                usleep_range(1000, 2000);
 604
 605        if (netif_running(netdev)) {
 606                vmxnet3_quiesce_dev(adapter);
 607                vmxnet3_reset_dev(adapter);
 608
 609                /* recreate the rx queue and the tx queue based on the
 610                 * new sizes */
 611                vmxnet3_tq_destroy_all(adapter);
 612                vmxnet3_rq_destroy_all(adapter);
 613
 614                err = vmxnet3_create_queues(adapter, new_tx_ring_size,
 615                                            new_rx_ring_size, new_rx_ring2_size,
 616                                            adapter->txdata_desc_size,
 617                                            new_rxdata_desc_size);
 618                if (err) {
 619                        /* failed, most likely because of OOM, try default
 620                         * size */
 621                        netdev_err(netdev, "failed to apply new sizes, "
 622                                   "try the default ones\n");
 623                        new_rx_ring_size = VMXNET3_DEF_RX_RING_SIZE;
 624                        new_rx_ring2_size = VMXNET3_DEF_RX_RING2_SIZE;
 625                        new_tx_ring_size = VMXNET3_DEF_TX_RING_SIZE;
 626                        new_rxdata_desc_size = VMXNET3_VERSION_GE_3(adapter) ?
 627                                VMXNET3_DEF_RXDATA_DESC_SIZE : 0;
 628
 629                        err = vmxnet3_create_queues(adapter,
 630                                                    new_tx_ring_size,
 631                                                    new_rx_ring_size,
 632                                                    new_rx_ring2_size,
 633                                                    adapter->txdata_desc_size,
 634                                                    new_rxdata_desc_size);
 635                        if (err) {
 636                                netdev_err(netdev, "failed to create queues "
 637                                           "with default sizes. Closing it\n");
 638                                goto out;
 639                        }
 640                }
 641
 642                err = vmxnet3_activate_dev(adapter);
 643                if (err)
 644                        netdev_err(netdev, "failed to re-activate, error %d."
 645                                   " Closing it\n", err);
 646        }
 647        adapter->tx_ring_size = new_tx_ring_size;
 648        adapter->rx_ring_size = new_rx_ring_size;
 649        adapter->rx_ring2_size = new_rx_ring2_size;
 650        adapter->rxdata_desc_size = new_rxdata_desc_size;
 651
 652out:
 653        clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
 654        if (err)
 655                vmxnet3_force_close(adapter);
 656
 657        return err;
 658}
 659
 660
 661static int
 662vmxnet3_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info,
 663                  u32 *rules)
 664{
 665        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 666        switch (info->cmd) {
 667        case ETHTOOL_GRXRINGS:
 668                info->data = adapter->num_rx_queues;
 669                return 0;
 670        }
 671        return -EOPNOTSUPP;
 672}
 673
 674#ifdef VMXNET3_RSS
 675static u32
 676vmxnet3_get_rss_indir_size(struct net_device *netdev)
 677{
 678        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 679        struct UPT1_RSSConf *rssConf = adapter->rss_conf;
 680
 681        return rssConf->indTableSize;
 682}
 683
 684static int
 685vmxnet3_get_rss(struct net_device *netdev, u32 *p, u8 *key, u8 *hfunc)
 686{
 687        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 688        struct UPT1_RSSConf *rssConf = adapter->rss_conf;
 689        unsigned int n = rssConf->indTableSize;
 690
 691        if (hfunc)
 692                *hfunc = ETH_RSS_HASH_TOP;
 693        if (!p)
 694                return 0;
 695        while (n--)
 696                p[n] = rssConf->indTable[n];
 697        return 0;
 698
 699}
 700
 701static int
 702vmxnet3_set_rss(struct net_device *netdev, const u32 *p, const u8 *key,
 703                const u8 hfunc)
 704{
 705        unsigned int i;
 706        unsigned long flags;
 707        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 708        struct UPT1_RSSConf *rssConf = adapter->rss_conf;
 709
 710        /* We do not allow change in unsupported parameters */
 711        if (key ||
 712            (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
 713                return -EOPNOTSUPP;
 714        if (!p)
 715                return 0;
 716        for (i = 0; i < rssConf->indTableSize; i++)
 717                rssConf->indTable[i] = p[i];
 718
 719        spin_lock_irqsave(&adapter->cmd_lock, flags);
 720        VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
 721                               VMXNET3_CMD_UPDATE_RSSIDT);
 722        spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 723
 724        return 0;
 725
 726}
 727#endif
 728
 729static int
 730vmxnet3_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec)
 731{
 732        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 733
 734        if (!VMXNET3_VERSION_GE_3(adapter))
 735                return -EOPNOTSUPP;
 736
 737        switch (adapter->coal_conf->coalMode) {
 738        case VMXNET3_COALESCE_DISABLED:
 739                /* struct ethtool_coalesce is already initialized to 0 */
 740                break;
 741        case VMXNET3_COALESCE_ADAPT:
 742                ec->use_adaptive_rx_coalesce = true;
 743                break;
 744        case VMXNET3_COALESCE_STATIC:
 745                ec->tx_max_coalesced_frames =
 746                        adapter->coal_conf->coalPara.coalStatic.tx_comp_depth;
 747                ec->rx_max_coalesced_frames =
 748                        adapter->coal_conf->coalPara.coalStatic.rx_depth;
 749                break;
 750        case VMXNET3_COALESCE_RBC: {
 751                u32 rbc_rate;
 752
 753                rbc_rate = adapter->coal_conf->coalPara.coalRbc.rbc_rate;
 754                ec->rx_coalesce_usecs = VMXNET3_COAL_RBC_USECS(rbc_rate);
 755        }
 756                break;
 757        default:
 758                return -EOPNOTSUPP;
 759        }
 760
 761        return 0;
 762}
 763
 764static int
 765vmxnet3_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec)
 766{
 767        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 768        struct Vmxnet3_DriverShared *shared = adapter->shared;
 769        union Vmxnet3_CmdInfo *cmdInfo = &shared->cu.cmdInfo;
 770        unsigned long flags;
 771
 772        if (!VMXNET3_VERSION_GE_3(adapter))
 773                return -EOPNOTSUPP;
 774
 775        if (ec->rx_coalesce_usecs_irq ||
 776            ec->rx_max_coalesced_frames_irq ||
 777            ec->tx_coalesce_usecs ||
 778            ec->tx_coalesce_usecs_irq ||
 779            ec->tx_max_coalesced_frames_irq ||
 780            ec->stats_block_coalesce_usecs ||
 781            ec->use_adaptive_tx_coalesce ||
 782            ec->pkt_rate_low ||
 783            ec->rx_coalesce_usecs_low ||
 784            ec->rx_max_coalesced_frames_low ||
 785            ec->tx_coalesce_usecs_low ||
 786            ec->tx_max_coalesced_frames_low ||
 787            ec->pkt_rate_high ||
 788            ec->rx_coalesce_usecs_high ||
 789            ec->rx_max_coalesced_frames_high ||
 790            ec->tx_coalesce_usecs_high ||
 791            ec->tx_max_coalesced_frames_high ||
 792            ec->rate_sample_interval) {
 793                return -EINVAL;
 794        }
 795
 796        if ((ec->rx_coalesce_usecs == 0) &&
 797            (ec->use_adaptive_rx_coalesce == 0) &&
 798            (ec->tx_max_coalesced_frames == 0) &&
 799            (ec->rx_max_coalesced_frames == 0)) {
 800                memset(adapter->coal_conf, 0, sizeof(*adapter->coal_conf));
 801                adapter->coal_conf->coalMode = VMXNET3_COALESCE_DISABLED;
 802                goto done;
 803        }
 804
 805        if (ec->rx_coalesce_usecs != 0) {
 806                u32 rbc_rate;
 807
 808                if ((ec->use_adaptive_rx_coalesce != 0) ||
 809                    (ec->tx_max_coalesced_frames != 0) ||
 810                    (ec->rx_max_coalesced_frames != 0)) {
 811                        return -EINVAL;
 812                }
 813
 814                rbc_rate = VMXNET3_COAL_RBC_RATE(ec->rx_coalesce_usecs);
 815                if (rbc_rate < VMXNET3_COAL_RBC_MIN_RATE ||
 816                    rbc_rate > VMXNET3_COAL_RBC_MAX_RATE) {
 817                        return -EINVAL;
 818                }
 819
 820                memset(adapter->coal_conf, 0, sizeof(*adapter->coal_conf));
 821                adapter->coal_conf->coalMode = VMXNET3_COALESCE_RBC;
 822                adapter->coal_conf->coalPara.coalRbc.rbc_rate = rbc_rate;
 823                goto done;
 824        }
 825
 826        if (ec->use_adaptive_rx_coalesce != 0) {
 827                if ((ec->rx_coalesce_usecs != 0) ||
 828                    (ec->tx_max_coalesced_frames != 0) ||
 829                    (ec->rx_max_coalesced_frames != 0)) {
 830                        return -EINVAL;
 831                }
 832                memset(adapter->coal_conf, 0, sizeof(*adapter->coal_conf));
 833                adapter->coal_conf->coalMode = VMXNET3_COALESCE_ADAPT;
 834                goto done;
 835        }
 836
 837        if ((ec->tx_max_coalesced_frames != 0) ||
 838            (ec->rx_max_coalesced_frames != 0)) {
 839                if ((ec->rx_coalesce_usecs != 0) ||
 840                    (ec->use_adaptive_rx_coalesce != 0)) {
 841                        return -EINVAL;
 842                }
 843
 844                if ((ec->tx_max_coalesced_frames >
 845                    VMXNET3_COAL_STATIC_MAX_DEPTH) ||
 846                    (ec->rx_max_coalesced_frames >
 847                     VMXNET3_COAL_STATIC_MAX_DEPTH)) {
 848                        return -EINVAL;
 849                }
 850
 851                memset(adapter->coal_conf, 0, sizeof(*adapter->coal_conf));
 852                adapter->coal_conf->coalMode = VMXNET3_COALESCE_STATIC;
 853
 854                adapter->coal_conf->coalPara.coalStatic.tx_comp_depth =
 855                        (ec->tx_max_coalesced_frames ?
 856                         ec->tx_max_coalesced_frames :
 857                         VMXNET3_COAL_STATIC_DEFAULT_DEPTH);
 858
 859                adapter->coal_conf->coalPara.coalStatic.rx_depth =
 860                        (ec->rx_max_coalesced_frames ?
 861                         ec->rx_max_coalesced_frames :
 862                         VMXNET3_COAL_STATIC_DEFAULT_DEPTH);
 863
 864                adapter->coal_conf->coalPara.coalStatic.tx_depth =
 865                         VMXNET3_COAL_STATIC_DEFAULT_DEPTH;
 866                goto done;
 867        }
 868
 869done:
 870        adapter->default_coal_mode = false;
 871        if (netif_running(netdev)) {
 872                spin_lock_irqsave(&adapter->cmd_lock, flags);
 873                cmdInfo->varConf.confVer = 1;
 874                cmdInfo->varConf.confLen =
 875                        cpu_to_le32(sizeof(*adapter->coal_conf));
 876                cmdInfo->varConf.confPA  = cpu_to_le64(adapter->coal_conf_pa);
 877                VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
 878                                       VMXNET3_CMD_SET_COALESCE);
 879                spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 880        }
 881
 882        return 0;
 883}
 884
 885static const struct ethtool_ops vmxnet3_ethtool_ops = {
 886        .get_drvinfo       = vmxnet3_get_drvinfo,
 887        .get_regs_len      = vmxnet3_get_regs_len,
 888        .get_regs          = vmxnet3_get_regs,
 889        .get_wol           = vmxnet3_get_wol,
 890        .set_wol           = vmxnet3_set_wol,
 891        .get_link          = ethtool_op_get_link,
 892        .get_coalesce      = vmxnet3_get_coalesce,
 893        .set_coalesce      = vmxnet3_set_coalesce,
 894        .get_strings       = vmxnet3_get_strings,
 895        .get_sset_count    = vmxnet3_get_sset_count,
 896        .get_ethtool_stats = vmxnet3_get_ethtool_stats,
 897        .get_ringparam     = vmxnet3_get_ringparam,
 898        .set_ringparam     = vmxnet3_set_ringparam,
 899        .get_rxnfc         = vmxnet3_get_rxnfc,
 900#ifdef VMXNET3_RSS
 901        .get_rxfh_indir_size = vmxnet3_get_rss_indir_size,
 902        .get_rxfh          = vmxnet3_get_rss,
 903        .set_rxfh          = vmxnet3_set_rss,
 904#endif
 905        .get_link_ksettings = vmxnet3_get_link_ksettings,
 906};
 907
 908void vmxnet3_set_ethtool_ops(struct net_device *netdev)
 909{
 910        netdev->ethtool_ops = &vmxnet3_ethtool_ops;
 911}
 912