Commit d853f111 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:

====================
1. Refactoring and cleanup in preparation for new hardware support.
2. Some bug fixes for firmware completion handling.  (They're not known
to cause real problems, otherwise I'd be submitting these for net and
stable.)
3. Update to the firmware protocol (MCDI) definitions.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b05930f5 f76fe120
sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \
sfc-y += efx.o nic.o farch.o falcon.o siena.o tx.o rx.o \
filter.o \
selftest.o ethtool.o qt202x_phy.o mdio_10g.o \
tenxpress.o txc43128_phy.o falcon_boards.o \
mcdi.o mcdi_port.o mcdi_mon.o ptp.o
......
This diff is collapsed.
......@@ -23,7 +23,6 @@ extern void efx_remove_tx_queue(struct efx_tx_queue *tx_queue);
extern void efx_init_tx_queue(struct efx_tx_queue *tx_queue);
extern void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue);
extern void efx_fini_tx_queue(struct efx_tx_queue *tx_queue);
extern void efx_release_tx_buffers(struct efx_tx_queue *tx_queue);
extern netdev_tx_t
efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev);
extern netdev_tx_t
......@@ -109,7 +108,6 @@ static inline void efx_filter_rfs_expire(struct efx_channel *channel) {}
/* Channels */
extern int efx_channel_dummy_op_int(struct efx_channel *channel);
extern void efx_channel_dummy_op_void(struct efx_channel *channel);
extern void efx_process_channel_now(struct efx_channel *channel);
extern int
efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries);
......@@ -155,7 +153,6 @@ static inline void efx_schedule_channel(struct efx_channel *channel)
netif_vdbg(channel->efx, intr, channel->efx->net_dev,
"channel %d scheduling NAPI poll on CPU%d\n",
channel->channel, raw_smp_processor_id());
channel->work_pending = true;
napi_schedule(&channel->napi_str);
}
......
......@@ -21,7 +21,7 @@
#include "efx.h"
#include "spi.h"
#include "nic.h"
#include "regs.h"
#include "farch_regs.h"
#include "io.h"
#include "phy.h"
#include "workarounds.h"
......@@ -336,7 +336,7 @@ static void falcon_prepare_flush(struct efx_nic *efx)
*
* NB most hardware supports MSI interrupts
*/
inline void falcon_irq_ack_a1(struct efx_nic *efx)
static inline void falcon_irq_ack_a1(struct efx_nic *efx)
{
efx_dword_t reg;
......@@ -346,7 +346,7 @@ inline void falcon_irq_ack_a1(struct efx_nic *efx)
}
irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
{
struct efx_nic *efx = dev_id;
efx_oword_t *int_ker = efx->irq_status.addr;
......@@ -367,10 +367,13 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
"IRQ %d on CPU %d status " EFX_OWORD_FMT "\n",
irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker));
if (!likely(ACCESS_ONCE(efx->irq_soft_enabled)))
return IRQ_HANDLED;
/* Check to see if we have a serious error condition */
syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);
if (unlikely(syserr))
return efx_nic_fatal_interrupt(efx);
return efx_farch_fatal_interrupt(efx);
/* Determine interrupting queues, clear interrupt status
* register and acknowledge the device interrupt.
......@@ -1418,7 +1421,7 @@ static int falcon_probe_port(struct efx_nic *efx)
/* Allocate buffer for stats */
rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
FALCON_MAC_STATS_SIZE);
FALCON_MAC_STATS_SIZE, GFP_KERNEL);
if (rc)
return rc;
netif_dbg(efx, probe, efx->net_dev,
......@@ -1555,7 +1558,7 @@ static int falcon_test_nvram(struct efx_nic *efx)
return falcon_read_nvram(efx, NULL);
}
static const struct efx_nic_register_test falcon_b0_register_tests[] = {
static const struct efx_farch_register_test falcon_b0_register_tests[] = {
{ FR_AZ_ADR_REGION,
EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) },
{ FR_AZ_RX_CFG,
......@@ -1615,8 +1618,8 @@ falcon_b0_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
efx_reset_down(efx, reset_method);
tests->registers =
efx_nic_test_registers(efx, falcon_b0_register_tests,
ARRAY_SIZE(falcon_b0_register_tests))
efx_farch_test_registers(efx, falcon_b0_register_tests,
ARRAY_SIZE(falcon_b0_register_tests))
? -1 : 1;
rc = falcon_reset_hw(efx, reset_method);
......@@ -1981,7 +1984,7 @@ static int falcon_probe_nic(struct efx_nic *efx)
rc = -ENODEV;
if (efx_nic_fpga_ver(efx) != 0) {
if (efx_farch_fpga_ver(efx) != 0) {
netif_err(efx, probe, efx->net_dev,
"Falcon FPGA not supported\n");
goto fail1;
......@@ -2035,7 +2038,8 @@ static int falcon_probe_nic(struct efx_nic *efx)
}
/* Allocate memory for INT_KER */
rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t));
rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t),
GFP_KERNEL);
if (rc)
goto fail4;
BUG_ON(efx->irq_status.dma_addr & 0x0f);
......@@ -2214,7 +2218,7 @@ static int falcon_init_nic(struct efx_nic *efx)
efx_writeo(efx, &temp, FR_BZ_DP_CTRL);
}
efx_nic_init_common(efx);
efx_farch_init_common(efx);
return 0;
}
......@@ -2339,7 +2343,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
.remove = falcon_remove_nic,
.init = falcon_init_nic,
.dimension_resources = falcon_dimension_resources,
.fini = efx_port_dummy_op_void,
.fini = falcon_irq_ack_a1,
.monitor = falcon_monitor,
.map_reset_reason = falcon_map_reset_reason,
.map_reset_flags = falcon_map_reset_flags,
......@@ -2347,6 +2351,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
.probe_port = falcon_probe_port,
.remove_port = falcon_remove_port,
.handle_global_event = falcon_handle_global_event,
.fini_dmaq = efx_farch_fini_dmaq,
.prepare_flush = falcon_prepare_flush,
.finish_flush = efx_port_dummy_op_void,
.update_stats = falcon_update_nic_stats,
......@@ -2362,6 +2367,28 @@ const struct efx_nic_type falcon_a1_nic_type = {
.set_wol = falcon_set_wol,
.resume_wol = efx_port_dummy_op_void,
.test_nvram = falcon_test_nvram,
.irq_enable_master = efx_farch_irq_enable_master,
.irq_test_generate = efx_farch_irq_test_generate,
.irq_disable_non_ev = efx_farch_irq_disable_master,
.irq_handle_msi = efx_farch_msi_interrupt,
.irq_handle_legacy = falcon_legacy_interrupt_a1,
.tx_probe = efx_farch_tx_probe,
.tx_init = efx_farch_tx_init,
.tx_remove = efx_farch_tx_remove,
.tx_write = efx_farch_tx_write,
.rx_push_indir_table = efx_farch_rx_push_indir_table,
.rx_probe = efx_farch_rx_probe,
.rx_init = efx_farch_rx_init,
.rx_remove = efx_farch_rx_remove,
.rx_write = efx_farch_rx_write,
.rx_defer_refill = efx_farch_rx_defer_refill,
.ev_probe = efx_farch_ev_probe,
.ev_init = efx_farch_ev_init,
.ev_fini = efx_farch_ev_fini,
.ev_remove = efx_farch_ev_remove,
.ev_process = efx_farch_ev_process,
.ev_read_ack = efx_farch_ev_read_ack,
.ev_test_generate = efx_farch_ev_test_generate,
.revision = EFX_REV_FALCON_A1,
.mem_map_size = 0x20000,
......@@ -2377,6 +2404,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
.phys_addr_channels = 4,
.timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH,
.offload_features = NETIF_F_IP_CSUM,
.mcdi_max_ver = -1,
};
const struct efx_nic_type falcon_b0_nic_type = {
......@@ -2392,6 +2420,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
.probe_port = falcon_probe_port,
.remove_port = falcon_remove_port,
.handle_global_event = falcon_handle_global_event,
.fini_dmaq = efx_farch_fini_dmaq,
.prepare_flush = falcon_prepare_flush,
.finish_flush = efx_port_dummy_op_void,
.update_stats = falcon_update_nic_stats,
......@@ -2408,6 +2437,28 @@ const struct efx_nic_type falcon_b0_nic_type = {
.resume_wol = efx_port_dummy_op_void,
.test_chip = falcon_b0_test_chip,
.test_nvram = falcon_test_nvram,
.irq_enable_master = efx_farch_irq_enable_master,
.irq_test_generate = efx_farch_irq_test_generate,
.irq_disable_non_ev = efx_farch_irq_disable_master,
.irq_handle_msi = efx_farch_msi_interrupt,
.irq_handle_legacy = efx_farch_legacy_interrupt,
.tx_probe = efx_farch_tx_probe,
.tx_init = efx_farch_tx_init,
.tx_remove = efx_farch_tx_remove,
.tx_write = efx_farch_tx_write,
.rx_push_indir_table = efx_farch_rx_push_indir_table,
.rx_probe = efx_farch_rx_probe,
.rx_init = efx_farch_rx_init,
.rx_remove = efx_farch_rx_remove,
.rx_write = efx_farch_rx_write,
.rx_defer_refill = efx_farch_rx_defer_refill,
.ev_probe = efx_farch_ev_probe,
.ev_init = efx_farch_ev_init,
.ev_fini = efx_farch_ev_fini,
.ev_remove = efx_farch_ev_remove,
.ev_process = efx_farch_ev_process,
.ev_read_ack = efx_farch_ev_read_ack,
.ev_test_generate = efx_farch_ev_test_generate,
.revision = EFX_REV_FALCON_B0,
/* Map everything up to and including the RSS indirection
......@@ -2431,5 +2482,6 @@ const struct efx_nic_type falcon_b0_nic_type = {
* channels */
.timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH,
.offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE,
.mcdi_max_ver = -1,
};
This diff is collapsed.
......@@ -8,8 +8,8 @@
* by the Free Software Foundation, incorporated herein by reference.
*/
#ifndef EFX_REGS_H
#define EFX_REGS_H
#ifndef EFX_FARCH_REGS_H
#define EFX_FARCH_REGS_H
/*
* Falcon hardware architecture definitions have a name prefix following
......@@ -2925,4 +2925,4 @@
#define FSF_AZ_DRV_GEN_EV_MAGIC_LBN 0
#define FSF_AZ_DRV_GEN_EV_MAGIC_WIDTH 32
#endif /* EFX_REGS_H */
#endif /* EFX_FARCH_REGS_H */
......@@ -13,7 +13,7 @@
#include "filter.h"
#include "io.h"
#include "nic.h"
#include "regs.h"
#include "farch_regs.h"
/* "Fudge factors" - difference between programmed value and actual depth.
* Due to pipelined implementation we need to program H/W with a value that
......
This diff is collapsed.
......@@ -11,14 +11,14 @@
#define EFX_MCDI_H
/**
* enum efx_mcdi_state
* enum efx_mcdi_state - MCDI request handling state
* @MCDI_STATE_QUIESCENT: No pending MCDI requests. If the caller holds the
* mcdi_lock then they are able to move to MCDI_STATE_RUNNING
* mcdi @iface_lock then they are able to move to %MCDI_STATE_RUNNING
* @MCDI_STATE_RUNNING: There is an MCDI request pending. Only the thread that
* moved into this state is allowed to move out of it.
* @MCDI_STATE_COMPLETED: An MCDI request has completed, but the owning thread
* has not yet consumed the result. For all other threads, equivalent to
* MCDI_STATE_RUNNING.
* %MCDI_STATE_RUNNING.
*/
enum efx_mcdi_state {
MCDI_STATE_QUIESCENT,
......@@ -32,28 +32,28 @@ enum efx_mcdi_mode {
};
/**
* struct efx_mcdi_iface
* @state: Interface state. Waited for by mcdi_wq.
* @wq: Wait queue for threads waiting for state != STATE_RUNNING
* @iface_lock: Protects @credits, @seqno, @resprc, @resplen
* struct efx_mcdi_iface - MCDI protocol context
* @state: Request handling state. Waited for by @wq.
* @mode: Poll for mcdi completion, or wait for an mcdi_event.
* Serialised by @lock
* @wq: Wait queue for threads waiting for @state != %MCDI_STATE_RUNNING
* @iface_lock: Serialises access to all the following fields
* @seqno: The next sequence number to use for mcdi requests.
* Serialised by @lock
* @credits: Number of spurious MCDI completion events allowed before we
* trigger a fatal error. Protected by @lock
* @resprc: Returned MCDI completion
* @resplen: Returned payload length
* trigger a fatal error
* @resprc: Response error/success code (Linux numbering)
* @resp_hdr_len: Response header length
* @resp_data_len: Response data (SDU or error) length
*/
struct efx_mcdi_iface {
atomic_t state;
enum efx_mcdi_mode mode;
wait_queue_head_t wq;
spinlock_t iface_lock;
enum efx_mcdi_mode mode;
unsigned int credits;
unsigned int seqno;
unsigned int resprc;
size_t resplen;
int resprc;
size_t resp_hdr_len;
size_t resp_data_len;
};
struct efx_mcdi_mon {
......@@ -65,15 +65,36 @@ struct efx_mcdi_mon {
unsigned int n_attrs;
};
/**
* struct efx_mcdi_data - extra state for NICs that implement MCDI
* @iface: Interface/protocol state
* @hwmon: Hardware monitor state
*/
struct efx_mcdi_data {
struct efx_mcdi_iface iface;
#ifdef CONFIG_SFC_MCDI_MON
struct efx_mcdi_mon hwmon;
#endif
};
#ifdef CONFIG_SFC_MCDI_MON
static inline struct efx_mcdi_mon *efx_mcdi_mon(struct efx_nic *efx)
{
EFX_BUG_ON_PARANOID(!efx->mcdi);
return &efx->mcdi->hwmon;
}
#endif
extern int efx_mcdi_init(struct efx_nic *efx);
extern void efx_mcdi_fini(struct efx_nic *efx);
extern 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);
extern void efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd,
const efx_dword_t *inbuf, size_t inlen);
extern int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd,
const efx_dword_t *inbuf, size_t inlen);
extern 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);
......
......@@ -261,7 +261,7 @@ int efx_mcdi_mon_probe(struct efx_nic *efx)
return -EIO;
rc = efx_nic_alloc_buffer(efx, &hwmon->dma_buf,
4 * MC_CMD_SENSOR_ENTRY_MAXNUM);
4 * MC_CMD_SENSOR_ENTRY_MAXNUM, GFP_KERNEL);
if (rc)
return rc;
......
This diff is collapsed.
......@@ -111,7 +111,8 @@ static int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes)
if (rc)
goto fail;
if (outlen < MC_CMD_GET_LOOPBACK_MODES_OUT_LEN) {
if (outlen < (MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN)) {
rc = -EIO;
goto fail;
}
......@@ -989,7 +990,7 @@ int efx_mcdi_port_probe(struct efx_nic *efx)
/* Allocate buffer for stats */
rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
MC_CMD_MAC_NSTATS * sizeof(u64));
MC_CMD_MAC_NSTATS * sizeof(u64), GFP_KERNEL);
if (rc)
return rc;
netif_dbg(efx, probe, efx->net_dev,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -46,7 +46,7 @@
#include "mcdi.h"
#include "mcdi_pcol.h"
#include "io.h"
#include "regs.h"
#include "farch_regs.h"
#include "nic.h"
/* Maximum number of events expected to make up a PTP event */
......@@ -538,8 +538,9 @@ static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings)
/* Clear flag that signals MC ready */
ACCESS_ONCE(*start) = 0;
efx_mcdi_rpc_start(efx, MC_CMD_PTP, synch_buf,
MC_CMD_PTP_IN_SYNCHRONIZE_LEN);
rc = efx_mcdi_rpc_start(efx, MC_CMD_PTP, synch_buf,
MC_CMD_PTP_IN_SYNCHRONIZE_LEN);
EFX_BUG_ON_PARANOID(rc);
/* Wait for start from MCDI (or timeout) */
timeout = jiffies + msecs_to_jiffies(MAX_SYNCHRONISE_WAIT_MS);
......@@ -875,7 +876,7 @@ static int efx_ptp_probe_channel(struct efx_channel *channel)
if (!efx->ptp_data)
return -ENOMEM;
rc = efx_nic_alloc_buffer(efx, &ptp->start, sizeof(int));
rc = efx_nic_alloc_buffer(efx, &ptp->start, sizeof(int), GFP_KERNEL);
if (rc != 0)
goto fail1;
......
......@@ -326,6 +326,9 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
unsigned int fill_level, batch_size;
int space, rc = 0;
if (!rx_queue->refill_enabled)
return;
/* Calculate current fill level, and exit if we don't need to fill */
fill_level = (rx_queue->added_count - rx_queue->removed_count);
EFX_BUG_ON_PARANOID(fill_level > rx_queue->efx->rxq_entries);
......@@ -738,9 +741,9 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue)
rx_queue->max_fill = max_fill;
rx_queue->fast_fill_trigger = trigger;
rx_queue->refill_enabled = true;
/* Set up RX descriptor ring */
rx_queue->enabled = true;
efx_nic_init_rx(rx_queue);
}
......@@ -753,11 +756,7 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue)
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
"shutting down RX queue %d\n", efx_rx_queue_index(rx_queue));
/* A flush failure might have left rx_queue->enabled */
rx_queue->enabled = false;
del_timer_sync(&rx_queue->slow_fill);
efx_nic_fini_rx(rx_queue);
/* Release RX buffers from the current read ptr to the write ptr */
if (rx_queue->buffer) {
......
......@@ -447,14 +447,7 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
static int efx_poll_loopback(struct efx_nic *efx)
{
struct efx_loopback_state *state = efx->loopback_selftest;
struct efx_channel *channel;
/* NAPI polling is not enabled, so process channels
* synchronously */
efx_for_each_channel(channel, efx) {
if (channel->work_pending)
efx_process_channel_now(channel);
}
return atomic_read(&state->rx_good) == state->packet_count;
}
......@@ -586,10 +579,6 @@ static int efx_wait_for_link(struct efx_nic *efx)
mutex_lock(&efx->mac_lock);
efx->type->monitor(efx);
mutex_unlock(&efx->mac_lock);
} else {
struct efx_channel *channel = efx_get_channel(efx, 0);
if (channel->work_pending)
efx_process_channel_now(channel);
}
mutex_lock(&efx->mac_lock);
......
......@@ -19,7 +19,7 @@
#include "efx.h"
#include "nic.h"
#include "spi.h"
#include "regs.h"
#include "farch_regs.h"
#include "io.h"
#include "phy.h"
#include "workarounds.h"
......@@ -63,7 +63,7 @@ void siena_finish_flush(struct efx_nic *efx)
efx_mcdi_set_mac(efx);
}
static const struct efx_nic_register_test siena_register_tests[] = {
static const struct efx_farch_register_test siena_register_tests[] = {
{ FR_AZ_ADR_REGION,
EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) },
{ FR_CZ_USR_EV_CFG,
......@@ -107,8 +107,8 @@ static int siena_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
goto out;
tests->registers =
efx_nic_test_registers(efx, siena_register_tests,
ARRAY_SIZE(siena_register_tests))
efx_farch_test_registers(efx, siena_register_tests,
ARRAY_SIZE(siena_register_tests))
? -1 : 1;
rc = efx_mcdi_reset(efx, reset_method);
......@@ -184,7 +184,7 @@ static void siena_dimension_resources(struct efx_nic *efx)
* the buffer table and descriptor caches. In theory we can
* map both blocks to one port, but we don't.
*/
efx_nic_dimension_resources(efx, FR_CZ_BUF_FULL_TBL_ROWS / 2);
efx_farch_dimension_resources(efx, FR_CZ_BUF_FULL_TBL_ROWS / 2);
}
static int siena_probe_nic(struct efx_nic *efx)
......@@ -200,7 +200,7 @@ static int siena_probe_nic(struct efx_nic *efx)
return -ENOMEM;
efx->nic_data = nic_data;
if (efx_nic_fpga_ver(efx) != 0) {
if (efx_farch_fpga_ver(efx) != 0) {
netif_err(efx, probe, efx->net_dev,
"Siena FPGA not supported\n");
rc = -ENODEV;
......@@ -237,7 +237,8 @@ static int siena_probe_nic(struct efx_nic *efx)
siena_init_wol(efx);
/* Allocate memory for INT_KER */
rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t));
rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t),
GFP_KERNEL);
if (rc)
goto fail4;
BUG_ON(efx->irq_status.dma_addr & 0x0f);
......@@ -274,6 +275,7 @@ static int siena_probe_nic(struct efx_nic *efx)
fail3:
efx_mcdi_drv_attach(efx, false, NULL);
fail2:
efx_mcdi_fini(efx);
fail1:
kfree(efx->nic_data);
return rc;
......@@ -349,7 +351,7 @@ static int siena_init_nic(struct efx_nic *efx)
EFX_POPULATE_OWORD_1(temp, FRF_CZ_USREV_DIS, 1);
efx_writeo(efx, &temp, FR_CZ_USR_EV_CFG);
efx_nic_init_common(efx);
efx_farch_init_common(efx);
return 0;
}
......@@ -367,6 +369,8 @@ static void siena_remove_nic(struct efx_nic *efx)
/* Tear down the private nic state */
kfree(efx->nic_data);
efx->nic_data = NULL;
efx_mcdi_fini(efx);
}
static int siena_try_update_nic_stats(struct efx_nic *efx)
......@@ -574,6 +578,89 @@ static void siena_init_wol(struct efx_nic *efx)
}
}
/**************************************************************************
*
* MCDI
*
**************************************************************************
*/
#define MCDI_PDU(efx) \
(efx_port_num(efx) ? MC_SMEM_P1_PDU_OFST : MC_SMEM_P0_PDU_OFST)
#define MCDI_DOORBELL(efx) \
(efx_port_num(efx) ? MC_SMEM_P1_DOORBELL_OFST : MC_SMEM_P0_DOORBELL_OFST)
#define MCDI_STATUS(efx) \
(efx_port_num(efx) ? MC_SMEM_P1_STATUS_OFST : MC_SMEM_P0_STATUS_OFST)
static void siena_mcdi_request(struct efx_nic *efx,
const efx_dword_t *hdr, size_t hdr_len,
const efx_dword_t *sdu, size_t sdu_len)
{
unsigned pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
unsigned doorbell = FR_CZ_MC_TREG_SMEM + MCDI_DOORBELL(efx);
unsigned int i;
unsigned int inlen_dw = DIV_ROUND_UP(sdu_len, 4);
EFX_BUG_ON_PARANOID(hdr_len != 4);
efx_writed(efx, hdr, pdu);
for (i = 0; i < inlen_dw; i++)
efx_writed(efx, &sdu[i], pdu + hdr_len + 4 * i);
/* Ensure the request is written out before the doorbell */
wmb();
/* ring the doorbell with a distinctive value */
_efx_writed(efx, (__force __le32) 0x45789abc, doorbell);
}
static bool siena_mcdi_poll_response(struct efx_nic *efx)
{
unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
efx_dword_t hdr;
efx_readd(efx, &hdr, pdu);
/* All 1's indicates that shared memory is in reset (and is
* not a valid hdr). Wait for it to come out reset before
* completing the command
*/
return EFX_DWORD_FIELD(hdr, EFX_DWORD_0) != 0xffffffff &&
EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE);
}
static void siena_mcdi_read_response(struct efx_nic *efx, efx_dword_t *outbuf,
size_t offset, size_t outlen)
{
unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
unsigned int outlen_dw = DIV_ROUND_UP(outlen, 4);
int i;
for (i = 0; i < outlen_dw; i++)
efx_readd(efx, &outbuf[i], pdu + offset + 4 * i);
}
static int siena_mcdi_poll_reboot(struct efx_nic *efx)
{
unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_STATUS(efx);
efx_dword_t reg;
u32 value;
efx_readd(efx, &reg, addr);
value = EFX_DWORD_FIELD(reg, EFX_DWORD_0);
if (value == 0)
return 0;
EFX_ZERO_DWORD(reg);
efx_writed(efx, &reg, addr);
if (value == MC_STATUS_DWORD_ASSERT)
return -EINTR;
else
return -EIO;
}
/**************************************************************************
*
......@@ -598,6 +685,7 @@ const struct efx_nic_type siena_a0_nic_type = {
.reset = efx_mcdi_reset,
.probe_port = efx_mcdi_port_probe,
.remove_port = efx_mcdi_port_remove,
.fini_dmaq = efx_farch_fini_dmaq,
.prepare_flush = siena_prepare_flush,
.finish_flush = siena_finish_flush,
.update_stats = siena_update_nic_stats,
......@@ -613,6 +701,32 @@ const struct efx_nic_type siena_a0_nic_type = {
.resume_wol = siena_init_wol,
.test_chip = siena_test_chip,
.test_nvram = efx_mcdi_nvram_test_all,
.mcdi_request = siena_mcdi_request,
.mcdi_poll_response = siena_mcdi_poll_response,
.mcdi_read_response = siena_mcdi_read_response,
.mcdi_poll_reboot = siena_mcdi_poll_reboot,
.irq_enable_master = efx_farch_irq_enable_master,
.irq_test_generate = efx_farch_irq_test_generate,
.irq_disable_non_ev = efx_farch_irq_disable_master,
.irq_handle_msi = efx_farch_msi_interrupt,
.irq_handle_legacy = efx_farch_legacy_interrupt,
.tx_probe = efx_farch_tx_probe,
.tx_init = efx_farch_tx_init,
.tx_remove = efx_farch_tx_remove,
.tx_write = efx_farch_tx_write,
.rx_push_indir_table = efx_farch_rx_push_indir_table,
.rx_probe = efx_farch_rx_probe,
.rx_init = efx_farch_rx_init,
.rx_remove = efx_farch_rx_remove,
.rx_write = efx_farch_rx_write,
.rx_defer_refill = efx_farch_rx_defer_refill,
.ev_probe = efx_farch_ev_probe,
.ev_init = efx_farch_ev_init,
.ev_fini = efx_farch_ev_fini,
.ev_remove = efx_farch_ev_remove,
.ev_process = efx_farch_ev_process,
.ev_read_ack = efx_farch_ev_read_ack,
.ev_test_generate = efx_farch_ev_test_generate,
.revision = EFX_REV_SIENA_A0,
.mem_map_size = (FR_CZ_MC_TREG_SMEM +
......@@ -633,4 +747,5 @@ const struct efx_nic_type siena_a0_nic_type = {
.timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH,
.offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXHASH | NETIF_F_NTUPLE),
.mcdi_max_ver = 1,
};
......@@ -15,7 +15,7 @@
#include "mcdi.h"
#include "filter.h"
#include "mcdi_pcol.h"
#include "regs.h"
#include "farch_regs.h"
#include "vfdi.h"
/* Number of longs required to track all the VIs in a VF */
......@@ -464,8 +464,9 @@ static void __efx_sriov_push_vf_status(struct efx_vf *vf)
VFDI_EV_SEQ, (vf->msg_seqno & 0xff),
VFDI_EV_TYPE, VFDI_EV_TYPE_STATUS);
++vf->msg_seqno;
efx_generate_event(efx, EFX_VI_BASE + vf->index * efx_vf_size(efx),
&event);
efx_farch_generate_event(efx,
EFX_VI_BASE + vf->index * efx_vf_size(efx),
&event);
}
static void efx_sriov_bufs(struct efx_nic *efx, unsigned offset,
......@@ -997,7 +998,7 @@ static void efx_sriov_reset_vf_work(struct work_struct *work)
struct efx_nic *efx = vf->efx;
struct efx_buffer buf;
if (!efx_nic_alloc_buffer(efx, &buf, EFX_PAGE_SIZE)) {
if (!efx_nic_alloc_buffer(efx, &buf, EFX_PAGE_SIZE, GFP_NOIO)) {
efx_sriov_reset_vf(vf, &buf);
efx_nic_free_buffer(efx, &buf);
}
......@@ -1241,7 +1242,8 @@ static int efx_sriov_vfs_init(struct efx_nic *efx)
pci_domain_nr(pci_dev->bus), pci_dev->bus->number,
PCI_SLOT(devfn), PCI_FUNC(devfn));
rc = efx_nic_alloc_buffer(efx, &vf->buf, EFX_PAGE_SIZE);
rc = efx_nic_alloc_buffer(efx, &vf->buf, EFX_PAGE_SIZE,
GFP_KERNEL);
if (rc)
goto fail;
......@@ -1273,7 +1275,8 @@ int efx_sriov_init(struct efx_nic *efx)
if (rc)
goto fail_cmd;
rc = efx_nic_alloc_buffer(efx, &efx->vfdi_status, sizeof(*vfdi_status));
rc = efx_nic_alloc_buffer(efx, &efx->vfdi_status, sizeof(*vfdi_status),
GFP_KERNEL);
if (rc)
goto fail_status;
vfdi_status = efx->vfdi_status.addr;
......@@ -1528,7 +1531,7 @@ void efx_sriov_reset(struct efx_nic *efx)
efx_sriov_usrev(efx, true);
(void)efx_sriov_cmd(efx, true, NULL, NULL);
if (efx_nic_alloc_buffer(efx, &buf, EFX_PAGE_SIZE))
if (efx_nic_alloc_buffer(efx, &buf, EFX_PAGE_SIZE, GFP_NOIO))
return;
for (vf_i = 0; vf_i < efx->vf_init_count; ++vf_i) {
......
......@@ -543,10 +543,13 @@ void efx_init_tx_queue(struct efx_tx_queue *tx_queue)
tx_queue->initialised = true;
}
void efx_release_tx_buffers(struct efx_tx_queue *tx_queue)
void efx_fini_tx_queue(struct efx_tx_queue *tx_queue)
{
struct efx_tx_buffer *buffer;
netif_dbg(tx_queue->efx, drv, tx_queue->efx->net_dev,
"shutting down TX queue %d\n", tx_queue->queue);
if (!tx_queue->buffer)
return;
......@@ -561,22 +564,6 @@ void efx_release_tx_buffers(struct efx_tx_queue *tx_queue)
netdev_tx_reset_queue(tx_queue->core_txq);
}
void efx_fini_tx_queue(struct efx_tx_queue *tx_queue)
{
if (!tx_queue->initialised)
return;
netif_dbg(tx_queue->efx, drv, tx_queue->efx->net_dev,
"shutting down TX queue %d\n", tx_queue->queue);
tx_queue->initialised = false;
/* Flush TX queue, remove descriptor ring */
efx_nic_fini_tx(tx_queue);
efx_release_tx_buffers(tx_queue);
}
void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
{
int i;
......@@ -708,7 +695,8 @@ static u8 *efx_tsoh_get_buffer(struct efx_tx_queue *tx_queue,
TSOH_STD_SIZE * (index % TSOH_PER_PAGE) + TSOH_OFFSET;
if (unlikely(!page_buf->addr) &&
efx_nic_alloc_buffer(tx_queue->efx, page_buf, PAGE_SIZE))
efx_nic_alloc_buffer(tx_queue->efx, page_buf, PAGE_SIZE,
GFP_ATOMIC))
return NULL;
result = (u8 *)page_buf->addr + offset;
......
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