0001
0002
0003
0004
0005
0006 #include <linux/netdevice.h>
0007 #include <linux/ethtool.h>
0008 #include <linux/pci.h>
0009 #include <linux/vmalloc.h>
0010 #include <linux/delay.h>
0011
0012 #include "igbvf.h"
0013 #include <linux/if_vlan.h>
0014
0015 struct igbvf_stats {
0016 char stat_string[ETH_GSTRING_LEN];
0017 int sizeof_stat;
0018 int stat_offset;
0019 int base_stat_offset;
0020 };
0021
0022 #define IGBVF_STAT(current, base) \
0023 sizeof(((struct igbvf_adapter *)0)->current), \
0024 offsetof(struct igbvf_adapter, current), \
0025 offsetof(struct igbvf_adapter, base)
0026
0027 static const struct igbvf_stats igbvf_gstrings_stats[] = {
0028 { "rx_packets", IGBVF_STAT(stats.gprc, stats.base_gprc) },
0029 { "tx_packets", IGBVF_STAT(stats.gptc, stats.base_gptc) },
0030 { "rx_bytes", IGBVF_STAT(stats.gorc, stats.base_gorc) },
0031 { "tx_bytes", IGBVF_STAT(stats.gotc, stats.base_gotc) },
0032 { "multicast", IGBVF_STAT(stats.mprc, stats.base_mprc) },
0033 { "lbrx_bytes", IGBVF_STAT(stats.gorlbc, stats.base_gorlbc) },
0034 { "lbrx_packets", IGBVF_STAT(stats.gprlbc, stats.base_gprlbc) },
0035 { "tx_restart_queue", IGBVF_STAT(restart_queue, zero_base) },
0036 { "rx_long_byte_count", IGBVF_STAT(stats.gorc, stats.base_gorc) },
0037 { "rx_csum_offload_good", IGBVF_STAT(hw_csum_good, zero_base) },
0038 { "rx_csum_offload_errors", IGBVF_STAT(hw_csum_err, zero_base) },
0039 { "rx_header_split", IGBVF_STAT(rx_hdr_split, zero_base) },
0040 { "alloc_rx_buff_failed", IGBVF_STAT(alloc_rx_buff_failed, zero_base) },
0041 };
0042
0043 #define IGBVF_GLOBAL_STATS_LEN ARRAY_SIZE(igbvf_gstrings_stats)
0044
0045 static const char igbvf_gstrings_test[][ETH_GSTRING_LEN] = {
0046 "Link test (on/offline)"
0047 };
0048
0049 #define IGBVF_TEST_LEN ARRAY_SIZE(igbvf_gstrings_test)
0050
0051 static int igbvf_get_link_ksettings(struct net_device *netdev,
0052 struct ethtool_link_ksettings *cmd)
0053 {
0054 struct igbvf_adapter *adapter = netdev_priv(netdev);
0055 struct e1000_hw *hw = &adapter->hw;
0056 u32 status;
0057
0058 ethtool_link_ksettings_zero_link_mode(cmd, supported);
0059 ethtool_link_ksettings_add_link_mode(cmd, supported, 1000baseT_Full);
0060 ethtool_link_ksettings_zero_link_mode(cmd, advertising);
0061 ethtool_link_ksettings_add_link_mode(cmd, advertising, 1000baseT_Full);
0062
0063 cmd->base.port = -1;
0064
0065 status = er32(STATUS);
0066 if (status & E1000_STATUS_LU) {
0067 if (status & E1000_STATUS_SPEED_1000)
0068 cmd->base.speed = SPEED_1000;
0069 else if (status & E1000_STATUS_SPEED_100)
0070 cmd->base.speed = SPEED_100;
0071 else
0072 cmd->base.speed = SPEED_10;
0073
0074 if (status & E1000_STATUS_FD)
0075 cmd->base.duplex = DUPLEX_FULL;
0076 else
0077 cmd->base.duplex = DUPLEX_HALF;
0078 } else {
0079 cmd->base.speed = SPEED_UNKNOWN;
0080 cmd->base.duplex = DUPLEX_UNKNOWN;
0081 }
0082
0083 cmd->base.autoneg = AUTONEG_DISABLE;
0084
0085 return 0;
0086 }
0087
0088 static int igbvf_set_link_ksettings(struct net_device *netdev,
0089 const struct ethtool_link_ksettings *cmd)
0090 {
0091 return -EOPNOTSUPP;
0092 }
0093
0094 static void igbvf_get_pauseparam(struct net_device *netdev,
0095 struct ethtool_pauseparam *pause)
0096 {
0097 }
0098
0099 static int igbvf_set_pauseparam(struct net_device *netdev,
0100 struct ethtool_pauseparam *pause)
0101 {
0102 return -EOPNOTSUPP;
0103 }
0104
0105 static u32 igbvf_get_msglevel(struct net_device *netdev)
0106 {
0107 struct igbvf_adapter *adapter = netdev_priv(netdev);
0108
0109 return adapter->msg_enable;
0110 }
0111
0112 static void igbvf_set_msglevel(struct net_device *netdev, u32 data)
0113 {
0114 struct igbvf_adapter *adapter = netdev_priv(netdev);
0115
0116 adapter->msg_enable = data;
0117 }
0118
0119 static int igbvf_get_regs_len(struct net_device *netdev)
0120 {
0121 #define IGBVF_REGS_LEN 8
0122 return IGBVF_REGS_LEN * sizeof(u32);
0123 }
0124
0125 static void igbvf_get_regs(struct net_device *netdev,
0126 struct ethtool_regs *regs, void *p)
0127 {
0128 struct igbvf_adapter *adapter = netdev_priv(netdev);
0129 struct e1000_hw *hw = &adapter->hw;
0130 u32 *regs_buff = p;
0131
0132 memset(p, 0, IGBVF_REGS_LEN * sizeof(u32));
0133
0134 regs->version = (1u << 24) |
0135 (adapter->pdev->revision << 16) |
0136 adapter->pdev->device;
0137
0138 regs_buff[0] = er32(CTRL);
0139 regs_buff[1] = er32(STATUS);
0140
0141 regs_buff[2] = er32(RDLEN(0));
0142 regs_buff[3] = er32(RDH(0));
0143 regs_buff[4] = er32(RDT(0));
0144
0145 regs_buff[5] = er32(TDLEN(0));
0146 regs_buff[6] = er32(TDH(0));
0147 regs_buff[7] = er32(TDT(0));
0148 }
0149
0150 static int igbvf_get_eeprom_len(struct net_device *netdev)
0151 {
0152 return 0;
0153 }
0154
0155 static int igbvf_get_eeprom(struct net_device *netdev,
0156 struct ethtool_eeprom *eeprom, u8 *bytes)
0157 {
0158 return -EOPNOTSUPP;
0159 }
0160
0161 static int igbvf_set_eeprom(struct net_device *netdev,
0162 struct ethtool_eeprom *eeprom, u8 *bytes)
0163 {
0164 return -EOPNOTSUPP;
0165 }
0166
0167 static void igbvf_get_drvinfo(struct net_device *netdev,
0168 struct ethtool_drvinfo *drvinfo)
0169 {
0170 struct igbvf_adapter *adapter = netdev_priv(netdev);
0171
0172 strlcpy(drvinfo->driver, igbvf_driver_name, sizeof(drvinfo->driver));
0173 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
0174 sizeof(drvinfo->bus_info));
0175 }
0176
0177 static void igbvf_get_ringparam(struct net_device *netdev,
0178 struct ethtool_ringparam *ring,
0179 struct kernel_ethtool_ringparam *kernel_ring,
0180 struct netlink_ext_ack *extack)
0181 {
0182 struct igbvf_adapter *adapter = netdev_priv(netdev);
0183 struct igbvf_ring *tx_ring = adapter->tx_ring;
0184 struct igbvf_ring *rx_ring = adapter->rx_ring;
0185
0186 ring->rx_max_pending = IGBVF_MAX_RXD;
0187 ring->tx_max_pending = IGBVF_MAX_TXD;
0188 ring->rx_pending = rx_ring->count;
0189 ring->tx_pending = tx_ring->count;
0190 }
0191
0192 static int igbvf_set_ringparam(struct net_device *netdev,
0193 struct ethtool_ringparam *ring,
0194 struct kernel_ethtool_ringparam *kernel_ring,
0195 struct netlink_ext_ack *extack)
0196 {
0197 struct igbvf_adapter *adapter = netdev_priv(netdev);
0198 struct igbvf_ring *temp_ring;
0199 int err = 0;
0200 u32 new_rx_count, new_tx_count;
0201
0202 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
0203 return -EINVAL;
0204
0205 new_rx_count = max_t(u32, ring->rx_pending, IGBVF_MIN_RXD);
0206 new_rx_count = min_t(u32, new_rx_count, IGBVF_MAX_RXD);
0207 new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);
0208
0209 new_tx_count = max_t(u32, ring->tx_pending, IGBVF_MIN_TXD);
0210 new_tx_count = min_t(u32, new_tx_count, IGBVF_MAX_TXD);
0211 new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
0212
0213 if ((new_tx_count == adapter->tx_ring->count) &&
0214 (new_rx_count == adapter->rx_ring->count)) {
0215
0216 return 0;
0217 }
0218
0219 while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
0220 usleep_range(1000, 2000);
0221
0222 if (!netif_running(adapter->netdev)) {
0223 adapter->tx_ring->count = new_tx_count;
0224 adapter->rx_ring->count = new_rx_count;
0225 goto clear_reset;
0226 }
0227
0228 temp_ring = vmalloc(sizeof(struct igbvf_ring));
0229 if (!temp_ring) {
0230 err = -ENOMEM;
0231 goto clear_reset;
0232 }
0233
0234 igbvf_down(adapter);
0235
0236
0237
0238
0239
0240 if (new_tx_count != adapter->tx_ring->count) {
0241 memcpy(temp_ring, adapter->tx_ring, sizeof(struct igbvf_ring));
0242
0243 temp_ring->count = new_tx_count;
0244 err = igbvf_setup_tx_resources(adapter, temp_ring);
0245 if (err)
0246 goto err_setup;
0247
0248 igbvf_free_tx_resources(adapter->tx_ring);
0249
0250 memcpy(adapter->tx_ring, temp_ring, sizeof(struct igbvf_ring));
0251 }
0252
0253 if (new_rx_count != adapter->rx_ring->count) {
0254 memcpy(temp_ring, adapter->rx_ring, sizeof(struct igbvf_ring));
0255
0256 temp_ring->count = new_rx_count;
0257 err = igbvf_setup_rx_resources(adapter, temp_ring);
0258 if (err)
0259 goto err_setup;
0260
0261 igbvf_free_rx_resources(adapter->rx_ring);
0262
0263 memcpy(adapter->rx_ring, temp_ring, sizeof(struct igbvf_ring));
0264 }
0265 err_setup:
0266 igbvf_up(adapter);
0267 vfree(temp_ring);
0268 clear_reset:
0269 clear_bit(__IGBVF_RESETTING, &adapter->state);
0270 return err;
0271 }
0272
0273 static int igbvf_link_test(struct igbvf_adapter *adapter, u64 *data)
0274 {
0275 struct e1000_hw *hw = &adapter->hw;
0276 *data = 0;
0277
0278 spin_lock_bh(&hw->mbx_lock);
0279
0280 hw->mac.ops.check_for_link(hw);
0281
0282 spin_unlock_bh(&hw->mbx_lock);
0283
0284 if (!(er32(STATUS) & E1000_STATUS_LU))
0285 *data = 1;
0286
0287 return *data;
0288 }
0289
0290 static void igbvf_diag_test(struct net_device *netdev,
0291 struct ethtool_test *eth_test, u64 *data)
0292 {
0293 struct igbvf_adapter *adapter = netdev_priv(netdev);
0294
0295 set_bit(__IGBVF_TESTING, &adapter->state);
0296
0297
0298
0299
0300 if (igbvf_link_test(adapter, &data[0]))
0301 eth_test->flags |= ETH_TEST_FL_FAILED;
0302
0303 clear_bit(__IGBVF_TESTING, &adapter->state);
0304 msleep_interruptible(4 * 1000);
0305 }
0306
0307 static void igbvf_get_wol(struct net_device *netdev,
0308 struct ethtool_wolinfo *wol)
0309 {
0310 wol->supported = 0;
0311 wol->wolopts = 0;
0312 }
0313
0314 static int igbvf_set_wol(struct net_device *netdev,
0315 struct ethtool_wolinfo *wol)
0316 {
0317 return -EOPNOTSUPP;
0318 }
0319
0320 static int igbvf_get_coalesce(struct net_device *netdev,
0321 struct ethtool_coalesce *ec,
0322 struct kernel_ethtool_coalesce *kernel_coal,
0323 struct netlink_ext_ack *extack)
0324 {
0325 struct igbvf_adapter *adapter = netdev_priv(netdev);
0326
0327 if (adapter->requested_itr <= 3)
0328 ec->rx_coalesce_usecs = adapter->requested_itr;
0329 else
0330 ec->rx_coalesce_usecs = adapter->current_itr >> 2;
0331
0332 return 0;
0333 }
0334
0335 static int igbvf_set_coalesce(struct net_device *netdev,
0336 struct ethtool_coalesce *ec,
0337 struct kernel_ethtool_coalesce *kernel_coal,
0338 struct netlink_ext_ack *extack)
0339 {
0340 struct igbvf_adapter *adapter = netdev_priv(netdev);
0341 struct e1000_hw *hw = &adapter->hw;
0342
0343 if ((ec->rx_coalesce_usecs >= IGBVF_MIN_ITR_USECS) &&
0344 (ec->rx_coalesce_usecs <= IGBVF_MAX_ITR_USECS)) {
0345 adapter->current_itr = ec->rx_coalesce_usecs << 2;
0346 adapter->requested_itr = 1000000000 /
0347 (adapter->current_itr * 256);
0348 } else if ((ec->rx_coalesce_usecs == 3) ||
0349 (ec->rx_coalesce_usecs == 2)) {
0350 adapter->current_itr = IGBVF_START_ITR;
0351 adapter->requested_itr = ec->rx_coalesce_usecs;
0352 } else if (ec->rx_coalesce_usecs == 0) {
0353
0354
0355
0356
0357
0358
0359 adapter->current_itr = 4;
0360 adapter->requested_itr = 1000000000 /
0361 (adapter->current_itr * 256);
0362 } else {
0363 return -EINVAL;
0364 }
0365
0366 writel(adapter->current_itr,
0367 hw->hw_addr + adapter->rx_ring->itr_register);
0368
0369 return 0;
0370 }
0371
0372 static int igbvf_nway_reset(struct net_device *netdev)
0373 {
0374 struct igbvf_adapter *adapter = netdev_priv(netdev);
0375
0376 if (netif_running(netdev))
0377 igbvf_reinit_locked(adapter);
0378 return 0;
0379 }
0380
0381 static void igbvf_get_ethtool_stats(struct net_device *netdev,
0382 struct ethtool_stats *stats,
0383 u64 *data)
0384 {
0385 struct igbvf_adapter *adapter = netdev_priv(netdev);
0386 int i;
0387
0388 igbvf_update_stats(adapter);
0389 for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) {
0390 char *p = (char *)adapter +
0391 igbvf_gstrings_stats[i].stat_offset;
0392 char *b = (char *)adapter +
0393 igbvf_gstrings_stats[i].base_stat_offset;
0394 data[i] = ((igbvf_gstrings_stats[i].sizeof_stat ==
0395 sizeof(u64)) ? (*(u64 *)p - *(u64 *)b) :
0396 (*(u32 *)p - *(u32 *)b));
0397 }
0398 }
0399
0400 static int igbvf_get_sset_count(struct net_device *dev, int stringset)
0401 {
0402 switch (stringset) {
0403 case ETH_SS_TEST:
0404 return IGBVF_TEST_LEN;
0405 case ETH_SS_STATS:
0406 return IGBVF_GLOBAL_STATS_LEN;
0407 default:
0408 return -EINVAL;
0409 }
0410 }
0411
0412 static void igbvf_get_strings(struct net_device *netdev, u32 stringset,
0413 u8 *data)
0414 {
0415 u8 *p = data;
0416 int i;
0417
0418 switch (stringset) {
0419 case ETH_SS_TEST:
0420 memcpy(data, *igbvf_gstrings_test, sizeof(igbvf_gstrings_test));
0421 break;
0422 case ETH_SS_STATS:
0423 for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) {
0424 memcpy(p, igbvf_gstrings_stats[i].stat_string,
0425 ETH_GSTRING_LEN);
0426 p += ETH_GSTRING_LEN;
0427 }
0428 break;
0429 }
0430 }
0431
0432 static const struct ethtool_ops igbvf_ethtool_ops = {
0433 .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS,
0434 .get_drvinfo = igbvf_get_drvinfo,
0435 .get_regs_len = igbvf_get_regs_len,
0436 .get_regs = igbvf_get_regs,
0437 .get_wol = igbvf_get_wol,
0438 .set_wol = igbvf_set_wol,
0439 .get_msglevel = igbvf_get_msglevel,
0440 .set_msglevel = igbvf_set_msglevel,
0441 .nway_reset = igbvf_nway_reset,
0442 .get_link = ethtool_op_get_link,
0443 .get_eeprom_len = igbvf_get_eeprom_len,
0444 .get_eeprom = igbvf_get_eeprom,
0445 .set_eeprom = igbvf_set_eeprom,
0446 .get_ringparam = igbvf_get_ringparam,
0447 .set_ringparam = igbvf_set_ringparam,
0448 .get_pauseparam = igbvf_get_pauseparam,
0449 .set_pauseparam = igbvf_set_pauseparam,
0450 .self_test = igbvf_diag_test,
0451 .get_sset_count = igbvf_get_sset_count,
0452 .get_strings = igbvf_get_strings,
0453 .get_ethtool_stats = igbvf_get_ethtool_stats,
0454 .get_coalesce = igbvf_get_coalesce,
0455 .set_coalesce = igbvf_set_coalesce,
0456 .get_link_ksettings = igbvf_get_link_ksettings,
0457 .set_link_ksettings = igbvf_set_link_ksettings,
0458 };
0459
0460 void igbvf_set_ethtool_ops(struct net_device *netdev)
0461 {
0462 netdev->ethtool_ops = &igbvf_ethtool_ops;
0463 }