Commit 86094f7f authored by Ben Hutchings's avatar Ben Hutchings

sfc: Move and rename Falcon/Siena common NIC operations

Add efx_nic_type operations for the many efx_nic functions that need
to be implemented different on EF10.  For now, change most of the
existing efx_nic_*() functions into inline wrappers.  As a later step,
we may be able to improve branch prediction for operations used on the
fast path by copying the pointers into each queue/channel structure.

Move the Falcon/Siena implementations to new file farch.c and rename
the functions and static data to use a prefix of 'efx_farch_'.

Move efx_may_push_tx_desc() to nic.h, as the EF10 TX code will also
use it.
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
parent e42c3d85
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 \ selftest.o ethtool.o qt202x_phy.o mdio_10g.o \
tenxpress.o txc43128_phy.o falcon_boards.o \ tenxpress.o txc43128_phy.o falcon_boards.o \
mcdi.o mcdi_port.o mcdi_mon.o ptp.o mcdi.o mcdi_port.o mcdi_mon.o ptp.o
......
...@@ -1386,7 +1386,7 @@ static void efx_enable_interrupts(struct efx_nic *efx) ...@@ -1386,7 +1386,7 @@ static void efx_enable_interrupts(struct efx_nic *efx)
efx->eeh_disabled_legacy_irq = false; efx->eeh_disabled_legacy_irq = false;
} }
efx_nic_enable_interrupts(efx); efx->type->irq_enable_master(efx);
efx_for_each_channel(channel, efx) { efx_for_each_channel(channel, efx) {
if (channel->type->keep_eventq) if (channel->type->keep_eventq)
...@@ -1407,7 +1407,7 @@ static void efx_disable_interrupts(struct efx_nic *efx) ...@@ -1407,7 +1407,7 @@ static void efx_disable_interrupts(struct efx_nic *efx)
efx_fini_eventq(channel); efx_fini_eventq(channel);
} }
efx_nic_disable_interrupts(efx); efx->type->irq_disable_non_ev(efx);
} }
static void efx_remove_interrupts(struct efx_nic *efx) static void efx_remove_interrupts(struct efx_nic *efx)
......
...@@ -346,7 +346,7 @@ static inline void falcon_irq_ack_a1(struct efx_nic *efx) ...@@ -346,7 +346,7 @@ static 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; struct efx_nic *efx = dev_id;
efx_oword_t *int_ker = efx->irq_status.addr; efx_oword_t *int_ker = efx->irq_status.addr;
...@@ -373,7 +373,7 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) ...@@ -373,7 +373,7 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
/* Check to see if we have a serious error condition */ /* Check to see if we have a serious error condition */
syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);
if (unlikely(syserr)) if (unlikely(syserr))
return efx_nic_fatal_interrupt(efx); return efx_farch_fatal_interrupt(efx);
/* Determine interrupting queues, clear interrupt status /* Determine interrupting queues, clear interrupt status
* register and acknowledge the device interrupt. * register and acknowledge the device interrupt.
...@@ -1558,7 +1558,7 @@ static int falcon_test_nvram(struct efx_nic *efx) ...@@ -1558,7 +1558,7 @@ static int falcon_test_nvram(struct efx_nic *efx)
return falcon_read_nvram(efx, NULL); 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, { FR_AZ_ADR_REGION,
EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) }, EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) },
{ FR_AZ_RX_CFG, { FR_AZ_RX_CFG,
...@@ -1618,7 +1618,7 @@ falcon_b0_test_chip(struct efx_nic *efx, struct efx_self_tests *tests) ...@@ -1618,7 +1618,7 @@ falcon_b0_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
efx_reset_down(efx, reset_method); efx_reset_down(efx, reset_method);
tests->registers = tests->registers =
efx_nic_test_registers(efx, falcon_b0_register_tests, efx_farch_test_registers(efx, falcon_b0_register_tests,
ARRAY_SIZE(falcon_b0_register_tests)) ARRAY_SIZE(falcon_b0_register_tests))
? -1 : 1; ? -1 : 1;
...@@ -1984,7 +1984,7 @@ static int falcon_probe_nic(struct efx_nic *efx) ...@@ -1984,7 +1984,7 @@ static int falcon_probe_nic(struct efx_nic *efx)
rc = -ENODEV; rc = -ENODEV;
if (efx_nic_fpga_ver(efx) != 0) { if (efx_farch_fpga_ver(efx) != 0) {
netif_err(efx, probe, efx->net_dev, netif_err(efx, probe, efx->net_dev,
"Falcon FPGA not supported\n"); "Falcon FPGA not supported\n");
goto fail1; goto fail1;
...@@ -2218,7 +2218,7 @@ static int falcon_init_nic(struct efx_nic *efx) ...@@ -2218,7 +2218,7 @@ static int falcon_init_nic(struct efx_nic *efx)
efx_writeo(efx, &temp, FR_BZ_DP_CTRL); efx_writeo(efx, &temp, FR_BZ_DP_CTRL);
} }
efx_nic_init_common(efx); efx_farch_init_common(efx);
return 0; return 0;
} }
...@@ -2367,6 +2367,28 @@ const struct efx_nic_type falcon_a1_nic_type = { ...@@ -2367,6 +2367,28 @@ const struct efx_nic_type falcon_a1_nic_type = {
.set_wol = falcon_set_wol, .set_wol = falcon_set_wol,
.resume_wol = efx_port_dummy_op_void, .resume_wol = efx_port_dummy_op_void,
.test_nvram = falcon_test_nvram, .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, .revision = EFX_REV_FALCON_A1,
.mem_map_size = 0x20000, .mem_map_size = 0x20000,
...@@ -2414,6 +2436,28 @@ const struct efx_nic_type falcon_b0_nic_type = { ...@@ -2414,6 +2436,28 @@ const struct efx_nic_type falcon_b0_nic_type = {
.resume_wol = efx_port_dummy_op_void, .resume_wol = efx_port_dummy_op_void,
.test_chip = falcon_b0_test_chip, .test_chip = falcon_b0_test_chip,
.test_nvram = falcon_test_nvram, .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, .revision = EFX_REV_FALCON_B0,
/* Map everything up to and including the RSS indirection /* Map everything up to and including the RSS indirection
......
This diff is collapsed.
...@@ -971,7 +971,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) ...@@ -971,7 +971,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
* @get_wol: Get WoL configuration from driver state * @get_wol: Get WoL configuration from driver state
* @set_wol: Push WoL configuration to the NIC * @set_wol: Push WoL configuration to the NIC
* @resume_wol: Synchronise WoL state between driver and MC (e.g. after resume) * @resume_wol: Synchronise WoL state between driver and MC (e.g. after resume)
* @test_chip: Test registers. Should use efx_nic_test_registers(), and is * @test_chip: Test registers. May use efx_farch_test_registers(), and is
* expected to reset the NIC. * expected to reset the NIC.
* @test_nvram: Test validity of NVRAM contents * @test_nvram: Test validity of NVRAM contents
* @mcdi_request: Send an MCDI request with the given header and SDU. * @mcdi_request: Send an MCDI request with the given header and SDU.
...@@ -985,6 +985,32 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) ...@@ -985,6 +985,32 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
* @mcdi_poll_reboot: Test whether the MCDI has rebooted. If so, * @mcdi_poll_reboot: Test whether the MCDI has rebooted. If so,
* return an appropriate error code for aborting any current * return an appropriate error code for aborting any current
* request; otherwise return 0. * request; otherwise return 0.
* @irq_enable_master: Enable IRQs on the NIC. Each event queue must
* be separately enabled after this.
* @irq_test_generate: Generate a test IRQ
* @irq_disable_non_ev: Disable non-event IRQs on the NIC. Each event
* queue must be separately disabled before this.
* @irq_handle_msi: Handle MSI for a channel. The @dev_id argument is
* a pointer to the &struct efx_msi_context for the channel.
* @irq_handle_legacy: Handle legacy interrupt. The @dev_id argument
* is a pointer to the &struct efx_nic.
* @tx_probe: Allocate resources for TX queue
* @tx_init: Initialise TX queue on the NIC
* @tx_remove: Free resources for TX queue
* @tx_write: Write TX descriptors and doorbell
* @rx_push_indir_table: Write RSS indirection table to the NIC
* @rx_probe: Allocate resources for RX queue
* @rx_init: Initialise RX queue on the NIC
* @rx_remove: Free resources for RX queue
* @rx_write: Write RX descriptors and doorbell
* @rx_defer_refill: Generate a refill reminder event
* @ev_probe: Allocate resources for event queue
* @ev_init: Initialise event queue on the NIC
* @ev_fini: Deinitialise event queue on the NIC
* @ev_remove: Free resources for event queue
* @ev_process: Process events for a queue, up to the given NAPI quota
* @ev_read_ack: Acknowledge read events on a queue, rearming its IRQ
* @ev_test_generate: Generate a test event
* @revision: Hardware architecture revision * @revision: Hardware architecture revision
* @mem_map_size: Memory BAR mapped size * @mem_map_size: Memory BAR mapped size
* @txd_ptr_tbl_base: TX descriptor ring base address * @txd_ptr_tbl_base: TX descriptor ring base address
...@@ -1041,6 +1067,28 @@ struct efx_nic_type { ...@@ -1041,6 +1067,28 @@ struct efx_nic_type {
void (*mcdi_read_response)(struct efx_nic *efx, efx_dword_t *pdu, void (*mcdi_read_response)(struct efx_nic *efx, efx_dword_t *pdu,
size_t pdu_offset, size_t pdu_len); size_t pdu_offset, size_t pdu_len);
int (*mcdi_poll_reboot)(struct efx_nic *efx); int (*mcdi_poll_reboot)(struct efx_nic *efx);
void (*irq_enable_master)(struct efx_nic *efx);
void (*irq_test_generate)(struct efx_nic *efx);
void (*irq_disable_non_ev)(struct efx_nic *efx);
irqreturn_t (*irq_handle_msi)(int irq, void *dev_id);
irqreturn_t (*irq_handle_legacy)(int irq, void *dev_id);
int (*tx_probe)(struct efx_tx_queue *tx_queue);
void (*tx_init)(struct efx_tx_queue *tx_queue);
void (*tx_remove)(struct efx_tx_queue *tx_queue);
void (*tx_write)(struct efx_tx_queue *tx_queue);
void (*rx_push_indir_table)(struct efx_nic *efx);
int (*rx_probe)(struct efx_rx_queue *rx_queue);
void (*rx_init)(struct efx_rx_queue *rx_queue);
void (*rx_remove)(struct efx_rx_queue *rx_queue);
void (*rx_write)(struct efx_rx_queue *rx_queue);
void (*rx_defer_refill)(struct efx_rx_queue *rx_queue);
int (*ev_probe)(struct efx_channel *channel);
void (*ev_init)(struct efx_channel *channel);
void (*ev_fini)(struct efx_channel *channel);
void (*ev_remove)(struct efx_channel *channel);
int (*ev_process)(struct efx_channel *channel, int quota);
void (*ev_read_ack)(struct efx_channel *channel);
void (*ev_test_generate)(struct efx_channel *channel);
int revision; int revision;
unsigned int mem_map_size; unsigned int mem_map_size;
......
This diff is collapsed.
...@@ -34,7 +34,7 @@ static inline int efx_nic_rev(struct efx_nic *efx) ...@@ -34,7 +34,7 @@ static inline int efx_nic_rev(struct efx_nic *efx)
return efx->type->revision; return efx->type->revision;
} }
extern u32 efx_nic_fpga_ver(struct efx_nic *efx); extern u32 efx_farch_fpga_ver(struct efx_nic *efx);
/* NIC has two interlinked PCI functions for the same port. */ /* NIC has two interlinked PCI functions for the same port. */
static inline bool efx_nic_is_dual_func(struct efx_nic *efx) static inline bool efx_nic_is_dual_func(struct efx_nic *efx)
...@@ -42,6 +42,65 @@ static inline bool efx_nic_is_dual_func(struct efx_nic *efx) ...@@ -42,6 +42,65 @@ static inline bool efx_nic_is_dual_func(struct efx_nic *efx)
return efx_nic_rev(efx) < EFX_REV_FALCON_B0; return efx_nic_rev(efx) < EFX_REV_FALCON_B0;
} }
/* Read the current event from the event queue */
static inline efx_qword_t *efx_event(struct efx_channel *channel,
unsigned int index)
{
return ((efx_qword_t *) (channel->eventq.buf.addr)) +
(index & channel->eventq_mask);
}
/* See if an event is present
*
* We check both the high and low dword of the event for all ones. We
* wrote all ones when we cleared the event, and no valid event can
* have all ones in either its high or low dwords. This approach is
* robust against reordering.
*
* Note that using a single 64-bit comparison is incorrect; even
* though the CPU read will be atomic, the DMA write may not be.
*/
static inline int efx_event_present(efx_qword_t *event)
{
return !(EFX_DWORD_IS_ALL_ONES(event->dword[0]) |
EFX_DWORD_IS_ALL_ONES(event->dword[1]));
}
/* Returns a pointer to the specified transmit descriptor in the TX
* descriptor queue belonging to the specified channel.
*/
static inline efx_qword_t *
efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
{
return ((efx_qword_t *) (tx_queue->txd.buf.addr)) + index;
}
/* Decide whether to push a TX descriptor to the NIC vs merely writing
* the doorbell. This can reduce latency when we are adding a single
* descriptor to an empty queue, but is otherwise pointless. Further,
* Falcon and Siena have hardware bugs (SF bug 33851) that may be
* triggered if we don't check this.
*/
static inline bool efx_nic_may_push_tx_desc(struct efx_tx_queue *tx_queue,
unsigned int write_count)
{
unsigned empty_read_count = ACCESS_ONCE(tx_queue->empty_read_count);
if (empty_read_count == 0)
return false;
tx_queue->empty_read_count = 0;
return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0
&& tx_queue->write_count - write_count == 1;
}
/* Returns a pointer to the specified descriptor in the RX descriptor queue */
static inline efx_qword_t *
efx_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index)
{
return ((efx_qword_t *) (rx_queue->rxd.buf.addr)) + index;
}
enum { enum {
PHY_TYPE_NONE = 0, PHY_TYPE_NONE = 0,
PHY_TYPE_TXC43128 = 1, PHY_TYPE_TXC43128 = 1,
...@@ -258,25 +317,93 @@ extern const struct efx_nic_type siena_a0_nic_type; ...@@ -258,25 +317,93 @@ extern const struct efx_nic_type siena_a0_nic_type;
extern int falcon_probe_board(struct efx_nic *efx, u16 revision_info); extern int falcon_probe_board(struct efx_nic *efx, u16 revision_info);
/* TX data path */ /* TX data path */
extern int efx_nic_probe_tx(struct efx_tx_queue *tx_queue); static inline int efx_nic_probe_tx(struct efx_tx_queue *tx_queue)
extern void efx_nic_init_tx(struct efx_tx_queue *tx_queue); {
extern void efx_nic_remove_tx(struct efx_tx_queue *tx_queue); return tx_queue->efx->type->tx_probe(tx_queue);
extern void efx_nic_push_buffers(struct efx_tx_queue *tx_queue); }
static inline void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
{
tx_queue->efx->type->tx_init(tx_queue);
}
static inline void efx_nic_remove_tx(struct efx_tx_queue *tx_queue)
{
tx_queue->efx->type->tx_remove(tx_queue);
}
static inline void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
{
tx_queue->efx->type->tx_write(tx_queue);
}
/* RX data path */ /* RX data path */
extern int efx_nic_probe_rx(struct efx_rx_queue *rx_queue); static inline int efx_nic_probe_rx(struct efx_rx_queue *rx_queue)
extern void efx_nic_init_rx(struct efx_rx_queue *rx_queue); {
extern void efx_nic_remove_rx(struct efx_rx_queue *rx_queue); return rx_queue->efx->type->rx_probe(rx_queue);
extern void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue); }
extern void efx_nic_generate_fill_event(struct efx_rx_queue *rx_queue); static inline void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
{
rx_queue->efx->type->rx_init(rx_queue);
}
static inline void efx_nic_remove_rx(struct efx_rx_queue *rx_queue)
{
rx_queue->efx->type->rx_remove(rx_queue);
}
static inline void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue)
{
rx_queue->efx->type->rx_write(rx_queue);
}
static inline void efx_nic_generate_fill_event(struct efx_rx_queue *rx_queue)
{
rx_queue->efx->type->rx_defer_refill(rx_queue);
}
/* Event data path */ /* Event data path */
extern int efx_nic_probe_eventq(struct efx_channel *channel); static inline int efx_nic_probe_eventq(struct efx_channel *channel)
extern void efx_nic_init_eventq(struct efx_channel *channel); {
extern void efx_nic_fini_eventq(struct efx_channel *channel); return channel->efx->type->ev_probe(channel);
extern void efx_nic_remove_eventq(struct efx_channel *channel); }
extern int efx_nic_process_eventq(struct efx_channel *channel, int rx_quota); static inline void efx_nic_init_eventq(struct efx_channel *channel)
extern void efx_nic_eventq_read_ack(struct efx_channel *channel); {
channel->efx->type->ev_init(channel);
}
static inline void efx_nic_fini_eventq(struct efx_channel *channel)
{
channel->efx->type->ev_fini(channel);
}
static inline void efx_nic_remove_eventq(struct efx_channel *channel)
{
channel->efx->type->ev_remove(channel);
}
static inline int
efx_nic_process_eventq(struct efx_channel *channel, int quota)
{
return channel->efx->type->ev_process(channel, quota);
}
static inline void efx_nic_eventq_read_ack(struct efx_channel *channel)
{
channel->efx->type->ev_read_ack(channel);
}
extern void efx_nic_event_test_start(struct efx_channel *channel);
/* Falcon/Siena queue operations */
extern int efx_farch_tx_probe(struct efx_tx_queue *tx_queue);
extern void efx_farch_tx_init(struct efx_tx_queue *tx_queue);
extern void efx_farch_tx_fini(struct efx_tx_queue *tx_queue);
extern void efx_farch_tx_remove(struct efx_tx_queue *tx_queue);
extern void efx_farch_tx_write(struct efx_tx_queue *tx_queue);
extern int efx_farch_rx_probe(struct efx_rx_queue *rx_queue);
extern void efx_farch_rx_init(struct efx_rx_queue *rx_queue);
extern void efx_farch_rx_fini(struct efx_rx_queue *rx_queue);
extern void efx_farch_rx_remove(struct efx_rx_queue *rx_queue);
extern void efx_farch_rx_write(struct efx_rx_queue *rx_queue);
extern void efx_farch_rx_defer_refill(struct efx_rx_queue *rx_queue);
extern int efx_farch_ev_probe(struct efx_channel *channel);
extern void efx_farch_ev_init(struct efx_channel *channel);
extern void efx_farch_ev_fini(struct efx_channel *channel);
extern void efx_farch_ev_remove(struct efx_channel *channel);
extern int efx_farch_ev_process(struct efx_channel *channel, int quota);
extern void efx_farch_ev_read_ack(struct efx_channel *channel);
extern void efx_farch_ev_test_generate(struct efx_channel *channel);
extern bool efx_nic_event_present(struct efx_channel *channel); extern bool efx_nic_event_present(struct efx_channel *channel);
/* Some statistics are computed as A - B where A and B each increase /* Some statistics are computed as A - B where A and B each increase
...@@ -297,15 +424,18 @@ static inline void efx_update_diff_stat(u64 *stat, u64 diff) ...@@ -297,15 +424,18 @@ static inline void efx_update_diff_stat(u64 *stat, u64 diff)
*stat = diff; *stat = diff;
} }
/* Interrupts and test events */ /* Interrupts */
extern int efx_nic_init_interrupt(struct efx_nic *efx); extern int efx_nic_init_interrupt(struct efx_nic *efx);
extern void efx_nic_enable_interrupts(struct efx_nic *efx);
extern void efx_nic_event_test_start(struct efx_channel *channel);
extern void efx_nic_irq_test_start(struct efx_nic *efx); extern void efx_nic_irq_test_start(struct efx_nic *efx);
extern void efx_nic_disable_interrupts(struct efx_nic *efx);
extern void efx_nic_fini_interrupt(struct efx_nic *efx); extern void efx_nic_fini_interrupt(struct efx_nic *efx);
extern irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx);
extern irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id); /* Falcon/Siena interrupts */
extern void efx_farch_irq_enable_master(struct efx_nic *efx);
extern void efx_farch_irq_test_generate(struct efx_nic *efx);
extern void efx_farch_irq_disable_master(struct efx_nic *efx);
extern irqreturn_t efx_farch_msi_interrupt(int irq, void *dev_id);
extern irqreturn_t efx_farch_legacy_interrupt(int irq, void *dev_id);
extern irqreturn_t efx_farch_fatal_interrupt(struct efx_nic *efx);
static inline int efx_nic_event_test_irq_cpu(struct efx_channel *channel) static inline int efx_nic_event_test_irq_cpu(struct efx_channel *channel)
{ {
...@@ -317,28 +447,32 @@ static inline int efx_nic_irq_test_irq_cpu(struct efx_nic *efx) ...@@ -317,28 +447,32 @@ static inline int efx_nic_irq_test_irq_cpu(struct efx_nic *efx)
} }
/* Global Resources */ /* Global Resources */
extern int efx_farch_fini_dmaq(struct efx_nic *efx); extern int efx_nic_flush_queues(struct efx_nic *efx);
extern void siena_prepare_flush(struct efx_nic *efx); extern void siena_prepare_flush(struct efx_nic *efx);
extern int efx_farch_fini_dmaq(struct efx_nic *efx);
extern void siena_finish_flush(struct efx_nic *efx); extern void siena_finish_flush(struct efx_nic *efx);
extern void falcon_start_nic_stats(struct efx_nic *efx); extern void falcon_start_nic_stats(struct efx_nic *efx);
extern void falcon_stop_nic_stats(struct efx_nic *efx); extern void falcon_stop_nic_stats(struct efx_nic *efx);
extern int falcon_reset_xaui(struct efx_nic *efx); extern int falcon_reset_xaui(struct efx_nic *efx);
extern void extern void efx_farch_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw);
efx_nic_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw); extern void efx_farch_init_common(struct efx_nic *efx);
extern void efx_nic_init_common(struct efx_nic *efx); static inline void efx_nic_push_rx_indir_table(struct efx_nic *efx)
extern void efx_nic_push_rx_indir_table(struct efx_nic *efx); {
efx->type->rx_push_indir_table(efx);
}
extern void efx_farch_rx_push_indir_table(struct efx_nic *efx);
int efx_nic_alloc_buffer(struct efx_nic *efx, struct efx_buffer *buffer, int efx_nic_alloc_buffer(struct efx_nic *efx, struct efx_buffer *buffer,
unsigned int len, gfp_t gfp_flags); unsigned int len, gfp_t gfp_flags);
void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer); void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer);
/* Tests */ /* Tests */
struct efx_nic_register_test { struct efx_farch_register_test {
unsigned address; unsigned address;
efx_oword_t mask; efx_oword_t mask;
}; };
extern int efx_nic_test_registers(struct efx_nic *efx, extern int efx_farch_test_registers(struct efx_nic *efx,
const struct efx_nic_register_test *regs, const struct efx_farch_register_test *regs,
size_t n_regs); size_t n_regs);
extern size_t efx_nic_get_regs_len(struct efx_nic *efx); extern size_t efx_nic_get_regs_len(struct efx_nic *efx);
...@@ -346,7 +480,7 @@ extern void efx_nic_get_regs(struct efx_nic *efx, void *buf); ...@@ -346,7 +480,7 @@ extern void efx_nic_get_regs(struct efx_nic *efx, void *buf);
#define EFX_MAX_FLUSH_TIME 5000 #define EFX_MAX_FLUSH_TIME 5000
extern void efx_generate_event(struct efx_nic *efx, unsigned int evq, extern void efx_farch_generate_event(struct efx_nic *efx, unsigned int evq,
efx_qword_t *event); efx_qword_t *event);
#endif /* EFX_NIC_H */ #endif /* EFX_NIC_H */
...@@ -63,7 +63,7 @@ void siena_finish_flush(struct efx_nic *efx) ...@@ -63,7 +63,7 @@ void siena_finish_flush(struct efx_nic *efx)
efx_mcdi_set_mac(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, { FR_AZ_ADR_REGION,
EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) }, EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) },
{ FR_CZ_USR_EV_CFG, { FR_CZ_USR_EV_CFG,
...@@ -107,7 +107,7 @@ static int siena_test_chip(struct efx_nic *efx, struct efx_self_tests *tests) ...@@ -107,7 +107,7 @@ static int siena_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
goto out; goto out;
tests->registers = tests->registers =
efx_nic_test_registers(efx, siena_register_tests, efx_farch_test_registers(efx, siena_register_tests,
ARRAY_SIZE(siena_register_tests)) ARRAY_SIZE(siena_register_tests))
? -1 : 1; ? -1 : 1;
...@@ -184,7 +184,7 @@ static void siena_dimension_resources(struct efx_nic *efx) ...@@ -184,7 +184,7 @@ static void siena_dimension_resources(struct efx_nic *efx)
* the buffer table and descriptor caches. In theory we can * the buffer table and descriptor caches. In theory we can
* map both blocks to one port, but we don't. * 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) static int siena_probe_nic(struct efx_nic *efx)
...@@ -200,7 +200,7 @@ static int siena_probe_nic(struct efx_nic *efx) ...@@ -200,7 +200,7 @@ static int siena_probe_nic(struct efx_nic *efx)
return -ENOMEM; return -ENOMEM;
efx->nic_data = nic_data; 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, netif_err(efx, probe, efx->net_dev,
"Siena FPGA not supported\n"); "Siena FPGA not supported\n");
rc = -ENODEV; rc = -ENODEV;
...@@ -351,7 +351,7 @@ static int siena_init_nic(struct efx_nic *efx) ...@@ -351,7 +351,7 @@ static int siena_init_nic(struct efx_nic *efx)
EFX_POPULATE_OWORD_1(temp, FRF_CZ_USREV_DIS, 1); EFX_POPULATE_OWORD_1(temp, FRF_CZ_USREV_DIS, 1);
efx_writeo(efx, &temp, FR_CZ_USR_EV_CFG); efx_writeo(efx, &temp, FR_CZ_USR_EV_CFG);
efx_nic_init_common(efx); efx_farch_init_common(efx);
return 0; return 0;
} }
...@@ -705,6 +705,28 @@ const struct efx_nic_type siena_a0_nic_type = { ...@@ -705,6 +705,28 @@ const struct efx_nic_type siena_a0_nic_type = {
.mcdi_poll_response = siena_mcdi_poll_response, .mcdi_poll_response = siena_mcdi_poll_response,
.mcdi_read_response = siena_mcdi_read_response, .mcdi_read_response = siena_mcdi_read_response,
.mcdi_poll_reboot = siena_mcdi_poll_reboot, .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, .revision = EFX_REV_SIENA_A0,
.mem_map_size = (FR_CZ_MC_TREG_SMEM + .mem_map_size = (FR_CZ_MC_TREG_SMEM +
......
...@@ -464,7 +464,8 @@ static void __efx_sriov_push_vf_status(struct efx_vf *vf) ...@@ -464,7 +464,8 @@ static void __efx_sriov_push_vf_status(struct efx_vf *vf)
VFDI_EV_SEQ, (vf->msg_seqno & 0xff), VFDI_EV_SEQ, (vf->msg_seqno & 0xff),
VFDI_EV_TYPE, VFDI_EV_TYPE_STATUS); VFDI_EV_TYPE, VFDI_EV_TYPE_STATUS);
++vf->msg_seqno; ++vf->msg_seqno;
efx_generate_event(efx, EFX_VI_BASE + vf->index * efx_vf_size(efx), efx_farch_generate_event(efx,
EFX_VI_BASE + vf->index * efx_vf_size(efx),
&event); &event);
} }
......
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