Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 17431928194b36a0f88082df875e2e036da7fddf 866 lines 25 kB view raw
1/**************************************************************************** 2 * Driver for Solarflare Solarstorm network controllers and boards 3 * Copyright 2005-2006 Fen Systems Ltd. 4 * Copyright 2006-2009 Solarflare Communications Inc. 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 version 2 as published 8 * by the Free Software Foundation, incorporated herein by reference. 9 */ 10 11#include <linux/netdevice.h> 12#include <linux/ethtool.h> 13#include <linux/rtnetlink.h> 14#include "net_driver.h" 15#include "workarounds.h" 16#include "selftest.h" 17#include "efx.h" 18#include "nic.h" 19#include "spi.h" 20#include "mdio_10g.h" 21 22struct ethtool_string { 23 char name[ETH_GSTRING_LEN]; 24}; 25 26struct efx_ethtool_stat { 27 const char *name; 28 enum { 29 EFX_ETHTOOL_STAT_SOURCE_mac_stats, 30 EFX_ETHTOOL_STAT_SOURCE_nic, 31 EFX_ETHTOOL_STAT_SOURCE_channel 32 } source; 33 unsigned offset; 34 u64(*get_stat) (void *field); /* Reader function */ 35}; 36 37/* Initialiser for a struct #efx_ethtool_stat with type-checking */ 38#define EFX_ETHTOOL_STAT(stat_name, source_name, field, field_type, \ 39 get_stat_function) { \ 40 .name = #stat_name, \ 41 .source = EFX_ETHTOOL_STAT_SOURCE_##source_name, \ 42 .offset = ((((field_type *) 0) == \ 43 &((struct efx_##source_name *)0)->field) ? \ 44 offsetof(struct efx_##source_name, field) : \ 45 offsetof(struct efx_##source_name, field)), \ 46 .get_stat = get_stat_function, \ 47} 48 49static u64 efx_get_uint_stat(void *field) 50{ 51 return *(unsigned int *)field; 52} 53 54static u64 efx_get_ulong_stat(void *field) 55{ 56 return *(unsigned long *)field; 57} 58 59static u64 efx_get_u64_stat(void *field) 60{ 61 return *(u64 *) field; 62} 63 64static u64 efx_get_atomic_stat(void *field) 65{ 66 return atomic_read((atomic_t *) field); 67} 68 69#define EFX_ETHTOOL_ULONG_MAC_STAT(field) \ 70 EFX_ETHTOOL_STAT(field, mac_stats, field, \ 71 unsigned long, efx_get_ulong_stat) 72 73#define EFX_ETHTOOL_U64_MAC_STAT(field) \ 74 EFX_ETHTOOL_STAT(field, mac_stats, field, \ 75 u64, efx_get_u64_stat) 76 77#define EFX_ETHTOOL_UINT_NIC_STAT(name) \ 78 EFX_ETHTOOL_STAT(name, nic, n_##name, \ 79 unsigned int, efx_get_uint_stat) 80 81#define EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(field) \ 82 EFX_ETHTOOL_STAT(field, nic, field, \ 83 atomic_t, efx_get_atomic_stat) 84 85#define EFX_ETHTOOL_UINT_CHANNEL_STAT(field) \ 86 EFX_ETHTOOL_STAT(field, channel, n_##field, \ 87 unsigned int, efx_get_uint_stat) 88 89static struct efx_ethtool_stat efx_ethtool_stats[] = { 90 EFX_ETHTOOL_U64_MAC_STAT(tx_bytes), 91 EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes), 92 EFX_ETHTOOL_U64_MAC_STAT(tx_bad_bytes), 93 EFX_ETHTOOL_ULONG_MAC_STAT(tx_packets), 94 EFX_ETHTOOL_ULONG_MAC_STAT(tx_bad), 95 EFX_ETHTOOL_ULONG_MAC_STAT(tx_pause), 96 EFX_ETHTOOL_ULONG_MAC_STAT(tx_control), 97 EFX_ETHTOOL_ULONG_MAC_STAT(tx_unicast), 98 EFX_ETHTOOL_ULONG_MAC_STAT(tx_multicast), 99 EFX_ETHTOOL_ULONG_MAC_STAT(tx_broadcast), 100 EFX_ETHTOOL_ULONG_MAC_STAT(tx_lt64), 101 EFX_ETHTOOL_ULONG_MAC_STAT(tx_64), 102 EFX_ETHTOOL_ULONG_MAC_STAT(tx_65_to_127), 103 EFX_ETHTOOL_ULONG_MAC_STAT(tx_128_to_255), 104 EFX_ETHTOOL_ULONG_MAC_STAT(tx_256_to_511), 105 EFX_ETHTOOL_ULONG_MAC_STAT(tx_512_to_1023), 106 EFX_ETHTOOL_ULONG_MAC_STAT(tx_1024_to_15xx), 107 EFX_ETHTOOL_ULONG_MAC_STAT(tx_15xx_to_jumbo), 108 EFX_ETHTOOL_ULONG_MAC_STAT(tx_gtjumbo), 109 EFX_ETHTOOL_ULONG_MAC_STAT(tx_collision), 110 EFX_ETHTOOL_ULONG_MAC_STAT(tx_single_collision), 111 EFX_ETHTOOL_ULONG_MAC_STAT(tx_multiple_collision), 112 EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_collision), 113 EFX_ETHTOOL_ULONG_MAC_STAT(tx_deferred), 114 EFX_ETHTOOL_ULONG_MAC_STAT(tx_late_collision), 115 EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_deferred), 116 EFX_ETHTOOL_ULONG_MAC_STAT(tx_non_tcpudp), 117 EFX_ETHTOOL_ULONG_MAC_STAT(tx_mac_src_error), 118 EFX_ETHTOOL_ULONG_MAC_STAT(tx_ip_src_error), 119 EFX_ETHTOOL_U64_MAC_STAT(rx_bytes), 120 EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes), 121 EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes), 122 EFX_ETHTOOL_ULONG_MAC_STAT(rx_packets), 123 EFX_ETHTOOL_ULONG_MAC_STAT(rx_good), 124 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad), 125 EFX_ETHTOOL_ULONG_MAC_STAT(rx_pause), 126 EFX_ETHTOOL_ULONG_MAC_STAT(rx_control), 127 EFX_ETHTOOL_ULONG_MAC_STAT(rx_unicast), 128 EFX_ETHTOOL_ULONG_MAC_STAT(rx_multicast), 129 EFX_ETHTOOL_ULONG_MAC_STAT(rx_broadcast), 130 EFX_ETHTOOL_ULONG_MAC_STAT(rx_lt64), 131 EFX_ETHTOOL_ULONG_MAC_STAT(rx_64), 132 EFX_ETHTOOL_ULONG_MAC_STAT(rx_65_to_127), 133 EFX_ETHTOOL_ULONG_MAC_STAT(rx_128_to_255), 134 EFX_ETHTOOL_ULONG_MAC_STAT(rx_256_to_511), 135 EFX_ETHTOOL_ULONG_MAC_STAT(rx_512_to_1023), 136 EFX_ETHTOOL_ULONG_MAC_STAT(rx_1024_to_15xx), 137 EFX_ETHTOOL_ULONG_MAC_STAT(rx_15xx_to_jumbo), 138 EFX_ETHTOOL_ULONG_MAC_STAT(rx_gtjumbo), 139 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_lt64), 140 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_64_to_15xx), 141 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_15xx_to_jumbo), 142 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_gtjumbo), 143 EFX_ETHTOOL_ULONG_MAC_STAT(rx_overflow), 144 EFX_ETHTOOL_ULONG_MAC_STAT(rx_missed), 145 EFX_ETHTOOL_ULONG_MAC_STAT(rx_false_carrier), 146 EFX_ETHTOOL_ULONG_MAC_STAT(rx_symbol_error), 147 EFX_ETHTOOL_ULONG_MAC_STAT(rx_align_error), 148 EFX_ETHTOOL_ULONG_MAC_STAT(rx_length_error), 149 EFX_ETHTOOL_ULONG_MAC_STAT(rx_internal_error), 150 EFX_ETHTOOL_UINT_NIC_STAT(rx_nodesc_drop_cnt), 151 EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset), 152 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc), 153 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_ip_hdr_chksum_err), 154 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tcp_udp_chksum_err), 155 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_mcast_mismatch), 156 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_frm_trunc), 157}; 158 159/* Number of ethtool statistics */ 160#define EFX_ETHTOOL_NUM_STATS ARRAY_SIZE(efx_ethtool_stats) 161 162#define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB 163 164/************************************************************************** 165 * 166 * Ethtool operations 167 * 168 ************************************************************************** 169 */ 170 171/* Identify device by flashing LEDs */ 172static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count) 173{ 174 struct efx_nic *efx = netdev_priv(net_dev); 175 176 do { 177 efx->type->set_id_led(efx, EFX_LED_ON); 178 schedule_timeout_interruptible(HZ / 2); 179 180 efx->type->set_id_led(efx, EFX_LED_OFF); 181 schedule_timeout_interruptible(HZ / 2); 182 } while (!signal_pending(current) && --count != 0); 183 184 efx->type->set_id_led(efx, EFX_LED_DEFAULT); 185 return 0; 186} 187 188/* This must be called with rtnl_lock held. */ 189int efx_ethtool_get_settings(struct net_device *net_dev, 190 struct ethtool_cmd *ecmd) 191{ 192 struct efx_nic *efx = netdev_priv(net_dev); 193 struct efx_link_state *link_state = &efx->link_state; 194 195 mutex_lock(&efx->mac_lock); 196 efx->phy_op->get_settings(efx, ecmd); 197 mutex_unlock(&efx->mac_lock); 198 199 /* GMAC does not support 1000Mbps HD */ 200 ecmd->supported &= ~SUPPORTED_1000baseT_Half; 201 /* Both MACs support pause frames (bidirectional and respond-only) */ 202 ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 203 204 if (LOOPBACK_INTERNAL(efx)) { 205 ecmd->speed = link_state->speed; 206 ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF; 207 } 208 209 return 0; 210} 211 212/* This must be called with rtnl_lock held. */ 213int efx_ethtool_set_settings(struct net_device *net_dev, 214 struct ethtool_cmd *ecmd) 215{ 216 struct efx_nic *efx = netdev_priv(net_dev); 217 int rc; 218 219 /* GMAC does not support 1000Mbps HD */ 220 if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { 221 EFX_LOG(efx, "rejecting unsupported 1000Mbps HD" 222 " setting\n"); 223 return -EINVAL; 224 } 225 226 mutex_lock(&efx->mac_lock); 227 rc = efx->phy_op->set_settings(efx, ecmd); 228 mutex_unlock(&efx->mac_lock); 229 return rc; 230} 231 232static void efx_ethtool_get_drvinfo(struct net_device *net_dev, 233 struct ethtool_drvinfo *info) 234{ 235 struct efx_nic *efx = netdev_priv(net_dev); 236 237 strlcpy(info->driver, EFX_DRIVER_NAME, sizeof(info->driver)); 238 strlcpy(info->version, EFX_DRIVER_VERSION, sizeof(info->version)); 239 if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) 240 siena_print_fwver(efx, info->fw_version, 241 sizeof(info->fw_version)); 242 strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); 243} 244 245/** 246 * efx_fill_test - fill in an individual self-test entry 247 * @test_index: Index of the test 248 * @strings: Ethtool strings, or %NULL 249 * @data: Ethtool test results, or %NULL 250 * @test: Pointer to test result (used only if data != %NULL) 251 * @unit_format: Unit name format (e.g. "chan\%d") 252 * @unit_id: Unit id (e.g. 0 for "chan0") 253 * @test_format: Test name format (e.g. "loopback.\%s.tx.sent") 254 * @test_id: Test id (e.g. "PHYXS" for "loopback.PHYXS.tx_sent") 255 * 256 * Fill in an individual self-test entry. 257 */ 258static void efx_fill_test(unsigned int test_index, 259 struct ethtool_string *strings, u64 *data, 260 int *test, const char *unit_format, int unit_id, 261 const char *test_format, const char *test_id) 262{ 263 struct ethtool_string unit_str, test_str; 264 265 /* Fill data value, if applicable */ 266 if (data) 267 data[test_index] = *test; 268 269 /* Fill string, if applicable */ 270 if (strings) { 271 if (strchr(unit_format, '%')) 272 snprintf(unit_str.name, sizeof(unit_str.name), 273 unit_format, unit_id); 274 else 275 strcpy(unit_str.name, unit_format); 276 snprintf(test_str.name, sizeof(test_str.name), 277 test_format, test_id); 278 snprintf(strings[test_index].name, 279 sizeof(strings[test_index].name), 280 "%-6s %-24s", unit_str.name, test_str.name); 281 } 282} 283 284#define EFX_CHANNEL_NAME(_channel) "chan%d", _channel->channel 285#define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue 286#define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue 287#define EFX_LOOPBACK_NAME(_mode, _counter) \ 288 "loopback.%s." _counter, STRING_TABLE_LOOKUP(_mode, efx_loopback_mode) 289 290/** 291 * efx_fill_loopback_test - fill in a block of loopback self-test entries 292 * @efx: Efx NIC 293 * @lb_tests: Efx loopback self-test results structure 294 * @mode: Loopback test mode 295 * @test_index: Starting index of the test 296 * @strings: Ethtool strings, or %NULL 297 * @data: Ethtool test results, or %NULL 298 */ 299static int efx_fill_loopback_test(struct efx_nic *efx, 300 struct efx_loopback_self_tests *lb_tests, 301 enum efx_loopback_mode mode, 302 unsigned int test_index, 303 struct ethtool_string *strings, u64 *data) 304{ 305 struct efx_tx_queue *tx_queue; 306 307 efx_for_each_channel_tx_queue(tx_queue, &efx->channel[0]) { 308 efx_fill_test(test_index++, strings, data, 309 &lb_tests->tx_sent[tx_queue->queue], 310 EFX_TX_QUEUE_NAME(tx_queue), 311 EFX_LOOPBACK_NAME(mode, "tx_sent")); 312 efx_fill_test(test_index++, strings, data, 313 &lb_tests->tx_done[tx_queue->queue], 314 EFX_TX_QUEUE_NAME(tx_queue), 315 EFX_LOOPBACK_NAME(mode, "tx_done")); 316 } 317 efx_fill_test(test_index++, strings, data, 318 &lb_tests->rx_good, 319 "rx", 0, 320 EFX_LOOPBACK_NAME(mode, "rx_good")); 321 efx_fill_test(test_index++, strings, data, 322 &lb_tests->rx_bad, 323 "rx", 0, 324 EFX_LOOPBACK_NAME(mode, "rx_bad")); 325 326 return test_index; 327} 328 329/** 330 * efx_ethtool_fill_self_tests - get self-test details 331 * @efx: Efx NIC 332 * @tests: Efx self-test results structure, or %NULL 333 * @strings: Ethtool strings, or %NULL 334 * @data: Ethtool test results, or %NULL 335 */ 336static int efx_ethtool_fill_self_tests(struct efx_nic *efx, 337 struct efx_self_tests *tests, 338 struct ethtool_string *strings, 339 u64 *data) 340{ 341 struct efx_channel *channel; 342 unsigned int n = 0, i; 343 enum efx_loopback_mode mode; 344 345 efx_fill_test(n++, strings, data, &tests->phy_alive, 346 "phy", 0, "alive", NULL); 347 efx_fill_test(n++, strings, data, &tests->nvram, 348 "core", 0, "nvram", NULL); 349 efx_fill_test(n++, strings, data, &tests->interrupt, 350 "core", 0, "interrupt", NULL); 351 352 /* Event queues */ 353 efx_for_each_channel(channel, efx) { 354 efx_fill_test(n++, strings, data, 355 &tests->eventq_dma[channel->channel], 356 EFX_CHANNEL_NAME(channel), 357 "eventq.dma", NULL); 358 efx_fill_test(n++, strings, data, 359 &tests->eventq_int[channel->channel], 360 EFX_CHANNEL_NAME(channel), 361 "eventq.int", NULL); 362 efx_fill_test(n++, strings, data, 363 &tests->eventq_poll[channel->channel], 364 EFX_CHANNEL_NAME(channel), 365 "eventq.poll", NULL); 366 } 367 368 efx_fill_test(n++, strings, data, &tests->registers, 369 "core", 0, "registers", NULL); 370 371 if (efx->phy_op->run_tests != NULL) { 372 EFX_BUG_ON_PARANOID(efx->phy_op->test_name == NULL); 373 374 for (i = 0; true; ++i) { 375 const char *name; 376 377 EFX_BUG_ON_PARANOID(i >= EFX_MAX_PHY_TESTS); 378 name = efx->phy_op->test_name(efx, i); 379 if (name == NULL) 380 break; 381 382 efx_fill_test(n++, strings, data, &tests->phy_ext[i], 383 "phy", 0, name, NULL); 384 } 385 } 386 387 /* Loopback tests */ 388 for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) { 389 if (!(efx->loopback_modes & (1 << mode))) 390 continue; 391 n = efx_fill_loopback_test(efx, 392 &tests->loopback[mode], mode, n, 393 strings, data); 394 } 395 396 return n; 397} 398 399static int efx_ethtool_get_sset_count(struct net_device *net_dev, 400 int string_set) 401{ 402 switch (string_set) { 403 case ETH_SS_STATS: 404 return EFX_ETHTOOL_NUM_STATS; 405 case ETH_SS_TEST: 406 return efx_ethtool_fill_self_tests(netdev_priv(net_dev), 407 NULL, NULL, NULL); 408 default: 409 return -EINVAL; 410 } 411} 412 413static void efx_ethtool_get_strings(struct net_device *net_dev, 414 u32 string_set, u8 *strings) 415{ 416 struct efx_nic *efx = netdev_priv(net_dev); 417 struct ethtool_string *ethtool_strings = 418 (struct ethtool_string *)strings; 419 int i; 420 421 switch (string_set) { 422 case ETH_SS_STATS: 423 for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) 424 strncpy(ethtool_strings[i].name, 425 efx_ethtool_stats[i].name, 426 sizeof(ethtool_strings[i].name)); 427 break; 428 case ETH_SS_TEST: 429 efx_ethtool_fill_self_tests(efx, NULL, 430 ethtool_strings, NULL); 431 break; 432 default: 433 /* No other string sets */ 434 break; 435 } 436} 437 438static void efx_ethtool_get_stats(struct net_device *net_dev, 439 struct ethtool_stats *stats, 440 u64 *data) 441{ 442 struct efx_nic *efx = netdev_priv(net_dev); 443 struct efx_mac_stats *mac_stats = &efx->mac_stats; 444 struct efx_ethtool_stat *stat; 445 struct efx_channel *channel; 446 int i; 447 448 EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS); 449 450 /* Update MAC and NIC statistics */ 451 dev_get_stats(net_dev); 452 453 /* Fill detailed statistics buffer */ 454 for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) { 455 stat = &efx_ethtool_stats[i]; 456 switch (stat->source) { 457 case EFX_ETHTOOL_STAT_SOURCE_mac_stats: 458 data[i] = stat->get_stat((void *)mac_stats + 459 stat->offset); 460 break; 461 case EFX_ETHTOOL_STAT_SOURCE_nic: 462 data[i] = stat->get_stat((void *)efx + stat->offset); 463 break; 464 case EFX_ETHTOOL_STAT_SOURCE_channel: 465 data[i] = 0; 466 efx_for_each_channel(channel, efx) 467 data[i] += stat->get_stat((void *)channel + 468 stat->offset); 469 break; 470 } 471 } 472} 473 474static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable) 475{ 476 struct efx_nic *efx __attribute__ ((unused)) = netdev_priv(net_dev); 477 unsigned long features; 478 479 features = NETIF_F_TSO; 480 if (efx->type->offload_features & NETIF_F_V6_CSUM) 481 features |= NETIF_F_TSO6; 482 483 if (enable) 484 net_dev->features |= features; 485 else 486 net_dev->features &= ~features; 487 488 return 0; 489} 490 491static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable) 492{ 493 struct efx_nic *efx = netdev_priv(net_dev); 494 unsigned long features = efx->type->offload_features & NETIF_F_ALL_CSUM; 495 496 if (enable) 497 net_dev->features |= features; 498 else 499 net_dev->features &= ~features; 500 501 return 0; 502} 503 504static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable) 505{ 506 struct efx_nic *efx = netdev_priv(net_dev); 507 508 /* No way to stop the hardware doing the checks; we just 509 * ignore the result. 510 */ 511 efx->rx_checksum_enabled = !!enable; 512 513 return 0; 514} 515 516static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev) 517{ 518 struct efx_nic *efx = netdev_priv(net_dev); 519 520 return efx->rx_checksum_enabled; 521} 522 523static void efx_ethtool_self_test(struct net_device *net_dev, 524 struct ethtool_test *test, u64 *data) 525{ 526 struct efx_nic *efx = netdev_priv(net_dev); 527 struct efx_self_tests efx_tests; 528 int already_up; 529 int rc; 530 531 ASSERT_RTNL(); 532 if (efx->state != STATE_RUNNING) { 533 rc = -EIO; 534 goto fail1; 535 } 536 537 /* We need rx buffers and interrupts. */ 538 already_up = (efx->net_dev->flags & IFF_UP); 539 if (!already_up) { 540 rc = dev_open(efx->net_dev); 541 if (rc) { 542 EFX_ERR(efx, "failed opening device.\n"); 543 goto fail2; 544 } 545 } 546 547 memset(&efx_tests, 0, sizeof(efx_tests)); 548 549 rc = efx_selftest(efx, &efx_tests, test->flags); 550 551 if (!already_up) 552 dev_close(efx->net_dev); 553 554 EFX_LOG(efx, "%s %sline self-tests\n", 555 rc == 0 ? "passed" : "failed", 556 (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); 557 558 fail2: 559 fail1: 560 /* Fill ethtool results structures */ 561 efx_ethtool_fill_self_tests(efx, &efx_tests, NULL, data); 562 if (rc) 563 test->flags |= ETH_TEST_FL_FAILED; 564} 565 566/* Restart autonegotiation */ 567static int efx_ethtool_nway_reset(struct net_device *net_dev) 568{ 569 struct efx_nic *efx = netdev_priv(net_dev); 570 571 return mdio45_nway_restart(&efx->mdio); 572} 573 574static u32 efx_ethtool_get_link(struct net_device *net_dev) 575{ 576 struct efx_nic *efx = netdev_priv(net_dev); 577 578 return efx->link_state.up; 579} 580 581static int efx_ethtool_get_eeprom_len(struct net_device *net_dev) 582{ 583 struct efx_nic *efx = netdev_priv(net_dev); 584 struct efx_spi_device *spi = efx->spi_eeprom; 585 586 if (!spi) 587 return 0; 588 return min(spi->size, EFX_EEPROM_BOOTCONFIG_END) - 589 min(spi->size, EFX_EEPROM_BOOTCONFIG_START); 590} 591 592static int efx_ethtool_get_eeprom(struct net_device *net_dev, 593 struct ethtool_eeprom *eeprom, u8 *buf) 594{ 595 struct efx_nic *efx = netdev_priv(net_dev); 596 struct efx_spi_device *spi = efx->spi_eeprom; 597 size_t len; 598 int rc; 599 600 rc = mutex_lock_interruptible(&efx->spi_lock); 601 if (rc) 602 return rc; 603 rc = falcon_spi_read(efx, spi, 604 eeprom->offset + EFX_EEPROM_BOOTCONFIG_START, 605 eeprom->len, &len, buf); 606 mutex_unlock(&efx->spi_lock); 607 608 eeprom->magic = EFX_ETHTOOL_EEPROM_MAGIC; 609 eeprom->len = len; 610 return rc; 611} 612 613static int efx_ethtool_set_eeprom(struct net_device *net_dev, 614 struct ethtool_eeprom *eeprom, u8 *buf) 615{ 616 struct efx_nic *efx = netdev_priv(net_dev); 617 struct efx_spi_device *spi = efx->spi_eeprom; 618 size_t len; 619 int rc; 620 621 if (eeprom->magic != EFX_ETHTOOL_EEPROM_MAGIC) 622 return -EINVAL; 623 624 rc = mutex_lock_interruptible(&efx->spi_lock); 625 if (rc) 626 return rc; 627 rc = falcon_spi_write(efx, spi, 628 eeprom->offset + EFX_EEPROM_BOOTCONFIG_START, 629 eeprom->len, &len, buf); 630 mutex_unlock(&efx->spi_lock); 631 632 eeprom->len = len; 633 return rc; 634} 635 636static int efx_ethtool_get_coalesce(struct net_device *net_dev, 637 struct ethtool_coalesce *coalesce) 638{ 639 struct efx_nic *efx = netdev_priv(net_dev); 640 struct efx_tx_queue *tx_queue; 641 struct efx_channel *channel; 642 643 memset(coalesce, 0, sizeof(*coalesce)); 644 645 /* Find lowest IRQ moderation across all used TX queues */ 646 coalesce->tx_coalesce_usecs_irq = ~((u32) 0); 647 efx_for_each_tx_queue(tx_queue, efx) { 648 channel = tx_queue->channel; 649 if (channel->irq_moderation < coalesce->tx_coalesce_usecs_irq) { 650 if (channel->channel < efx->n_rx_channels) 651 coalesce->tx_coalesce_usecs_irq = 652 channel->irq_moderation; 653 else 654 coalesce->tx_coalesce_usecs_irq = 0; 655 } 656 } 657 658 coalesce->use_adaptive_rx_coalesce = efx->irq_rx_adaptive; 659 coalesce->rx_coalesce_usecs_irq = efx->irq_rx_moderation; 660 661 coalesce->tx_coalesce_usecs_irq *= EFX_IRQ_MOD_RESOLUTION; 662 coalesce->rx_coalesce_usecs_irq *= EFX_IRQ_MOD_RESOLUTION; 663 664 return 0; 665} 666 667/* Set coalescing parameters 668 * The difficulties occur for shared channels 669 */ 670static int efx_ethtool_set_coalesce(struct net_device *net_dev, 671 struct ethtool_coalesce *coalesce) 672{ 673 struct efx_nic *efx = netdev_priv(net_dev); 674 struct efx_channel *channel; 675 struct efx_tx_queue *tx_queue; 676 unsigned tx_usecs, rx_usecs, adaptive; 677 678 if (coalesce->use_adaptive_tx_coalesce) 679 return -EOPNOTSUPP; 680 681 if (coalesce->rx_coalesce_usecs || coalesce->tx_coalesce_usecs) { 682 EFX_ERR(efx, "invalid coalescing setting. " 683 "Only rx/tx_coalesce_usecs_irq are supported\n"); 684 return -EOPNOTSUPP; 685 } 686 687 rx_usecs = coalesce->rx_coalesce_usecs_irq; 688 tx_usecs = coalesce->tx_coalesce_usecs_irq; 689 adaptive = coalesce->use_adaptive_rx_coalesce; 690 691 /* If the channel is shared only allow RX parameters to be set */ 692 efx_for_each_tx_queue(tx_queue, efx) { 693 if ((tx_queue->channel->channel < efx->n_rx_channels) && 694 tx_usecs) { 695 EFX_ERR(efx, "Channel is shared. " 696 "Only RX coalescing may be set\n"); 697 return -EOPNOTSUPP; 698 } 699 } 700 701 efx_init_irq_moderation(efx, tx_usecs, rx_usecs, adaptive); 702 efx_for_each_channel(channel, efx) 703 efx->type->push_irq_moderation(channel); 704 705 return 0; 706} 707 708static int efx_ethtool_set_pauseparam(struct net_device *net_dev, 709 struct ethtool_pauseparam *pause) 710{ 711 struct efx_nic *efx = netdev_priv(net_dev); 712 enum efx_fc_type wanted_fc, old_fc; 713 u32 old_adv; 714 bool reset; 715 int rc = 0; 716 717 mutex_lock(&efx->mac_lock); 718 719 wanted_fc = ((pause->rx_pause ? EFX_FC_RX : 0) | 720 (pause->tx_pause ? EFX_FC_TX : 0) | 721 (pause->autoneg ? EFX_FC_AUTO : 0)); 722 723 if ((wanted_fc & EFX_FC_TX) && !(wanted_fc & EFX_FC_RX)) { 724 EFX_LOG(efx, "Flow control unsupported: tx ON rx OFF\n"); 725 rc = -EINVAL; 726 goto out; 727 } 728 729 if ((wanted_fc & EFX_FC_AUTO) && !efx->link_advertising) { 730 EFX_LOG(efx, "Autonegotiation is disabled\n"); 731 rc = -EINVAL; 732 goto out; 733 } 734 735 /* TX flow control may automatically turn itself off if the 736 * link partner (intermittently) stops responding to pause 737 * frames. There isn't any indication that this has happened, 738 * so the best we do is leave it up to the user to spot this 739 * and fix it be cycling transmit flow control on this end. */ 740 reset = (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX); 741 if (EFX_WORKAROUND_11482(efx) && reset) { 742 if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) { 743 /* Recover by resetting the EM block */ 744 falcon_stop_nic_stats(efx); 745 falcon_drain_tx_fifo(efx); 746 efx->mac_op->reconfigure(efx); 747 falcon_start_nic_stats(efx); 748 } else { 749 /* Schedule a reset to recover */ 750 efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); 751 } 752 } 753 754 old_adv = efx->link_advertising; 755 old_fc = efx->wanted_fc; 756 efx_link_set_wanted_fc(efx, wanted_fc); 757 if (efx->link_advertising != old_adv || 758 (efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) { 759 rc = efx->phy_op->reconfigure(efx); 760 if (rc) { 761 EFX_ERR(efx, "Unable to advertise requested flow " 762 "control setting\n"); 763 goto out; 764 } 765 } 766 767 /* Reconfigure the MAC. The PHY *may* generate a link state change event 768 * if the user just changed the advertised capabilities, but there's no 769 * harm doing this twice */ 770 efx->mac_op->reconfigure(efx); 771 772out: 773 mutex_unlock(&efx->mac_lock); 774 775 return rc; 776} 777 778static void efx_ethtool_get_pauseparam(struct net_device *net_dev, 779 struct ethtool_pauseparam *pause) 780{ 781 struct efx_nic *efx = netdev_priv(net_dev); 782 783 pause->rx_pause = !!(efx->wanted_fc & EFX_FC_RX); 784 pause->tx_pause = !!(efx->wanted_fc & EFX_FC_TX); 785 pause->autoneg = !!(efx->wanted_fc & EFX_FC_AUTO); 786} 787 788 789static void efx_ethtool_get_wol(struct net_device *net_dev, 790 struct ethtool_wolinfo *wol) 791{ 792 struct efx_nic *efx = netdev_priv(net_dev); 793 return efx->type->get_wol(efx, wol); 794} 795 796 797static int efx_ethtool_set_wol(struct net_device *net_dev, 798 struct ethtool_wolinfo *wol) 799{ 800 struct efx_nic *efx = netdev_priv(net_dev); 801 return efx->type->set_wol(efx, wol->wolopts); 802} 803 804extern int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) 805{ 806 struct efx_nic *efx = netdev_priv(net_dev); 807 enum reset_type method; 808 enum { 809 ETH_RESET_EFX_INVISIBLE = (ETH_RESET_DMA | ETH_RESET_FILTER | 810 ETH_RESET_OFFLOAD | ETH_RESET_MAC) 811 }; 812 813 /* Check for minimal reset flags */ 814 if ((*flags & ETH_RESET_EFX_INVISIBLE) != ETH_RESET_EFX_INVISIBLE) 815 return -EINVAL; 816 *flags ^= ETH_RESET_EFX_INVISIBLE; 817 method = RESET_TYPE_INVISIBLE; 818 819 if (*flags & ETH_RESET_PHY) { 820 *flags ^= ETH_RESET_PHY; 821 method = RESET_TYPE_ALL; 822 } 823 824 if ((*flags & efx->type->reset_world_flags) == 825 efx->type->reset_world_flags) { 826 *flags ^= efx->type->reset_world_flags; 827 method = RESET_TYPE_WORLD; 828 } 829 830 return efx_reset(efx, method); 831} 832 833const struct ethtool_ops efx_ethtool_ops = { 834 .get_settings = efx_ethtool_get_settings, 835 .set_settings = efx_ethtool_set_settings, 836 .get_drvinfo = efx_ethtool_get_drvinfo, 837 .nway_reset = efx_ethtool_nway_reset, 838 .get_link = efx_ethtool_get_link, 839 .get_eeprom_len = efx_ethtool_get_eeprom_len, 840 .get_eeprom = efx_ethtool_get_eeprom, 841 .set_eeprom = efx_ethtool_set_eeprom, 842 .get_coalesce = efx_ethtool_get_coalesce, 843 .set_coalesce = efx_ethtool_set_coalesce, 844 .get_pauseparam = efx_ethtool_get_pauseparam, 845 .set_pauseparam = efx_ethtool_set_pauseparam, 846 .get_rx_csum = efx_ethtool_get_rx_csum, 847 .set_rx_csum = efx_ethtool_set_rx_csum, 848 .get_tx_csum = ethtool_op_get_tx_csum, 849 /* Need to enable/disable IPv6 too */ 850 .set_tx_csum = efx_ethtool_set_tx_csum, 851 .get_sg = ethtool_op_get_sg, 852 .set_sg = ethtool_op_set_sg, 853 .get_tso = ethtool_op_get_tso, 854 /* Need to enable/disable TSO-IPv6 too */ 855 .set_tso = efx_ethtool_set_tso, 856 .get_flags = ethtool_op_get_flags, 857 .set_flags = ethtool_op_set_flags, 858 .get_sset_count = efx_ethtool_get_sset_count, 859 .self_test = efx_ethtool_self_test, 860 .get_strings = efx_ethtool_get_strings, 861 .phys_id = efx_ethtool_phys_id, 862 .get_ethtool_stats = efx_ethtool_get_stats, 863 .get_wol = efx_ethtool_get_wol, 864 .set_wol = efx_ethtool_set_wol, 865 .reset = efx_ethtool_reset, 866};