| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /**************************************************************************** |
|---|
| 2 | 3 | * Driver for Solarflare network controllers and boards |
|---|
| 3 | 4 | * Copyright 2005-2006 Fen Systems Ltd. |
|---|
| 4 | 5 | * Copyright 2006-2012 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 | 6 | */ |
|---|
| 10 | 7 | |
|---|
| 11 | 8 | #include <linux/netdevice.h> |
|---|
| .. | .. |
|---|
| 21 | 18 | #include <linux/slab.h> |
|---|
| 22 | 19 | #include "net_driver.h" |
|---|
| 23 | 20 | #include "efx.h" |
|---|
| 21 | +#include "efx_common.h" |
|---|
| 22 | +#include "efx_channels.h" |
|---|
| 24 | 23 | #include "nic.h" |
|---|
| 24 | +#include "mcdi_port_common.h" |
|---|
| 25 | 25 | #include "selftest.h" |
|---|
| 26 | 26 | #include "workarounds.h" |
|---|
| 27 | 27 | |
|---|
| .. | .. |
|---|
| 68 | 68 | STRING_TABLE_LOOKUP(efx->interrupt_mode, efx_interrupt_mode) |
|---|
| 69 | 69 | |
|---|
| 70 | 70 | /** |
|---|
| 71 | | - * efx_loopback_state - persistent state during a loopback selftest |
|---|
| 71 | + * struct efx_loopback_state - persistent state during a loopback selftest |
|---|
| 72 | 72 | * @flush: Drop all packets in efx_loopback_rx_packet |
|---|
| 73 | 73 | * @packet_count: Number of packets being used in this test |
|---|
| 74 | 74 | * @skbs: An array of skbs transmitted |
|---|
| .. | .. |
|---|
| 100 | 100 | { |
|---|
| 101 | 101 | int rc = 0; |
|---|
| 102 | 102 | |
|---|
| 103 | | - if (efx->phy_op->test_alive) { |
|---|
| 104 | | - rc = efx->phy_op->test_alive(efx); |
|---|
| 105 | | - tests->phy_alive = rc ? -1 : 1; |
|---|
| 106 | | - } |
|---|
| 103 | + rc = efx_mcdi_phy_test_alive(efx); |
|---|
| 104 | + tests->phy_alive = rc ? -1 : 1; |
|---|
| 107 | 105 | |
|---|
| 108 | 106 | return rc; |
|---|
| 109 | 107 | } |
|---|
| .. | .. |
|---|
| 258 | 256 | { |
|---|
| 259 | 257 | int rc; |
|---|
| 260 | 258 | |
|---|
| 261 | | - if (!efx->phy_op->run_tests) |
|---|
| 262 | | - return 0; |
|---|
| 263 | | - |
|---|
| 264 | 259 | mutex_lock(&efx->mac_lock); |
|---|
| 265 | | - rc = efx->phy_op->run_tests(efx, tests->phy_ext, flags); |
|---|
| 260 | + rc = efx_mcdi_phy_run_tests(efx, tests->phy_ext, flags); |
|---|
| 266 | 261 | mutex_unlock(&efx->mac_lock); |
|---|
| 267 | 262 | if (rc == -EPERM) |
|---|
| 268 | 263 | rc = 0; |
|---|
| .. | .. |
|---|
| 446 | 441 | if (rc != NETDEV_TX_OK) { |
|---|
| 447 | 442 | netif_err(efx, drv, efx->net_dev, |
|---|
| 448 | 443 | "TX queue %d could not transmit packet %d of " |
|---|
| 449 | | - "%d in %s loopback test\n", tx_queue->queue, |
|---|
| 444 | + "%d in %s loopback test\n", tx_queue->label, |
|---|
| 450 | 445 | i + 1, state->packet_count, |
|---|
| 451 | 446 | LOOPBACK_MODE(efx)); |
|---|
| 452 | 447 | |
|---|
| .. | .. |
|---|
| 498 | 493 | netif_err(efx, drv, efx->net_dev, |
|---|
| 499 | 494 | "TX queue %d saw only %d out of an expected %d " |
|---|
| 500 | 495 | "TX completion events in %s loopback test\n", |
|---|
| 501 | | - tx_queue->queue, tx_done, state->packet_count, |
|---|
| 496 | + tx_queue->label, tx_done, state->packet_count, |
|---|
| 502 | 497 | LOOPBACK_MODE(efx)); |
|---|
| 503 | 498 | rc = -ETIMEDOUT; |
|---|
| 504 | 499 | /* Allow to fall through so we see the RX errors as well */ |
|---|
| .. | .. |
|---|
| 509 | 504 | netif_dbg(efx, drv, efx->net_dev, |
|---|
| 510 | 505 | "TX queue %d saw only %d out of an expected %d " |
|---|
| 511 | 506 | "received packets in %s loopback test\n", |
|---|
| 512 | | - tx_queue->queue, rx_good, state->packet_count, |
|---|
| 507 | + tx_queue->label, rx_good, state->packet_count, |
|---|
| 513 | 508 | LOOPBACK_MODE(efx)); |
|---|
| 514 | 509 | rc = -ETIMEDOUT; |
|---|
| 515 | 510 | /* Fall through */ |
|---|
| 516 | 511 | } |
|---|
| 517 | 512 | |
|---|
| 518 | 513 | /* Update loopback test structure */ |
|---|
| 519 | | - lb_tests->tx_sent[tx_queue->queue] += state->packet_count; |
|---|
| 520 | | - lb_tests->tx_done[tx_queue->queue] += tx_done; |
|---|
| 514 | + lb_tests->tx_sent[tx_queue->label] += state->packet_count; |
|---|
| 515 | + lb_tests->tx_done[tx_queue->label] += tx_done; |
|---|
| 521 | 516 | lb_tests->rx_good += rx_good; |
|---|
| 522 | 517 | lb_tests->rx_bad += rx_bad; |
|---|
| 523 | 518 | |
|---|
| .. | .. |
|---|
| 543 | 538 | state->flush = false; |
|---|
| 544 | 539 | |
|---|
| 545 | 540 | netif_dbg(efx, drv, efx->net_dev, |
|---|
| 546 | | - "TX queue %d testing %s loopback with %d packets\n", |
|---|
| 547 | | - tx_queue->queue, LOOPBACK_MODE(efx), |
|---|
| 541 | + "TX queue %d (hw %d) testing %s loopback with %d packets\n", |
|---|
| 542 | + tx_queue->label, tx_queue->queue, LOOPBACK_MODE(efx), |
|---|
| 548 | 543 | state->packet_count); |
|---|
| 549 | 544 | |
|---|
| 550 | 545 | efx_iterate_state(efx); |
|---|
| .. | .. |
|---|
| 571 | 566 | |
|---|
| 572 | 567 | netif_dbg(efx, drv, efx->net_dev, |
|---|
| 573 | 568 | "TX queue %d passed %s loopback test with a burst length " |
|---|
| 574 | | - "of %d packets\n", tx_queue->queue, LOOPBACK_MODE(efx), |
|---|
| 569 | + "of %d packets\n", tx_queue->label, LOOPBACK_MODE(efx), |
|---|
| 575 | 570 | state->packet_count); |
|---|
| 576 | 571 | |
|---|
| 577 | 572 | return 0; |
|---|
| .. | .. |
|---|
| 661 | 656 | |
|---|
| 662 | 657 | /* Test all enabled types of TX queue */ |
|---|
| 663 | 658 | efx_for_each_channel_tx_queue(tx_queue, channel) { |
|---|
| 664 | | - state->offload_csum = (tx_queue->queue & |
|---|
| 665 | | - EFX_TXQ_TYPE_OFFLOAD); |
|---|
| 659 | + state->offload_csum = (tx_queue->type & |
|---|
| 660 | + EFX_TXQ_TYPE_OUTER_CSUM); |
|---|
| 666 | 661 | rc = efx_test_loopback(tx_queue, |
|---|
| 667 | 662 | &tests->loopback[mode]); |
|---|
| 668 | 663 | if (rc) |
|---|
| .. | .. |
|---|
| 786 | 781 | cancel_delayed_work_sync(&efx->selftest_work); |
|---|
| 787 | 782 | } |
|---|
| 788 | 783 | |
|---|
| 789 | | -void efx_selftest_async_work(struct work_struct *data) |
|---|
| 784 | +static void efx_selftest_async_work(struct work_struct *data) |
|---|
| 790 | 785 | { |
|---|
| 791 | 786 | struct efx_nic *efx = container_of(data, struct efx_nic, |
|---|
| 792 | 787 | selftest_work.work); |
|---|
| .. | .. |
|---|
| 805 | 800 | channel->channel, cpu); |
|---|
| 806 | 801 | } |
|---|
| 807 | 802 | } |
|---|
| 803 | + |
|---|
| 804 | +void efx_selftest_async_init(struct efx_nic *efx) |
|---|
| 805 | +{ |
|---|
| 806 | + INIT_DELAYED_WORK(&efx->selftest_work, efx_selftest_async_work); |
|---|
| 807 | +} |
|---|