Commit 59bcaed5 authored by David S. Miller's avatar David S. Miller

Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next

Ben Hutchings says:

====================
An assortment of changes for Linux 3.14:

1. Merge the sfc fixes that you have already merged into net.git.
   (The branch point for those was such that this does not bring in any
   other changes.)
2. Reduce log level for a generally useless warning message, from
   Robert Stonehouse.
3. Include BISTs in ethtool offline self-test for EF10 and recover from
   BISTs initiated through other functions, from Jon Cooper.
4. Improve a sanity check on RX completions.
5. Avoid incrementing RX dropped count while the interface is down, from
   Jon Cooper.
6. Improve hardware sensor naming and log messages, from Edward Cree.
7. Log all unexpected errors returned by firmware, from Edward Cree.
8. Expose another NVRAM partition to userland.
9. Some refactoring of the PTP code in preparation for EF10 support.
10. Various minor cleanups.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0aac68f7 ac36baf8
......@@ -14,6 +14,7 @@
#include "mcdi_pcol.h"
#include "nic.h"
#include "workarounds.h"
#include "selftest.h"
#include <linux/in.h>
#include <linux/jhash.h>
#include <linux/wait.h>
......@@ -277,11 +278,17 @@ static int efx_ef10_probe(struct efx_nic *efx)
static int efx_ef10_free_vis(struct efx_nic *efx)
{
int rc = efx_mcdi_rpc(efx, MC_CMD_FREE_VIS, NULL, 0, NULL, 0, NULL);
MCDI_DECLARE_BUF_OUT_OR_ERR(outbuf, 0);
size_t outlen;
int rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FREE_VIS, NULL, 0,
outbuf, sizeof(outbuf), &outlen);
/* -EALREADY means nothing to free, so ignore */
if (rc == -EALREADY)
rc = 0;
if (rc)
efx_mcdi_display_error(efx, MC_CMD_FREE_VIS, 0, outbuf, outlen,
rc);
return rc;
}
......@@ -901,6 +908,7 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx)
return -EAGAIN;
/* Update derived statistics */
efx_nic_fix_nodesc_drop_stat(efx, &stats[EF10_STAT_rx_nodesc_drops]);
stats[EF10_STAT_rx_good_bytes] =
stats[EF10_STAT_rx_bytes] -
stats[EF10_STAT_rx_bytes_minus_good_bytes];
......@@ -1242,7 +1250,6 @@ static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
fail:
WARN_ON(true);
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
}
static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue)
......@@ -1256,7 +1263,7 @@ static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue)
MCDI_SET_DWORD(inbuf, FINI_TXQ_IN_INSTANCE,
tx_queue->queue);
rc = efx_mcdi_rpc(efx, MC_CMD_FINI_TXQ, inbuf, sizeof(inbuf),
rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_TXQ, inbuf, sizeof(inbuf),
outbuf, sizeof(outbuf), &outlen);
if (rc && rc != -EALREADY)
......@@ -1265,7 +1272,8 @@ static void efx_ef10_tx_fini(struct efx_tx_queue *tx_queue)
return;
fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
efx_mcdi_display_error(efx, MC_CMD_FINI_TXQ, MC_CMD_FINI_TXQ_IN_LEN,
outbuf, outlen, rc);
}
static void efx_ef10_tx_remove(struct efx_tx_queue *tx_queue)
......@@ -1480,14 +1488,9 @@ static void efx_ef10_rx_init(struct efx_rx_queue *rx_queue)
rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, inlen,
outbuf, sizeof(outbuf), &outlen);
if (rc)
goto fail;
WARN_ON(rc);
return;
fail:
WARN_ON(true);
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
}
static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue)
......@@ -1501,7 +1504,7 @@ static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue)
MCDI_SET_DWORD(inbuf, FINI_RXQ_IN_INSTANCE,
efx_rx_queue_index(rx_queue));
rc = efx_mcdi_rpc(efx, MC_CMD_FINI_RXQ, inbuf, sizeof(inbuf),
rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_RXQ, inbuf, sizeof(inbuf),
outbuf, sizeof(outbuf), &outlen);
if (rc && rc != -EALREADY)
......@@ -1510,7 +1513,8 @@ static void efx_ef10_rx_fini(struct efx_rx_queue *rx_queue)
return;
fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
efx_mcdi_display_error(efx, MC_CMD_FINI_RXQ, MC_CMD_FINI_RXQ_IN_LEN,
outbuf, outlen, rc);
}
static void efx_ef10_rx_remove(struct efx_rx_queue *rx_queue)
......@@ -1647,15 +1651,7 @@ static int efx_ef10_ev_init(struct efx_channel *channel)
rc = efx_mcdi_rpc(efx, MC_CMD_INIT_EVQ, inbuf, inlen,
outbuf, sizeof(outbuf), &outlen);
if (rc)
goto fail;
/* IRQ return is ignored */
return 0;
fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
return rc;
}
......@@ -1669,7 +1665,7 @@ static void efx_ef10_ev_fini(struct efx_channel *channel)
MCDI_SET_DWORD(inbuf, FINI_EVQ_IN_INSTANCE, channel->channel);
rc = efx_mcdi_rpc(efx, MC_CMD_FINI_EVQ, inbuf, sizeof(inbuf),
rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FINI_EVQ, inbuf, sizeof(inbuf),
outbuf, sizeof(outbuf), &outlen);
if (rc && rc != -EALREADY)
......@@ -1678,7 +1674,8 @@ static void efx_ef10_ev_fini(struct efx_channel *channel)
return;
fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
efx_mcdi_display_error(efx, MC_CMD_FINI_EVQ, MC_CMD_FINI_EVQ_IN_LEN,
outbuf, outlen, rc);
}
static void efx_ef10_ev_remove(struct efx_channel *channel)
......@@ -1765,6 +1762,8 @@ static int efx_ef10_handle_rx_event(struct efx_channel *channel,
((1 << ESF_DZ_RX_DSC_PTR_LBITS_WIDTH) - 1));
if (n_descs != rx_queue->scatter_n + 1) {
struct efx_ef10_nic_data *nic_data = efx->nic_data;
/* detect rx abort */
if (unlikely(n_descs == rx_queue->scatter_n)) {
WARN_ON(rx_bytes != 0);
......@@ -1772,10 +1771,13 @@ static int efx_ef10_handle_rx_event(struct efx_channel *channel,
return 0;
}
if (unlikely(rx_queue->scatter_n != 0)) {
/* Scattered packet completions cannot be
* merged, so something has gone wrong.
/* Check that RX completion merging is valid, i.e.
* the current firmware supports it and this is a
* non-scattered packet.
*/
if (!(nic_data->datapath_caps &
(1 << MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_LBN)) ||
rx_queue->scatter_n != 0 || rx_cont) {
efx_ef10_handle_rx_bad_lbits(
rx_queue, next_ptr_lbits,
(rx_queue->removed_count +
......@@ -1901,7 +1903,7 @@ static void efx_ef10_handle_driver_generated_event(struct efx_channel *channel,
* events, so efx_process_channel() won't refill the
* queue. Refill it here
*/
efx_fast_push_rx_descriptors(&channel->rx_queue);
efx_fast_push_rx_descriptors(&channel->rx_queue, true);
break;
default:
netif_err(efx, hw, efx->net_dev,
......@@ -2257,6 +2259,8 @@ static int efx_ef10_filter_push(struct efx_nic *efx,
outbuf, sizeof(outbuf), NULL);
if (rc == 0)
*handle = MCDI_QWORD(outbuf, FILTER_OP_OUT_HANDLE);
if (rc == -ENOSPC)
rc = -EBUSY; /* to match efx_farch_filter_insert() */
return rc;
}
......@@ -3195,6 +3199,87 @@ static int efx_ef10_mac_reconfigure(struct efx_nic *efx)
return efx_mcdi_set_mac(efx);
}
static int efx_ef10_start_bist(struct efx_nic *efx, u32 bist_type)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_START_BIST_IN_LEN);
MCDI_SET_DWORD(inbuf, START_BIST_IN_TYPE, bist_type);
return efx_mcdi_rpc(efx, MC_CMD_START_BIST, inbuf, sizeof(inbuf),
NULL, 0, NULL);
}
/* MC BISTs follow a different poll mechanism to phy BISTs.
* The BIST is done in the poll handler on the MC, and the MCDI command
* will block until the BIST is done.
*/
static int efx_ef10_poll_bist(struct efx_nic *efx)
{
int rc;
MCDI_DECLARE_BUF(outbuf, MC_CMD_POLL_BIST_OUT_LEN);
size_t outlen;
u32 result;
rc = efx_mcdi_rpc(efx, MC_CMD_POLL_BIST, NULL, 0,
outbuf, sizeof(outbuf), &outlen);
if (rc != 0)
return rc;
if (outlen < MC_CMD_POLL_BIST_OUT_LEN)
return -EIO;
result = MCDI_DWORD(outbuf, POLL_BIST_OUT_RESULT);
switch (result) {
case MC_CMD_POLL_BIST_PASSED:
netif_dbg(efx, hw, efx->net_dev, "BIST passed.\n");
return 0;
case MC_CMD_POLL_BIST_TIMEOUT:
netif_err(efx, hw, efx->net_dev, "BIST timed out\n");
return -EIO;
case MC_CMD_POLL_BIST_FAILED:
netif_err(efx, hw, efx->net_dev, "BIST failed.\n");
return -EIO;
default:
netif_err(efx, hw, efx->net_dev,
"BIST returned unknown result %u", result);
return -EIO;
}
}
static int efx_ef10_run_bist(struct efx_nic *efx, u32 bist_type)
{
int rc;
netif_dbg(efx, drv, efx->net_dev, "starting BIST type %u\n", bist_type);
rc = efx_ef10_start_bist(efx, bist_type);
if (rc != 0)
return rc;
return efx_ef10_poll_bist(efx);
}
static int
efx_ef10_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
{
int rc, rc2;
efx_reset_down(efx, RESET_TYPE_WORLD);
rc = efx_mcdi_rpc(efx, MC_CMD_ENABLE_OFFLINE_BIST,
NULL, 0, NULL, 0, NULL);
if (rc != 0)
goto out;
tests->memory = efx_ef10_run_bist(efx, MC_CMD_MC_MEM_BIST) ? -1 : 1;
tests->registers = efx_ef10_run_bist(efx, MC_CMD_REG_BIST) ? -1 : 1;
rc = efx_mcdi_reset(efx, RESET_TYPE_WORLD);
out:
rc2 = efx_reset_up(efx, RESET_TYPE_WORLD, rc == 0);
return rc ? rc : rc2;
}
#ifdef CONFIG_SFC_MTD
struct efx_ef10_nvram_type_info {
......@@ -3213,6 +3298,7 @@ static const struct efx_ef10_nvram_type_info efx_ef10_nvram_types[] = {
{ NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT1, 0, 1, "sfc_exp_rom_cfg" },
{ NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT2, 0, 2, "sfc_exp_rom_cfg" },
{ NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT3, 0, 3, "sfc_exp_rom_cfg" },
{ NVRAM_PARTITION_TYPE_LICENSE, 0, 0, "sfc_license" },
{ NVRAM_PARTITION_TYPE_PHY_MIN, 0xff, 0, "sfc_phy_fw" },
};
......@@ -3336,6 +3422,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.describe_stats = efx_ef10_describe_stats,
.update_stats = efx_ef10_update_stats,
.start_stats = efx_mcdi_mac_start_stats,
.pull_stats = efx_mcdi_mac_pull_stats,
.stop_stats = efx_mcdi_mac_stop_stats,
.set_id_led = efx_mcdi_set_id_led,
.push_irq_moderation = efx_ef10_push_irq_moderation,
......@@ -3345,7 +3432,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.get_wol = efx_ef10_get_wol,
.set_wol = efx_ef10_set_wol,
.resume_wol = efx_port_dummy_op_void,
/* TODO: test_chip */
.test_chip = efx_ef10_test_chip,
.test_nvram = efx_mcdi_nvram_test_all,
.mcdi_request = efx_ef10_mcdi_request,
.mcdi_poll_response = efx_ef10_mcdi_poll_response,
......
......@@ -83,6 +83,7 @@ const char *const efx_reset_type_names[] = {
[RESET_TYPE_DMA_ERROR] = "DMA_ERROR",
[RESET_TYPE_TX_SKIP] = "TX_SKIP",
[RESET_TYPE_MC_FAILURE] = "MC_FAILURE",
[RESET_TYPE_MC_BIST] = "MC_BIST",
};
/* Reset workqueue. If any NIC has a hardware failure then a reset will be
......@@ -91,6 +92,12 @@ const char *const efx_reset_type_names[] = {
*/
static struct workqueue_struct *reset_workqueue;
/* How often and how many times to poll for a reset while waiting for a
* BIST that another function started to complete.
*/
#define BIST_WAIT_DELAY_MS 100
#define BIST_WAIT_DELAY_COUNT 100
/**************************************************************************
*
* Configurable values
......@@ -246,7 +253,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget)
efx_channel_get_rx_queue(channel);
efx_rx_flush_packet(channel);
efx_fast_push_rx_descriptors(rx_queue);
efx_fast_push_rx_descriptors(rx_queue, true);
}
return spent;
......@@ -585,7 +592,7 @@ static void efx_start_datapath(struct efx_nic *efx)
EFX_MAX_FRAME_LEN(efx->net_dev->mtu) +
efx->type->rx_buffer_padding);
rx_buf_len = (sizeof(struct efx_rx_page_state) +
NET_IP_ALIGN + efx->rx_dma_len);
efx->rx_ip_align + efx->rx_dma_len);
if (rx_buf_len <= PAGE_SIZE) {
efx->rx_scatter = efx->type->always_rx_scatter;
efx->rx_buffer_order = 0;
......@@ -639,12 +646,16 @@ static void efx_start_datapath(struct efx_nic *efx)
efx_for_each_channel_rx_queue(rx_queue, channel) {
efx_init_rx_queue(rx_queue);
atomic_inc(&efx->active_queues);
efx_nic_generate_fill_event(rx_queue);
efx_stop_eventq(channel);
efx_fast_push_rx_descriptors(rx_queue, false);
efx_start_eventq(channel);
}
WARN_ON(channel->rx_pkt_n_frags);
}
efx_ptp_start_datapath(efx);
if (netif_device_present(efx->net_dev))
netif_tx_wake_all_queues(efx->net_dev);
}
......@@ -659,6 +670,8 @@ static void efx_stop_datapath(struct efx_nic *efx)
EFX_ASSERT_RESET_SERIALISED(efx);
BUG_ON(efx->port_enabled);
efx_ptp_stop_datapath(efx);
/* Stop RX refill */
efx_for_each_channel(channel, efx) {
efx_for_each_channel_rx_queue(rx_queue, channel)
......@@ -1047,18 +1060,23 @@ static void efx_start_port(struct efx_nic *efx)
mutex_lock(&efx->mac_lock);
efx->port_enabled = true;
/* efx_mac_work() might have been scheduled after efx_stop_port(),
* and then cancelled by efx_flush_all() */
/* Ensure MAC ingress/egress is enabled */
efx->type->reconfigure_mac(efx);
mutex_unlock(&efx->mac_lock);
}
/* Prevent efx_mac_work() and efx_monitor() from working */
/* Cancel work for MAC reconfiguration, periodic hardware monitoring
* and the async self-test, wait for them to finish and prevent them
* being scheduled again. This doesn't cover online resets, which
* should only be cancelled when removing the device.
*/
static void efx_stop_port(struct efx_nic *efx)
{
netif_dbg(efx, ifdown, efx->net_dev, "stop port\n");
EFX_ASSERT_RESET_SERIALISED(efx);
mutex_lock(&efx->mac_lock);
efx->port_enabled = false;
mutex_unlock(&efx->mac_lock);
......@@ -1066,6 +1084,10 @@ static void efx_stop_port(struct efx_nic *efx)
/* Serialise against efx_set_multicast_list() */
netif_addr_lock_bh(efx->net_dev);
netif_addr_unlock_bh(efx->net_dev);
cancel_delayed_work_sync(&efx->monitor_work);
efx_selftest_async_cancel(efx);
cancel_work_sync(&efx->mac_work);
}
static void efx_fini_port(struct efx_nic *efx)
......@@ -1671,18 +1693,10 @@ static void efx_start_all(struct efx_nic *efx)
}
efx->type->start_stats(efx);
}
/* Flush all delayed work. Should only be called when no more delayed work
* will be scheduled. This doesn't flush pending online resets (efx_reset),
* since we're holding the rtnl_lock at this point. */
static void efx_flush_all(struct efx_nic *efx)
{
/* Make sure the hardware monitor and event self-test are stopped */
cancel_delayed_work_sync(&efx->monitor_work);
efx_selftest_async_cancel(efx);
/* Stop scheduled port reconfigurations */
cancel_work_sync(&efx->mac_work);
efx->type->pull_stats(efx);
spin_lock_bh(&efx->stats_lock);
efx->type->update_stats(efx, NULL, NULL);
spin_unlock_bh(&efx->stats_lock);
}
/* Quiesce the hardware and software data path, and regular activity
......@@ -1698,12 +1712,16 @@ static void efx_stop_all(struct efx_nic *efx)
if (!efx->port_enabled)
return;
/* update stats before we go down so we can accurately count
* rx_nodesc_drops
*/
efx->type->pull_stats(efx);
spin_lock_bh(&efx->stats_lock);
efx->type->update_stats(efx, NULL, NULL);
spin_unlock_bh(&efx->stats_lock);
efx->type->stop_stats(efx);
efx_stop_port(efx);
/* Flush efx_mac_work(), refill_workqueue, monitor_work */
efx_flush_all(efx);
/* Stop the kernel transmit interface. This is only valid if
* the device is stopped or detached; otherwise the watchdog
* may fire immediately.
......@@ -2385,6 +2403,24 @@ int efx_try_recovery(struct efx_nic *efx)
return 0;
}
static void efx_wait_for_bist_end(struct efx_nic *efx)
{
int i;
for (i = 0; i < BIST_WAIT_DELAY_COUNT; ++i) {
if (efx_mcdi_poll_reboot(efx))
goto out;
msleep(BIST_WAIT_DELAY_MS);
}
netif_err(efx, drv, efx->net_dev, "Warning: No MC reboot after BIST mode\n");
out:
/* Either way unset the BIST flag. If we found no reboot we probably
* won't recover, but we should try.
*/
efx->mc_bist_for_other_fn = false;
}
/* The worker thread exists so that code that cannot sleep can
* schedule a reset for later.
*/
......@@ -2397,6 +2433,9 @@ static void efx_reset_work(struct work_struct *data)
pending = ACCESS_ONCE(efx->reset_pending);
method = fls(pending) - 1;
if (method == RESET_TYPE_MC_BIST)
efx_wait_for_bist_end(efx);
if ((method == RESET_TYPE_RECOVER_OR_DISABLE ||
method == RESET_TYPE_RECOVER_OR_ALL) &&
efx_try_recovery(efx))
......@@ -2435,6 +2474,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
case RESET_TYPE_WORLD:
case RESET_TYPE_DISABLE:
case RESET_TYPE_RECOVER_OR_DISABLE:
case RESET_TYPE_MC_BIST:
method = type;
netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n",
RESET_TYPE(method));
......@@ -2542,6 +2582,8 @@ static int efx_init_struct(struct efx_nic *efx,
efx->net_dev = net_dev;
efx->rx_prefix_size = efx->type->rx_prefix_size;
efx->rx_ip_align =
NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0;
efx->rx_packet_hash_offset =
efx->type->rx_hash_offset - efx->type->rx_prefix_size;
spin_lock_init(&efx->stats_lock);
......
......@@ -37,7 +37,7 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
void efx_remove_rx_queue(struct efx_rx_queue *rx_queue);
void efx_init_rx_queue(struct efx_rx_queue *rx_queue);
void efx_fini_rx_queue(struct efx_rx_queue *rx_queue);
void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue);
void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, bool atomic);
void efx_rx_slow_fill(unsigned long context);
void __efx_rx_packet(struct efx_channel *channel);
void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
......
......@@ -165,6 +165,7 @@ enum reset_type {
RESET_TYPE_DMA_ERROR,
RESET_TYPE_TX_SKIP,
RESET_TYPE_MC_FAILURE,
RESET_TYPE_MC_BIST,
RESET_TYPE_MAX,
};
......
......@@ -318,6 +318,8 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
"eventq.int", NULL);
}
efx_fill_test(n++, strings, data, &tests->memory,
"core", 0, "memory", NULL);
efx_fill_test(n++, strings, data, &tests->registers,
"core", 0, "registers", NULL);
......
......@@ -2593,6 +2593,14 @@ void falcon_start_nic_stats(struct efx_nic *efx)
spin_unlock_bh(&efx->stats_lock);
}
/* We don't acutally pull stats on falcon. Wait 10ms so that
* they arrive when we call this just after start_stats
*/
void falcon_pull_nic_stats(struct efx_nic *efx)
{
msleep(10);
}
void falcon_stop_nic_stats(struct efx_nic *efx)
{
struct falcon_nic_data *nic_data = efx->nic_data;
......@@ -2672,6 +2680,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
.describe_stats = falcon_describe_nic_stats,
.update_stats = falcon_update_nic_stats,
.start_stats = falcon_start_nic_stats,
.pull_stats = falcon_pull_nic_stats,
.stop_stats = falcon_stop_nic_stats,
.set_id_led = falcon_set_id_led,
.push_irq_moderation = falcon_push_irq_moderation,
......@@ -2765,6 +2774,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
.describe_stats = falcon_describe_nic_stats,
.update_stats = falcon_update_nic_stats,
.start_stats = falcon_start_nic_stats,
.pull_stats = falcon_pull_nic_stats,
.stop_stats = falcon_stop_nic_stats,
.set_id_led = falcon_set_id_led,
.push_irq_moderation = falcon_push_irq_moderation,
......
......@@ -1147,7 +1147,7 @@ static void efx_farch_handle_generated_event(struct efx_channel *channel,
/* The queue must be empty, so we won't receive any rx
* events, so efx_process_channel() won't refill the
* queue. Refill it here */
efx_fast_push_rx_descriptors(rx_queue);
efx_fast_push_rx_descriptors(rx_queue, true);
} else if (rx_queue && magic == EFX_CHANNEL_MAGIC_RX_DRAIN(rx_queue)) {
efx_farch_handle_drain_event(channel);
} else if (code == _EFX_CHANNEL_MAGIC_TX_DRAIN) {
......
This diff is collapsed.
......@@ -116,12 +116,19 @@ void efx_mcdi_fini(struct efx_nic *efx);
int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, const efx_dword_t *inbuf,
size_t inlen, efx_dword_t *outbuf, size_t outlen,
size_t *outlen_actual);
int efx_mcdi_rpc_quiet(struct efx_nic *efx, unsigned cmd,
const efx_dword_t *inbuf, size_t inlen,
efx_dword_t *outbuf, size_t outlen,
size_t *outlen_actual);
int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd,
const efx_dword_t *inbuf, size_t inlen);
int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen,
efx_dword_t *outbuf, size_t outlen,
size_t *outlen_actual);
int efx_mcdi_rpc_finish_quiet(struct efx_nic *efx, unsigned cmd,
size_t inlen, efx_dword_t *outbuf,
size_t outlen, size_t *outlen_actual);
typedef void efx_mcdi_async_completer(struct efx_nic *efx,
unsigned long cookie, int rc,
......@@ -131,6 +138,15 @@ int efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd,
const efx_dword_t *inbuf, size_t inlen, size_t outlen,
efx_mcdi_async_completer *complete,
unsigned long cookie);
int efx_mcdi_rpc_async_quiet(struct efx_nic *efx, unsigned int cmd,
const efx_dword_t *inbuf, size_t inlen,
size_t outlen,
efx_mcdi_async_completer *complete,
unsigned long cookie);
void efx_mcdi_display_error(struct efx_nic *efx, unsigned cmd,
size_t inlen, efx_dword_t *outbuf,
size_t outlen, int rc);
int efx_mcdi_poll_reboot(struct efx_nic *efx);
void efx_mcdi_mode_poll(struct efx_nic *efx);
......@@ -147,6 +163,8 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);
*/
#define MCDI_DECLARE_BUF(_name, _len) \
efx_dword_t _name[DIV_ROUND_UP(_len, 4)]
#define MCDI_DECLARE_BUF_OUT_OR_ERR(_name, _len) \
MCDI_DECLARE_BUF(_name, max_t(size_t, _len, 8))
#define _MCDI_PTR(_buf, _offset) \
((u8 *)(_buf) + (_offset))
#define MCDI_PTR(_buf, _field) \
......@@ -301,6 +319,7 @@ int efx_mcdi_set_mac(struct efx_nic *efx);
#define EFX_MC_STATS_GENERATION_INVALID ((__force __le64)(-1))
void efx_mcdi_mac_start_stats(struct efx_nic *efx);
void efx_mcdi_mac_stop_stats(struct efx_nic *efx);
void efx_mcdi_mac_pull_stats(struct efx_nic *efx);
bool efx_mcdi_mac_check_fault(struct efx_nic *efx);
enum reset_type efx_mcdi_map_reset_reason(enum reset_type reason);
int efx_mcdi_reset(struct efx_nic *efx, enum reset_type method);
......
......@@ -24,6 +24,15 @@ enum efx_hwmon_type {
EFX_HWMON_IN, /* voltage */
EFX_HWMON_CURR, /* current */
EFX_HWMON_POWER, /* power */
EFX_HWMON_TYPES_COUNT
};
static const char *const efx_hwmon_unit[EFX_HWMON_TYPES_COUNT] = {
[EFX_HWMON_TEMP] = " degC",
[EFX_HWMON_COOL] = " rpm", /* though nonsense for a heatsink */
[EFX_HWMON_IN] = " mV",
[EFX_HWMON_CURR] = " mA",
[EFX_HWMON_POWER] = " W",
};
static const struct {
......@@ -33,13 +42,13 @@ static const struct {
} efx_mcdi_sensor_type[] = {
#define SENSOR(name, label, hwmon_type, port) \
[MC_CMD_SENSOR_##name] = { label, EFX_HWMON_ ## hwmon_type, port }
SENSOR(CONTROLLER_TEMP, "Controller ext. temp.", TEMP, -1),
SENSOR(CONTROLLER_TEMP, "Controller board temp.", TEMP, -1),
SENSOR(PHY_COMMON_TEMP, "PHY temp.", TEMP, -1),
SENSOR(CONTROLLER_COOLING, "Controller cooling", COOL, -1),
SENSOR(CONTROLLER_COOLING, "Controller heat sink", COOL, -1),
SENSOR(PHY0_TEMP, "PHY temp.", TEMP, 0),
SENSOR(PHY0_COOLING, "PHY cooling", COOL, 0),
SENSOR(PHY0_COOLING, "PHY heat sink", COOL, 0),
SENSOR(PHY1_TEMP, "PHY temp.", TEMP, 1),
SENSOR(PHY1_COOLING, "PHY cooling", COOL, 1),
SENSOR(PHY1_COOLING, "PHY heat sink", COOL, 1),
SENSOR(IN_1V0, "1.0V supply", IN, -1),
SENSOR(IN_1V2, "1.2V supply", IN, -1),
SENSOR(IN_1V8, "1.8V supply", IN, -1),
......@@ -47,36 +56,42 @@ static const struct {
SENSOR(IN_3V3, "3.3V supply", IN, -1),
SENSOR(IN_12V0, "12.0V supply", IN, -1),
SENSOR(IN_1V2A, "1.2V analogue supply", IN, -1),
SENSOR(IN_VREF, "ref. voltage", IN, -1),
SENSOR(OUT_VAOE, "AOE power supply", IN, -1),
SENSOR(AOE_TEMP, "AOE temp.", TEMP, -1),
SENSOR(PSU_AOE_TEMP, "AOE PSU temp.", TEMP, -1),
SENSOR(PSU_TEMP, "Controller PSU temp.", TEMP, -1),
SENSOR(FAN_0, NULL, COOL, -1),
SENSOR(FAN_1, NULL, COOL, -1),
SENSOR(FAN_2, NULL, COOL, -1),
SENSOR(FAN_3, NULL, COOL, -1),
SENSOR(FAN_4, NULL, COOL, -1),
SENSOR(IN_VREF, "Ref. voltage", IN, -1),
SENSOR(OUT_VAOE, "AOE FPGA supply", IN, -1),
SENSOR(AOE_TEMP, "AOE FPGA temp.", TEMP, -1),
SENSOR(PSU_AOE_TEMP, "AOE regulator temp.", TEMP, -1),
SENSOR(PSU_TEMP, "Controller regulator temp.",
TEMP, -1),
SENSOR(FAN_0, "Fan 0", COOL, -1),
SENSOR(FAN_1, "Fan 1", COOL, -1),
SENSOR(FAN_2, "Fan 2", COOL, -1),
SENSOR(FAN_3, "Fan 3", COOL, -1),
SENSOR(FAN_4, "Fan 4", COOL, -1),
SENSOR(IN_VAOE, "AOE input supply", IN, -1),
SENSOR(OUT_IAOE, "AOE output current", CURR, -1),
SENSOR(IN_IAOE, "AOE input current", CURR, -1),
SENSOR(NIC_POWER, "Board power use", POWER, -1),
SENSOR(IN_0V9, "0.9V supply", IN, -1),
SENSOR(IN_I0V9, "0.9V input current", CURR, -1),
SENSOR(IN_I1V2, "1.2V input current", CURR, -1),
SENSOR(IN_0V9_ADC, "0.9V supply (at ADC)", IN, -1),
SENSOR(CONTROLLER_2_TEMP, "Controller ext. temp. 2", TEMP, -1),
SENSOR(VREG_INTERNAL_TEMP, "Voltage regulator temp.", TEMP, -1),
SENSOR(IN_I0V9, "0.9V supply current", CURR, -1),
SENSOR(IN_I1V2, "1.2V supply current", CURR, -1),
SENSOR(IN_0V9_ADC, "0.9V supply (ext. ADC)", IN, -1),
SENSOR(CONTROLLER_2_TEMP, "Controller board temp. 2", TEMP, -1),
SENSOR(VREG_INTERNAL_TEMP, "Regulator die temp.", TEMP, -1),
SENSOR(VREG_0V9_TEMP, "0.9V regulator temp.", TEMP, -1),
SENSOR(VREG_1V2_TEMP, "1.2V regulator temp.", TEMP, -1),
SENSOR(CONTROLLER_VPTAT, "Controller int. temp. raw", IN, -1),
SENSOR(CONTROLLER_INTERNAL_TEMP, "Controller int. temp.", TEMP, -1),
SENSOR(CONTROLLER_VPTAT,
"Controller PTAT voltage (int. ADC)", IN, -1),
SENSOR(CONTROLLER_INTERNAL_TEMP,
"Controller die temp. (int. ADC)", TEMP, -1),
SENSOR(CONTROLLER_VPTAT_EXTADC,
"Controller int. temp. raw (at ADC)", IN, -1),
"Controller PTAT voltage (ext. ADC)", IN, -1),
SENSOR(CONTROLLER_INTERNAL_TEMP_EXTADC,
"Controller int. temp. (via ADC)", TEMP, -1),
"Controller die temp. (ext. ADC)", TEMP, -1),
SENSOR(AMBIENT_TEMP, "Ambient temp.", TEMP, -1),
SENSOR(AIRFLOW, "Air flow raw", IN, -1),
SENSOR(VDD08D_VSS08D_CSR, "0.9V die (int. ADC)", IN, -1),
SENSOR(VDD08D_VSS08D_CSR_EXTADC, "0.9V die (ext. ADC)", IN, -1),
SENSOR(HOTPOINT_TEMP, "Controller board temp. (hotpoint)", TEMP, -1),
#undef SENSOR
};
......@@ -91,7 +106,8 @@ static const char *const sensor_status_names[] = {
void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev)
{
unsigned int type, state, value;
const char *name = NULL, *state_txt;
enum efx_hwmon_type hwmon_type = EFX_HWMON_UNKNOWN;
const char *name = NULL, *state_txt, *unit;
type = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR);
state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE);
......@@ -99,16 +115,22 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev)
/* Deal gracefully with the board having more drivers than we
* know about, but do not expect new sensor states. */
if (type < ARRAY_SIZE(efx_mcdi_sensor_type))
if (type < ARRAY_SIZE(efx_mcdi_sensor_type)) {
name = efx_mcdi_sensor_type[type].label;
hwmon_type = efx_mcdi_sensor_type[type].hwmon_type;
}
if (!name)
name = "No sensor name available";
EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names));
state_txt = sensor_status_names[state];
EFX_BUG_ON_PARANOID(hwmon_type >= EFX_HWMON_TYPES_COUNT);
unit = efx_hwmon_unit[hwmon_type];
if (!unit)
unit = "";
netif_err(efx, hw, efx->net_dev,
"Sensor %d (%s) reports condition '%s' for raw value %d\n",
type, name, state_txt, value);
"Sensor %d (%s) reports condition '%s' for value %d%s\n",
type, name, state_txt, value, unit);
}
#ifdef CONFIG_SFC_MCDI_MON
......
This diff is collapsed.
......@@ -90,13 +90,6 @@ static int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities,
rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf),
NULL, 0, NULL);
if (rc)
goto fail;
return 0;
fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
return rc;
}
......@@ -143,17 +136,13 @@ static int efx_mcdi_mdio_read(struct net_device *net_dev,
rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_READ, inbuf, sizeof(inbuf),
outbuf, sizeof(outbuf), &outlen);
if (rc)
goto fail;
return rc;
if (MCDI_DWORD(outbuf, MDIO_READ_OUT_STATUS) !=
MC_CMD_MDIO_STATUS_GOOD)
return -EIO;
return (u16)MCDI_DWORD(outbuf, MDIO_READ_OUT_VALUE);
fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
return rc;
}
static int efx_mcdi_mdio_write(struct net_device *net_dev,
......@@ -174,17 +163,13 @@ static int efx_mcdi_mdio_write(struct net_device *net_dev,
rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_WRITE, inbuf, sizeof(inbuf),
outbuf, sizeof(outbuf), &outlen);
if (rc)
goto fail;
return rc;
if (MCDI_DWORD(outbuf, MDIO_WRITE_OUT_STATUS) !=
MC_CMD_MDIO_STATUS_GOOD)
return -EIO;
return 0;
fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
return rc;
}
static u32 mcdi_to_ethtool_cap(u32 media, u32 cap)
......@@ -487,17 +472,14 @@ static bool efx_mcdi_phy_poll(struct efx_nic *efx)
rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
outbuf, sizeof(outbuf), NULL);
if (rc) {
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
__func__, rc);
if (rc)
efx->link_state.up = false;
} else {
else
efx_mcdi_phy_decode_link(
efx, &efx->link_state,
MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
}
return !efx_link_state_equal(&efx->link_state, &old_state);
}
......@@ -531,11 +513,8 @@ static void efx_mcdi_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *e
BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
outbuf, sizeof(outbuf), NULL);
if (rc) {
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
__func__, rc);
if (rc)
return;
}
ecmd->lp_advertising =
mcdi_to_ethtool_cap(phy_cfg->media,
MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP));
......@@ -918,21 +897,29 @@ bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
outbuf, sizeof(outbuf), &outlength);
if (rc) {
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
__func__, rc);
if (rc)
return true;
}
return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0;
}
static int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
u32 dma_len, int enable, int clear)
enum efx_stats_action {
EFX_STATS_ENABLE,
EFX_STATS_DISABLE,
EFX_STATS_PULL,
};
static int efx_mcdi_mac_stats(struct efx_nic *efx,
enum efx_stats_action action, int clear)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
int rc;
int period = enable ? 1000 : 0;
int change = action == EFX_STATS_PULL ? 0 : 1;
int enable = action == EFX_STATS_ENABLE ? 1 : 0;
int period = action == EFX_STATS_ENABLE ? 1000 : 0;
dma_addr_t dma_addr = efx->stats_buffer.dma_addr;
u32 dma_len = action != EFX_STATS_DISABLE ?
MC_CMD_MAC_NSTATS * sizeof(u64) : 0;
BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
......@@ -940,8 +927,8 @@ static int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD,
MAC_STATS_IN_DMA, !!enable,
MAC_STATS_IN_CLEAR, clear,
MAC_STATS_IN_PERIODIC_CHANGE, 1,
MAC_STATS_IN_PERIODIC_ENABLE, !!enable,
MAC_STATS_IN_PERIODIC_CHANGE, change,
MAC_STATS_IN_PERIODIC_ENABLE, enable,
MAC_STATS_IN_PERIODIC_CLEAR, 0,
MAC_STATS_IN_PERIODIC_NOEVENT, 1,
MAC_STATS_IN_PERIOD_MS, period);
......@@ -949,14 +936,6 @@ static int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
NULL, 0, NULL);
if (rc)
goto fail;
return 0;
fail:
netif_err(efx, hw, efx->net_dev, "%s: %s failed rc=%d\n",
__func__, enable ? "enable" : "disable", rc);
return rc;
}
......@@ -966,13 +945,29 @@ void efx_mcdi_mac_start_stats(struct efx_nic *efx)
dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID;
efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr,
MC_CMD_MAC_NSTATS * sizeof(u64), 1, 0);
efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0);
}
void efx_mcdi_mac_stop_stats(struct efx_nic *efx)
{
efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr, 0, 0, 0);
efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0);
}
#define EFX_MAC_STATS_WAIT_US 100
#define EFX_MAC_STATS_WAIT_ATTEMPTS 10
void efx_mcdi_mac_pull_stats(struct efx_nic *efx)
{
__le64 *dma_stats = efx->stats_buffer.addr;
int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS;
dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID;
efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0);
while (dma_stats[MC_CMD_MAC_GENERATION_END] ==
EFX_MC_STATS_GENERATION_INVALID &&
attempts-- != 0)
udelay(EFX_MAC_STATS_WAIT_US);
}
int efx_mcdi_port_probe(struct efx_nic *efx)
......@@ -1003,7 +998,7 @@ int efx_mcdi_port_probe(struct efx_nic *efx)
efx->stats_buffer.addr,
(u64)virt_to_phys(efx->stats_buffer.addr));
efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr, 0, 0, 1);
efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 1);
return 0;
}
......
......@@ -683,6 +683,8 @@ struct vfdi_status;
* @n_channels: Number of channels in use
* @n_rx_channels: Number of channels used for RX (= number of RX queues)
* @n_tx_channels: Number of channels used for TX
* @rx_ip_align: RX DMA address offset to have IP header aligned in
* in accordance with NET_IP_ALIGN
* @rx_dma_len: Current maximum RX DMA length
* @rx_buffer_order: Order (log2) of number of pages for each RX buffer
* @rx_buffer_truesize: Amortised allocation size of an RX buffer,
......@@ -816,6 +818,7 @@ struct efx_nic {
unsigned rss_spread;
unsigned tx_channel_offset;
unsigned n_tx_channels;
unsigned int rx_ip_align;
unsigned int rx_dma_len;
unsigned int rx_buffer_order;
unsigned int rx_buffer_truesize;
......@@ -849,10 +852,14 @@ struct efx_nic {
struct work_struct mac_work;
bool port_enabled;
bool mc_bist_for_other_fn;
bool port_initialized;
struct net_device *net_dev;
struct efx_buffer stats_buffer;
u64 rx_nodesc_drops_total;
u64 rx_nodesc_drops_while_down;
bool rx_nodesc_drops_prev_state;
unsigned int phy_type;
const struct efx_phy_operations *phy_op;
......@@ -956,6 +963,7 @@ struct efx_mtd_partition {
* @update_stats: Update statistics not provided by event handling.
* Either argument may be %NULL.
* @start_stats: Start the regular fetching of statistics
* @pull_stats: Pull stats from the NIC and wait until they arrive.
* @stop_stats: Stop the regular fetching of statistics
* @set_id_led: Set state of identifying LED or revert to automatic function
* @push_irq_moderation: Apply interrupt moderation value
......@@ -1074,6 +1082,7 @@ struct efx_nic_type {
size_t (*update_stats)(struct efx_nic *efx, u64 *full_stats,
struct rtnl_link_stats64 *core_stats);
void (*start_stats)(struct efx_nic *efx);
void (*pull_stats)(struct efx_nic *efx);
void (*stop_stats)(struct efx_nic *efx);
void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode);
void (*push_irq_moderation)(struct efx_channel *channel);
......
......@@ -519,3 +519,15 @@ void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count,
}
}
}
void efx_nic_fix_nodesc_drop_stat(struct efx_nic *efx, u64 *rx_nodesc_drops)
{
/* if down, or this is the first update after coming up */
if (!(efx->net_dev->flags & IFF_UP) || !efx->rx_nodesc_drops_prev_state)
efx->rx_nodesc_drops_while_down +=
*rx_nodesc_drops - efx->rx_nodesc_drops_total;
efx->rx_nodesc_drops_total = *rx_nodesc_drops;
efx->rx_nodesc_drops_prev_state = !!(efx->net_dev->flags & IFF_UP);
*rx_nodesc_drops -= efx->rx_nodesc_drops_while_down;
}
......@@ -554,13 +554,17 @@ int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf,
bool spoofchk);
struct ethtool_ts_info;
void efx_ptp_probe(struct efx_nic *efx);
int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel);
void efx_ptp_defer_probe_with_channel(struct efx_nic *efx);
void efx_ptp_remove(struct efx_nic *efx);
int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr);
int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr);
void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
void efx_ptp_start_datapath(struct efx_nic *efx);
void efx_ptp_stop_datapath(struct efx_nic *efx);
extern const struct efx_nic_type falcon_a1_nic_type;
extern const struct efx_nic_type falcon_b0_nic_type;
......@@ -773,6 +777,7 @@ size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count,
void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count,
const unsigned long *mask, u64 *stats,
const void *dma_buf, bool accumulate);
void efx_nic_fix_nodesc_drop_stat(struct efx_nic *efx, u64 *stat);
#define EFX_MAX_FLUSH_TIME 5000
......
This diff is collapsed.
......@@ -94,7 +94,7 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx,
void efx_rx_config_page_split(struct efx_nic *efx)
{
efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN,
efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + efx->rx_ip_align,
EFX_RX_BUF_ALIGNMENT);
efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 :
((PAGE_SIZE - sizeof(struct efx_rx_page_state)) /
......@@ -149,7 +149,7 @@ static struct page *efx_reuse_page(struct efx_rx_queue *rx_queue)
* 0 on success. If a single page can be used for multiple buffers,
* then the page will either be inserted fully, or not at all.
*/
static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue)
static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue, bool atomic)
{
struct efx_nic *efx = rx_queue->efx;
struct efx_rx_buffer *rx_buf;
......@@ -163,7 +163,8 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue)
do {
page = efx_reuse_page(rx_queue);
if (page == NULL) {
page = alloc_pages(__GFP_COLD | __GFP_COMP | GFP_ATOMIC,
page = alloc_pages(__GFP_COLD | __GFP_COMP |
(atomic ? GFP_ATOMIC : GFP_KERNEL),
efx->rx_buffer_order);
if (unlikely(page == NULL))
return -ENOMEM;
......@@ -189,9 +190,9 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue)
do {
index = rx_queue->added_count & rx_queue->ptr_mask;
rx_buf = efx_rx_buffer(rx_queue, index);
rx_buf->dma_addr = dma_addr + NET_IP_ALIGN;
rx_buf->dma_addr = dma_addr + efx->rx_ip_align;
rx_buf->page = page;
rx_buf->page_offset = page_offset + NET_IP_ALIGN;
rx_buf->page_offset = page_offset + efx->rx_ip_align;
rx_buf->len = efx->rx_dma_len;
rx_buf->flags = 0;
++rx_queue->added_count;
......@@ -321,7 +322,7 @@ static void efx_discard_rx_packet(struct efx_channel *channel,
* this means this function must run from the NAPI handler, or be called
* when NAPI is disabled.
*/
void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, bool atomic)
{
struct efx_nic *efx = rx_queue->efx;
unsigned int fill_level, batch_size;
......@@ -354,7 +355,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
do {
rc = efx_init_rx_buffers(rx_queue);
rc = efx_init_rx_buffers(rx_queue, atomic);
if (unlikely(rc)) {
/* Ensure that we don't leave the rx queue empty */
if (rx_queue->added_count == rx_queue->removed_count)
......
......@@ -722,7 +722,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
return rc_reset;
}
if ((tests->registers < 0) && !rc_test)
if ((tests->memory < 0 || tests->registers < 0) && !rc_test)
rc_test = -EIO;
}
......
......@@ -38,6 +38,7 @@ struct efx_self_tests {
int eventq_dma[EFX_MAX_CHANNELS];
int eventq_int[EFX_MAX_CHANNELS];
/* offline tests */
int memory;
int registers;
int phy_ext[EFX_MAX_PHY_TESTS];
struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1];
......
......@@ -259,7 +259,7 @@ static int siena_probe_nic(struct efx_nic *efx)
goto fail5;
efx_sriov_probe(efx);
efx_ptp_probe(efx);
efx_ptp_defer_probe_with_channel(efx);
return 0;
......@@ -458,6 +458,8 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
return -EAGAIN;
/* Update derived statistics */
efx_nic_fix_nodesc_drop_stat(efx,
&stats[SIENA_STAT_rx_nodesc_drop_cnt]);
efx_update_diff_stat(&stats[SIENA_STAT_tx_good_bytes],
stats[SIENA_STAT_tx_bytes] -
stats[SIENA_STAT_tx_bad_bytes]);
......@@ -878,6 +880,7 @@ const struct efx_nic_type siena_a0_nic_type = {
.describe_stats = siena_describe_nic_stats,
.update_stats = siena_update_nic_stats,
.start_stats = efx_mcdi_mac_start_stats,
.pull_stats = efx_mcdi_mac_pull_stats,
.stop_stats = efx_mcdi_mac_stop_stats,
.set_id_led = efx_mcdi_set_id_led,
.push_irq_moderation = siena_push_irq_moderation,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment