aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/ethtool.c')
-rw-r--r--drivers/net/sfc/ethtool.c386
1 files changed, 208 insertions, 178 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index fd19d6ab97a2..d229027dc363 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -1,7 +1,7 @@
1/**************************************************************************** 1/****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards 2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2005-2006 Fen Systems Ltd. 3 * Copyright 2005-2006 Fen Systems Ltd.
4 * Copyright 2006-2009 Solarflare Communications Inc. 4 * Copyright 2006-2010 Solarflare Communications Inc.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 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 7 * under the terms of the GNU General Public License version 2 as published
@@ -11,13 +11,13 @@
11#include <linux/netdevice.h> 11#include <linux/netdevice.h>
12#include <linux/ethtool.h> 12#include <linux/ethtool.h>
13#include <linux/rtnetlink.h> 13#include <linux/rtnetlink.h>
14#include <linux/in.h>
14#include "net_driver.h" 15#include "net_driver.h"
15#include "workarounds.h" 16#include "workarounds.h"
16#include "selftest.h" 17#include "selftest.h"
17#include "efx.h" 18#include "efx.h"
19#include "filter.h"
18#include "nic.h" 20#include "nic.h"
19#include "spi.h"
20#include "mdio_10g.h"
21 21
22struct ethtool_string { 22struct ethtool_string {
23 char name[ETH_GSTRING_LEN]; 23 char name[ETH_GSTRING_LEN];
@@ -28,7 +28,8 @@ struct efx_ethtool_stat {
28 enum { 28 enum {
29 EFX_ETHTOOL_STAT_SOURCE_mac_stats, 29 EFX_ETHTOOL_STAT_SOURCE_mac_stats,
30 EFX_ETHTOOL_STAT_SOURCE_nic, 30 EFX_ETHTOOL_STAT_SOURCE_nic,
31 EFX_ETHTOOL_STAT_SOURCE_channel 31 EFX_ETHTOOL_STAT_SOURCE_channel,
32 EFX_ETHTOOL_STAT_SOURCE_tx_queue
32 } source; 33 } source;
33 unsigned offset; 34 unsigned offset;
34 u64(*get_stat) (void *field); /* Reader function */ 35 u64(*get_stat) (void *field); /* Reader function */
@@ -86,6 +87,10 @@ static u64 efx_get_atomic_stat(void *field)
86 EFX_ETHTOOL_STAT(field, channel, n_##field, \ 87 EFX_ETHTOOL_STAT(field, channel, n_##field, \
87 unsigned int, efx_get_uint_stat) 88 unsigned int, efx_get_uint_stat)
88 89
90#define EFX_ETHTOOL_UINT_TXQ_STAT(field) \
91 EFX_ETHTOOL_STAT(tx_##field, tx_queue, field, \
92 unsigned int, efx_get_uint_stat)
93
89static struct efx_ethtool_stat efx_ethtool_stats[] = { 94static struct efx_ethtool_stat efx_ethtool_stats[] = {
90 EFX_ETHTOOL_U64_MAC_STAT(tx_bytes), 95 EFX_ETHTOOL_U64_MAC_STAT(tx_bytes),
91 EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes), 96 EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes),
@@ -116,6 +121,10 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = {
116 EFX_ETHTOOL_ULONG_MAC_STAT(tx_non_tcpudp), 121 EFX_ETHTOOL_ULONG_MAC_STAT(tx_non_tcpudp),
117 EFX_ETHTOOL_ULONG_MAC_STAT(tx_mac_src_error), 122 EFX_ETHTOOL_ULONG_MAC_STAT(tx_mac_src_error),
118 EFX_ETHTOOL_ULONG_MAC_STAT(tx_ip_src_error), 123 EFX_ETHTOOL_ULONG_MAC_STAT(tx_ip_src_error),
124 EFX_ETHTOOL_UINT_TXQ_STAT(tso_bursts),
125 EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers),
126 EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets),
127 EFX_ETHTOOL_UINT_TXQ_STAT(pushes),
119 EFX_ETHTOOL_U64_MAC_STAT(rx_bytes), 128 EFX_ETHTOOL_U64_MAC_STAT(rx_bytes),
120 EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes), 129 EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes),
121 EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes), 130 EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes),
@@ -169,25 +178,33 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = {
169 */ 178 */
170 179
171/* Identify device by flashing LEDs */ 180/* Identify device by flashing LEDs */
172static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count) 181static int efx_ethtool_phys_id(struct net_device *net_dev,
182 enum ethtool_phys_id_state state)
173{ 183{
174 struct efx_nic *efx = netdev_priv(net_dev); 184 struct efx_nic *efx = netdev_priv(net_dev);
185 enum efx_led_mode mode = EFX_LED_DEFAULT;
175 186
176 do { 187 switch (state) {
177 efx->type->set_id_led(efx, EFX_LED_ON); 188 case ETHTOOL_ID_ON:
178 schedule_timeout_interruptible(HZ / 2); 189 mode = EFX_LED_ON;
179 190 break;
180 efx->type->set_id_led(efx, EFX_LED_OFF); 191 case ETHTOOL_ID_OFF:
181 schedule_timeout_interruptible(HZ / 2); 192 mode = EFX_LED_OFF;
182 } while (!signal_pending(current) && --count != 0); 193 break;
194 case ETHTOOL_ID_INACTIVE:
195 mode = EFX_LED_DEFAULT;
196 break;
197 case ETHTOOL_ID_ACTIVE:
198 return 1; /* cycle on/off once per second */
199 }
183 200
184 efx->type->set_id_led(efx, EFX_LED_DEFAULT); 201 efx->type->set_id_led(efx, mode);
185 return 0; 202 return 0;
186} 203}
187 204
188/* This must be called with rtnl_lock held. */ 205/* This must be called with rtnl_lock held. */
189int efx_ethtool_get_settings(struct net_device *net_dev, 206static int efx_ethtool_get_settings(struct net_device *net_dev,
190 struct ethtool_cmd *ecmd) 207 struct ethtool_cmd *ecmd)
191{ 208{
192 struct efx_nic *efx = netdev_priv(net_dev); 209 struct efx_nic *efx = netdev_priv(net_dev);
193 struct efx_link_state *link_state = &efx->link_state; 210 struct efx_link_state *link_state = &efx->link_state;
@@ -202,7 +219,7 @@ int efx_ethtool_get_settings(struct net_device *net_dev,
202 ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 219 ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
203 220
204 if (LOOPBACK_INTERNAL(efx)) { 221 if (LOOPBACK_INTERNAL(efx)) {
205 ecmd->speed = link_state->speed; 222 ethtool_cmd_speed_set(ecmd, link_state->speed);
206 ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF; 223 ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF;
207 } 224 }
208 225
@@ -210,14 +227,15 @@ int efx_ethtool_get_settings(struct net_device *net_dev,
210} 227}
211 228
212/* This must be called with rtnl_lock held. */ 229/* This must be called with rtnl_lock held. */
213int efx_ethtool_set_settings(struct net_device *net_dev, 230static int efx_ethtool_set_settings(struct net_device *net_dev,
214 struct ethtool_cmd *ecmd) 231 struct ethtool_cmd *ecmd)
215{ 232{
216 struct efx_nic *efx = netdev_priv(net_dev); 233 struct efx_nic *efx = netdev_priv(net_dev);
217 int rc; 234 int rc;
218 235
219 /* GMAC does not support 1000Mbps HD */ 236 /* GMAC does not support 1000Mbps HD */
220 if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { 237 if ((ethtool_cmd_speed(ecmd) == SPEED_1000) &&
238 (ecmd->duplex != DUPLEX_FULL)) {
221 netif_dbg(efx, drv, efx->net_dev, 239 netif_dbg(efx, drv, efx->net_dev,
222 "rejecting unsupported 1000Mbps HD setting\n"); 240 "rejecting unsupported 1000Mbps HD setting\n");
223 return -EINVAL; 241 return -EINVAL;
@@ -237,8 +255,8 @@ static void efx_ethtool_get_drvinfo(struct net_device *net_dev,
237 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 255 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
238 strlcpy(info->version, EFX_DRIVER_VERSION, sizeof(info->version)); 256 strlcpy(info->version, EFX_DRIVER_VERSION, sizeof(info->version));
239 if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) 257 if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0)
240 siena_print_fwver(efx, info->fw_version, 258 efx_mcdi_print_fwver(efx, info->fw_version,
241 sizeof(info->fw_version)); 259 sizeof(info->fw_version));
242 strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); 260 strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info));
243} 261}
244 262
@@ -328,9 +346,10 @@ static int efx_fill_loopback_test(struct efx_nic *efx,
328 unsigned int test_index, 346 unsigned int test_index,
329 struct ethtool_string *strings, u64 *data) 347 struct ethtool_string *strings, u64 *data)
330{ 348{
349 struct efx_channel *channel = efx_get_channel(efx, 0);
331 struct efx_tx_queue *tx_queue; 350 struct efx_tx_queue *tx_queue;
332 351
333 efx_for_each_channel_tx_queue(tx_queue, &efx->channel[0]) { 352 efx_for_each_channel_tx_queue(tx_queue, channel) {
334 efx_fill_test(test_index++, strings, data, 353 efx_fill_test(test_index++, strings, data,
335 &lb_tests->tx_sent[tx_queue->queue], 354 &lb_tests->tx_sent[tx_queue->queue],
336 EFX_TX_QUEUE_NAME(tx_queue), 355 EFX_TX_QUEUE_NAME(tx_queue),
@@ -469,6 +488,7 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
469 struct efx_mac_stats *mac_stats = &efx->mac_stats; 488 struct efx_mac_stats *mac_stats = &efx->mac_stats;
470 struct efx_ethtool_stat *stat; 489 struct efx_ethtool_stat *stat;
471 struct efx_channel *channel; 490 struct efx_channel *channel;
491 struct efx_tx_queue *tx_queue;
472 struct rtnl_link_stats64 temp; 492 struct rtnl_link_stats64 temp;
473 int i; 493 int i;
474 494
@@ -494,74 +514,31 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
494 data[i] += stat->get_stat((void *)channel + 514 data[i] += stat->get_stat((void *)channel +
495 stat->offset); 515 stat->offset);
496 break; 516 break;
517 case EFX_ETHTOOL_STAT_SOURCE_tx_queue:
518 data[i] = 0;
519 efx_for_each_channel(channel, efx) {
520 efx_for_each_channel_tx_queue(tx_queue, channel)
521 data[i] +=
522 stat->get_stat((void *)tx_queue
523 + stat->offset);
524 }
525 break;
497 } 526 }
498 } 527 }
499} 528}
500 529
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, 530static void efx_ethtool_self_test(struct net_device *net_dev,
559 struct ethtool_test *test, u64 *data) 531 struct ethtool_test *test, u64 *data)
560{ 532{
561 struct efx_nic *efx = netdev_priv(net_dev); 533 struct efx_nic *efx = netdev_priv(net_dev);
562 struct efx_self_tests efx_tests; 534 struct efx_self_tests *efx_tests;
563 int already_up; 535 int already_up;
564 int rc; 536 int rc = -ENOMEM;
537
538 efx_tests = kzalloc(sizeof(*efx_tests), GFP_KERNEL);
539 if (!efx_tests)
540 goto fail;
541
565 542
566 ASSERT_RTNL(); 543 ASSERT_RTNL();
567 if (efx->state != STATE_RUNNING) { 544 if (efx->state != STATE_RUNNING) {
@@ -569,6 +546,9 @@ static void efx_ethtool_self_test(struct net_device *net_dev,
569 goto fail1; 546 goto fail1;
570 } 547 }
571 548
549 netif_info(efx, drv, efx->net_dev, "starting %sline testing\n",
550 (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
551
572 /* We need rx buffers and interrupts. */ 552 /* We need rx buffers and interrupts. */
573 already_up = (efx->net_dev->flags & IFF_UP); 553 already_up = (efx->net_dev->flags & IFF_UP);
574 if (!already_up) { 554 if (!already_up) {
@@ -576,25 +556,24 @@ static void efx_ethtool_self_test(struct net_device *net_dev,
576 if (rc) { 556 if (rc) {
577 netif_err(efx, drv, efx->net_dev, 557 netif_err(efx, drv, efx->net_dev,
578 "failed opening device.\n"); 558 "failed opening device.\n");
579 goto fail2; 559 goto fail1;
580 } 560 }
581 } 561 }
582 562
583 memset(&efx_tests, 0, sizeof(efx_tests)); 563 rc = efx_selftest(efx, efx_tests, test->flags);
584
585 rc = efx_selftest(efx, &efx_tests, test->flags);
586 564
587 if (!already_up) 565 if (!already_up)
588 dev_close(efx->net_dev); 566 dev_close(efx->net_dev);
589 567
590 netif_dbg(efx, drv, efx->net_dev, "%s %sline self-tests\n", 568 netif_info(efx, drv, efx->net_dev, "%s %sline self-tests\n",
591 rc == 0 ? "passed" : "failed", 569 rc == 0 ? "passed" : "failed",
592 (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); 570 (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
593 571
594 fail2: 572fail1:
595 fail1:
596 /* Fill ethtool results structures */ 573 /* Fill ethtool results structures */
597 efx_ethtool_fill_self_tests(efx, &efx_tests, NULL, data); 574 efx_ethtool_fill_self_tests(efx, efx_tests, NULL, data);
575 kfree(efx_tests);
576fail:
598 if (rc) 577 if (rc)
599 test->flags |= ETH_TEST_FL_FAILED; 578 test->flags |= ETH_TEST_FL_FAILED;
600} 579}
@@ -607,81 +586,19 @@ static int efx_ethtool_nway_reset(struct net_device *net_dev)
607 return mdio45_nway_restart(&efx->mdio); 586 return mdio45_nway_restart(&efx->mdio);
608} 587}
609 588
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, 589static int efx_ethtool_get_coalesce(struct net_device *net_dev,
673 struct ethtool_coalesce *coalesce) 590 struct ethtool_coalesce *coalesce)
674{ 591{
675 struct efx_nic *efx = netdev_priv(net_dev); 592 struct efx_nic *efx = netdev_priv(net_dev);
676 struct efx_tx_queue *tx_queue;
677 struct efx_channel *channel; 593 struct efx_channel *channel;
678 594
679 memset(coalesce, 0, sizeof(*coalesce)); 595 memset(coalesce, 0, sizeof(*coalesce));
680 596
681 /* Find lowest IRQ moderation across all used TX queues */ 597 /* Find lowest IRQ moderation across all used TX queues */
682 coalesce->tx_coalesce_usecs_irq = ~((u32) 0); 598 coalesce->tx_coalesce_usecs_irq = ~((u32) 0);
683 efx_for_each_tx_queue(tx_queue, efx) { 599 efx_for_each_channel(channel, efx) {
684 channel = tx_queue->channel; 600 if (!efx_channel_has_tx_queues(channel))
601 continue;
685 if (channel->irq_moderation < coalesce->tx_coalesce_usecs_irq) { 602 if (channel->irq_moderation < coalesce->tx_coalesce_usecs_irq) {
686 if (channel->channel < efx->n_rx_channels) 603 if (channel->channel < efx->n_rx_channels)
687 coalesce->tx_coalesce_usecs_irq = 604 coalesce->tx_coalesce_usecs_irq =
@@ -708,7 +625,6 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
708{ 625{
709 struct efx_nic *efx = netdev_priv(net_dev); 626 struct efx_nic *efx = netdev_priv(net_dev);
710 struct efx_channel *channel; 627 struct efx_channel *channel;
711 struct efx_tx_queue *tx_queue;
712 unsigned tx_usecs, rx_usecs, adaptive; 628 unsigned tx_usecs, rx_usecs, adaptive;
713 629
714 if (coalesce->use_adaptive_tx_coalesce) 630 if (coalesce->use_adaptive_tx_coalesce)
@@ -725,8 +641,9 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
725 adaptive = coalesce->use_adaptive_rx_coalesce; 641 adaptive = coalesce->use_adaptive_rx_coalesce;
726 642
727 /* If the channel is shared only allow RX parameters to be set */ 643 /* If the channel is shared only allow RX parameters to be set */
728 efx_for_each_tx_queue(tx_queue, efx) { 644 efx_for_each_channel(channel, efx) {
729 if ((tx_queue->channel->channel < efx->n_rx_channels) && 645 if (efx_channel_has_rx_queue(channel) &&
646 efx_channel_has_tx_queues(channel) &&
730 tx_usecs) { 647 tx_usecs) {
731 netif_err(efx, drv, efx->net_dev, "Channel is shared. " 648 netif_err(efx, drv, efx->net_dev, "Channel is shared. "
732 "Only RX coalescing may be set\n"); 649 "Only RX coalescing may be set\n");
@@ -741,11 +658,47 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
741 return 0; 658 return 0;
742} 659}
743 660
661static void efx_ethtool_get_ringparam(struct net_device *net_dev,
662 struct ethtool_ringparam *ring)
663{
664 struct efx_nic *efx = netdev_priv(net_dev);
665
666 ring->rx_max_pending = EFX_MAX_DMAQ_SIZE;
667 ring->tx_max_pending = EFX_MAX_DMAQ_SIZE;
668 ring->rx_mini_max_pending = 0;
669 ring->rx_jumbo_max_pending = 0;
670 ring->rx_pending = efx->rxq_entries;
671 ring->tx_pending = efx->txq_entries;
672 ring->rx_mini_pending = 0;
673 ring->rx_jumbo_pending = 0;
674}
675
676static int efx_ethtool_set_ringparam(struct net_device *net_dev,
677 struct ethtool_ringparam *ring)
678{
679 struct efx_nic *efx = netdev_priv(net_dev);
680
681 if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
682 ring->rx_pending > EFX_MAX_DMAQ_SIZE ||
683 ring->tx_pending > EFX_MAX_DMAQ_SIZE)
684 return -EINVAL;
685
686 if (ring->rx_pending < EFX_MIN_RING_SIZE ||
687 ring->tx_pending < EFX_MIN_RING_SIZE) {
688 netif_err(efx, drv, efx->net_dev,
689 "TX and RX queues cannot be smaller than %ld\n",
690 EFX_MIN_RING_SIZE);
691 return -EINVAL;
692 }
693
694 return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending);
695}
696
744static int efx_ethtool_set_pauseparam(struct net_device *net_dev, 697static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
745 struct ethtool_pauseparam *pause) 698 struct ethtool_pauseparam *pause)
746{ 699{
747 struct efx_nic *efx = netdev_priv(net_dev); 700 struct efx_nic *efx = netdev_priv(net_dev);
748 enum efx_fc_type wanted_fc, old_fc; 701 u8 wanted_fc, old_fc;
749 u32 old_adv; 702 u32 old_adv;
750 bool reset; 703 bool reset;
751 int rc = 0; 704 int rc = 0;
@@ -840,7 +793,7 @@ static int efx_ethtool_set_wol(struct net_device *net_dev,
840 return efx->type->set_wol(efx, wol->wolopts); 793 return efx->type->set_wol(efx, wol->wolopts);
841} 794}
842 795
843extern int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) 796static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags)
844{ 797{
845 struct efx_nic *efx = netdev_priv(net_dev); 798 struct efx_nic *efx = netdev_priv(net_dev);
846 enum reset_type method; 799 enum reset_type method;
@@ -918,6 +871,95 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev,
918 } 871 }
919} 872}
920 873
874static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
875 struct ethtool_rx_ntuple *ntuple)
876{
877 struct efx_nic *efx = netdev_priv(net_dev);
878 struct ethtool_tcpip4_spec *ip_entry = &ntuple->fs.h_u.tcp_ip4_spec;
879 struct ethtool_tcpip4_spec *ip_mask = &ntuple->fs.m_u.tcp_ip4_spec;
880 struct ethhdr *mac_entry = &ntuple->fs.h_u.ether_spec;
881 struct ethhdr *mac_mask = &ntuple->fs.m_u.ether_spec;
882 struct efx_filter_spec filter;
883 int rc;
884
885 /* Range-check action */
886 if (ntuple->fs.action < ETHTOOL_RXNTUPLE_ACTION_CLEAR ||
887 ntuple->fs.action >= (s32)efx->n_rx_channels)
888 return -EINVAL;
889
890 if (~ntuple->fs.data_mask)
891 return -EINVAL;
892
893 efx_filter_init_rx(&filter, EFX_FILTER_PRI_MANUAL, 0,
894 (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) ?
895 0xfff : ntuple->fs.action);
896
897 switch (ntuple->fs.flow_type) {
898 case TCP_V4_FLOW:
899 case UDP_V4_FLOW: {
900 u8 proto = (ntuple->fs.flow_type == TCP_V4_FLOW ?
901 IPPROTO_TCP : IPPROTO_UDP);
902
903 /* Must match all of destination, */
904 if (ip_mask->ip4dst | ip_mask->pdst)
905 return -EINVAL;
906 /* all or none of source, */
907 if ((ip_mask->ip4src | ip_mask->psrc) &&
908 ((__force u32)~ip_mask->ip4src |
909 (__force u16)~ip_mask->psrc))
910 return -EINVAL;
911 /* and nothing else */
912 if ((u8)~ip_mask->tos | (u16)~ntuple->fs.vlan_tag_mask)
913 return -EINVAL;
914
915 if (!ip_mask->ip4src)
916 rc = efx_filter_set_ipv4_full(&filter, proto,
917 ip_entry->ip4dst,
918 ip_entry->pdst,
919 ip_entry->ip4src,
920 ip_entry->psrc);
921 else
922 rc = efx_filter_set_ipv4_local(&filter, proto,
923 ip_entry->ip4dst,
924 ip_entry->pdst);
925 if (rc)
926 return rc;
927 break;
928 }
929
930 case ETHER_FLOW:
931 /* Must match all of destination, */
932 if (!is_zero_ether_addr(mac_mask->h_dest))
933 return -EINVAL;
934 /* all or none of VID, */
935 if (ntuple->fs.vlan_tag_mask != 0xf000 &&
936 ntuple->fs.vlan_tag_mask != 0xffff)
937 return -EINVAL;
938 /* and nothing else */
939 if (!is_broadcast_ether_addr(mac_mask->h_source) ||
940 mac_mask->h_proto != htons(0xffff))
941 return -EINVAL;
942
943 rc = efx_filter_set_eth_local(
944 &filter,
945 (ntuple->fs.vlan_tag_mask == 0xf000) ?
946 ntuple->fs.vlan_tag : EFX_FILTER_VID_UNSPEC,
947 mac_entry->h_dest);
948 if (rc)
949 return rc;
950 break;
951
952 default:
953 return -EINVAL;
954 }
955
956 if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR)
957 return efx_filter_remove_filter(efx, &filter);
958
959 rc = efx_filter_insert_filter(efx, &filter, true);
960 return rc < 0 ? rc : 0;
961}
962
921static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev, 963static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev,
922 struct ethtool_rxfh_indir *indir) 964 struct ethtool_rxfh_indir *indir)
923{ 965{
@@ -965,35 +1007,23 @@ const struct ethtool_ops efx_ethtool_ops = {
965 .get_msglevel = efx_ethtool_get_msglevel, 1007 .get_msglevel = efx_ethtool_get_msglevel,
966 .set_msglevel = efx_ethtool_set_msglevel, 1008 .set_msglevel = efx_ethtool_set_msglevel,
967 .nway_reset = efx_ethtool_nway_reset, 1009 .nway_reset = efx_ethtool_nway_reset,
968 .get_link = efx_ethtool_get_link, 1010 .get_link = ethtool_op_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, 1011 .get_coalesce = efx_ethtool_get_coalesce,
973 .set_coalesce = efx_ethtool_set_coalesce, 1012 .set_coalesce = efx_ethtool_set_coalesce,
1013 .get_ringparam = efx_ethtool_get_ringparam,
1014 .set_ringparam = efx_ethtool_set_ringparam,
974 .get_pauseparam = efx_ethtool_get_pauseparam, 1015 .get_pauseparam = efx_ethtool_get_pauseparam,
975 .set_pauseparam = efx_ethtool_set_pauseparam, 1016 .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, 1017 .get_sset_count = efx_ethtool_get_sset_count,
989 .self_test = efx_ethtool_self_test, 1018 .self_test = efx_ethtool_self_test,
990 .get_strings = efx_ethtool_get_strings, 1019 .get_strings = efx_ethtool_get_strings,
991 .phys_id = efx_ethtool_phys_id, 1020 .set_phys_id = efx_ethtool_phys_id,
992 .get_ethtool_stats = efx_ethtool_get_stats, 1021 .get_ethtool_stats = efx_ethtool_get_stats,
993 .get_wol = efx_ethtool_get_wol, 1022 .get_wol = efx_ethtool_get_wol,
994 .set_wol = efx_ethtool_set_wol, 1023 .set_wol = efx_ethtool_set_wol,
995 .reset = efx_ethtool_reset, 1024 .reset = efx_ethtool_reset,
996 .get_rxnfc = efx_ethtool_get_rxnfc, 1025 .get_rxnfc = efx_ethtool_get_rxnfc,
1026 .set_rx_ntuple = efx_ethtool_set_rx_ntuple,
997 .get_rxfh_indir = efx_ethtool_get_rxfh_indir, 1027 .get_rxfh_indir = efx_ethtool_get_rxfh_indir,
998 .set_rxfh_indir = efx_ethtool_set_rxfh_indir, 1028 .set_rxfh_indir = efx_ethtool_set_rxfh_indir,
999}; 1029};