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 v2.6.36-rc2 999 lines 29 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 netif_dbg(efx, drv, efx->net_dev, 222 "rejecting unsupported 1000Mbps HD 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, KBUILD_MODNAME, 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 245static int efx_ethtool_get_regs_len(struct net_device *net_dev) 246{ 247 return efx_nic_get_regs_len(netdev_priv(net_dev)); 248} 249 250static void efx_ethtool_get_regs(struct net_device *net_dev, 251 struct ethtool_regs *regs, void *buf) 252{ 253 struct efx_nic *efx = netdev_priv(net_dev); 254 255 regs->version = efx->type->revision; 256 efx_nic_get_regs(efx, buf); 257} 258 259static u32 efx_ethtool_get_msglevel(struct net_device *net_dev) 260{ 261 struct efx_nic *efx = netdev_priv(net_dev); 262 return efx->msg_enable; 263} 264 265static void efx_ethtool_set_msglevel(struct net_device *net_dev, u32 msg_enable) 266{ 267 struct efx_nic *efx = netdev_priv(net_dev); 268 efx->msg_enable = msg_enable; 269} 270 271/** 272 * efx_fill_test - fill in an individual self-test entry 273 * @test_index: Index of the test 274 * @strings: Ethtool strings, or %NULL 275 * @data: Ethtool test results, or %NULL 276 * @test: Pointer to test result (used only if data != %NULL) 277 * @unit_format: Unit name format (e.g. "chan\%d") 278 * @unit_id: Unit id (e.g. 0 for "chan0") 279 * @test_format: Test name format (e.g. "loopback.\%s.tx.sent") 280 * @test_id: Test id (e.g. "PHYXS" for "loopback.PHYXS.tx_sent") 281 * 282 * Fill in an individual self-test entry. 283 */ 284static void efx_fill_test(unsigned int test_index, 285 struct ethtool_string *strings, u64 *data, 286 int *test, const char *unit_format, int unit_id, 287 const char *test_format, const char *test_id) 288{ 289 struct ethtool_string unit_str, test_str; 290 291 /* Fill data value, if applicable */ 292 if (data) 293 data[test_index] = *test; 294 295 /* Fill string, if applicable */ 296 if (strings) { 297 if (strchr(unit_format, '%')) 298 snprintf(unit_str.name, sizeof(unit_str.name), 299 unit_format, unit_id); 300 else 301 strcpy(unit_str.name, unit_format); 302 snprintf(test_str.name, sizeof(test_str.name), 303 test_format, test_id); 304 snprintf(strings[test_index].name, 305 sizeof(strings[test_index].name), 306 "%-6s %-24s", unit_str.name, test_str.name); 307 } 308} 309 310#define EFX_CHANNEL_NAME(_channel) "chan%d", _channel->channel 311#define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue 312#define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue 313#define EFX_LOOPBACK_NAME(_mode, _counter) \ 314 "loopback.%s." _counter, STRING_TABLE_LOOKUP(_mode, efx_loopback_mode) 315 316/** 317 * efx_fill_loopback_test - fill in a block of loopback self-test entries 318 * @efx: Efx NIC 319 * @lb_tests: Efx loopback self-test results structure 320 * @mode: Loopback test mode 321 * @test_index: Starting index of the test 322 * @strings: Ethtool strings, or %NULL 323 * @data: Ethtool test results, or %NULL 324 */ 325static int efx_fill_loopback_test(struct efx_nic *efx, 326 struct efx_loopback_self_tests *lb_tests, 327 enum efx_loopback_mode mode, 328 unsigned int test_index, 329 struct ethtool_string *strings, u64 *data) 330{ 331 struct efx_tx_queue *tx_queue; 332 333 efx_for_each_channel_tx_queue(tx_queue, &efx->channel[0]) { 334 efx_fill_test(test_index++, strings, data, 335 &lb_tests->tx_sent[tx_queue->queue], 336 EFX_TX_QUEUE_NAME(tx_queue), 337 EFX_LOOPBACK_NAME(mode, "tx_sent")); 338 efx_fill_test(test_index++, strings, data, 339 &lb_tests->tx_done[tx_queue->queue], 340 EFX_TX_QUEUE_NAME(tx_queue), 341 EFX_LOOPBACK_NAME(mode, "tx_done")); 342 } 343 efx_fill_test(test_index++, strings, data, 344 &lb_tests->rx_good, 345 "rx", 0, 346 EFX_LOOPBACK_NAME(mode, "rx_good")); 347 efx_fill_test(test_index++, strings, data, 348 &lb_tests->rx_bad, 349 "rx", 0, 350 EFX_LOOPBACK_NAME(mode, "rx_bad")); 351 352 return test_index; 353} 354 355/** 356 * efx_ethtool_fill_self_tests - get self-test details 357 * @efx: Efx NIC 358 * @tests: Efx self-test results structure, or %NULL 359 * @strings: Ethtool strings, or %NULL 360 * @data: Ethtool test results, or %NULL 361 */ 362static int efx_ethtool_fill_self_tests(struct efx_nic *efx, 363 struct efx_self_tests *tests, 364 struct ethtool_string *strings, 365 u64 *data) 366{ 367 struct efx_channel *channel; 368 unsigned int n = 0, i; 369 enum efx_loopback_mode mode; 370 371 efx_fill_test(n++, strings, data, &tests->phy_alive, 372 "phy", 0, "alive", NULL); 373 efx_fill_test(n++, strings, data, &tests->nvram, 374 "core", 0, "nvram", NULL); 375 efx_fill_test(n++, strings, data, &tests->interrupt, 376 "core", 0, "interrupt", NULL); 377 378 /* Event queues */ 379 efx_for_each_channel(channel, efx) { 380 efx_fill_test(n++, strings, data, 381 &tests->eventq_dma[channel->channel], 382 EFX_CHANNEL_NAME(channel), 383 "eventq.dma", NULL); 384 efx_fill_test(n++, strings, data, 385 &tests->eventq_int[channel->channel], 386 EFX_CHANNEL_NAME(channel), 387 "eventq.int", NULL); 388 efx_fill_test(n++, strings, data, 389 &tests->eventq_poll[channel->channel], 390 EFX_CHANNEL_NAME(channel), 391 "eventq.poll", NULL); 392 } 393 394 efx_fill_test(n++, strings, data, &tests->registers, 395 "core", 0, "registers", NULL); 396 397 if (efx->phy_op->run_tests != NULL) { 398 EFX_BUG_ON_PARANOID(efx->phy_op->test_name == NULL); 399 400 for (i = 0; true; ++i) { 401 const char *name; 402 403 EFX_BUG_ON_PARANOID(i >= EFX_MAX_PHY_TESTS); 404 name = efx->phy_op->test_name(efx, i); 405 if (name == NULL) 406 break; 407 408 efx_fill_test(n++, strings, data, &tests->phy_ext[i], 409 "phy", 0, name, NULL); 410 } 411 } 412 413 /* Loopback tests */ 414 for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) { 415 if (!(efx->loopback_modes & (1 << mode))) 416 continue; 417 n = efx_fill_loopback_test(efx, 418 &tests->loopback[mode], mode, n, 419 strings, data); 420 } 421 422 return n; 423} 424 425static int efx_ethtool_get_sset_count(struct net_device *net_dev, 426 int string_set) 427{ 428 switch (string_set) { 429 case ETH_SS_STATS: 430 return EFX_ETHTOOL_NUM_STATS; 431 case ETH_SS_TEST: 432 return efx_ethtool_fill_self_tests(netdev_priv(net_dev), 433 NULL, NULL, NULL); 434 default: 435 return -EINVAL; 436 } 437} 438 439static void efx_ethtool_get_strings(struct net_device *net_dev, 440 u32 string_set, u8 *strings) 441{ 442 struct efx_nic *efx = netdev_priv(net_dev); 443 struct ethtool_string *ethtool_strings = 444 (struct ethtool_string *)strings; 445 int i; 446 447 switch (string_set) { 448 case ETH_SS_STATS: 449 for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) 450 strncpy(ethtool_strings[i].name, 451 efx_ethtool_stats[i].name, 452 sizeof(ethtool_strings[i].name)); 453 break; 454 case ETH_SS_TEST: 455 efx_ethtool_fill_self_tests(efx, NULL, 456 ethtool_strings, NULL); 457 break; 458 default: 459 /* No other string sets */ 460 break; 461 } 462} 463 464static void efx_ethtool_get_stats(struct net_device *net_dev, 465 struct ethtool_stats *stats, 466 u64 *data) 467{ 468 struct efx_nic *efx = netdev_priv(net_dev); 469 struct efx_mac_stats *mac_stats = &efx->mac_stats; 470 struct efx_ethtool_stat *stat; 471 struct efx_channel *channel; 472 struct rtnl_link_stats64 temp; 473 int i; 474 475 EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS); 476 477 /* Update MAC and NIC statistics */ 478 dev_get_stats(net_dev, &temp); 479 480 /* Fill detailed statistics buffer */ 481 for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) { 482 stat = &efx_ethtool_stats[i]; 483 switch (stat->source) { 484 case EFX_ETHTOOL_STAT_SOURCE_mac_stats: 485 data[i] = stat->get_stat((void *)mac_stats + 486 stat->offset); 487 break; 488 case EFX_ETHTOOL_STAT_SOURCE_nic: 489 data[i] = stat->get_stat((void *)efx + stat->offset); 490 break; 491 case EFX_ETHTOOL_STAT_SOURCE_channel: 492 data[i] = 0; 493 efx_for_each_channel(channel, efx) 494 data[i] += stat->get_stat((void *)channel + 495 stat->offset); 496 break; 497 } 498 } 499} 500 501static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable) 502{ 503 struct efx_nic *efx __attribute__ ((unused)) = netdev_priv(net_dev); 504 unsigned long features; 505 506 features = NETIF_F_TSO; 507 if (efx->type->offload_features & NETIF_F_V6_CSUM) 508 features |= NETIF_F_TSO6; 509 510 if (enable) 511 net_dev->features |= features; 512 else 513 net_dev->features &= ~features; 514 515 return 0; 516} 517 518static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable) 519{ 520 struct efx_nic *efx = netdev_priv(net_dev); 521 unsigned long features = efx->type->offload_features & NETIF_F_ALL_CSUM; 522 523 if (enable) 524 net_dev->features |= features; 525 else 526 net_dev->features &= ~features; 527 528 return 0; 529} 530 531static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable) 532{ 533 struct efx_nic *efx = netdev_priv(net_dev); 534 535 /* No way to stop the hardware doing the checks; we just 536 * ignore the result. 537 */ 538 efx->rx_checksum_enabled = !!enable; 539 540 return 0; 541} 542 543static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev) 544{ 545 struct efx_nic *efx = netdev_priv(net_dev); 546 547 return efx->rx_checksum_enabled; 548} 549 550static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data) 551{ 552 struct efx_nic *efx = netdev_priv(net_dev); 553 u32 supported = efx->type->offload_features & ETH_FLAG_RXHASH; 554 555 return ethtool_op_set_flags(net_dev, data, supported); 556} 557 558static void efx_ethtool_self_test(struct net_device *net_dev, 559 struct ethtool_test *test, u64 *data) 560{ 561 struct efx_nic *efx = netdev_priv(net_dev); 562 struct efx_self_tests efx_tests; 563 int already_up; 564 int rc; 565 566 ASSERT_RTNL(); 567 if (efx->state != STATE_RUNNING) { 568 rc = -EIO; 569 goto fail1; 570 } 571 572 /* We need rx buffers and interrupts. */ 573 already_up = (efx->net_dev->flags & IFF_UP); 574 if (!already_up) { 575 rc = dev_open(efx->net_dev); 576 if (rc) { 577 netif_err(efx, drv, efx->net_dev, 578 "failed opening device.\n"); 579 goto fail2; 580 } 581 } 582 583 memset(&efx_tests, 0, sizeof(efx_tests)); 584 585 rc = efx_selftest(efx, &efx_tests, test->flags); 586 587 if (!already_up) 588 dev_close(efx->net_dev); 589 590 netif_dbg(efx, drv, efx->net_dev, "%s %sline self-tests\n", 591 rc == 0 ? "passed" : "failed", 592 (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); 593 594 fail2: 595 fail1: 596 /* Fill ethtool results structures */ 597 efx_ethtool_fill_self_tests(efx, &efx_tests, NULL, data); 598 if (rc) 599 test->flags |= ETH_TEST_FL_FAILED; 600} 601 602/* Restart autonegotiation */ 603static int efx_ethtool_nway_reset(struct net_device *net_dev) 604{ 605 struct efx_nic *efx = netdev_priv(net_dev); 606 607 return mdio45_nway_restart(&efx->mdio); 608} 609 610static u32 efx_ethtool_get_link(struct net_device *net_dev) 611{ 612 struct efx_nic *efx = netdev_priv(net_dev); 613 614 return efx->link_state.up; 615} 616 617static int efx_ethtool_get_eeprom_len(struct net_device *net_dev) 618{ 619 struct efx_nic *efx = netdev_priv(net_dev); 620 struct efx_spi_device *spi = efx->spi_eeprom; 621 622 if (!spi) 623 return 0; 624 return min(spi->size, EFX_EEPROM_BOOTCONFIG_END) - 625 min(spi->size, EFX_EEPROM_BOOTCONFIG_START); 626} 627 628static int efx_ethtool_get_eeprom(struct net_device *net_dev, 629 struct ethtool_eeprom *eeprom, u8 *buf) 630{ 631 struct efx_nic *efx = netdev_priv(net_dev); 632 struct efx_spi_device *spi = efx->spi_eeprom; 633 size_t len; 634 int rc; 635 636 rc = mutex_lock_interruptible(&efx->spi_lock); 637 if (rc) 638 return rc; 639 rc = falcon_spi_read(efx, spi, 640 eeprom->offset + EFX_EEPROM_BOOTCONFIG_START, 641 eeprom->len, &len, buf); 642 mutex_unlock(&efx->spi_lock); 643 644 eeprom->magic = EFX_ETHTOOL_EEPROM_MAGIC; 645 eeprom->len = len; 646 return rc; 647} 648 649static int efx_ethtool_set_eeprom(struct net_device *net_dev, 650 struct ethtool_eeprom *eeprom, u8 *buf) 651{ 652 struct efx_nic *efx = netdev_priv(net_dev); 653 struct efx_spi_device *spi = efx->spi_eeprom; 654 size_t len; 655 int rc; 656 657 if (eeprom->magic != EFX_ETHTOOL_EEPROM_MAGIC) 658 return -EINVAL; 659 660 rc = mutex_lock_interruptible(&efx->spi_lock); 661 if (rc) 662 return rc; 663 rc = falcon_spi_write(efx, spi, 664 eeprom->offset + EFX_EEPROM_BOOTCONFIG_START, 665 eeprom->len, &len, buf); 666 mutex_unlock(&efx->spi_lock); 667 668 eeprom->len = len; 669 return rc; 670} 671 672static int efx_ethtool_get_coalesce(struct net_device *net_dev, 673 struct ethtool_coalesce *coalesce) 674{ 675 struct efx_nic *efx = netdev_priv(net_dev); 676 struct efx_tx_queue *tx_queue; 677 struct efx_channel *channel; 678 679 memset(coalesce, 0, sizeof(*coalesce)); 680 681 /* Find lowest IRQ moderation across all used TX queues */ 682 coalesce->tx_coalesce_usecs_irq = ~((u32) 0); 683 efx_for_each_tx_queue(tx_queue, efx) { 684 channel = tx_queue->channel; 685 if (channel->irq_moderation < coalesce->tx_coalesce_usecs_irq) { 686 if (channel->channel < efx->n_rx_channels) 687 coalesce->tx_coalesce_usecs_irq = 688 channel->irq_moderation; 689 else 690 coalesce->tx_coalesce_usecs_irq = 0; 691 } 692 } 693 694 coalesce->use_adaptive_rx_coalesce = efx->irq_rx_adaptive; 695 coalesce->rx_coalesce_usecs_irq = efx->irq_rx_moderation; 696 697 coalesce->tx_coalesce_usecs_irq *= EFX_IRQ_MOD_RESOLUTION; 698 coalesce->rx_coalesce_usecs_irq *= EFX_IRQ_MOD_RESOLUTION; 699 700 return 0; 701} 702 703/* Set coalescing parameters 704 * The difficulties occur for shared channels 705 */ 706static int efx_ethtool_set_coalesce(struct net_device *net_dev, 707 struct ethtool_coalesce *coalesce) 708{ 709 struct efx_nic *efx = netdev_priv(net_dev); 710 struct efx_channel *channel; 711 struct efx_tx_queue *tx_queue; 712 unsigned tx_usecs, rx_usecs, adaptive; 713 714 if (coalesce->use_adaptive_tx_coalesce) 715 return -EOPNOTSUPP; 716 717 if (coalesce->rx_coalesce_usecs || coalesce->tx_coalesce_usecs) { 718 netif_err(efx, drv, efx->net_dev, "invalid coalescing setting. " 719 "Only rx/tx_coalesce_usecs_irq are supported\n"); 720 return -EOPNOTSUPP; 721 } 722 723 rx_usecs = coalesce->rx_coalesce_usecs_irq; 724 tx_usecs = coalesce->tx_coalesce_usecs_irq; 725 adaptive = coalesce->use_adaptive_rx_coalesce; 726 727 /* If the channel is shared only allow RX parameters to be set */ 728 efx_for_each_tx_queue(tx_queue, efx) { 729 if ((tx_queue->channel->channel < efx->n_rx_channels) && 730 tx_usecs) { 731 netif_err(efx, drv, efx->net_dev, "Channel is shared. " 732 "Only RX coalescing may be set\n"); 733 return -EOPNOTSUPP; 734 } 735 } 736 737 efx_init_irq_moderation(efx, tx_usecs, rx_usecs, adaptive); 738 efx_for_each_channel(channel, efx) 739 efx->type->push_irq_moderation(channel); 740 741 return 0; 742} 743 744static int efx_ethtool_set_pauseparam(struct net_device *net_dev, 745 struct ethtool_pauseparam *pause) 746{ 747 struct efx_nic *efx = netdev_priv(net_dev); 748 enum efx_fc_type wanted_fc, old_fc; 749 u32 old_adv; 750 bool reset; 751 int rc = 0; 752 753 mutex_lock(&efx->mac_lock); 754 755 wanted_fc = ((pause->rx_pause ? EFX_FC_RX : 0) | 756 (pause->tx_pause ? EFX_FC_TX : 0) | 757 (pause->autoneg ? EFX_FC_AUTO : 0)); 758 759 if ((wanted_fc & EFX_FC_TX) && !(wanted_fc & EFX_FC_RX)) { 760 netif_dbg(efx, drv, efx->net_dev, 761 "Flow control unsupported: tx ON rx OFF\n"); 762 rc = -EINVAL; 763 goto out; 764 } 765 766 if ((wanted_fc & EFX_FC_AUTO) && !efx->link_advertising) { 767 netif_dbg(efx, drv, efx->net_dev, 768 "Autonegotiation is disabled\n"); 769 rc = -EINVAL; 770 goto out; 771 } 772 773 /* TX flow control may automatically turn itself off if the 774 * link partner (intermittently) stops responding to pause 775 * frames. There isn't any indication that this has happened, 776 * so the best we do is leave it up to the user to spot this 777 * and fix it be cycling transmit flow control on this end. */ 778 reset = (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX); 779 if (EFX_WORKAROUND_11482(efx) && reset) { 780 if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) { 781 /* Recover by resetting the EM block */ 782 falcon_stop_nic_stats(efx); 783 falcon_drain_tx_fifo(efx); 784 efx->mac_op->reconfigure(efx); 785 falcon_start_nic_stats(efx); 786 } else { 787 /* Schedule a reset to recover */ 788 efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); 789 } 790 } 791 792 old_adv = efx->link_advertising; 793 old_fc = efx->wanted_fc; 794 efx_link_set_wanted_fc(efx, wanted_fc); 795 if (efx->link_advertising != old_adv || 796 (efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) { 797 rc = efx->phy_op->reconfigure(efx); 798 if (rc) { 799 netif_err(efx, drv, efx->net_dev, 800 "Unable to advertise requested flow " 801 "control setting\n"); 802 goto out; 803 } 804 } 805 806 /* Reconfigure the MAC. The PHY *may* generate a link state change event 807 * if the user just changed the advertised capabilities, but there's no 808 * harm doing this twice */ 809 efx->mac_op->reconfigure(efx); 810 811out: 812 mutex_unlock(&efx->mac_lock); 813 814 return rc; 815} 816 817static void efx_ethtool_get_pauseparam(struct net_device *net_dev, 818 struct ethtool_pauseparam *pause) 819{ 820 struct efx_nic *efx = netdev_priv(net_dev); 821 822 pause->rx_pause = !!(efx->wanted_fc & EFX_FC_RX); 823 pause->tx_pause = !!(efx->wanted_fc & EFX_FC_TX); 824 pause->autoneg = !!(efx->wanted_fc & EFX_FC_AUTO); 825} 826 827 828static void efx_ethtool_get_wol(struct net_device *net_dev, 829 struct ethtool_wolinfo *wol) 830{ 831 struct efx_nic *efx = netdev_priv(net_dev); 832 return efx->type->get_wol(efx, wol); 833} 834 835 836static int efx_ethtool_set_wol(struct net_device *net_dev, 837 struct ethtool_wolinfo *wol) 838{ 839 struct efx_nic *efx = netdev_priv(net_dev); 840 return efx->type->set_wol(efx, wol->wolopts); 841} 842 843extern int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) 844{ 845 struct efx_nic *efx = netdev_priv(net_dev); 846 enum reset_type method; 847 enum { 848 ETH_RESET_EFX_INVISIBLE = (ETH_RESET_DMA | ETH_RESET_FILTER | 849 ETH_RESET_OFFLOAD | ETH_RESET_MAC) 850 }; 851 852 /* Check for minimal reset flags */ 853 if ((*flags & ETH_RESET_EFX_INVISIBLE) != ETH_RESET_EFX_INVISIBLE) 854 return -EINVAL; 855 *flags ^= ETH_RESET_EFX_INVISIBLE; 856 method = RESET_TYPE_INVISIBLE; 857 858 if (*flags & ETH_RESET_PHY) { 859 *flags ^= ETH_RESET_PHY; 860 method = RESET_TYPE_ALL; 861 } 862 863 if ((*flags & efx->type->reset_world_flags) == 864 efx->type->reset_world_flags) { 865 *flags ^= efx->type->reset_world_flags; 866 method = RESET_TYPE_WORLD; 867 } 868 869 return efx_reset(efx, method); 870} 871 872static int 873efx_ethtool_get_rxnfc(struct net_device *net_dev, 874 struct ethtool_rxnfc *info, void *rules __always_unused) 875{ 876 struct efx_nic *efx = netdev_priv(net_dev); 877 878 switch (info->cmd) { 879 case ETHTOOL_GRXRINGS: 880 info->data = efx->n_rx_channels; 881 return 0; 882 883 case ETHTOOL_GRXFH: { 884 unsigned min_revision = 0; 885 886 info->data = 0; 887 switch (info->flow_type) { 888 case TCP_V4_FLOW: 889 info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 890 /* fall through */ 891 case UDP_V4_FLOW: 892 case SCTP_V4_FLOW: 893 case AH_ESP_V4_FLOW: 894 case IPV4_FLOW: 895 info->data |= RXH_IP_SRC | RXH_IP_DST; 896 min_revision = EFX_REV_FALCON_B0; 897 break; 898 case TCP_V6_FLOW: 899 info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 900 /* fall through */ 901 case UDP_V6_FLOW: 902 case SCTP_V6_FLOW: 903 case AH_ESP_V6_FLOW: 904 case IPV6_FLOW: 905 info->data |= RXH_IP_SRC | RXH_IP_DST; 906 min_revision = EFX_REV_SIENA_A0; 907 break; 908 default: 909 break; 910 } 911 if (efx_nic_rev(efx) < min_revision) 912 info->data = 0; 913 return 0; 914 } 915 916 default: 917 return -EOPNOTSUPP; 918 } 919} 920 921static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev, 922 struct ethtool_rxfh_indir *indir) 923{ 924 struct efx_nic *efx = netdev_priv(net_dev); 925 size_t copy_size = 926 min_t(size_t, indir->size, ARRAY_SIZE(efx->rx_indir_table)); 927 928 if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) 929 return -EOPNOTSUPP; 930 931 indir->size = ARRAY_SIZE(efx->rx_indir_table); 932 memcpy(indir->ring_index, efx->rx_indir_table, 933 copy_size * sizeof(indir->ring_index[0])); 934 return 0; 935} 936 937static int efx_ethtool_set_rxfh_indir(struct net_device *net_dev, 938 const struct ethtool_rxfh_indir *indir) 939{ 940 struct efx_nic *efx = netdev_priv(net_dev); 941 size_t i; 942 943 if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) 944 return -EOPNOTSUPP; 945 946 /* Validate size and indices */ 947 if (indir->size != ARRAY_SIZE(efx->rx_indir_table)) 948 return -EINVAL; 949 for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++) 950 if (indir->ring_index[i] >= efx->n_rx_channels) 951 return -EINVAL; 952 953 memcpy(efx->rx_indir_table, indir->ring_index, 954 sizeof(efx->rx_indir_table)); 955 efx_nic_push_rx_indir_table(efx); 956 return 0; 957} 958 959const struct ethtool_ops efx_ethtool_ops = { 960 .get_settings = efx_ethtool_get_settings, 961 .set_settings = efx_ethtool_set_settings, 962 .get_drvinfo = efx_ethtool_get_drvinfo, 963 .get_regs_len = efx_ethtool_get_regs_len, 964 .get_regs = efx_ethtool_get_regs, 965 .get_msglevel = efx_ethtool_get_msglevel, 966 .set_msglevel = efx_ethtool_set_msglevel, 967 .nway_reset = efx_ethtool_nway_reset, 968 .get_link = efx_ethtool_get_link, 969 .get_eeprom_len = efx_ethtool_get_eeprom_len, 970 .get_eeprom = efx_ethtool_get_eeprom, 971 .set_eeprom = efx_ethtool_set_eeprom, 972 .get_coalesce = efx_ethtool_get_coalesce, 973 .set_coalesce = efx_ethtool_set_coalesce, 974 .get_pauseparam = efx_ethtool_get_pauseparam, 975 .set_pauseparam = efx_ethtool_set_pauseparam, 976 .get_rx_csum = efx_ethtool_get_rx_csum, 977 .set_rx_csum = efx_ethtool_set_rx_csum, 978 .get_tx_csum = ethtool_op_get_tx_csum, 979 /* Need to enable/disable IPv6 too */ 980 .set_tx_csum = efx_ethtool_set_tx_csum, 981 .get_sg = ethtool_op_get_sg, 982 .set_sg = ethtool_op_set_sg, 983 .get_tso = ethtool_op_get_tso, 984 /* Need to enable/disable TSO-IPv6 too */ 985 .set_tso = efx_ethtool_set_tso, 986 .get_flags = ethtool_op_get_flags, 987 .set_flags = efx_ethtool_set_flags, 988 .get_sset_count = efx_ethtool_get_sset_count, 989 .self_test = efx_ethtool_self_test, 990 .get_strings = efx_ethtool_get_strings, 991 .phys_id = efx_ethtool_phys_id, 992 .get_ethtool_stats = efx_ethtool_get_stats, 993 .get_wol = efx_ethtool_get_wol, 994 .set_wol = efx_ethtool_set_wol, 995 .reset = efx_ethtool_reset, 996 .get_rxnfc = efx_ethtool_get_rxnfc, 997 .get_rxfh_indir = efx_ethtool_get_rxfh_indir, 998 .set_rxfh_indir = efx_ethtool_set_rxfh_indir, 999};