at v2.6.26 717 lines 21 kB view raw
1/**************************************************************************** 2 * Driver for Solarflare Solarstorm network controllers and boards 3 * Copyright 2005-2006 Fen Systems Ltd. 4 * Copyright 2006-2008 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 "selftest.h" 16#include "efx.h" 17#include "ethtool.h" 18#include "falcon.h" 19#include "gmii.h" 20#include "mac.h" 21 22const char *efx_loopback_mode_names[] = { 23 [LOOPBACK_NONE] = "NONE", 24 [LOOPBACK_MAC] = "MAC", 25 [LOOPBACK_XGMII] = "XGMII", 26 [LOOPBACK_XGXS] = "XGXS", 27 [LOOPBACK_XAUI] = "XAUI", 28 [LOOPBACK_PHY] = "PHY", 29 [LOOPBACK_PHYXS] = "PHY(XS)", 30 [LOOPBACK_PCS] = "PHY(PCS)", 31 [LOOPBACK_PMAPMD] = "PHY(PMAPMD)", 32 [LOOPBACK_NETWORK] = "NETWORK", 33}; 34 35static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable); 36 37struct ethtool_string { 38 char name[ETH_GSTRING_LEN]; 39}; 40 41struct efx_ethtool_stat { 42 const char *name; 43 enum { 44 EFX_ETHTOOL_STAT_SOURCE_mac_stats, 45 EFX_ETHTOOL_STAT_SOURCE_nic, 46 EFX_ETHTOOL_STAT_SOURCE_channel 47 } source; 48 unsigned offset; 49 u64(*get_stat) (void *field); /* Reader function */ 50}; 51 52/* Initialiser for a struct #efx_ethtool_stat with type-checking */ 53#define EFX_ETHTOOL_STAT(stat_name, source_name, field, field_type, \ 54 get_stat_function) { \ 55 .name = #stat_name, \ 56 .source = EFX_ETHTOOL_STAT_SOURCE_##source_name, \ 57 .offset = ((((field_type *) 0) == \ 58 &((struct efx_##source_name *)0)->field) ? \ 59 offsetof(struct efx_##source_name, field) : \ 60 offsetof(struct efx_##source_name, field)), \ 61 .get_stat = get_stat_function, \ 62} 63 64static u64 efx_get_uint_stat(void *field) 65{ 66 return *(unsigned int *)field; 67} 68 69static u64 efx_get_ulong_stat(void *field) 70{ 71 return *(unsigned long *)field; 72} 73 74static u64 efx_get_u64_stat(void *field) 75{ 76 return *(u64 *) field; 77} 78 79static u64 efx_get_atomic_stat(void *field) 80{ 81 return atomic_read((atomic_t *) field); 82} 83 84#define EFX_ETHTOOL_ULONG_MAC_STAT(field) \ 85 EFX_ETHTOOL_STAT(field, mac_stats, field, \ 86 unsigned long, efx_get_ulong_stat) 87 88#define EFX_ETHTOOL_U64_MAC_STAT(field) \ 89 EFX_ETHTOOL_STAT(field, mac_stats, field, \ 90 u64, efx_get_u64_stat) 91 92#define EFX_ETHTOOL_UINT_NIC_STAT(name) \ 93 EFX_ETHTOOL_STAT(name, nic, n_##name, \ 94 unsigned int, efx_get_uint_stat) 95 96#define EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(field) \ 97 EFX_ETHTOOL_STAT(field, nic, field, \ 98 atomic_t, efx_get_atomic_stat) 99 100#define EFX_ETHTOOL_UINT_CHANNEL_STAT(field) \ 101 EFX_ETHTOOL_STAT(field, channel, n_##field, \ 102 unsigned int, efx_get_uint_stat) 103 104static struct efx_ethtool_stat efx_ethtool_stats[] = { 105 EFX_ETHTOOL_U64_MAC_STAT(tx_bytes), 106 EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes), 107 EFX_ETHTOOL_U64_MAC_STAT(tx_bad_bytes), 108 EFX_ETHTOOL_ULONG_MAC_STAT(tx_packets), 109 EFX_ETHTOOL_ULONG_MAC_STAT(tx_bad), 110 EFX_ETHTOOL_ULONG_MAC_STAT(tx_pause), 111 EFX_ETHTOOL_ULONG_MAC_STAT(tx_control), 112 EFX_ETHTOOL_ULONG_MAC_STAT(tx_unicast), 113 EFX_ETHTOOL_ULONG_MAC_STAT(tx_multicast), 114 EFX_ETHTOOL_ULONG_MAC_STAT(tx_broadcast), 115 EFX_ETHTOOL_ULONG_MAC_STAT(tx_lt64), 116 EFX_ETHTOOL_ULONG_MAC_STAT(tx_64), 117 EFX_ETHTOOL_ULONG_MAC_STAT(tx_65_to_127), 118 EFX_ETHTOOL_ULONG_MAC_STAT(tx_128_to_255), 119 EFX_ETHTOOL_ULONG_MAC_STAT(tx_256_to_511), 120 EFX_ETHTOOL_ULONG_MAC_STAT(tx_512_to_1023), 121 EFX_ETHTOOL_ULONG_MAC_STAT(tx_1024_to_15xx), 122 EFX_ETHTOOL_ULONG_MAC_STAT(tx_15xx_to_jumbo), 123 EFX_ETHTOOL_ULONG_MAC_STAT(tx_gtjumbo), 124 EFX_ETHTOOL_ULONG_MAC_STAT(tx_collision), 125 EFX_ETHTOOL_ULONG_MAC_STAT(tx_single_collision), 126 EFX_ETHTOOL_ULONG_MAC_STAT(tx_multiple_collision), 127 EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_collision), 128 EFX_ETHTOOL_ULONG_MAC_STAT(tx_deferred), 129 EFX_ETHTOOL_ULONG_MAC_STAT(tx_late_collision), 130 EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_deferred), 131 EFX_ETHTOOL_ULONG_MAC_STAT(tx_non_tcpudp), 132 EFX_ETHTOOL_ULONG_MAC_STAT(tx_mac_src_error), 133 EFX_ETHTOOL_ULONG_MAC_STAT(tx_ip_src_error), 134 EFX_ETHTOOL_U64_MAC_STAT(rx_bytes), 135 EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes), 136 EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes), 137 EFX_ETHTOOL_ULONG_MAC_STAT(rx_packets), 138 EFX_ETHTOOL_ULONG_MAC_STAT(rx_good), 139 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad), 140 EFX_ETHTOOL_ULONG_MAC_STAT(rx_pause), 141 EFX_ETHTOOL_ULONG_MAC_STAT(rx_control), 142 EFX_ETHTOOL_ULONG_MAC_STAT(rx_unicast), 143 EFX_ETHTOOL_ULONG_MAC_STAT(rx_multicast), 144 EFX_ETHTOOL_ULONG_MAC_STAT(rx_broadcast), 145 EFX_ETHTOOL_ULONG_MAC_STAT(rx_lt64), 146 EFX_ETHTOOL_ULONG_MAC_STAT(rx_64), 147 EFX_ETHTOOL_ULONG_MAC_STAT(rx_65_to_127), 148 EFX_ETHTOOL_ULONG_MAC_STAT(rx_128_to_255), 149 EFX_ETHTOOL_ULONG_MAC_STAT(rx_256_to_511), 150 EFX_ETHTOOL_ULONG_MAC_STAT(rx_512_to_1023), 151 EFX_ETHTOOL_ULONG_MAC_STAT(rx_1024_to_15xx), 152 EFX_ETHTOOL_ULONG_MAC_STAT(rx_15xx_to_jumbo), 153 EFX_ETHTOOL_ULONG_MAC_STAT(rx_gtjumbo), 154 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_lt64), 155 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_64_to_15xx), 156 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_15xx_to_jumbo), 157 EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_gtjumbo), 158 EFX_ETHTOOL_ULONG_MAC_STAT(rx_overflow), 159 EFX_ETHTOOL_ULONG_MAC_STAT(rx_missed), 160 EFX_ETHTOOL_ULONG_MAC_STAT(rx_false_carrier), 161 EFX_ETHTOOL_ULONG_MAC_STAT(rx_symbol_error), 162 EFX_ETHTOOL_ULONG_MAC_STAT(rx_align_error), 163 EFX_ETHTOOL_ULONG_MAC_STAT(rx_length_error), 164 EFX_ETHTOOL_ULONG_MAC_STAT(rx_internal_error), 165 EFX_ETHTOOL_UINT_NIC_STAT(rx_nodesc_drop_cnt), 166 EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset), 167 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc), 168 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_ip_hdr_chksum_err), 169 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tcp_udp_chksum_err), 170 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_frm_trunc), 171}; 172 173/* Number of ethtool statistics */ 174#define EFX_ETHTOOL_NUM_STATS ARRAY_SIZE(efx_ethtool_stats) 175 176/************************************************************************** 177 * 178 * Ethtool operations 179 * 180 ************************************************************************** 181 */ 182 183/* Identify device by flashing LEDs */ 184static int efx_ethtool_phys_id(struct net_device *net_dev, u32 seconds) 185{ 186 struct efx_nic *efx = net_dev->priv; 187 188 efx->board_info.blink(efx, 1); 189 schedule_timeout_interruptible(seconds * HZ); 190 efx->board_info.blink(efx, 0); 191 return 0; 192} 193 194/* This must be called with rtnl_lock held. */ 195int efx_ethtool_get_settings(struct net_device *net_dev, 196 struct ethtool_cmd *ecmd) 197{ 198 struct efx_nic *efx = net_dev->priv; 199 int rc; 200 201 mutex_lock(&efx->mac_lock); 202 rc = falcon_xmac_get_settings(efx, ecmd); 203 mutex_unlock(&efx->mac_lock); 204 205 return rc; 206} 207 208/* This must be called with rtnl_lock held. */ 209int efx_ethtool_set_settings(struct net_device *net_dev, 210 struct ethtool_cmd *ecmd) 211{ 212 struct efx_nic *efx = net_dev->priv; 213 int rc; 214 215 mutex_lock(&efx->mac_lock); 216 rc = falcon_xmac_set_settings(efx, ecmd); 217 mutex_unlock(&efx->mac_lock); 218 if (!rc) 219 efx_reconfigure_port(efx); 220 221 return rc; 222} 223 224static void efx_ethtool_get_drvinfo(struct net_device *net_dev, 225 struct ethtool_drvinfo *info) 226{ 227 struct efx_nic *efx = net_dev->priv; 228 229 strlcpy(info->driver, EFX_DRIVER_NAME, sizeof(info->driver)); 230 strlcpy(info->version, EFX_DRIVER_VERSION, sizeof(info->version)); 231 strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); 232} 233 234/** 235 * efx_fill_test - fill in an individual self-test entry 236 * @test_index: Index of the test 237 * @strings: Ethtool strings, or %NULL 238 * @data: Ethtool test results, or %NULL 239 * @test: Pointer to test result (used only if data != %NULL) 240 * @unit_format: Unit name format (e.g. "channel\%d") 241 * @unit_id: Unit id (e.g. 0 for "channel0") 242 * @test_format: Test name format (e.g. "loopback.\%s.tx.sent") 243 * @test_id: Test id (e.g. "PHY" for "loopback.PHY.tx_sent") 244 * 245 * Fill in an individual self-test entry. 246 */ 247static void efx_fill_test(unsigned int test_index, 248 struct ethtool_string *strings, u64 *data, 249 int *test, const char *unit_format, int unit_id, 250 const char *test_format, const char *test_id) 251{ 252 struct ethtool_string unit_str, test_str; 253 254 /* Fill data value, if applicable */ 255 if (data) 256 data[test_index] = *test; 257 258 /* Fill string, if applicable */ 259 if (strings) { 260 snprintf(unit_str.name, sizeof(unit_str.name), 261 unit_format, unit_id); 262 snprintf(test_str.name, sizeof(test_str.name), 263 test_format, test_id); 264 snprintf(strings[test_index].name, 265 sizeof(strings[test_index].name), 266 "%-9s%-17s", unit_str.name, test_str.name); 267 } 268} 269 270#define EFX_PORT_NAME "port%d", 0 271#define EFX_CHANNEL_NAME(_channel) "channel%d", _channel->channel 272#define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue 273#define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue 274#define EFX_LOOPBACK_NAME(_mode, _counter) \ 275 "loopback.%s." _counter, LOOPBACK_MODE_NAME(mode) 276 277/** 278 * efx_fill_loopback_test - fill in a block of loopback self-test entries 279 * @efx: Efx NIC 280 * @lb_tests: Efx loopback self-test results structure 281 * @mode: Loopback test mode 282 * @test_index: Starting index of the test 283 * @strings: Ethtool strings, or %NULL 284 * @data: Ethtool test results, or %NULL 285 */ 286static int efx_fill_loopback_test(struct efx_nic *efx, 287 struct efx_loopback_self_tests *lb_tests, 288 enum efx_loopback_mode mode, 289 unsigned int test_index, 290 struct ethtool_string *strings, u64 *data) 291{ 292 struct efx_tx_queue *tx_queue; 293 294 efx_for_each_tx_queue(tx_queue, efx) { 295 efx_fill_test(test_index++, strings, data, 296 &lb_tests->tx_sent[tx_queue->queue], 297 EFX_TX_QUEUE_NAME(tx_queue), 298 EFX_LOOPBACK_NAME(mode, "tx_sent")); 299 efx_fill_test(test_index++, strings, data, 300 &lb_tests->tx_done[tx_queue->queue], 301 EFX_TX_QUEUE_NAME(tx_queue), 302 EFX_LOOPBACK_NAME(mode, "tx_done")); 303 } 304 efx_fill_test(test_index++, strings, data, 305 &lb_tests->rx_good, 306 EFX_PORT_NAME, 307 EFX_LOOPBACK_NAME(mode, "rx_good")); 308 efx_fill_test(test_index++, strings, data, 309 &lb_tests->rx_bad, 310 EFX_PORT_NAME, 311 EFX_LOOPBACK_NAME(mode, "rx_bad")); 312 313 return test_index; 314} 315 316/** 317 * efx_ethtool_fill_self_tests - get self-test details 318 * @efx: Efx NIC 319 * @tests: Efx self-test results structure, or %NULL 320 * @strings: Ethtool strings, or %NULL 321 * @data: Ethtool test results, or %NULL 322 */ 323static int efx_ethtool_fill_self_tests(struct efx_nic *efx, 324 struct efx_self_tests *tests, 325 struct ethtool_string *strings, 326 u64 *data) 327{ 328 struct efx_channel *channel; 329 unsigned int n = 0; 330 enum efx_loopback_mode mode; 331 332 /* Interrupt */ 333 efx_fill_test(n++, strings, data, &tests->interrupt, 334 "core", 0, "interrupt", NULL); 335 336 /* Event queues */ 337 efx_for_each_channel(channel, efx) { 338 efx_fill_test(n++, strings, data, 339 &tests->eventq_dma[channel->channel], 340 EFX_CHANNEL_NAME(channel), 341 "eventq.dma", NULL); 342 efx_fill_test(n++, strings, data, 343 &tests->eventq_int[channel->channel], 344 EFX_CHANNEL_NAME(channel), 345 "eventq.int", NULL); 346 efx_fill_test(n++, strings, data, 347 &tests->eventq_poll[channel->channel], 348 EFX_CHANNEL_NAME(channel), 349 "eventq.poll", NULL); 350 } 351 352 /* PHY presence */ 353 efx_fill_test(n++, strings, data, &tests->phy_ok, 354 EFX_PORT_NAME, "phy_ok", NULL); 355 356 /* Loopback tests */ 357 efx_fill_test(n++, strings, data, &tests->loopback_speed, 358 EFX_PORT_NAME, "loopback.speed", NULL); 359 efx_fill_test(n++, strings, data, &tests->loopback_full_duplex, 360 EFX_PORT_NAME, "loopback.full_duplex", NULL); 361 for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) { 362 if (!(efx->loopback_modes & (1 << mode))) 363 continue; 364 n = efx_fill_loopback_test(efx, 365 &tests->loopback[mode], mode, n, 366 strings, data); 367 } 368 369 return n; 370} 371 372static int efx_ethtool_get_stats_count(struct net_device *net_dev) 373{ 374 return EFX_ETHTOOL_NUM_STATS; 375} 376 377static int efx_ethtool_self_test_count(struct net_device *net_dev) 378{ 379 struct efx_nic *efx = net_dev->priv; 380 381 return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL); 382} 383 384static void efx_ethtool_get_strings(struct net_device *net_dev, 385 u32 string_set, u8 *strings) 386{ 387 struct efx_nic *efx = net_dev->priv; 388 struct ethtool_string *ethtool_strings = 389 (struct ethtool_string *)strings; 390 int i; 391 392 switch (string_set) { 393 case ETH_SS_STATS: 394 for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) 395 strncpy(ethtool_strings[i].name, 396 efx_ethtool_stats[i].name, 397 sizeof(ethtool_strings[i].name)); 398 break; 399 case ETH_SS_TEST: 400 efx_ethtool_fill_self_tests(efx, NULL, 401 ethtool_strings, NULL); 402 break; 403 default: 404 /* No other string sets */ 405 break; 406 } 407} 408 409static void efx_ethtool_get_stats(struct net_device *net_dev, 410 struct ethtool_stats *stats, 411 u64 *data) 412{ 413 struct efx_nic *efx = net_dev->priv; 414 struct efx_mac_stats *mac_stats = &efx->mac_stats; 415 struct efx_ethtool_stat *stat; 416 struct efx_channel *channel; 417 int i; 418 419 EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS); 420 421 /* Update MAC and NIC statistics */ 422 net_dev->get_stats(net_dev); 423 424 /* Fill detailed statistics buffer */ 425 for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) { 426 stat = &efx_ethtool_stats[i]; 427 switch (stat->source) { 428 case EFX_ETHTOOL_STAT_SOURCE_mac_stats: 429 data[i] = stat->get_stat((void *)mac_stats + 430 stat->offset); 431 break; 432 case EFX_ETHTOOL_STAT_SOURCE_nic: 433 data[i] = stat->get_stat((void *)efx + stat->offset); 434 break; 435 case EFX_ETHTOOL_STAT_SOURCE_channel: 436 data[i] = 0; 437 efx_for_each_channel(channel, efx) 438 data[i] += stat->get_stat((void *)channel + 439 stat->offset); 440 break; 441 } 442 } 443} 444 445static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable) 446{ 447 int rc; 448 449 /* Our TSO requires TX checksumming, so force TX checksumming 450 * on when TSO is enabled. 451 */ 452 if (enable) { 453 rc = efx_ethtool_set_tx_csum(net_dev, 1); 454 if (rc) 455 return rc; 456 } 457 458 return ethtool_op_set_tso(net_dev, enable); 459} 460 461static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable) 462{ 463 struct efx_nic *efx = net_dev->priv; 464 int rc; 465 466 rc = ethtool_op_set_tx_csum(net_dev, enable); 467 if (rc) 468 return rc; 469 470 efx_flush_queues(efx); 471 472 /* Our TSO requires TX checksumming, so disable TSO when 473 * checksumming is disabled 474 */ 475 if (!enable) { 476 rc = efx_ethtool_set_tso(net_dev, 0); 477 if (rc) 478 return rc; 479 } 480 481 return 0; 482} 483 484static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable) 485{ 486 struct efx_nic *efx = net_dev->priv; 487 488 /* No way to stop the hardware doing the checks; we just 489 * ignore the result. 490 */ 491 efx->rx_checksum_enabled = (enable ? 1 : 0); 492 493 return 0; 494} 495 496static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev) 497{ 498 struct efx_nic *efx = net_dev->priv; 499 500 return efx->rx_checksum_enabled; 501} 502 503static void efx_ethtool_self_test(struct net_device *net_dev, 504 struct ethtool_test *test, u64 *data) 505{ 506 struct efx_nic *efx = net_dev->priv; 507 struct efx_self_tests efx_tests; 508 int offline, already_up; 509 int rc; 510 511 ASSERT_RTNL(); 512 if (efx->state != STATE_RUNNING) { 513 rc = -EIO; 514 goto fail1; 515 } 516 517 /* We need rx buffers and interrupts. */ 518 already_up = (efx->net_dev->flags & IFF_UP); 519 if (!already_up) { 520 rc = dev_open(efx->net_dev); 521 if (rc) { 522 EFX_ERR(efx, "failed opening device.\n"); 523 goto fail2; 524 } 525 } 526 527 memset(&efx_tests, 0, sizeof(efx_tests)); 528 offline = (test->flags & ETH_TEST_FL_OFFLINE); 529 530 /* Perform online self tests first */ 531 rc = efx_online_test(efx, &efx_tests); 532 if (rc) 533 goto out; 534 535 /* Perform offline tests only if online tests passed */ 536 if (offline) { 537 /* Stop the kernel from sending packets during the test. */ 538 efx_stop_queue(efx); 539 rc = efx_flush_queues(efx); 540 if (!rc) 541 rc = efx_offline_test(efx, &efx_tests, 542 efx->loopback_modes); 543 efx_wake_queue(efx); 544 } 545 546 out: 547 if (!already_up) 548 dev_close(efx->net_dev); 549 550 EFX_LOG(efx, "%s all %sline self-tests\n", 551 rc == 0 ? "passed" : "failed", offline ? "off" : "on"); 552 553 fail2: 554 fail1: 555 /* Fill ethtool results structures */ 556 efx_ethtool_fill_self_tests(efx, &efx_tests, NULL, data); 557 if (rc) 558 test->flags |= ETH_TEST_FL_FAILED; 559} 560 561/* Restart autonegotiation */ 562static int efx_ethtool_nway_reset(struct net_device *net_dev) 563{ 564 struct efx_nic *efx = net_dev->priv; 565 566 return mii_nway_restart(&efx->mii); 567} 568 569static u32 efx_ethtool_get_link(struct net_device *net_dev) 570{ 571 struct efx_nic *efx = net_dev->priv; 572 573 return efx->link_up; 574} 575 576static int efx_ethtool_get_coalesce(struct net_device *net_dev, 577 struct ethtool_coalesce *coalesce) 578{ 579 struct efx_nic *efx = net_dev->priv; 580 struct efx_tx_queue *tx_queue; 581 struct efx_rx_queue *rx_queue; 582 struct efx_channel *channel; 583 584 memset(coalesce, 0, sizeof(*coalesce)); 585 586 /* Find lowest IRQ moderation across all used TX queues */ 587 coalesce->tx_coalesce_usecs_irq = ~((u32) 0); 588 efx_for_each_tx_queue(tx_queue, efx) { 589 channel = tx_queue->channel; 590 if (channel->irq_moderation < coalesce->tx_coalesce_usecs_irq) { 591 if (channel->used_flags != EFX_USED_BY_RX_TX) 592 coalesce->tx_coalesce_usecs_irq = 593 channel->irq_moderation; 594 else 595 coalesce->tx_coalesce_usecs_irq = 0; 596 } 597 } 598 599 /* Find lowest IRQ moderation across all used RX queues */ 600 coalesce->rx_coalesce_usecs_irq = ~((u32) 0); 601 efx_for_each_rx_queue(rx_queue, efx) { 602 channel = rx_queue->channel; 603 if (channel->irq_moderation < coalesce->rx_coalesce_usecs_irq) 604 coalesce->rx_coalesce_usecs_irq = 605 channel->irq_moderation; 606 } 607 608 return 0; 609} 610 611/* Set coalescing parameters 612 * The difficulties occur for shared channels 613 */ 614static int efx_ethtool_set_coalesce(struct net_device *net_dev, 615 struct ethtool_coalesce *coalesce) 616{ 617 struct efx_nic *efx = net_dev->priv; 618 struct efx_channel *channel; 619 struct efx_tx_queue *tx_queue; 620 unsigned tx_usecs, rx_usecs; 621 622 if (coalesce->use_adaptive_rx_coalesce || 623 coalesce->use_adaptive_tx_coalesce) 624 return -EOPNOTSUPP; 625 626 if (coalesce->rx_coalesce_usecs || coalesce->tx_coalesce_usecs) { 627 EFX_ERR(efx, "invalid coalescing setting. " 628 "Only rx/tx_coalesce_usecs_irq are supported\n"); 629 return -EOPNOTSUPP; 630 } 631 632 rx_usecs = coalesce->rx_coalesce_usecs_irq; 633 tx_usecs = coalesce->tx_coalesce_usecs_irq; 634 635 /* If the channel is shared only allow RX parameters to be set */ 636 efx_for_each_tx_queue(tx_queue, efx) { 637 if ((tx_queue->channel->used_flags == EFX_USED_BY_RX_TX) && 638 tx_usecs) { 639 EFX_ERR(efx, "Channel is shared. " 640 "Only RX coalescing may be set\n"); 641 return -EOPNOTSUPP; 642 } 643 } 644 645 efx_init_irq_moderation(efx, tx_usecs, rx_usecs); 646 647 /* Reset channel to pick up new moderation value. Note that 648 * this may change the value of the irq_moderation field 649 * (e.g. to allow for hardware timer granularity). 650 */ 651 efx_for_each_channel(channel, efx) 652 falcon_set_int_moderation(channel); 653 654 return 0; 655} 656 657static int efx_ethtool_set_pauseparam(struct net_device *net_dev, 658 struct ethtool_pauseparam *pause) 659{ 660 struct efx_nic *efx = net_dev->priv; 661 enum efx_fc_type flow_control = efx->flow_control; 662 int rc; 663 664 flow_control &= ~(EFX_FC_RX | EFX_FC_TX | EFX_FC_AUTO); 665 flow_control |= pause->rx_pause ? EFX_FC_RX : 0; 666 flow_control |= pause->tx_pause ? EFX_FC_TX : 0; 667 flow_control |= pause->autoneg ? EFX_FC_AUTO : 0; 668 669 /* Try to push the pause parameters */ 670 mutex_lock(&efx->mac_lock); 671 rc = falcon_xmac_set_pause(efx, flow_control); 672 mutex_unlock(&efx->mac_lock); 673 674 if (!rc) 675 efx_reconfigure_port(efx); 676 677 return rc; 678} 679 680static void efx_ethtool_get_pauseparam(struct net_device *net_dev, 681 struct ethtool_pauseparam *pause) 682{ 683 struct efx_nic *efx = net_dev->priv; 684 685 pause->rx_pause = (efx->flow_control & EFX_FC_RX) ? 1 : 0; 686 pause->tx_pause = (efx->flow_control & EFX_FC_TX) ? 1 : 0; 687 pause->autoneg = (efx->flow_control & EFX_FC_AUTO) ? 1 : 0; 688} 689 690 691struct ethtool_ops efx_ethtool_ops = { 692 .get_settings = efx_ethtool_get_settings, 693 .set_settings = efx_ethtool_set_settings, 694 .get_drvinfo = efx_ethtool_get_drvinfo, 695 .nway_reset = efx_ethtool_nway_reset, 696 .get_link = efx_ethtool_get_link, 697 .get_coalesce = efx_ethtool_get_coalesce, 698 .set_coalesce = efx_ethtool_set_coalesce, 699 .get_pauseparam = efx_ethtool_get_pauseparam, 700 .set_pauseparam = efx_ethtool_set_pauseparam, 701 .get_rx_csum = efx_ethtool_get_rx_csum, 702 .set_rx_csum = efx_ethtool_set_rx_csum, 703 .get_tx_csum = ethtool_op_get_tx_csum, 704 .set_tx_csum = efx_ethtool_set_tx_csum, 705 .get_sg = ethtool_op_get_sg, 706 .set_sg = ethtool_op_set_sg, 707 .get_tso = ethtool_op_get_tso, 708 .set_tso = efx_ethtool_set_tso, 709 .get_flags = ethtool_op_get_flags, 710 .set_flags = ethtool_op_set_flags, 711 .self_test_count = efx_ethtool_self_test_count, 712 .self_test = efx_ethtool_self_test, 713 .get_strings = efx_ethtool_get_strings, 714 .phys_id = efx_ethtool_phys_id, 715 .get_stats_count = efx_ethtool_get_stats_count, 716 .get_ethtool_stats = efx_ethtool_get_stats, 717};