aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/selftest.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/selftest.c')
-rw-r--r--drivers/net/sfc/selftest.c183
1 files changed, 83 insertions, 100 deletions
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 817c7efc11e0..0106b1d9aae2 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.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-2008 Solarflare Communications Inc. 4 * Copyright 2006-2009 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
@@ -18,17 +18,13 @@
18#include <linux/in.h> 18#include <linux/in.h>
19#include <linux/udp.h> 19#include <linux/udp.h>
20#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
21#include <linux/slab.h>
21#include <asm/io.h> 22#include <asm/io.h>
22#include "net_driver.h" 23#include "net_driver.h"
23#include "ethtool.h"
24#include "efx.h" 24#include "efx.h"
25#include "falcon.h" 25#include "nic.h"
26#include "selftest.h" 26#include "selftest.h"
27#include "boards.h"
28#include "workarounds.h" 27#include "workarounds.h"
29#include "spi.h"
30#include "falcon_io.h"
31#include "mdio_10g.h"
32 28
33/* 29/*
34 * Loopback test packet structure 30 * Loopback test packet structure
@@ -49,7 +45,7 @@ static const unsigned char payload_source[ETH_ALEN] = {
49 0x00, 0x0f, 0x53, 0x1b, 0x1b, 0x1b, 45 0x00, 0x0f, 0x53, 0x1b, 0x1b, 0x1b,
50}; 46};
51 47
52static const char *payload_msg = 48static const char payload_msg[] =
53 "Hello world! This is an Efx loopback test in progress!"; 49 "Hello world! This is an Efx loopback test in progress!";
54 50
55/** 51/**
@@ -57,6 +53,7 @@ static const char *payload_msg =
57 * @flush: Drop all packets in efx_loopback_rx_packet 53 * @flush: Drop all packets in efx_loopback_rx_packet
58 * @packet_count: Number of packets being used in this test 54 * @packet_count: Number of packets being used in this test
59 * @skbs: An array of skbs transmitted 55 * @skbs: An array of skbs transmitted
56 * @offload_csum: Checksums are being offloaded
60 * @rx_good: RX good packet count 57 * @rx_good: RX good packet count
61 * @rx_bad: RX bad packet count 58 * @rx_bad: RX bad packet count
62 * @payload: Payload used in tests 59 * @payload: Payload used in tests
@@ -65,10 +62,7 @@ struct efx_loopback_state {
65 bool flush; 62 bool flush;
66 int packet_count; 63 int packet_count;
67 struct sk_buff **skbs; 64 struct sk_buff **skbs;
68
69 /* Checksums are being offloaded */
70 bool offload_csum; 65 bool offload_csum;
71
72 atomic_t rx_good; 66 atomic_t rx_good;
73 atomic_t rx_bad; 67 atomic_t rx_bad;
74 struct efx_loopback_payload payload; 68 struct efx_loopback_payload payload;
@@ -80,60 +74,40 @@ struct efx_loopback_state {
80 * 74 *
81 **************************************************************************/ 75 **************************************************************************/
82 76
83static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests) 77static int efx_test_phy_alive(struct efx_nic *efx, struct efx_self_tests *tests)
84{ 78{
85 int rc = 0; 79 int rc = 0;
86 int devad = __ffs(efx->mdio.mmds);
87 u16 physid1, physid2;
88
89 if (efx->phy_type == PHY_TYPE_NONE)
90 return 0;
91
92 mutex_lock(&efx->mac_lock);
93 tests->mdio = -1;
94
95 physid1 = efx_mdio_read(efx, devad, MDIO_DEVID1);
96 physid2 = efx_mdio_read(efx, devad, MDIO_DEVID2);
97 80
98 if ((physid1 == 0x0000) || (physid1 == 0xffff) || 81 if (efx->phy_op->test_alive) {
99 (physid2 == 0x0000) || (physid2 == 0xffff)) { 82 rc = efx->phy_op->test_alive(efx);
100 EFX_ERR(efx, "no MDIO PHY present with ID %d\n", 83 tests->phy_alive = rc ? -1 : 1;
101 efx->mdio.prtad);
102 rc = -EINVAL;
103 goto out;
104 } 84 }
105 85
106 if (EFX_IS10G(efx)) {
107 rc = efx_mdio_check_mmds(efx, efx->phy_op->mmds, 0);
108 if (rc)
109 goto out;
110 }
111
112out:
113 mutex_unlock(&efx->mac_lock);
114 tests->mdio = rc ? -1 : 1;
115 return rc; 86 return rc;
116} 87}
117 88
118static int efx_test_nvram(struct efx_nic *efx, struct efx_self_tests *tests) 89static int efx_test_nvram(struct efx_nic *efx, struct efx_self_tests *tests)
119{ 90{
120 int rc; 91 int rc = 0;
92
93 if (efx->type->test_nvram) {
94 rc = efx->type->test_nvram(efx);
95 tests->nvram = rc ? -1 : 1;
96 }
121 97
122 rc = falcon_read_nvram(efx, NULL);
123 tests->nvram = rc ? -1 : 1;
124 return rc; 98 return rc;
125} 99}
126 100
127static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests) 101static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
128{ 102{
129 int rc; 103 int rc = 0;
130 104
131 /* Not supported on A-series silicon */ 105 /* Test register access */
132 if (falcon_rev(efx) < FALCON_REV_B0) 106 if (efx->type->test_registers) {
133 return 0; 107 rc = efx->type->test_registers(efx);
108 tests->registers = rc ? -1 : 1;
109 }
134 110
135 rc = falcon_test_registers(efx);
136 tests->registers = rc ? -1 : 1;
137 return rc; 111 return rc;
138} 112}
139 113
@@ -165,7 +139,7 @@ static int efx_test_interrupts(struct efx_nic *efx,
165 goto success; 139 goto success;
166 } 140 }
167 141
168 falcon_generate_interrupt(efx); 142 efx_nic_generate_interrupt(efx);
169 143
170 /* Wait for arrival of test interrupt. */ 144 /* Wait for arrival of test interrupt. */
171 EFX_LOG(efx, "waiting for test interrupt\n"); 145 EFX_LOG(efx, "waiting for test interrupt\n");
@@ -177,8 +151,8 @@ static int efx_test_interrupts(struct efx_nic *efx,
177 return -ETIMEDOUT; 151 return -ETIMEDOUT;
178 152
179 success: 153 success:
180 EFX_LOG(efx, "test interrupt (mode %d) seen on CPU%d\n", 154 EFX_LOG(efx, "%s test interrupt seen on CPU%d\n", INT_MODE(efx),
181 efx->interrupt_mode, efx->last_irq_cpu); 155 efx->last_irq_cpu);
182 tests->interrupt = 1; 156 tests->interrupt = 1;
183 return 0; 157 return 0;
184} 158}
@@ -203,7 +177,7 @@ static int efx_test_eventq_irq(struct efx_channel *channel,
203 channel->eventq_magic = 0; 177 channel->eventq_magic = 0;
204 smp_wmb(); 178 smp_wmb();
205 179
206 falcon_generate_test_event(channel, magic); 180 efx_nic_generate_test_event(channel, magic);
207 181
208 /* Wait for arrival of interrupt */ 182 /* Wait for arrival of interrupt */
209 count = 0; 183 count = 0;
@@ -254,11 +228,8 @@ static int efx_test_phy(struct efx_nic *efx, struct efx_self_tests *tests,
254 if (!efx->phy_op->run_tests) 228 if (!efx->phy_op->run_tests)
255 return 0; 229 return 0;
256 230
257 EFX_BUG_ON_PARANOID(efx->phy_op->num_tests == 0 ||
258 efx->phy_op->num_tests > EFX_MAX_PHY_TESTS);
259
260 mutex_lock(&efx->mac_lock); 231 mutex_lock(&efx->mac_lock);
261 rc = efx->phy_op->run_tests(efx, tests->phy, flags); 232 rc = efx->phy_op->run_tests(efx, tests->phy_ext, flags);
262 mutex_unlock(&efx->mac_lock); 233 mutex_unlock(&efx->mac_lock);
263 return rc; 234 return rc;
264} 235}
@@ -426,7 +397,7 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
426 397
427 if (efx_dev_registered(efx)) 398 if (efx_dev_registered(efx))
428 netif_tx_lock_bh(efx->net_dev); 399 netif_tx_lock_bh(efx->net_dev);
429 rc = efx_xmit(efx, tx_queue, skb); 400 rc = efx_enqueue_skb(tx_queue, skb);
430 if (efx_dev_registered(efx)) 401 if (efx_dev_registered(efx))
431 netif_tx_unlock_bh(efx->net_dev); 402 netif_tx_unlock_bh(efx->net_dev);
432 403
@@ -439,7 +410,6 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
439 kfree_skb(skb); 410 kfree_skb(skb);
440 return -EPIPE; 411 return -EPIPE;
441 } 412 }
442 efx->net_dev->trans_start = jiffies;
443 } 413 }
444 414
445 return 0; 415 return 0;
@@ -527,7 +497,7 @@ efx_test_loopback(struct efx_tx_queue *tx_queue,
527 497
528 for (i = 0; i < 3; i++) { 498 for (i = 0; i < 3; i++) {
529 /* Determine how many packets to send */ 499 /* Determine how many packets to send */
530 state->packet_count = (efx->type->txd_ring_mask + 1) / 3; 500 state->packet_count = EFX_TXQ_SIZE / 3;
531 state->packet_count = min(1 << (i << 2), state->packet_count); 501 state->packet_count = min(1 << (i << 2), state->packet_count);
532 state->skbs = kzalloc(sizeof(state->skbs[0]) * 502 state->skbs = kzalloc(sizeof(state->skbs[0]) *
533 state->packet_count, GFP_KERNEL); 503 state->packet_count, GFP_KERNEL);
@@ -568,14 +538,49 @@ efx_test_loopback(struct efx_tx_queue *tx_queue,
568 return 0; 538 return 0;
569} 539}
570 540
541/* Wait for link up. On Falcon, we would prefer to rely on efx_monitor, but
542 * any contention on the mac lock (via e.g. efx_mac_mcast_work) causes it
543 * to delay and retry. Therefore, it's safer to just poll directly. Wait
544 * for link up and any faults to dissipate. */
545static int efx_wait_for_link(struct efx_nic *efx)
546{
547 struct efx_link_state *link_state = &efx->link_state;
548 int count;
549 bool link_up;
550
551 for (count = 0; count < 40; count++) {
552 schedule_timeout_uninterruptible(HZ / 10);
553
554 if (efx->type->monitor != NULL) {
555 mutex_lock(&efx->mac_lock);
556 efx->type->monitor(efx);
557 mutex_unlock(&efx->mac_lock);
558 } else {
559 struct efx_channel *channel = &efx->channel[0];
560 if (channel->work_pending)
561 efx_process_channel_now(channel);
562 }
563
564 mutex_lock(&efx->mac_lock);
565 link_up = link_state->up;
566 if (link_up)
567 link_up = !efx->mac_op->check_fault(efx);
568 mutex_unlock(&efx->mac_lock);
569
570 if (link_up)
571 return 0;
572 }
573
574 return -ETIMEDOUT;
575}
576
571static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests, 577static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
572 unsigned int loopback_modes) 578 unsigned int loopback_modes)
573{ 579{
574 enum efx_loopback_mode mode; 580 enum efx_loopback_mode mode;
575 struct efx_loopback_state *state; 581 struct efx_loopback_state *state;
576 struct efx_tx_queue *tx_queue; 582 struct efx_tx_queue *tx_queue;
577 bool link_up; 583 int rc = 0;
578 int count, rc = 0;
579 584
580 /* Set the port loopback_selftest member. From this point on 585 /* Set the port loopback_selftest member. From this point on
581 * all received packets will be dropped. Mark the state as 586 * all received packets will be dropped. Mark the state as
@@ -594,46 +599,23 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
594 599
595 /* Move the port into the specified loopback mode. */ 600 /* Move the port into the specified loopback mode. */
596 state->flush = true; 601 state->flush = true;
602 mutex_lock(&efx->mac_lock);
597 efx->loopback_mode = mode; 603 efx->loopback_mode = mode;
598 efx_reconfigure_port(efx); 604 rc = __efx_reconfigure_port(efx);
599 605 mutex_unlock(&efx->mac_lock);
600 /* Wait for the PHY to signal the link is up. Interrupts 606 if (rc) {
601 * are enabled for PHY's using LASI, otherwise we poll() 607 EFX_ERR(efx, "unable to move into %s loopback\n",
602 * quickly */ 608 LOOPBACK_MODE(efx));
603 count = 0; 609 goto out;
604 do { 610 }
605 struct efx_channel *channel = &efx->channel[0];
606 611
607 efx->phy_op->poll(efx); 612 rc = efx_wait_for_link(efx);
608 schedule_timeout_uninterruptible(HZ / 10); 613 if (rc) {
609 if (channel->work_pending)
610 efx_process_channel_now(channel);
611 /* Wait for PHY events to be processed */
612 flush_workqueue(efx->workqueue);
613 rmb();
614
615 /* We need both the phy and xaui links to be ok.
616 * rather than relying on the falcon_xmac irq/poll
617 * regime, just poll xaui directly */
618 link_up = efx->link_up;
619 if (link_up && EFX_IS10G(efx) &&
620 !falcon_xaui_link_ok(efx))
621 link_up = false;
622
623 } while ((++count < 20) && !link_up);
624
625 /* The link should now be up. If it isn't, there is no point
626 * in attempting a loopback test */
627 if (!link_up) {
628 EFX_ERR(efx, "loopback %s never came up\n", 614 EFX_ERR(efx, "loopback %s never came up\n",
629 LOOPBACK_MODE(efx)); 615 LOOPBACK_MODE(efx));
630 rc = -EIO;
631 goto out; 616 goto out;
632 } 617 }
633 618
634 EFX_LOG(efx, "link came up in %s loopback in %d iterations\n",
635 LOOPBACK_MODE(efx), count);
636
637 /* Test every TX queue */ 619 /* Test every TX queue */
638 efx_for_each_tx_queue(tx_queue, efx) { 620 efx_for_each_tx_queue(tx_queue, efx) {
639 state->offload_csum = (tx_queue->queue == 621 state->offload_csum = (tx_queue->queue ==
@@ -667,14 +649,13 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
667 enum efx_loopback_mode loopback_mode = efx->loopback_mode; 649 enum efx_loopback_mode loopback_mode = efx->loopback_mode;
668 int phy_mode = efx->phy_mode; 650 int phy_mode = efx->phy_mode;
669 enum reset_type reset_method = RESET_TYPE_INVISIBLE; 651 enum reset_type reset_method = RESET_TYPE_INVISIBLE;
670 struct ethtool_cmd ecmd;
671 struct efx_channel *channel; 652 struct efx_channel *channel;
672 int rc_test = 0, rc_reset = 0, rc; 653 int rc_test = 0, rc_reset = 0, rc;
673 654
674 /* Online (i.e. non-disruptive) testing 655 /* Online (i.e. non-disruptive) testing
675 * This checks interrupt generation, event delivery and PHY presence. */ 656 * This checks interrupt generation, event delivery and PHY presence. */
676 657
677 rc = efx_test_mdio(efx, tests); 658 rc = efx_test_phy_alive(efx, tests);
678 if (rc && !rc_test) 659 if (rc && !rc_test)
679 rc_test = rc; 660 rc_test = rc;
680 661
@@ -720,21 +701,21 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
720 mutex_unlock(&efx->mac_lock); 701 mutex_unlock(&efx->mac_lock);
721 702
722 /* free up all consumers of SRAM (including all the queues) */ 703 /* free up all consumers of SRAM (including all the queues) */
723 efx_reset_down(efx, reset_method, &ecmd); 704 efx_reset_down(efx, reset_method);
724 705
725 rc = efx_test_chip(efx, tests); 706 rc = efx_test_chip(efx, tests);
726 if (rc && !rc_test) 707 if (rc && !rc_test)
727 rc_test = rc; 708 rc_test = rc;
728 709
729 /* reset the chip to recover from the register test */ 710 /* reset the chip to recover from the register test */
730 rc_reset = falcon_reset_hw(efx, reset_method); 711 rc_reset = efx->type->reset(efx, reset_method);
731 712
732 /* Ensure that the phy is powered and out of loopback 713 /* Ensure that the phy is powered and out of loopback
733 * for the bist and loopback tests */ 714 * for the bist and loopback tests */
734 efx->phy_mode &= ~PHY_MODE_LOW_POWER; 715 efx->phy_mode &= ~PHY_MODE_LOW_POWER;
735 efx->loopback_mode = LOOPBACK_NONE; 716 efx->loopback_mode = LOOPBACK_NONE;
736 717
737 rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0); 718 rc = efx_reset_up(efx, reset_method, rc_reset == 0);
738 if (rc && !rc_reset) 719 if (rc && !rc_reset)
739 rc_reset = rc; 720 rc_reset = rc;
740 721
@@ -753,10 +734,12 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
753 rc_test = rc; 734 rc_test = rc;
754 735
755 /* restore the PHY to the previous state */ 736 /* restore the PHY to the previous state */
756 efx->loopback_mode = loopback_mode; 737 mutex_lock(&efx->mac_lock);
757 efx->phy_mode = phy_mode; 738 efx->phy_mode = phy_mode;
758 efx->port_inhibited = false; 739 efx->port_inhibited = false;
759 efx_ethtool_set_settings(efx->net_dev, &ecmd); 740 efx->loopback_mode = loopback_mode;
741 __efx_reconfigure_port(efx);
742 mutex_unlock(&efx->mac_lock);
760 743
761 return rc_test; 744 return rc_test;
762} 745}