1 /******************************************************************************* 2 3 Intel(R) 82576 Virtual Function Linux driver 4 Copyright(c) 2009 - 2012 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 e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 24 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 25 26 *******************************************************************************/ 27 28 /* ethtool support for igbvf */ 29 30 #include <linux/netdevice.h> 31 #include <linux/ethtool.h> 32 #include <linux/pci.h> 33 #include <linux/vmalloc.h> 34 #include <linux/delay.h> 35 36 #include "igbvf.h" 37 #include <linux/if_vlan.h> 38 39 40 struct igbvf_stats { 41 char stat_string[ETH_GSTRING_LEN]; 42 int sizeof_stat; 43 int stat_offset; 44 int base_stat_offset; 45 }; 46 47 #define IGBVF_STAT(current, base) \ 48 sizeof(((struct igbvf_adapter *)0)->current), \ 49 offsetof(struct igbvf_adapter, current), \ 50 offsetof(struct igbvf_adapter, base) 51 52 static const struct igbvf_stats igbvf_gstrings_stats[] = { 53 { "rx_packets", IGBVF_STAT(stats.gprc, stats.base_gprc) }, 54 { "tx_packets", IGBVF_STAT(stats.gptc, stats.base_gptc) }, 55 { "rx_bytes", IGBVF_STAT(stats.gorc, stats.base_gorc) }, 56 { "tx_bytes", IGBVF_STAT(stats.gotc, stats.base_gotc) }, 57 { "multicast", IGBVF_STAT(stats.mprc, stats.base_mprc) }, 58 { "lbrx_bytes", IGBVF_STAT(stats.gorlbc, stats.base_gorlbc) }, 59 { "lbrx_packets", IGBVF_STAT(stats.gprlbc, stats.base_gprlbc) }, 60 { "tx_restart_queue", IGBVF_STAT(restart_queue, zero_base) }, 61 { "rx_long_byte_count", IGBVF_STAT(stats.gorc, stats.base_gorc) }, 62 { "rx_csum_offload_good", IGBVF_STAT(hw_csum_good, zero_base) }, 63 { "rx_csum_offload_errors", IGBVF_STAT(hw_csum_err, zero_base) }, 64 { "rx_header_split", IGBVF_STAT(rx_hdr_split, zero_base) }, 65 { "alloc_rx_buff_failed", IGBVF_STAT(alloc_rx_buff_failed, zero_base) }, 66 }; 67 68 #define IGBVF_GLOBAL_STATS_LEN ARRAY_SIZE(igbvf_gstrings_stats) 69 70 static const char igbvf_gstrings_test[][ETH_GSTRING_LEN] = { 71 "Link test (on/offline)" 72 }; 73 74 #define IGBVF_TEST_LEN ARRAY_SIZE(igbvf_gstrings_test) 75 76 static int igbvf_get_settings(struct net_device *netdev, 77 struct ethtool_cmd *ecmd) 78 { 79 struct igbvf_adapter *adapter = netdev_priv(netdev); 80 struct e1000_hw *hw = &adapter->hw; 81 u32 status; 82 83 ecmd->supported = SUPPORTED_1000baseT_Full; 84 85 ecmd->advertising = ADVERTISED_1000baseT_Full; 86 87 ecmd->port = -1; 88 ecmd->transceiver = XCVR_DUMMY1; 89 90 status = er32(STATUS); 91 if (status & E1000_STATUS_LU) { 92 if (status & E1000_STATUS_SPEED_1000) 93 ethtool_cmd_speed_set(ecmd, SPEED_1000); 94 else if (status & E1000_STATUS_SPEED_100) 95 ethtool_cmd_speed_set(ecmd, SPEED_100); 96 else 97 ethtool_cmd_speed_set(ecmd, SPEED_10); 98 99 if (status & E1000_STATUS_FD) 100 ecmd->duplex = DUPLEX_FULL; 101 else 102 ecmd->duplex = DUPLEX_HALF; 103 } else { 104 ethtool_cmd_speed_set(ecmd, -1); 105 ecmd->duplex = -1; 106 } 107 108 ecmd->autoneg = AUTONEG_DISABLE; 109 110 return 0; 111 } 112 113 static int igbvf_set_settings(struct net_device *netdev, 114 struct ethtool_cmd *ecmd) 115 { 116 return -EOPNOTSUPP; 117 } 118 119 static void igbvf_get_pauseparam(struct net_device *netdev, 120 struct ethtool_pauseparam *pause) 121 { 122 return; 123 } 124 125 static int igbvf_set_pauseparam(struct net_device *netdev, 126 struct ethtool_pauseparam *pause) 127 { 128 return -EOPNOTSUPP; 129 } 130 131 static u32 igbvf_get_msglevel(struct net_device *netdev) 132 { 133 struct igbvf_adapter *adapter = netdev_priv(netdev); 134 return adapter->msg_enable; 135 } 136 137 static void igbvf_set_msglevel(struct net_device *netdev, u32 data) 138 { 139 struct igbvf_adapter *adapter = netdev_priv(netdev); 140 adapter->msg_enable = data; 141 } 142 143 static int igbvf_get_regs_len(struct net_device *netdev) 144 { 145 #define IGBVF_REGS_LEN 8 146 return IGBVF_REGS_LEN * sizeof(u32); 147 } 148 149 static void igbvf_get_regs(struct net_device *netdev, 150 struct ethtool_regs *regs, void *p) 151 { 152 struct igbvf_adapter *adapter = netdev_priv(netdev); 153 struct e1000_hw *hw = &adapter->hw; 154 u32 *regs_buff = p; 155 156 memset(p, 0, IGBVF_REGS_LEN * sizeof(u32)); 157 158 regs->version = (1 << 24) | (adapter->pdev->revision << 16) | 159 adapter->pdev->device; 160 161 regs_buff[0] = er32(CTRL); 162 regs_buff[1] = er32(STATUS); 163 164 regs_buff[2] = er32(RDLEN(0)); 165 regs_buff[3] = er32(RDH(0)); 166 regs_buff[4] = er32(RDT(0)); 167 168 regs_buff[5] = er32(TDLEN(0)); 169 regs_buff[6] = er32(TDH(0)); 170 regs_buff[7] = er32(TDT(0)); 171 } 172 173 static int igbvf_get_eeprom_len(struct net_device *netdev) 174 { 175 return 0; 176 } 177 178 static int igbvf_get_eeprom(struct net_device *netdev, 179 struct ethtool_eeprom *eeprom, u8 *bytes) 180 { 181 return -EOPNOTSUPP; 182 } 183 184 static int igbvf_set_eeprom(struct net_device *netdev, 185 struct ethtool_eeprom *eeprom, u8 *bytes) 186 { 187 return -EOPNOTSUPP; 188 } 189 190 static void igbvf_get_drvinfo(struct net_device *netdev, 191 struct ethtool_drvinfo *drvinfo) 192 { 193 struct igbvf_adapter *adapter = netdev_priv(netdev); 194 195 strlcpy(drvinfo->driver, igbvf_driver_name, sizeof(drvinfo->driver)); 196 strlcpy(drvinfo->version, igbvf_driver_version, 197 sizeof(drvinfo->version)); 198 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 199 sizeof(drvinfo->bus_info)); 200 drvinfo->regdump_len = igbvf_get_regs_len(netdev); 201 drvinfo->eedump_len = igbvf_get_eeprom_len(netdev); 202 } 203 204 static void igbvf_get_ringparam(struct net_device *netdev, 205 struct ethtool_ringparam *ring) 206 { 207 struct igbvf_adapter *adapter = netdev_priv(netdev); 208 struct igbvf_ring *tx_ring = adapter->tx_ring; 209 struct igbvf_ring *rx_ring = adapter->rx_ring; 210 211 ring->rx_max_pending = IGBVF_MAX_RXD; 212 ring->tx_max_pending = IGBVF_MAX_TXD; 213 ring->rx_pending = rx_ring->count; 214 ring->tx_pending = tx_ring->count; 215 } 216 217 static int igbvf_set_ringparam(struct net_device *netdev, 218 struct ethtool_ringparam *ring) 219 { 220 struct igbvf_adapter *adapter = netdev_priv(netdev); 221 struct igbvf_ring *temp_ring; 222 int err = 0; 223 u32 new_rx_count, new_tx_count; 224 225 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 226 return -EINVAL; 227 228 new_rx_count = max(ring->rx_pending, (u32)IGBVF_MIN_RXD); 229 new_rx_count = min(new_rx_count, (u32)IGBVF_MAX_RXD); 230 new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE); 231 232 new_tx_count = max(ring->tx_pending, (u32)IGBVF_MIN_TXD); 233 new_tx_count = min(new_tx_count, (u32)IGBVF_MAX_TXD); 234 new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE); 235 236 if ((new_tx_count == adapter->tx_ring->count) && 237 (new_rx_count == adapter->rx_ring->count)) { 238 /* nothing to do */ 239 return 0; 240 } 241 242 while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state)) 243 msleep(1); 244 245 if (!netif_running(adapter->netdev)) { 246 adapter->tx_ring->count = new_tx_count; 247 adapter->rx_ring->count = new_rx_count; 248 goto clear_reset; 249 } 250 251 temp_ring = vmalloc(sizeof(struct igbvf_ring)); 252 if (!temp_ring) { 253 err = -ENOMEM; 254 goto clear_reset; 255 } 256 257 igbvf_down(adapter); 258 259 /* 260 * We can't just free everything and then setup again, 261 * because the ISRs in MSI-X mode get passed pointers 262 * to the tx and rx ring structs. 263 */ 264 if (new_tx_count != adapter->tx_ring->count) { 265 memcpy(temp_ring, adapter->tx_ring, sizeof(struct igbvf_ring)); 266 267 temp_ring->count = new_tx_count; 268 err = igbvf_setup_tx_resources(adapter, temp_ring); 269 if (err) 270 goto err_setup; 271 272 igbvf_free_tx_resources(adapter->tx_ring); 273 274 memcpy(adapter->tx_ring, temp_ring, sizeof(struct igbvf_ring)); 275 } 276 277 if (new_rx_count != adapter->rx_ring->count) { 278 memcpy(temp_ring, adapter->rx_ring, sizeof(struct igbvf_ring)); 279 280 temp_ring->count = new_rx_count; 281 err = igbvf_setup_rx_resources(adapter, temp_ring); 282 if (err) 283 goto err_setup; 284 285 igbvf_free_rx_resources(adapter->rx_ring); 286 287 memcpy(adapter->rx_ring, temp_ring,sizeof(struct igbvf_ring)); 288 } 289 err_setup: 290 igbvf_up(adapter); 291 vfree(temp_ring); 292 clear_reset: 293 clear_bit(__IGBVF_RESETTING, &adapter->state); 294 return err; 295 } 296 297 static int igbvf_link_test(struct igbvf_adapter *adapter, u64 *data) 298 { 299 struct e1000_hw *hw = &adapter->hw; 300 *data = 0; 301 302 hw->mac.ops.check_for_link(hw); 303 304 if (!(er32(STATUS) & E1000_STATUS_LU)) 305 *data = 1; 306 307 return *data; 308 } 309 310 static void igbvf_diag_test(struct net_device *netdev, 311 struct ethtool_test *eth_test, u64 *data) 312 { 313 struct igbvf_adapter *adapter = netdev_priv(netdev); 314 315 set_bit(__IGBVF_TESTING, &adapter->state); 316 317 /* 318 * Link test performed before hardware reset so autoneg doesn't 319 * interfere with test result 320 */ 321 if (igbvf_link_test(adapter, &data[0])) 322 eth_test->flags |= ETH_TEST_FL_FAILED; 323 324 clear_bit(__IGBVF_TESTING, &adapter->state); 325 msleep_interruptible(4 * 1000); 326 } 327 328 static void igbvf_get_wol(struct net_device *netdev, 329 struct ethtool_wolinfo *wol) 330 { 331 wol->supported = 0; 332 wol->wolopts = 0; 333 } 334 335 static int igbvf_set_wol(struct net_device *netdev, 336 struct ethtool_wolinfo *wol) 337 { 338 return -EOPNOTSUPP; 339 } 340 341 static int igbvf_get_coalesce(struct net_device *netdev, 342 struct ethtool_coalesce *ec) 343 { 344 struct igbvf_adapter *adapter = netdev_priv(netdev); 345 346 if (adapter->requested_itr <= 3) 347 ec->rx_coalesce_usecs = adapter->requested_itr; 348 else 349 ec->rx_coalesce_usecs = adapter->current_itr >> 2; 350 351 return 0; 352 } 353 354 static int igbvf_set_coalesce(struct net_device *netdev, 355 struct ethtool_coalesce *ec) 356 { 357 struct igbvf_adapter *adapter = netdev_priv(netdev); 358 struct e1000_hw *hw = &adapter->hw; 359 360 if ((ec->rx_coalesce_usecs >= IGBVF_MIN_ITR_USECS) && 361 (ec->rx_coalesce_usecs <= IGBVF_MAX_ITR_USECS)) { 362 adapter->current_itr = ec->rx_coalesce_usecs << 2; 363 adapter->requested_itr = 1000000000 / 364 (adapter->current_itr * 256); 365 } else if ((ec->rx_coalesce_usecs == 3) || 366 (ec->rx_coalesce_usecs == 2)) { 367 adapter->current_itr = IGBVF_START_ITR; 368 adapter->requested_itr = ec->rx_coalesce_usecs; 369 } else if (ec->rx_coalesce_usecs == 0) { 370 /* 371 * The user's desire is to turn off interrupt throttling 372 * altogether, but due to HW limitations, we can't do that. 373 * Instead we set a very small value in EITR, which would 374 * allow ~967k interrupts per second, but allow the adapter's 375 * internal clocking to still function properly. 376 */ 377 adapter->current_itr = 4; 378 adapter->requested_itr = 1000000000 / 379 (adapter->current_itr * 256); 380 } else 381 return -EINVAL; 382 383 writel(adapter->current_itr, 384 hw->hw_addr + adapter->rx_ring->itr_register); 385 386 return 0; 387 } 388 389 static int igbvf_nway_reset(struct net_device *netdev) 390 { 391 struct igbvf_adapter *adapter = netdev_priv(netdev); 392 if (netif_running(netdev)) 393 igbvf_reinit_locked(adapter); 394 return 0; 395 } 396 397 398 static void igbvf_get_ethtool_stats(struct net_device *netdev, 399 struct ethtool_stats *stats, 400 u64 *data) 401 { 402 struct igbvf_adapter *adapter = netdev_priv(netdev); 403 int i; 404 405 igbvf_update_stats(adapter); 406 for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) { 407 char *p = (char *)adapter + 408 igbvf_gstrings_stats[i].stat_offset; 409 char *b = (char *)adapter + 410 igbvf_gstrings_stats[i].base_stat_offset; 411 data[i] = ((igbvf_gstrings_stats[i].sizeof_stat == 412 sizeof(u64)) ? (*(u64 *)p - *(u64 *)b) : 413 (*(u32 *)p - *(u32 *)b)); 414 } 415 416 } 417 418 static int igbvf_get_sset_count(struct net_device *dev, int stringset) 419 { 420 switch(stringset) { 421 case ETH_SS_TEST: 422 return IGBVF_TEST_LEN; 423 case ETH_SS_STATS: 424 return IGBVF_GLOBAL_STATS_LEN; 425 default: 426 return -EINVAL; 427 } 428 } 429 430 static void igbvf_get_strings(struct net_device *netdev, u32 stringset, 431 u8 *data) 432 { 433 u8 *p = data; 434 int i; 435 436 switch (stringset) { 437 case ETH_SS_TEST: 438 memcpy(data, *igbvf_gstrings_test, sizeof(igbvf_gstrings_test)); 439 break; 440 case ETH_SS_STATS: 441 for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) { 442 memcpy(p, igbvf_gstrings_stats[i].stat_string, 443 ETH_GSTRING_LEN); 444 p += ETH_GSTRING_LEN; 445 } 446 break; 447 } 448 } 449 450 static const struct ethtool_ops igbvf_ethtool_ops = { 451 .get_settings = igbvf_get_settings, 452 .set_settings = igbvf_set_settings, 453 .get_drvinfo = igbvf_get_drvinfo, 454 .get_regs_len = igbvf_get_regs_len, 455 .get_regs = igbvf_get_regs, 456 .get_wol = igbvf_get_wol, 457 .set_wol = igbvf_set_wol, 458 .get_msglevel = igbvf_get_msglevel, 459 .set_msglevel = igbvf_set_msglevel, 460 .nway_reset = igbvf_nway_reset, 461 .get_link = ethtool_op_get_link, 462 .get_eeprom_len = igbvf_get_eeprom_len, 463 .get_eeprom = igbvf_get_eeprom, 464 .set_eeprom = igbvf_set_eeprom, 465 .get_ringparam = igbvf_get_ringparam, 466 .set_ringparam = igbvf_set_ringparam, 467 .get_pauseparam = igbvf_get_pauseparam, 468 .set_pauseparam = igbvf_set_pauseparam, 469 .self_test = igbvf_diag_test, 470 .get_sset_count = igbvf_get_sset_count, 471 .get_strings = igbvf_get_strings, 472 .get_ethtool_stats = igbvf_get_ethtool_stats, 473 .get_coalesce = igbvf_get_coalesce, 474 .set_coalesce = igbvf_set_coalesce, 475 }; 476 477 void igbvf_set_ethtool_ops(struct net_device *netdev) 478 { 479 SET_ETHTOOL_OPS(netdev, &igbvf_ethtool_ops); 480 } 481