0001
0002
0003
0004
0005
0006 #include "ixgb.h"
0007
0008 #include <linux/uaccess.h>
0009
0010 #define IXGB_ALL_RAR_ENTRIES 16
0011
0012 enum {NETDEV_STATS, IXGB_STATS};
0013
0014 struct ixgb_stats {
0015 char stat_string[ETH_GSTRING_LEN];
0016 int type;
0017 int sizeof_stat;
0018 int stat_offset;
0019 };
0020
0021 #define IXGB_STAT(m) IXGB_STATS, \
0022 sizeof_field(struct ixgb_adapter, m), \
0023 offsetof(struct ixgb_adapter, m)
0024 #define IXGB_NETDEV_STAT(m) NETDEV_STATS, \
0025 sizeof_field(struct net_device, m), \
0026 offsetof(struct net_device, m)
0027
0028 static struct ixgb_stats ixgb_gstrings_stats[] = {
0029 {"rx_packets", IXGB_NETDEV_STAT(stats.rx_packets)},
0030 {"tx_packets", IXGB_NETDEV_STAT(stats.tx_packets)},
0031 {"rx_bytes", IXGB_NETDEV_STAT(stats.rx_bytes)},
0032 {"tx_bytes", IXGB_NETDEV_STAT(stats.tx_bytes)},
0033 {"rx_errors", IXGB_NETDEV_STAT(stats.rx_errors)},
0034 {"tx_errors", IXGB_NETDEV_STAT(stats.tx_errors)},
0035 {"rx_dropped", IXGB_NETDEV_STAT(stats.rx_dropped)},
0036 {"tx_dropped", IXGB_NETDEV_STAT(stats.tx_dropped)},
0037 {"multicast", IXGB_NETDEV_STAT(stats.multicast)},
0038 {"collisions", IXGB_NETDEV_STAT(stats.collisions)},
0039
0040
0041 {"rx_over_errors", IXGB_NETDEV_STAT(stats.rx_over_errors)},
0042 {"rx_crc_errors", IXGB_NETDEV_STAT(stats.rx_crc_errors)},
0043 {"rx_frame_errors", IXGB_NETDEV_STAT(stats.rx_frame_errors)},
0044 {"rx_no_buffer_count", IXGB_STAT(stats.rnbc)},
0045 {"rx_fifo_errors", IXGB_NETDEV_STAT(stats.rx_fifo_errors)},
0046 {"rx_missed_errors", IXGB_NETDEV_STAT(stats.rx_missed_errors)},
0047 {"tx_aborted_errors", IXGB_NETDEV_STAT(stats.tx_aborted_errors)},
0048 {"tx_carrier_errors", IXGB_NETDEV_STAT(stats.tx_carrier_errors)},
0049 {"tx_fifo_errors", IXGB_NETDEV_STAT(stats.tx_fifo_errors)},
0050 {"tx_heartbeat_errors", IXGB_NETDEV_STAT(stats.tx_heartbeat_errors)},
0051 {"tx_window_errors", IXGB_NETDEV_STAT(stats.tx_window_errors)},
0052 {"tx_deferred_ok", IXGB_STAT(stats.dc)},
0053 {"tx_timeout_count", IXGB_STAT(tx_timeout_count) },
0054 {"tx_restart_queue", IXGB_STAT(restart_queue) },
0055 {"rx_long_length_errors", IXGB_STAT(stats.roc)},
0056 {"rx_short_length_errors", IXGB_STAT(stats.ruc)},
0057 {"tx_tcp_seg_good", IXGB_STAT(stats.tsctc)},
0058 {"tx_tcp_seg_failed", IXGB_STAT(stats.tsctfc)},
0059 {"rx_flow_control_xon", IXGB_STAT(stats.xonrxc)},
0060 {"rx_flow_control_xoff", IXGB_STAT(stats.xoffrxc)},
0061 {"tx_flow_control_xon", IXGB_STAT(stats.xontxc)},
0062 {"tx_flow_control_xoff", IXGB_STAT(stats.xofftxc)},
0063 {"rx_csum_offload_good", IXGB_STAT(hw_csum_rx_good)},
0064 {"rx_csum_offload_errors", IXGB_STAT(hw_csum_rx_error)},
0065 {"tx_csum_offload_good", IXGB_STAT(hw_csum_tx_good)},
0066 {"tx_csum_offload_errors", IXGB_STAT(hw_csum_tx_error)}
0067 };
0068
0069 #define IXGB_STATS_LEN ARRAY_SIZE(ixgb_gstrings_stats)
0070
0071 static int
0072 ixgb_get_link_ksettings(struct net_device *netdev,
0073 struct ethtool_link_ksettings *cmd)
0074 {
0075 struct ixgb_adapter *adapter = netdev_priv(netdev);
0076
0077 ethtool_link_ksettings_zero_link_mode(cmd, supported);
0078 ethtool_link_ksettings_add_link_mode(cmd, supported, 10000baseT_Full);
0079 ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
0080
0081 ethtool_link_ksettings_zero_link_mode(cmd, advertising);
0082 ethtool_link_ksettings_add_link_mode(cmd, advertising, 10000baseT_Full);
0083 ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
0084
0085 cmd->base.port = PORT_FIBRE;
0086
0087 if (netif_carrier_ok(adapter->netdev)) {
0088 cmd->base.speed = SPEED_10000;
0089 cmd->base.duplex = DUPLEX_FULL;
0090 } else {
0091 cmd->base.speed = SPEED_UNKNOWN;
0092 cmd->base.duplex = DUPLEX_UNKNOWN;
0093 }
0094
0095 cmd->base.autoneg = AUTONEG_DISABLE;
0096 return 0;
0097 }
0098
0099 void ixgb_set_speed_duplex(struct net_device *netdev)
0100 {
0101 struct ixgb_adapter *adapter = netdev_priv(netdev);
0102
0103 adapter->link_speed = 10000;
0104 adapter->link_duplex = FULL_DUPLEX;
0105 netif_carrier_on(netdev);
0106 netif_wake_queue(netdev);
0107 }
0108
0109 static int
0110 ixgb_set_link_ksettings(struct net_device *netdev,
0111 const struct ethtool_link_ksettings *cmd)
0112 {
0113 struct ixgb_adapter *adapter = netdev_priv(netdev);
0114 u32 speed = cmd->base.speed;
0115
0116 if (cmd->base.autoneg == AUTONEG_ENABLE ||
0117 (speed + cmd->base.duplex != SPEED_10000 + DUPLEX_FULL))
0118 return -EINVAL;
0119
0120 if (netif_running(adapter->netdev)) {
0121 ixgb_down(adapter, true);
0122 ixgb_reset(adapter);
0123 ixgb_up(adapter);
0124 ixgb_set_speed_duplex(netdev);
0125 } else
0126 ixgb_reset(adapter);
0127
0128 return 0;
0129 }
0130
0131 static void
0132 ixgb_get_pauseparam(struct net_device *netdev,
0133 struct ethtool_pauseparam *pause)
0134 {
0135 struct ixgb_adapter *adapter = netdev_priv(netdev);
0136 struct ixgb_hw *hw = &adapter->hw;
0137
0138 pause->autoneg = AUTONEG_DISABLE;
0139
0140 if (hw->fc.type == ixgb_fc_rx_pause)
0141 pause->rx_pause = 1;
0142 else if (hw->fc.type == ixgb_fc_tx_pause)
0143 pause->tx_pause = 1;
0144 else if (hw->fc.type == ixgb_fc_full) {
0145 pause->rx_pause = 1;
0146 pause->tx_pause = 1;
0147 }
0148 }
0149
0150 static int
0151 ixgb_set_pauseparam(struct net_device *netdev,
0152 struct ethtool_pauseparam *pause)
0153 {
0154 struct ixgb_adapter *adapter = netdev_priv(netdev);
0155 struct ixgb_hw *hw = &adapter->hw;
0156
0157 if (pause->autoneg == AUTONEG_ENABLE)
0158 return -EINVAL;
0159
0160 if (pause->rx_pause && pause->tx_pause)
0161 hw->fc.type = ixgb_fc_full;
0162 else if (pause->rx_pause && !pause->tx_pause)
0163 hw->fc.type = ixgb_fc_rx_pause;
0164 else if (!pause->rx_pause && pause->tx_pause)
0165 hw->fc.type = ixgb_fc_tx_pause;
0166 else if (!pause->rx_pause && !pause->tx_pause)
0167 hw->fc.type = ixgb_fc_none;
0168
0169 if (netif_running(adapter->netdev)) {
0170 ixgb_down(adapter, true);
0171 ixgb_up(adapter);
0172 ixgb_set_speed_duplex(netdev);
0173 } else
0174 ixgb_reset(adapter);
0175
0176 return 0;
0177 }
0178
0179 static u32
0180 ixgb_get_msglevel(struct net_device *netdev)
0181 {
0182 struct ixgb_adapter *adapter = netdev_priv(netdev);
0183 return adapter->msg_enable;
0184 }
0185
0186 static void
0187 ixgb_set_msglevel(struct net_device *netdev, u32 data)
0188 {
0189 struct ixgb_adapter *adapter = netdev_priv(netdev);
0190 adapter->msg_enable = data;
0191 }
0192 #define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
0193
0194 static int
0195 ixgb_get_regs_len(struct net_device *netdev)
0196 {
0197 #define IXGB_REG_DUMP_LEN 136*sizeof(u32)
0198 return IXGB_REG_DUMP_LEN;
0199 }
0200
0201 static void
0202 ixgb_get_regs(struct net_device *netdev,
0203 struct ethtool_regs *regs, void *p)
0204 {
0205 struct ixgb_adapter *adapter = netdev_priv(netdev);
0206 struct ixgb_hw *hw = &adapter->hw;
0207 u32 *reg = p;
0208 u32 *reg_start = reg;
0209 u8 i;
0210
0211
0212
0213
0214 regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id;
0215
0216
0217 *reg++ = IXGB_READ_REG(hw, CTRL0);
0218 *reg++ = IXGB_READ_REG(hw, CTRL1);
0219 *reg++ = IXGB_READ_REG(hw, STATUS);
0220 *reg++ = IXGB_READ_REG(hw, EECD);
0221 *reg++ = IXGB_READ_REG(hw, MFS);
0222
0223
0224 *reg++ = IXGB_READ_REG(hw, ICR);
0225 *reg++ = IXGB_READ_REG(hw, ICS);
0226 *reg++ = IXGB_READ_REG(hw, IMS);
0227 *reg++ = IXGB_READ_REG(hw, IMC);
0228
0229
0230 *reg++ = IXGB_READ_REG(hw, RCTL);
0231 *reg++ = IXGB_READ_REG(hw, FCRTL);
0232 *reg++ = IXGB_READ_REG(hw, FCRTH);
0233 *reg++ = IXGB_READ_REG(hw, RDBAL);
0234 *reg++ = IXGB_READ_REG(hw, RDBAH);
0235 *reg++ = IXGB_READ_REG(hw, RDLEN);
0236 *reg++ = IXGB_READ_REG(hw, RDH);
0237 *reg++ = IXGB_READ_REG(hw, RDT);
0238 *reg++ = IXGB_READ_REG(hw, RDTR);
0239 *reg++ = IXGB_READ_REG(hw, RXDCTL);
0240 *reg++ = IXGB_READ_REG(hw, RAIDC);
0241 *reg++ = IXGB_READ_REG(hw, RXCSUM);
0242
0243
0244 for (i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) {
0245 *reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1));
0246 *reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1));
0247 }
0248
0249
0250 *reg++ = IXGB_READ_REG(hw, TCTL);
0251 *reg++ = IXGB_READ_REG(hw, TDBAL);
0252 *reg++ = IXGB_READ_REG(hw, TDBAH);
0253 *reg++ = IXGB_READ_REG(hw, TDLEN);
0254 *reg++ = IXGB_READ_REG(hw, TDH);
0255 *reg++ = IXGB_READ_REG(hw, TDT);
0256 *reg++ = IXGB_READ_REG(hw, TIDV);
0257 *reg++ = IXGB_READ_REG(hw, TXDCTL);
0258 *reg++ = IXGB_READ_REG(hw, TSPMT);
0259 *reg++ = IXGB_READ_REG(hw, PAP);
0260
0261
0262 *reg++ = IXGB_READ_REG(hw, PCSC1);
0263 *reg++ = IXGB_READ_REG(hw, PCSC2);
0264 *reg++ = IXGB_READ_REG(hw, PCSS1);
0265 *reg++ = IXGB_READ_REG(hw, PCSS2);
0266 *reg++ = IXGB_READ_REG(hw, XPCSS);
0267 *reg++ = IXGB_READ_REG(hw, UCCR);
0268 *reg++ = IXGB_READ_REG(hw, XPCSTC);
0269 *reg++ = IXGB_READ_REG(hw, MACA);
0270 *reg++ = IXGB_READ_REG(hw, APAE);
0271 *reg++ = IXGB_READ_REG(hw, ARD);
0272 *reg++ = IXGB_READ_REG(hw, AIS);
0273 *reg++ = IXGB_READ_REG(hw, MSCA);
0274 *reg++ = IXGB_READ_REG(hw, MSRWD);
0275
0276
0277 *reg++ = IXGB_GET_STAT(adapter, tprl);
0278 *reg++ = IXGB_GET_STAT(adapter, tprh);
0279 *reg++ = IXGB_GET_STAT(adapter, gprcl);
0280 *reg++ = IXGB_GET_STAT(adapter, gprch);
0281 *reg++ = IXGB_GET_STAT(adapter, bprcl);
0282 *reg++ = IXGB_GET_STAT(adapter, bprch);
0283 *reg++ = IXGB_GET_STAT(adapter, mprcl);
0284 *reg++ = IXGB_GET_STAT(adapter, mprch);
0285 *reg++ = IXGB_GET_STAT(adapter, uprcl);
0286 *reg++ = IXGB_GET_STAT(adapter, uprch);
0287 *reg++ = IXGB_GET_STAT(adapter, vprcl);
0288 *reg++ = IXGB_GET_STAT(adapter, vprch);
0289 *reg++ = IXGB_GET_STAT(adapter, jprcl);
0290 *reg++ = IXGB_GET_STAT(adapter, jprch);
0291 *reg++ = IXGB_GET_STAT(adapter, gorcl);
0292 *reg++ = IXGB_GET_STAT(adapter, gorch);
0293 *reg++ = IXGB_GET_STAT(adapter, torl);
0294 *reg++ = IXGB_GET_STAT(adapter, torh);
0295 *reg++ = IXGB_GET_STAT(adapter, rnbc);
0296 *reg++ = IXGB_GET_STAT(adapter, ruc);
0297 *reg++ = IXGB_GET_STAT(adapter, roc);
0298 *reg++ = IXGB_GET_STAT(adapter, rlec);
0299 *reg++ = IXGB_GET_STAT(adapter, crcerrs);
0300 *reg++ = IXGB_GET_STAT(adapter, icbc);
0301 *reg++ = IXGB_GET_STAT(adapter, ecbc);
0302 *reg++ = IXGB_GET_STAT(adapter, mpc);
0303 *reg++ = IXGB_GET_STAT(adapter, tptl);
0304 *reg++ = IXGB_GET_STAT(adapter, tpth);
0305 *reg++ = IXGB_GET_STAT(adapter, gptcl);
0306 *reg++ = IXGB_GET_STAT(adapter, gptch);
0307 *reg++ = IXGB_GET_STAT(adapter, bptcl);
0308 *reg++ = IXGB_GET_STAT(adapter, bptch);
0309 *reg++ = IXGB_GET_STAT(adapter, mptcl);
0310 *reg++ = IXGB_GET_STAT(adapter, mptch);
0311 *reg++ = IXGB_GET_STAT(adapter, uptcl);
0312 *reg++ = IXGB_GET_STAT(adapter, uptch);
0313 *reg++ = IXGB_GET_STAT(adapter, vptcl);
0314 *reg++ = IXGB_GET_STAT(adapter, vptch);
0315 *reg++ = IXGB_GET_STAT(adapter, jptcl);
0316 *reg++ = IXGB_GET_STAT(adapter, jptch);
0317 *reg++ = IXGB_GET_STAT(adapter, gotcl);
0318 *reg++ = IXGB_GET_STAT(adapter, gotch);
0319 *reg++ = IXGB_GET_STAT(adapter, totl);
0320 *reg++ = IXGB_GET_STAT(adapter, toth);
0321 *reg++ = IXGB_GET_STAT(adapter, dc);
0322 *reg++ = IXGB_GET_STAT(adapter, plt64c);
0323 *reg++ = IXGB_GET_STAT(adapter, tsctc);
0324 *reg++ = IXGB_GET_STAT(adapter, tsctfc);
0325 *reg++ = IXGB_GET_STAT(adapter, ibic);
0326 *reg++ = IXGB_GET_STAT(adapter, rfc);
0327 *reg++ = IXGB_GET_STAT(adapter, lfc);
0328 *reg++ = IXGB_GET_STAT(adapter, pfrc);
0329 *reg++ = IXGB_GET_STAT(adapter, pftc);
0330 *reg++ = IXGB_GET_STAT(adapter, mcfrc);
0331 *reg++ = IXGB_GET_STAT(adapter, mcftc);
0332 *reg++ = IXGB_GET_STAT(adapter, xonrxc);
0333 *reg++ = IXGB_GET_STAT(adapter, xontxc);
0334 *reg++ = IXGB_GET_STAT(adapter, xoffrxc);
0335 *reg++ = IXGB_GET_STAT(adapter, xofftxc);
0336 *reg++ = IXGB_GET_STAT(adapter, rjc);
0337
0338 regs->len = (reg - reg_start) * sizeof(u32);
0339 }
0340
0341 static int
0342 ixgb_get_eeprom_len(struct net_device *netdev)
0343 {
0344
0345 return IXGB_EEPROM_SIZE << 1;
0346 }
0347
0348 static int
0349 ixgb_get_eeprom(struct net_device *netdev,
0350 struct ethtool_eeprom *eeprom, u8 *bytes)
0351 {
0352 struct ixgb_adapter *adapter = netdev_priv(netdev);
0353 struct ixgb_hw *hw = &adapter->hw;
0354 __le16 *eeprom_buff;
0355 int i, max_len, first_word, last_word;
0356 int ret_val = 0;
0357
0358 if (eeprom->len == 0) {
0359 ret_val = -EINVAL;
0360 goto geeprom_error;
0361 }
0362
0363 eeprom->magic = hw->vendor_id | (hw->device_id << 16);
0364
0365 max_len = ixgb_get_eeprom_len(netdev);
0366
0367 if (eeprom->offset > eeprom->offset + eeprom->len) {
0368 ret_val = -EINVAL;
0369 goto geeprom_error;
0370 }
0371
0372 if ((eeprom->offset + eeprom->len) > max_len)
0373 eeprom->len = (max_len - eeprom->offset);
0374
0375 first_word = eeprom->offset >> 1;
0376 last_word = (eeprom->offset + eeprom->len - 1) >> 1;
0377
0378 eeprom_buff = kmalloc_array(last_word - first_word + 1,
0379 sizeof(__le16),
0380 GFP_KERNEL);
0381 if (!eeprom_buff)
0382 return -ENOMEM;
0383
0384
0385 for (i = 0; i <= (last_word - first_word); i++)
0386 eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i));
0387
0388 memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
0389 kfree(eeprom_buff);
0390
0391 geeprom_error:
0392 return ret_val;
0393 }
0394
0395 static int
0396 ixgb_set_eeprom(struct net_device *netdev,
0397 struct ethtool_eeprom *eeprom, u8 *bytes)
0398 {
0399 struct ixgb_adapter *adapter = netdev_priv(netdev);
0400 struct ixgb_hw *hw = &adapter->hw;
0401 u16 *eeprom_buff;
0402 void *ptr;
0403 int max_len, first_word, last_word;
0404 u16 i;
0405
0406 if (eeprom->len == 0)
0407 return -EINVAL;
0408
0409 if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
0410 return -EFAULT;
0411
0412 max_len = ixgb_get_eeprom_len(netdev);
0413
0414 if (eeprom->offset > eeprom->offset + eeprom->len)
0415 return -EINVAL;
0416
0417 if ((eeprom->offset + eeprom->len) > max_len)
0418 eeprom->len = (max_len - eeprom->offset);
0419
0420 first_word = eeprom->offset >> 1;
0421 last_word = (eeprom->offset + eeprom->len - 1) >> 1;
0422 eeprom_buff = kmalloc(max_len, GFP_KERNEL);
0423 if (!eeprom_buff)
0424 return -ENOMEM;
0425
0426 ptr = (void *)eeprom_buff;
0427
0428 if (eeprom->offset & 1) {
0429
0430
0431 eeprom_buff[0] = ixgb_read_eeprom(hw, first_word);
0432 ptr++;
0433 }
0434 if ((eeprom->offset + eeprom->len) & 1) {
0435
0436
0437 eeprom_buff[last_word - first_word]
0438 = ixgb_read_eeprom(hw, last_word);
0439 }
0440
0441 memcpy(ptr, bytes, eeprom->len);
0442 for (i = 0; i <= (last_word - first_word); i++)
0443 ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]);
0444
0445
0446 if (first_word <= EEPROM_CHECKSUM_REG)
0447 ixgb_update_eeprom_checksum(hw);
0448
0449 kfree(eeprom_buff);
0450 return 0;
0451 }
0452
0453 static void
0454 ixgb_get_drvinfo(struct net_device *netdev,
0455 struct ethtool_drvinfo *drvinfo)
0456 {
0457 struct ixgb_adapter *adapter = netdev_priv(netdev);
0458
0459 strlcpy(drvinfo->driver, ixgb_driver_name,
0460 sizeof(drvinfo->driver));
0461 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
0462 sizeof(drvinfo->bus_info));
0463 }
0464
0465 static void
0466 ixgb_get_ringparam(struct net_device *netdev,
0467 struct ethtool_ringparam *ring,
0468 struct kernel_ethtool_ringparam *kernel_ring,
0469 struct netlink_ext_ack *extack)
0470 {
0471 struct ixgb_adapter *adapter = netdev_priv(netdev);
0472 struct ixgb_desc_ring *txdr = &adapter->tx_ring;
0473 struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
0474
0475 ring->rx_max_pending = MAX_RXD;
0476 ring->tx_max_pending = MAX_TXD;
0477 ring->rx_pending = rxdr->count;
0478 ring->tx_pending = txdr->count;
0479 }
0480
0481 static int
0482 ixgb_set_ringparam(struct net_device *netdev,
0483 struct ethtool_ringparam *ring,
0484 struct kernel_ethtool_ringparam *kernel_ring,
0485 struct netlink_ext_ack *extack)
0486 {
0487 struct ixgb_adapter *adapter = netdev_priv(netdev);
0488 struct ixgb_desc_ring *txdr = &adapter->tx_ring;
0489 struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
0490 struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new;
0491 int err;
0492
0493 tx_old = adapter->tx_ring;
0494 rx_old = adapter->rx_ring;
0495
0496 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
0497 return -EINVAL;
0498
0499 if (netif_running(adapter->netdev))
0500 ixgb_down(adapter, true);
0501
0502 rxdr->count = max(ring->rx_pending,(u32)MIN_RXD);
0503 rxdr->count = min(rxdr->count,(u32)MAX_RXD);
0504 rxdr->count = ALIGN(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
0505
0506 txdr->count = max(ring->tx_pending,(u32)MIN_TXD);
0507 txdr->count = min(txdr->count,(u32)MAX_TXD);
0508 txdr->count = ALIGN(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
0509
0510 if (netif_running(adapter->netdev)) {
0511
0512 if ((err = ixgb_setup_rx_resources(adapter)))
0513 goto err_setup_rx;
0514 if ((err = ixgb_setup_tx_resources(adapter)))
0515 goto err_setup_tx;
0516
0517
0518
0519
0520 rx_new = adapter->rx_ring;
0521 tx_new = adapter->tx_ring;
0522 adapter->rx_ring = rx_old;
0523 adapter->tx_ring = tx_old;
0524 ixgb_free_rx_resources(adapter);
0525 ixgb_free_tx_resources(adapter);
0526 adapter->rx_ring = rx_new;
0527 adapter->tx_ring = tx_new;
0528 if ((err = ixgb_up(adapter)))
0529 return err;
0530 ixgb_set_speed_duplex(netdev);
0531 }
0532
0533 return 0;
0534 err_setup_tx:
0535 ixgb_free_rx_resources(adapter);
0536 err_setup_rx:
0537 adapter->rx_ring = rx_old;
0538 adapter->tx_ring = tx_old;
0539 ixgb_up(adapter);
0540 return err;
0541 }
0542
0543 static int
0544 ixgb_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
0545 {
0546 struct ixgb_adapter *adapter = netdev_priv(netdev);
0547
0548 switch (state) {
0549 case ETHTOOL_ID_ACTIVE:
0550 return 2;
0551
0552 case ETHTOOL_ID_ON:
0553 ixgb_led_on(&adapter->hw);
0554 break;
0555
0556 case ETHTOOL_ID_OFF:
0557 case ETHTOOL_ID_INACTIVE:
0558 ixgb_led_off(&adapter->hw);
0559 }
0560
0561 return 0;
0562 }
0563
0564 static int
0565 ixgb_get_sset_count(struct net_device *netdev, int sset)
0566 {
0567 switch (sset) {
0568 case ETH_SS_STATS:
0569 return IXGB_STATS_LEN;
0570 default:
0571 return -EOPNOTSUPP;
0572 }
0573 }
0574
0575 static void
0576 ixgb_get_ethtool_stats(struct net_device *netdev,
0577 struct ethtool_stats *stats, u64 *data)
0578 {
0579 struct ixgb_adapter *adapter = netdev_priv(netdev);
0580 int i;
0581 char *p = NULL;
0582
0583 ixgb_update_stats(adapter);
0584 for (i = 0; i < IXGB_STATS_LEN; i++) {
0585 switch (ixgb_gstrings_stats[i].type) {
0586 case NETDEV_STATS:
0587 p = (char *) netdev +
0588 ixgb_gstrings_stats[i].stat_offset;
0589 break;
0590 case IXGB_STATS:
0591 p = (char *) adapter +
0592 ixgb_gstrings_stats[i].stat_offset;
0593 break;
0594 }
0595
0596 data[i] = (ixgb_gstrings_stats[i].sizeof_stat ==
0597 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
0598 }
0599 }
0600
0601 static void
0602 ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
0603 {
0604 int i;
0605
0606 switch(stringset) {
0607 case ETH_SS_STATS:
0608 for (i = 0; i < IXGB_STATS_LEN; i++) {
0609 memcpy(data + i * ETH_GSTRING_LEN,
0610 ixgb_gstrings_stats[i].stat_string,
0611 ETH_GSTRING_LEN);
0612 }
0613 break;
0614 }
0615 }
0616
0617 static const struct ethtool_ops ixgb_ethtool_ops = {
0618 .get_drvinfo = ixgb_get_drvinfo,
0619 .get_regs_len = ixgb_get_regs_len,
0620 .get_regs = ixgb_get_regs,
0621 .get_link = ethtool_op_get_link,
0622 .get_eeprom_len = ixgb_get_eeprom_len,
0623 .get_eeprom = ixgb_get_eeprom,
0624 .set_eeprom = ixgb_set_eeprom,
0625 .get_ringparam = ixgb_get_ringparam,
0626 .set_ringparam = ixgb_set_ringparam,
0627 .get_pauseparam = ixgb_get_pauseparam,
0628 .set_pauseparam = ixgb_set_pauseparam,
0629 .get_msglevel = ixgb_get_msglevel,
0630 .set_msglevel = ixgb_set_msglevel,
0631 .get_strings = ixgb_get_strings,
0632 .set_phys_id = ixgb_set_phys_id,
0633 .get_sset_count = ixgb_get_sset_count,
0634 .get_ethtool_stats = ixgb_get_ethtool_stats,
0635 .get_link_ksettings = ixgb_get_link_ksettings,
0636 .set_link_ksettings = ixgb_set_link_ksettings,
0637 };
0638
0639 void ixgb_set_ethtool_ops(struct net_device *netdev)
0640 {
0641 netdev->ethtool_ops = &ixgb_ethtool_ops;
0642 }