linux/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c
<<
>>
Prefs
   1/*******************************************************************************
   2
   3  Intel PRO/10GbE Linux driver
   4  Copyright(c) 1999 - 2008 Intel Corporation.
   5
   6  This program is free software; you can redistribute it and/or modify it
   7  under the terms and conditions of the GNU General Public License,
   8  version 2, as published by the Free Software Foundation.
   9
  10  This program is distributed in the hope it will be useful, but WITHOUT
  11  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13  more details.
  14
  15  You should have received a copy of the GNU General Public License along with
  16  this program; if not, write to the Free Software Foundation, Inc.,
  17  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  18
  19  The full GNU General Public License is included in this distribution in
  20  the file called "COPYING".
  21
  22  Contact Information:
  23  Linux NICS <linux.nics@intel.com>
  24  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  25  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  26
  27*******************************************************************************/
  28
  29/* ethtool support for ixgb */
  30
  31#include "ixgb.h"
  32
  33#include <linux/uaccess.h>
  34
  35#define IXGB_ALL_RAR_ENTRIES 16
  36
  37enum {NETDEV_STATS, IXGB_STATS};
  38
  39struct ixgb_stats {
  40        char stat_string[ETH_GSTRING_LEN];
  41        int type;
  42        int sizeof_stat;
  43        int stat_offset;
  44};
  45
  46#define IXGB_STAT(m)            IXGB_STATS, \
  47                                FIELD_SIZEOF(struct ixgb_adapter, m), \
  48                                offsetof(struct ixgb_adapter, m)
  49#define IXGB_NETDEV_STAT(m)     NETDEV_STATS, \
  50                                FIELD_SIZEOF(struct net_device, m), \
  51                                offsetof(struct net_device, m)
  52
  53static struct ixgb_stats ixgb_gstrings_stats[] = {
  54        {"rx_packets", IXGB_NETDEV_STAT(stats.rx_packets)},
  55        {"tx_packets", IXGB_NETDEV_STAT(stats.tx_packets)},
  56        {"rx_bytes", IXGB_NETDEV_STAT(stats.rx_bytes)},
  57        {"tx_bytes", IXGB_NETDEV_STAT(stats.tx_bytes)},
  58        {"rx_errors", IXGB_NETDEV_STAT(stats.rx_errors)},
  59        {"tx_errors", IXGB_NETDEV_STAT(stats.tx_errors)},
  60        {"rx_dropped", IXGB_NETDEV_STAT(stats.rx_dropped)},
  61        {"tx_dropped", IXGB_NETDEV_STAT(stats.tx_dropped)},
  62        {"multicast", IXGB_NETDEV_STAT(stats.multicast)},
  63        {"collisions", IXGB_NETDEV_STAT(stats.collisions)},
  64
  65/*      { "rx_length_errors", IXGB_NETDEV_STAT(stats.rx_length_errors) },       */
  66        {"rx_over_errors", IXGB_NETDEV_STAT(stats.rx_over_errors)},
  67        {"rx_crc_errors", IXGB_NETDEV_STAT(stats.rx_crc_errors)},
  68        {"rx_frame_errors", IXGB_NETDEV_STAT(stats.rx_frame_errors)},
  69        {"rx_no_buffer_count", IXGB_STAT(stats.rnbc)},
  70        {"rx_fifo_errors", IXGB_NETDEV_STAT(stats.rx_fifo_errors)},
  71        {"rx_missed_errors", IXGB_NETDEV_STAT(stats.rx_missed_errors)},
  72        {"tx_aborted_errors", IXGB_NETDEV_STAT(stats.tx_aborted_errors)},
  73        {"tx_carrier_errors", IXGB_NETDEV_STAT(stats.tx_carrier_errors)},
  74        {"tx_fifo_errors", IXGB_NETDEV_STAT(stats.tx_fifo_errors)},
  75        {"tx_heartbeat_errors", IXGB_NETDEV_STAT(stats.tx_heartbeat_errors)},
  76        {"tx_window_errors", IXGB_NETDEV_STAT(stats.tx_window_errors)},
  77        {"tx_deferred_ok", IXGB_STAT(stats.dc)},
  78        {"tx_timeout_count", IXGB_STAT(tx_timeout_count) },
  79        {"tx_restart_queue", IXGB_STAT(restart_queue) },
  80        {"rx_long_length_errors", IXGB_STAT(stats.roc)},
  81        {"rx_short_length_errors", IXGB_STAT(stats.ruc)},
  82        {"tx_tcp_seg_good", IXGB_STAT(stats.tsctc)},
  83        {"tx_tcp_seg_failed", IXGB_STAT(stats.tsctfc)},
  84        {"rx_flow_control_xon", IXGB_STAT(stats.xonrxc)},
  85        {"rx_flow_control_xoff", IXGB_STAT(stats.xoffrxc)},
  86        {"tx_flow_control_xon", IXGB_STAT(stats.xontxc)},
  87        {"tx_flow_control_xoff", IXGB_STAT(stats.xofftxc)},
  88        {"rx_csum_offload_good", IXGB_STAT(hw_csum_rx_good)},
  89        {"rx_csum_offload_errors", IXGB_STAT(hw_csum_rx_error)},
  90        {"tx_csum_offload_good", IXGB_STAT(hw_csum_tx_good)},
  91        {"tx_csum_offload_errors", IXGB_STAT(hw_csum_tx_error)}
  92};
  93
  94#define IXGB_STATS_LEN  ARRAY_SIZE(ixgb_gstrings_stats)
  95
  96static int
  97ixgb_get_link_ksettings(struct net_device *netdev,
  98                        struct ethtool_link_ksettings *cmd)
  99{
 100        struct ixgb_adapter *adapter = netdev_priv(netdev);
 101
 102        ethtool_link_ksettings_zero_link_mode(cmd, supported);
 103        ethtool_link_ksettings_add_link_mode(cmd, supported, 10000baseT_Full);
 104        ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
 105
 106        ethtool_link_ksettings_zero_link_mode(cmd, advertising);
 107        ethtool_link_ksettings_add_link_mode(cmd, advertising, 10000baseT_Full);
 108        ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
 109
 110        cmd->base.port = PORT_FIBRE;
 111
 112        if (netif_carrier_ok(adapter->netdev)) {
 113                cmd->base.speed = SPEED_10000;
 114                cmd->base.duplex = DUPLEX_FULL;
 115        } else {
 116                cmd->base.speed = SPEED_UNKNOWN;
 117                cmd->base.duplex = DUPLEX_UNKNOWN;
 118        }
 119
 120        cmd->base.autoneg = AUTONEG_DISABLE;
 121        return 0;
 122}
 123
 124void ixgb_set_speed_duplex(struct net_device *netdev)
 125{
 126        struct ixgb_adapter *adapter = netdev_priv(netdev);
 127        /* be optimistic about our link, since we were up before */
 128        adapter->link_speed = 10000;
 129        adapter->link_duplex = FULL_DUPLEX;
 130        netif_carrier_on(netdev);
 131        netif_wake_queue(netdev);
 132}
 133
 134static int
 135ixgb_set_link_ksettings(struct net_device *netdev,
 136                        const struct ethtool_link_ksettings *cmd)
 137{
 138        struct ixgb_adapter *adapter = netdev_priv(netdev);
 139        u32 speed = cmd->base.speed;
 140
 141        if (cmd->base.autoneg == AUTONEG_ENABLE ||
 142            (speed + cmd->base.duplex != SPEED_10000 + DUPLEX_FULL))
 143                return -EINVAL;
 144
 145        if (netif_running(adapter->netdev)) {
 146                ixgb_down(adapter, true);
 147                ixgb_reset(adapter);
 148                ixgb_up(adapter);
 149                ixgb_set_speed_duplex(netdev);
 150        } else
 151                ixgb_reset(adapter);
 152
 153        return 0;
 154}
 155
 156static void
 157ixgb_get_pauseparam(struct net_device *netdev,
 158                         struct ethtool_pauseparam *pause)
 159{
 160        struct ixgb_adapter *adapter = netdev_priv(netdev);
 161        struct ixgb_hw *hw = &adapter->hw;
 162
 163        pause->autoneg = AUTONEG_DISABLE;
 164
 165        if (hw->fc.type == ixgb_fc_rx_pause)
 166                pause->rx_pause = 1;
 167        else if (hw->fc.type == ixgb_fc_tx_pause)
 168                pause->tx_pause = 1;
 169        else if (hw->fc.type == ixgb_fc_full) {
 170                pause->rx_pause = 1;
 171                pause->tx_pause = 1;
 172        }
 173}
 174
 175static int
 176ixgb_set_pauseparam(struct net_device *netdev,
 177                         struct ethtool_pauseparam *pause)
 178{
 179        struct ixgb_adapter *adapter = netdev_priv(netdev);
 180        struct ixgb_hw *hw = &adapter->hw;
 181
 182        if (pause->autoneg == AUTONEG_ENABLE)
 183                return -EINVAL;
 184
 185        if (pause->rx_pause && pause->tx_pause)
 186                hw->fc.type = ixgb_fc_full;
 187        else if (pause->rx_pause && !pause->tx_pause)
 188                hw->fc.type = ixgb_fc_rx_pause;
 189        else if (!pause->rx_pause && pause->tx_pause)
 190                hw->fc.type = ixgb_fc_tx_pause;
 191        else if (!pause->rx_pause && !pause->tx_pause)
 192                hw->fc.type = ixgb_fc_none;
 193
 194        if (netif_running(adapter->netdev)) {
 195                ixgb_down(adapter, true);
 196                ixgb_up(adapter);
 197                ixgb_set_speed_duplex(netdev);
 198        } else
 199                ixgb_reset(adapter);
 200
 201        return 0;
 202}
 203
 204static u32
 205ixgb_get_msglevel(struct net_device *netdev)
 206{
 207        struct ixgb_adapter *adapter = netdev_priv(netdev);
 208        return adapter->msg_enable;
 209}
 210
 211static void
 212ixgb_set_msglevel(struct net_device *netdev, u32 data)
 213{
 214        struct ixgb_adapter *adapter = netdev_priv(netdev);
 215        adapter->msg_enable = data;
 216}
 217#define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
 218
 219static int
 220ixgb_get_regs_len(struct net_device *netdev)
 221{
 222#define IXGB_REG_DUMP_LEN  136*sizeof(u32)
 223        return IXGB_REG_DUMP_LEN;
 224}
 225
 226static void
 227ixgb_get_regs(struct net_device *netdev,
 228                   struct ethtool_regs *regs, void *p)
 229{
 230        struct ixgb_adapter *adapter = netdev_priv(netdev);
 231        struct ixgb_hw *hw = &adapter->hw;
 232        u32 *reg = p;
 233        u32 *reg_start = reg;
 234        u8 i;
 235
 236        /* the 1 (one) below indicates an attempt at versioning, if the
 237         * interface in ethtool or the driver changes, this 1 should be
 238         * incremented */
 239        regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id;
 240
 241        /* General Registers */
 242        *reg++ = IXGB_READ_REG(hw, CTRL0);      /*   0 */
 243        *reg++ = IXGB_READ_REG(hw, CTRL1);      /*   1 */
 244        *reg++ = IXGB_READ_REG(hw, STATUS);     /*   2 */
 245        *reg++ = IXGB_READ_REG(hw, EECD);       /*   3 */
 246        *reg++ = IXGB_READ_REG(hw, MFS);        /*   4 */
 247
 248        /* Interrupt */
 249        *reg++ = IXGB_READ_REG(hw, ICR);        /*   5 */
 250        *reg++ = IXGB_READ_REG(hw, ICS);        /*   6 */
 251        *reg++ = IXGB_READ_REG(hw, IMS);        /*   7 */
 252        *reg++ = IXGB_READ_REG(hw, IMC);        /*   8 */
 253
 254        /* Receive */
 255        *reg++ = IXGB_READ_REG(hw, RCTL);       /*   9 */
 256        *reg++ = IXGB_READ_REG(hw, FCRTL);      /*  10 */
 257        *reg++ = IXGB_READ_REG(hw, FCRTH);      /*  11 */
 258        *reg++ = IXGB_READ_REG(hw, RDBAL);      /*  12 */
 259        *reg++ = IXGB_READ_REG(hw, RDBAH);      /*  13 */
 260        *reg++ = IXGB_READ_REG(hw, RDLEN);      /*  14 */
 261        *reg++ = IXGB_READ_REG(hw, RDH);        /*  15 */
 262        *reg++ = IXGB_READ_REG(hw, RDT);        /*  16 */
 263        *reg++ = IXGB_READ_REG(hw, RDTR);       /*  17 */
 264        *reg++ = IXGB_READ_REG(hw, RXDCTL);     /*  18 */
 265        *reg++ = IXGB_READ_REG(hw, RAIDC);      /*  19 */
 266        *reg++ = IXGB_READ_REG(hw, RXCSUM);     /*  20 */
 267
 268        /* there are 16 RAR entries in hardware, we only use 3 */
 269        for (i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) {
 270                *reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */
 271                *reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */
 272        }
 273
 274        /* Transmit */
 275        *reg++ = IXGB_READ_REG(hw, TCTL);       /*  53 */
 276        *reg++ = IXGB_READ_REG(hw, TDBAL);      /*  54 */
 277        *reg++ = IXGB_READ_REG(hw, TDBAH);      /*  55 */
 278        *reg++ = IXGB_READ_REG(hw, TDLEN);      /*  56 */
 279        *reg++ = IXGB_READ_REG(hw, TDH);        /*  57 */
 280        *reg++ = IXGB_READ_REG(hw, TDT);        /*  58 */
 281        *reg++ = IXGB_READ_REG(hw, TIDV);       /*  59 */
 282        *reg++ = IXGB_READ_REG(hw, TXDCTL);     /*  60 */
 283        *reg++ = IXGB_READ_REG(hw, TSPMT);      /*  61 */
 284        *reg++ = IXGB_READ_REG(hw, PAP);        /*  62 */
 285
 286        /* Physical */
 287        *reg++ = IXGB_READ_REG(hw, PCSC1);      /*  63 */
 288        *reg++ = IXGB_READ_REG(hw, PCSC2);      /*  64 */
 289        *reg++ = IXGB_READ_REG(hw, PCSS1);      /*  65 */
 290        *reg++ = IXGB_READ_REG(hw, PCSS2);      /*  66 */
 291        *reg++ = IXGB_READ_REG(hw, XPCSS);      /*  67 */
 292        *reg++ = IXGB_READ_REG(hw, UCCR);       /*  68 */
 293        *reg++ = IXGB_READ_REG(hw, XPCSTC);     /*  69 */
 294        *reg++ = IXGB_READ_REG(hw, MACA);       /*  70 */
 295        *reg++ = IXGB_READ_REG(hw, APAE);       /*  71 */
 296        *reg++ = IXGB_READ_REG(hw, ARD);        /*  72 */
 297        *reg++ = IXGB_READ_REG(hw, AIS);        /*  73 */
 298        *reg++ = IXGB_READ_REG(hw, MSCA);       /*  74 */
 299        *reg++ = IXGB_READ_REG(hw, MSRWD);      /*  75 */
 300
 301        /* Statistics */
 302        *reg++ = IXGB_GET_STAT(adapter, tprl);  /*  76 */
 303        *reg++ = IXGB_GET_STAT(adapter, tprh);  /*  77 */
 304        *reg++ = IXGB_GET_STAT(adapter, gprcl); /*  78 */
 305        *reg++ = IXGB_GET_STAT(adapter, gprch); /*  79 */
 306        *reg++ = IXGB_GET_STAT(adapter, bprcl); /*  80 */
 307        *reg++ = IXGB_GET_STAT(adapter, bprch); /*  81 */
 308        *reg++ = IXGB_GET_STAT(adapter, mprcl); /*  82 */
 309        *reg++ = IXGB_GET_STAT(adapter, mprch); /*  83 */
 310        *reg++ = IXGB_GET_STAT(adapter, uprcl); /*  84 */
 311        *reg++ = IXGB_GET_STAT(adapter, uprch); /*  85 */
 312        *reg++ = IXGB_GET_STAT(adapter, vprcl); /*  86 */
 313        *reg++ = IXGB_GET_STAT(adapter, vprch); /*  87 */
 314        *reg++ = IXGB_GET_STAT(adapter, jprcl); /*  88 */
 315        *reg++ = IXGB_GET_STAT(adapter, jprch); /*  89 */
 316        *reg++ = IXGB_GET_STAT(adapter, gorcl); /*  90 */
 317        *reg++ = IXGB_GET_STAT(adapter, gorch); /*  91 */
 318        *reg++ = IXGB_GET_STAT(adapter, torl);  /*  92 */
 319        *reg++ = IXGB_GET_STAT(adapter, torh);  /*  93 */
 320        *reg++ = IXGB_GET_STAT(adapter, rnbc);  /*  94 */
 321        *reg++ = IXGB_GET_STAT(adapter, ruc);   /*  95 */
 322        *reg++ = IXGB_GET_STAT(adapter, roc);   /*  96 */
 323        *reg++ = IXGB_GET_STAT(adapter, rlec);  /*  97 */
 324        *reg++ = IXGB_GET_STAT(adapter, crcerrs);       /*  98 */
 325        *reg++ = IXGB_GET_STAT(adapter, icbc);  /*  99 */
 326        *reg++ = IXGB_GET_STAT(adapter, ecbc);  /* 100 */
 327        *reg++ = IXGB_GET_STAT(adapter, mpc);   /* 101 */
 328        *reg++ = IXGB_GET_STAT(adapter, tptl);  /* 102 */
 329        *reg++ = IXGB_GET_STAT(adapter, tpth);  /* 103 */
 330        *reg++ = IXGB_GET_STAT(adapter, gptcl); /* 104 */
 331        *reg++ = IXGB_GET_STAT(adapter, gptch); /* 105 */
 332        *reg++ = IXGB_GET_STAT(adapter, bptcl); /* 106 */
 333        *reg++ = IXGB_GET_STAT(adapter, bptch); /* 107 */
 334        *reg++ = IXGB_GET_STAT(adapter, mptcl); /* 108 */
 335        *reg++ = IXGB_GET_STAT(adapter, mptch); /* 109 */
 336        *reg++ = IXGB_GET_STAT(adapter, uptcl); /* 110 */
 337        *reg++ = IXGB_GET_STAT(adapter, uptch); /* 111 */
 338        *reg++ = IXGB_GET_STAT(adapter, vptcl); /* 112 */
 339        *reg++ = IXGB_GET_STAT(adapter, vptch); /* 113 */
 340        *reg++ = IXGB_GET_STAT(adapter, jptcl); /* 114 */
 341        *reg++ = IXGB_GET_STAT(adapter, jptch); /* 115 */
 342        *reg++ = IXGB_GET_STAT(adapter, gotcl); /* 116 */
 343        *reg++ = IXGB_GET_STAT(adapter, gotch); /* 117 */
 344        *reg++ = IXGB_GET_STAT(adapter, totl);  /* 118 */
 345        *reg++ = IXGB_GET_STAT(adapter, toth);  /* 119 */
 346        *reg++ = IXGB_GET_STAT(adapter, dc);    /* 120 */
 347        *reg++ = IXGB_GET_STAT(adapter, plt64c);        /* 121 */
 348        *reg++ = IXGB_GET_STAT(adapter, tsctc); /* 122 */
 349        *reg++ = IXGB_GET_STAT(adapter, tsctfc);        /* 123 */
 350        *reg++ = IXGB_GET_STAT(adapter, ibic);  /* 124 */
 351        *reg++ = IXGB_GET_STAT(adapter, rfc);   /* 125 */
 352        *reg++ = IXGB_GET_STAT(adapter, lfc);   /* 126 */
 353        *reg++ = IXGB_GET_STAT(adapter, pfrc);  /* 127 */
 354        *reg++ = IXGB_GET_STAT(adapter, pftc);  /* 128 */
 355        *reg++ = IXGB_GET_STAT(adapter, mcfrc); /* 129 */
 356        *reg++ = IXGB_GET_STAT(adapter, mcftc); /* 130 */
 357        *reg++ = IXGB_GET_STAT(adapter, xonrxc);        /* 131 */
 358        *reg++ = IXGB_GET_STAT(adapter, xontxc);        /* 132 */
 359        *reg++ = IXGB_GET_STAT(adapter, xoffrxc);       /* 133 */
 360        *reg++ = IXGB_GET_STAT(adapter, xofftxc);       /* 134 */
 361        *reg++ = IXGB_GET_STAT(adapter, rjc);   /* 135 */
 362
 363        regs->len = (reg - reg_start) * sizeof(u32);
 364}
 365
 366static int
 367ixgb_get_eeprom_len(struct net_device *netdev)
 368{
 369        /* return size in bytes */
 370        return IXGB_EEPROM_SIZE << 1;
 371}
 372
 373static int
 374ixgb_get_eeprom(struct net_device *netdev,
 375                  struct ethtool_eeprom *eeprom, u8 *bytes)
 376{
 377        struct ixgb_adapter *adapter = netdev_priv(netdev);
 378        struct ixgb_hw *hw = &adapter->hw;
 379        __le16 *eeprom_buff;
 380        int i, max_len, first_word, last_word;
 381        int ret_val = 0;
 382
 383        if (eeprom->len == 0) {
 384                ret_val = -EINVAL;
 385                goto geeprom_error;
 386        }
 387
 388        eeprom->magic = hw->vendor_id | (hw->device_id << 16);
 389
 390        max_len = ixgb_get_eeprom_len(netdev);
 391
 392        if (eeprom->offset > eeprom->offset + eeprom->len) {
 393                ret_val = -EINVAL;
 394                goto geeprom_error;
 395        }
 396
 397        if ((eeprom->offset + eeprom->len) > max_len)
 398                eeprom->len = (max_len - eeprom->offset);
 399
 400        first_word = eeprom->offset >> 1;
 401        last_word = (eeprom->offset + eeprom->len - 1) >> 1;
 402
 403        eeprom_buff = kmalloc(sizeof(__le16) *
 404                        (last_word - first_word + 1), GFP_KERNEL);
 405        if (!eeprom_buff)
 406                return -ENOMEM;
 407
 408        /* note the eeprom was good because the driver loaded */
 409        for (i = 0; i <= (last_word - first_word); i++)
 410                eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i));
 411
 412        memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
 413        kfree(eeprom_buff);
 414
 415geeprom_error:
 416        return ret_val;
 417}
 418
 419static int
 420ixgb_set_eeprom(struct net_device *netdev,
 421                  struct ethtool_eeprom *eeprom, u8 *bytes)
 422{
 423        struct ixgb_adapter *adapter = netdev_priv(netdev);
 424        struct ixgb_hw *hw = &adapter->hw;
 425        u16 *eeprom_buff;
 426        void *ptr;
 427        int max_len, first_word, last_word;
 428        u16 i;
 429
 430        if (eeprom->len == 0)
 431                return -EINVAL;
 432
 433        if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
 434                return -EFAULT;
 435
 436        max_len = ixgb_get_eeprom_len(netdev);
 437
 438        if (eeprom->offset > eeprom->offset + eeprom->len)
 439                return -EINVAL;
 440
 441        if ((eeprom->offset + eeprom->len) > max_len)
 442                eeprom->len = (max_len - eeprom->offset);
 443
 444        first_word = eeprom->offset >> 1;
 445        last_word = (eeprom->offset + eeprom->len - 1) >> 1;
 446        eeprom_buff = kmalloc(max_len, GFP_KERNEL);
 447        if (!eeprom_buff)
 448                return -ENOMEM;
 449
 450        ptr = (void *)eeprom_buff;
 451
 452        if (eeprom->offset & 1) {
 453                /* need read/modify/write of first changed EEPROM word */
 454                /* only the second byte of the word is being modified */
 455                eeprom_buff[0] = ixgb_read_eeprom(hw, first_word);
 456                ptr++;
 457        }
 458        if ((eeprom->offset + eeprom->len) & 1) {
 459                /* need read/modify/write of last changed EEPROM word */
 460                /* only the first byte of the word is being modified */
 461                eeprom_buff[last_word - first_word]
 462                        = ixgb_read_eeprom(hw, last_word);
 463        }
 464
 465        memcpy(ptr, bytes, eeprom->len);
 466        for (i = 0; i <= (last_word - first_word); i++)
 467                ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]);
 468
 469        /* Update the checksum over the first part of the EEPROM if needed */
 470        if (first_word <= EEPROM_CHECKSUM_REG)
 471                ixgb_update_eeprom_checksum(hw);
 472
 473        kfree(eeprom_buff);
 474        return 0;
 475}
 476
 477static void
 478ixgb_get_drvinfo(struct net_device *netdev,
 479                   struct ethtool_drvinfo *drvinfo)
 480{
 481        struct ixgb_adapter *adapter = netdev_priv(netdev);
 482
 483        strlcpy(drvinfo->driver,  ixgb_driver_name,
 484                sizeof(drvinfo->driver));
 485        strlcpy(drvinfo->version, ixgb_driver_version,
 486                sizeof(drvinfo->version));
 487        strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
 488                sizeof(drvinfo->bus_info));
 489}
 490
 491static void
 492ixgb_get_ringparam(struct net_device *netdev,
 493                struct ethtool_ringparam *ring)
 494{
 495        struct ixgb_adapter *adapter = netdev_priv(netdev);
 496        struct ixgb_desc_ring *txdr = &adapter->tx_ring;
 497        struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
 498
 499        ring->rx_max_pending = MAX_RXD;
 500        ring->tx_max_pending = MAX_TXD;
 501        ring->rx_pending = rxdr->count;
 502        ring->tx_pending = txdr->count;
 503}
 504
 505static int
 506ixgb_set_ringparam(struct net_device *netdev,
 507                struct ethtool_ringparam *ring)
 508{
 509        struct ixgb_adapter *adapter = netdev_priv(netdev);
 510        struct ixgb_desc_ring *txdr = &adapter->tx_ring;
 511        struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
 512        struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new;
 513        int err;
 514
 515        tx_old = adapter->tx_ring;
 516        rx_old = adapter->rx_ring;
 517
 518        if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 519                return -EINVAL;
 520
 521        if (netif_running(adapter->netdev))
 522                ixgb_down(adapter, true);
 523
 524        rxdr->count = max(ring->rx_pending,(u32)MIN_RXD);
 525        rxdr->count = min(rxdr->count,(u32)MAX_RXD);
 526        rxdr->count = ALIGN(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
 527
 528        txdr->count = max(ring->tx_pending,(u32)MIN_TXD);
 529        txdr->count = min(txdr->count,(u32)MAX_TXD);
 530        txdr->count = ALIGN(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
 531
 532        if (netif_running(adapter->netdev)) {
 533                /* Try to get new resources before deleting old */
 534                if ((err = ixgb_setup_rx_resources(adapter)))
 535                        goto err_setup_rx;
 536                if ((err = ixgb_setup_tx_resources(adapter)))
 537                        goto err_setup_tx;
 538
 539                /* save the new, restore the old in order to free it,
 540                 * then restore the new back again */
 541
 542                rx_new = adapter->rx_ring;
 543                tx_new = adapter->tx_ring;
 544                adapter->rx_ring = rx_old;
 545                adapter->tx_ring = tx_old;
 546                ixgb_free_rx_resources(adapter);
 547                ixgb_free_tx_resources(adapter);
 548                adapter->rx_ring = rx_new;
 549                adapter->tx_ring = tx_new;
 550                if ((err = ixgb_up(adapter)))
 551                        return err;
 552                ixgb_set_speed_duplex(netdev);
 553        }
 554
 555        return 0;
 556err_setup_tx:
 557        ixgb_free_rx_resources(adapter);
 558err_setup_rx:
 559        adapter->rx_ring = rx_old;
 560        adapter->tx_ring = tx_old;
 561        ixgb_up(adapter);
 562        return err;
 563}
 564
 565static int
 566ixgb_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
 567{
 568        struct ixgb_adapter *adapter = netdev_priv(netdev);
 569
 570        switch (state) {
 571        case ETHTOOL_ID_ACTIVE:
 572                return 2;
 573
 574        case ETHTOOL_ID_ON:
 575                ixgb_led_on(&adapter->hw);
 576                break;
 577
 578        case ETHTOOL_ID_OFF:
 579        case ETHTOOL_ID_INACTIVE:
 580                ixgb_led_off(&adapter->hw);
 581        }
 582
 583        return 0;
 584}
 585
 586static int
 587ixgb_get_sset_count(struct net_device *netdev, int sset)
 588{
 589        switch (sset) {
 590        case ETH_SS_STATS:
 591                return IXGB_STATS_LEN;
 592        default:
 593                return -EOPNOTSUPP;
 594        }
 595}
 596
 597static void
 598ixgb_get_ethtool_stats(struct net_device *netdev,
 599                struct ethtool_stats *stats, u64 *data)
 600{
 601        struct ixgb_adapter *adapter = netdev_priv(netdev);
 602        int i;
 603        char *p = NULL;
 604
 605        ixgb_update_stats(adapter);
 606        for (i = 0; i < IXGB_STATS_LEN; i++) {
 607                switch (ixgb_gstrings_stats[i].type) {
 608                case NETDEV_STATS:
 609                        p = (char *) netdev +
 610                                        ixgb_gstrings_stats[i].stat_offset;
 611                        break;
 612                case IXGB_STATS:
 613                        p = (char *) adapter +
 614                                        ixgb_gstrings_stats[i].stat_offset;
 615                        break;
 616                }
 617
 618                data[i] = (ixgb_gstrings_stats[i].sizeof_stat ==
 619                        sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 620        }
 621}
 622
 623static void
 624ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 625{
 626        int i;
 627
 628        switch(stringset) {
 629        case ETH_SS_STATS:
 630                for (i = 0; i < IXGB_STATS_LEN; i++) {
 631                        memcpy(data + i * ETH_GSTRING_LEN,
 632                        ixgb_gstrings_stats[i].stat_string,
 633                        ETH_GSTRING_LEN);
 634                }
 635                break;
 636        }
 637}
 638
 639static const struct ethtool_ops ixgb_ethtool_ops = {
 640        .get_drvinfo = ixgb_get_drvinfo,
 641        .get_regs_len = ixgb_get_regs_len,
 642        .get_regs = ixgb_get_regs,
 643        .get_link = ethtool_op_get_link,
 644        .get_eeprom_len = ixgb_get_eeprom_len,
 645        .get_eeprom = ixgb_get_eeprom,
 646        .set_eeprom = ixgb_set_eeprom,
 647        .get_ringparam = ixgb_get_ringparam,
 648        .set_ringparam = ixgb_set_ringparam,
 649        .get_pauseparam = ixgb_get_pauseparam,
 650        .set_pauseparam = ixgb_set_pauseparam,
 651        .get_msglevel = ixgb_get_msglevel,
 652        .set_msglevel = ixgb_set_msglevel,
 653        .get_strings = ixgb_get_strings,
 654        .set_phys_id = ixgb_set_phys_id,
 655        .get_sset_count = ixgb_get_sset_count,
 656        .get_ethtool_stats = ixgb_get_ethtool_stats,
 657        .get_link_ksettings = ixgb_get_link_ksettings,
 658        .set_link_ksettings = ixgb_set_link_ksettings,
 659};
 660
 661void ixgb_set_ethtool_ops(struct net_device *netdev)
 662{
 663        netdev->ethtool_ops = &ixgb_ethtool_ops;
 664}
 665