18ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/****************************************************************************
28ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * Driver for Solarflare Solarstorm network controllers and boards
38ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * Copyright 2005-2006 Fen Systems Ltd.
40a6f40c66ba388e6349a11bea146955716c4d492Ben Hutchings * Copyright 2006-2010 Solarflare Communications Inc.
58ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
68ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * This program is free software; you can redistribute it and/or modify it
78ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * under the terms of the GNU General Public License version 2 as published
88ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * by the Free Software Foundation, incorporated herein by reference.
98ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings */
108ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
118ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include <linux/bitops.h>
128ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include <linux/delay.h>
138ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include <linux/pci.h>
148ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include <linux/module.h>
158ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include <linux/seq_file.h>
1637b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings#include <linux/i2c.h>
17f31a45d2f45a7667acd6e85ab6613b0910c55ea9Ben Hutchings#include <linux/mii.h>
185a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
198ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include "net_driver.h"
208ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include "bitfield.h"
218ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include "efx.h"
228ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include "spi.h"
23744093c98363f8a65853aed39708c9effc80f8ffBen Hutchings#include "nic.h"
243e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings#include "regs.h"
2512d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings#include "io.h"
268ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include "phy.h"
278ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include "workarounds.h"
288ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
298986352a32485f9dd9069e370ffa6d5b0737a854Ben Hutchings/* Hardware control for SFC4000 (aka Falcon). */
308ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
312f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchingsstatic const unsigned int
322f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings/* "Large" EEPROM device: Atmel AT25640 or similar
332f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings * 8 KB, 16-bit address, 32 B write block */
342f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchingslarge_eeprom_type = ((13 << SPI_DEV_TYPE_SIZE_LBN)
352f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings		     | (2 << SPI_DEV_TYPE_ADDR_LEN_LBN)
362f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings		     | (5 << SPI_DEV_TYPE_BLOCK_SIZE_LBN)),
372f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings/* Default flash device: Atmel AT25F1024
382f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings * 128 KB, 24-bit address, 32 KB erase block, 256 B write block */
392f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchingsdefault_flash_type = ((17 << SPI_DEV_TYPE_SIZE_LBN)
402f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings		      | (3 << SPI_DEV_TYPE_ADDR_LEN_LBN)
412f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings		      | (0x52 << SPI_DEV_TYPE_ERASE_CMD_LBN)
422f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings		      | (15 << SPI_DEV_TYPE_ERASE_SIZE_LBN)
432f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings		      | (8 << SPI_DEV_TYPE_BLOCK_SIZE_LBN));
442f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings
458ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/**************************************************************************
468ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
478ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * I2C bus - this is a bit-bashing interface using GPIO pins
488ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * Note that it uses the output enables to tristate the outputs
498ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * SDA is the data pin and SCL is the clock
508ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
518ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings **************************************************************************
528ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings */
5337b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchingsstatic void falcon_setsda(void *data, int state)
548ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
5537b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings	struct efx_nic *efx = (struct efx_nic *)data;
568ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_oword_t reg;
578ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
5812d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &reg, FR_AB_GPIO_CTL);
593e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO3_OEN, !state);
6012d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
618ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
628ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
6337b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchingsstatic void falcon_setscl(void *data, int state)
648ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
6537b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings	struct efx_nic *efx = (struct efx_nic *)data;
668ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_oword_t reg;
678ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
6812d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &reg, FR_AB_GPIO_CTL);
693e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO0_OEN, !state);
7012d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
7137b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings}
7237b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings
738e730c15e1560415f33d7301b617be26050ffb86Ben Hutchingsstatic int falcon_getsda(void *data)
748e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings{
758e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	struct efx_nic *efx = (struct efx_nic *)data;
768e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	efx_oword_t reg;
778ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
788e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	efx_reado(efx, &reg, FR_AB_GPIO_CTL);
798e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	return EFX_OWORD_FIELD(reg, FRF_AB_GPIO3_IN);
808e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings}
818ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
828e730c15e1560415f33d7301b617be26050ffb86Ben Hutchingsstatic int falcon_getscl(void *data)
838e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings{
848e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	struct efx_nic *efx = (struct efx_nic *)data;
858e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	efx_oword_t reg;
868ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
878e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	efx_reado(efx, &reg, FR_AB_GPIO_CTL);
888e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	return EFX_OWORD_FIELD(reg, FRF_AB_GPIO0_IN);
898ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
908ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
9118e83e4cd144e30fb38bf1f714914182c6c8bcedBen Hutchingsstatic const struct i2c_algo_bit_data falcon_i2c_bit_operations = {
928e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	.setsda		= falcon_setsda,
938e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	.setscl		= falcon_setscl,
948e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	.getsda		= falcon_getsda,
958e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	.getscl		= falcon_getscl,
968e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	.udelay		= 5,
978e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	/* Wait up to 50 ms for slave to let us pull SCL high */
988e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings	.timeout	= DIV_ROUND_UP(HZ, 20),
998e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings};
1008e730c15e1560415f33d7301b617be26050ffb86Ben Hutchings
101ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchingsstatic void falcon_push_irq_moderation(struct efx_channel *channel)
1028ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
1038ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_dword_t timer_cmd;
1048ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	struct efx_nic *efx = channel->efx;
1058ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1068ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Set timer register */
1078ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (channel->irq_moderation) {
1088ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		EFX_POPULATE_DWORD_2(timer_cmd,
1093e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_TC_TIMER_MODE,
1103e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FFE_BB_TIMER_MODE_INT_HLDOFF,
1113e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_TC_TIMER_VAL,
1120d86ebd815416efb4e95ca70c3b8e65b476c5f9fBen Hutchings				     channel->irq_moderation - 1);
1138ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	} else {
1148ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		EFX_POPULATE_DWORD_2(timer_cmd,
1153e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_TC_TIMER_MODE,
1163e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FFE_BB_TIMER_MODE_DIS,
1173e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_TC_TIMER_VAL, 0);
1188ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
1193e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	BUILD_BUG_ON(FR_AA_TIMER_COMMAND_KER != FR_BZ_TIMER_COMMAND_P0);
12012d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writed_page_locked(efx, &timer_cmd, FR_BZ_TIMER_COMMAND_P0,
12112d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings			       channel->channel);
122127e6e10ad17585c48cba8e1dcf30d98b90ee583Ben Hutchings}
123127e6e10ad17585c48cba8e1dcf30d98b90ee583Ben Hutchings
124d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchingsstatic void falcon_deconfigure_mac_wrapper(struct efx_nic *efx);
125d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
126127e6e10ad17585c48cba8e1dcf30d98b90ee583Ben Hutchingsstatic void falcon_prepare_flush(struct efx_nic *efx)
127127e6e10ad17585c48cba8e1dcf30d98b90ee583Ben Hutchings{
128127e6e10ad17585c48cba8e1dcf30d98b90ee583Ben Hutchings	falcon_deconfigure_mac_wrapper(efx);
129127e6e10ad17585c48cba8e1dcf30d98b90ee583Ben Hutchings
130127e6e10ad17585c48cba8e1dcf30d98b90ee583Ben Hutchings	/* Wait for the tx and rx fifo's to get to the next packet boundary
131127e6e10ad17585c48cba8e1dcf30d98b90ee583Ben Hutchings	 * (~1ms without back-pressure), then to drain the remainder of the
132127e6e10ad17585c48cba8e1dcf30d98b90ee583Ben Hutchings	 * fifo's at data path speeds (negligible), with a healthy margin. */
133127e6e10ad17585c48cba8e1dcf30d98b90ee583Ben Hutchings	msleep(10);
1346bc5d3a9334401d788e1adf8b71add211265bc8bBen Hutchings}
1356bc5d3a9334401d788e1adf8b71add211265bc8bBen Hutchings
1368ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Acknowledge a legacy interrupt from Falcon
1378ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
1388ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * This acknowledges a legacy (not MSI) interrupt via INT_ACK_KER_REG.
1398ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
1408ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * Due to SFC bug 3706 (silicon revision <=A1) reads can be duplicated in the
1418ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * BIU. Interrupt acknowledge is read sensitive so must write instead
1428ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * (then read to ensure the BIU collector is flushed)
1438ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
1448ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * NB most hardware supports MSI interrupts
1458ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings */
146152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchingsinline void falcon_irq_ack_a1(struct efx_nic *efx)
1478ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
1488ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_dword_t reg;
1498ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1503e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_POPULATE_DWORD_1(reg, FRF_AA_INT_ACK_KER_FIELD, 0xb7eb7e);
15112d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writed(efx, &reg, FR_AA_INT_ACK_KER);
15212d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_readd(efx, &reg, FR_AA_WORK_AROUND_BROKEN_PCI_READS);
1538ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
1548ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1558ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
156152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchingsirqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
1578ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
158d3208b5ebae9e62c32f0cf74dce1d4ddfac3f895Ben Hutchings	struct efx_nic *efx = dev_id;
159d3208b5ebae9e62c32f0cf74dce1d4ddfac3f895Ben Hutchings	efx_oword_t *int_ker = efx->irq_status.addr;
1608ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int syserr;
1618ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int queues;
1628ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1638ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Check to see if this is our interrupt.  If it isn't, we
1648ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 * exit without having touched the hardware.
1658ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 */
1668ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (unlikely(EFX_OWORD_IS_ZERO(*int_ker))) {
16762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_vdbg(efx, intr, efx->net_dev,
16862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			   "IRQ %d on CPU %d not for me\n", irq,
16962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			   raw_smp_processor_id());
1708ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		return IRQ_NONE;
1718ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
1728ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx->last_irq_cpu = raw_smp_processor_id();
17362776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings	netif_vdbg(efx, intr, efx->net_dev,
17462776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		   "IRQ %d on CPU %d status " EFX_OWORD_FMT "\n",
17562776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		   irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker));
1768ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
177f70d1847348e9548a9a56e4434946315bca297c8Ben Hutchings	/* Check to see if we have a serious error condition */
178f70d1847348e9548a9a56e4434946315bca297c8Ben Hutchings	syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);
179f70d1847348e9548a9a56e4434946315bca297c8Ben Hutchings	if (unlikely(syserr))
180f70d1847348e9548a9a56e4434946315bca297c8Ben Hutchings		return efx_nic_fatal_interrupt(efx);
181f70d1847348e9548a9a56e4434946315bca297c8Ben Hutchings
1828ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Determine interrupting queues, clear interrupt status
1838ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 * register and acknowledge the device interrupt.
1848ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 */
185674979d33566ab7e524e25fdc227923e27a3fb78Ben Hutchings	BUILD_BUG_ON(FSF_AZ_NET_IVEC_INT_Q_WIDTH > EFX_MAX_CHANNELS);
186674979d33566ab7e524e25fdc227923e27a3fb78Ben Hutchings	queues = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_INT_Q);
1878ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	EFX_ZERO_OWORD(*int_ker);
1888ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	wmb(); /* Ensure the vector is cleared before interrupt ack */
1898ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	falcon_irq_ack_a1(efx);
1908ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1918313aca38b3937947fffebca6e34bac8e24300c8Ben Hutchings	if (queues & 1)
1921646a6f352a6f70fcca828589ed04797aa09d494Ben Hutchings		efx_schedule_channel_irq(efx_get_channel(efx, 0));
1938313aca38b3937947fffebca6e34bac8e24300c8Ben Hutchings	if (queues & 2)
1941646a6f352a6f70fcca828589ed04797aa09d494Ben Hutchings		efx_schedule_channel_irq(efx_get_channel(efx, 1));
1958ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return IRQ_HANDLED;
1968ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
1978ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/**************************************************************************
1988ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
1998ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * EEPROM/flash
2008ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
2018ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings **************************************************************************
2028ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings */
2038ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
20423d30f027d1e8ad3bcd6192613122ce925947563Ben Hutchings#define FALCON_SPI_MAX_LEN sizeof(efx_oword_t)
2058ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
206be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchingsstatic int falcon_spi_poll(struct efx_nic *efx)
207be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings{
208be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	efx_oword_t reg;
20912d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &reg, FR_AB_EE_SPI_HCMD);
2103e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	return EFX_OWORD_FIELD(reg, FRF_AB_EE_SPI_HCMD_CMD_EN) ? -EBUSY : 0;
211be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings}
212be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings
2138ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Wait for SPI command completion */
2148ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchingsstatic int falcon_spi_wait(struct efx_nic *efx)
2158ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
216be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	/* Most commands will finish quickly, so we start polling at
217be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	 * very short intervals.  Sometimes the command may have to
218be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	 * wait for VPD or expansion ROM access outside of our
219be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	 * control, so we allow up to 100 ms. */
220be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 10);
221be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	int i;
222be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings
223be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	for (i = 0; i < 10; i++) {
224be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings		if (!falcon_spi_poll(efx))
225be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings			return 0;
226be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings		udelay(10);
227be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	}
2288ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
2294a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	for (;;) {
230be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings		if (!falcon_spi_poll(efx))
2318ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			return 0;
2324a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		if (time_after_eq(jiffies, timeout)) {
23362776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			netif_err(efx, hw, efx->net_dev,
23462776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  "timed out waiting for SPI\n");
2354a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			return -ETIMEDOUT;
2364a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		}
237be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings		schedule_timeout_uninterruptible(1);
2384a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	}
2398ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
2408ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
24176884835684411264cda2f15585261eb02183541Ben Hutchingsint falcon_spi_cmd(struct efx_nic *efx, const struct efx_spi_device *spi,
242f41507245ef8b079685aba8da5b5b2b5e87e70bcBen Hutchings		   unsigned int command, int address,
24323d30f027d1e8ad3bcd6192613122ce925947563Ben Hutchings		   const void *in, void *out, size_t len)
2448ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
2454a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	bool addressed = (address >= 0);
2464a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	bool reading = (out != NULL);
2478ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_oword_t reg;
2488ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int rc;
2498ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
2504a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	/* Input validation */
2514a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	if (len > FALCON_SPI_MAX_LEN)
2524a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		return -EINVAL;
2538ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
254be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	/* Check that previous command is not still running */
255be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	rc = falcon_spi_poll(efx);
2568ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (rc)
2578ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		return rc;
2588ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
2594a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	/* Program address register, if we have an address */
2604a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	if (addressed) {
2613e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_POPULATE_OWORD_1(reg, FRF_AB_EE_SPI_HADR_ADR, address);
26212d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_writeo(efx, &reg, FR_AB_EE_SPI_HADR);
2634a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	}
2644a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
2654a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	/* Program data register, if we have data */
2664a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	if (in != NULL) {
2674a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		memcpy(&reg, in, len);
26812d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_writeo(efx, &reg, FR_AB_EE_SPI_HDATA);
2694a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	}
2708ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
2714a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	/* Issue read/write command */
2728ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	EFX_POPULATE_OWORD_7(reg,
2733e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_EE_SPI_HCMD_CMD_EN, 1,
2743e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_EE_SPI_HCMD_SF_SEL, spi->device_id,
2753e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_EE_SPI_HCMD_DABCNT, len,
2763e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_EE_SPI_HCMD_READ, reading,
2773e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_EE_SPI_HCMD_DUBCNT, 0,
2783e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_EE_SPI_HCMD_ADBCNT,
2794a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			     (addressed ? spi->addr_len : 0),
2803e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_EE_SPI_HCMD_ENC, command);
28112d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_EE_SPI_HCMD);
2828ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
2834a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	/* Wait for read/write to complete */
2848ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	rc = falcon_spi_wait(efx);
2858ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (rc)
2868ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		return rc;
2878ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
2888ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Read data */
2894a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	if (out != NULL) {
29012d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_reado(efx, &reg, FR_AB_EE_SPI_HDATA);
2914a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		memcpy(out, &reg, len);
2924a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	}
2934a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
2948ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return 0;
2958ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
2968ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
29723d30f027d1e8ad3bcd6192613122ce925947563Ben Hutchingsstatic size_t
29823d30f027d1e8ad3bcd6192613122ce925947563Ben Hutchingsfalcon_spi_write_limit(const struct efx_spi_device *spi, size_t start)
2994a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings{
3004a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	return min(FALCON_SPI_MAX_LEN,
3014a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		   (spi->block_size - (start & (spi->block_size - 1))));
3024a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings}
3034a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
3044a5b504d0c582db80813b70359b616ea30e91743Ben Hutchingsstatic inline u8
3054a5b504d0c582db80813b70359b616ea30e91743Ben Hutchingsefx_spi_munge_command(const struct efx_spi_device *spi,
3064a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		      const u8 command, const unsigned int address)
3074a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings{
3084a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	return command | (((address >> 8) & spi->munge_address) << 3);
3094a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings}
3104a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
311be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings/* Wait up to 10 ms for buffered write completion */
31276884835684411264cda2f15585261eb02183541Ben Hutchingsint
31376884835684411264cda2f15585261eb02183541Ben Hutchingsfalcon_spi_wait_write(struct efx_nic *efx, const struct efx_spi_device *spi)
3144a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings{
315be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100);
3164a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	u8 status;
317be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	int rc;
3184a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
319be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings	for (;;) {
32076884835684411264cda2f15585261eb02183541Ben Hutchings		rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
3214a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings				    &status, sizeof(status));
3224a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		if (rc)
3234a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			return rc;
3244a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		if (!(status & SPI_STATUS_NRDY))
3254a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			return 0;
326be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings		if (time_after_eq(jiffies, timeout)) {
32762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			netif_err(efx, hw, efx->net_dev,
32862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  "SPI write timeout on device %d"
32962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  " last status=0x%02x\n",
33062776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  spi->device_id, status);
331be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings			return -ETIMEDOUT;
332be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings		}
333be4ea89c8df06f48d0d64cf1d9d20009e83c77c8Ben Hutchings		schedule_timeout_uninterruptible(1);
3344a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	}
3354a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings}
3364a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
33776884835684411264cda2f15585261eb02183541Ben Hutchingsint falcon_spi_read(struct efx_nic *efx, const struct efx_spi_device *spi,
33876884835684411264cda2f15585261eb02183541Ben Hutchings		    loff_t start, size_t len, size_t *retlen, u8 *buffer)
3394a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings{
34023d30f027d1e8ad3bcd6192613122ce925947563Ben Hutchings	size_t block_len, pos = 0;
34123d30f027d1e8ad3bcd6192613122ce925947563Ben Hutchings	unsigned int command;
3424a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	int rc = 0;
3434a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
3444a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	while (pos < len) {
34523d30f027d1e8ad3bcd6192613122ce925947563Ben Hutchings		block_len = min(len - pos, FALCON_SPI_MAX_LEN);
3464a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
3474a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		command = efx_spi_munge_command(spi, SPI_READ, start + pos);
34876884835684411264cda2f15585261eb02183541Ben Hutchings		rc = falcon_spi_cmd(efx, spi, command, start + pos, NULL,
3494a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings				    buffer + pos, block_len);
3504a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		if (rc)
3514a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			break;
3524a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		pos += block_len;
3534a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
3544a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		/* Avoid locking up the system */
3554a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		cond_resched();
3564a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		if (signal_pending(current)) {
3574a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			rc = -EINTR;
3584a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			break;
3594a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		}
3604a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	}
3614a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
3624a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	if (retlen)
3634a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		*retlen = pos;
3644a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	return rc;
3654a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings}
3664a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
36776884835684411264cda2f15585261eb02183541Ben Hutchingsint
36876884835684411264cda2f15585261eb02183541Ben Hutchingsfalcon_spi_write(struct efx_nic *efx, const struct efx_spi_device *spi,
36976884835684411264cda2f15585261eb02183541Ben Hutchings		 loff_t start, size_t len, size_t *retlen, const u8 *buffer)
3704a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings{
3714a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	u8 verify_buffer[FALCON_SPI_MAX_LEN];
37223d30f027d1e8ad3bcd6192613122ce925947563Ben Hutchings	size_t block_len, pos = 0;
37323d30f027d1e8ad3bcd6192613122ce925947563Ben Hutchings	unsigned int command;
3744a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	int rc = 0;
3754a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
3764a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	while (pos < len) {
37776884835684411264cda2f15585261eb02183541Ben Hutchings		rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
3784a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		if (rc)
3794a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			break;
3804a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
38123d30f027d1e8ad3bcd6192613122ce925947563Ben Hutchings		block_len = min(len - pos,
3824a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings				falcon_spi_write_limit(spi, start + pos));
3834a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		command = efx_spi_munge_command(spi, SPI_WRITE, start + pos);
38476884835684411264cda2f15585261eb02183541Ben Hutchings		rc = falcon_spi_cmd(efx, spi, command, start + pos,
3854a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings				    buffer + pos, NULL, block_len);
3864a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		if (rc)
3874a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			break;
3884a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
38976884835684411264cda2f15585261eb02183541Ben Hutchings		rc = falcon_spi_wait_write(efx, spi);
3904a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		if (rc)
3914a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			break;
3924a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
3934a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		command = efx_spi_munge_command(spi, SPI_READ, start + pos);
39476884835684411264cda2f15585261eb02183541Ben Hutchings		rc = falcon_spi_cmd(efx, spi, command, start + pos,
3954a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings				    NULL, verify_buffer, block_len);
3964a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		if (memcmp(verify_buffer, buffer + pos, block_len)) {
3974a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			rc = -EIO;
3984a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			break;
3994a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		}
4004a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
4014a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		pos += block_len;
4024a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
4034a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		/* Avoid locking up the system */
4044a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		cond_resched();
4054a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		if (signal_pending(current)) {
4064a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			rc = -EINTR;
4074a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			break;
4084a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		}
4094a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	}
4104a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
4114a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	if (retlen)
4124a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		*retlen = pos;
4134a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	return rc;
4144a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings}
4154a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
4168ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/**************************************************************************
4178ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
4188ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * MAC wrapper
4198ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
4208ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings **************************************************************************
4218ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings */
422177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings
423ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchingsstatic void falcon_push_multicast_hash(struct efx_nic *efx)
424ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings{
425ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	union efx_multicast_hash *mc_hash = &efx->multicast_hash;
426ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings
427ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	WARN_ON(!mutex_is_locked(&efx->mac_lock));
428ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings
429ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	efx_writeo(efx, &mc_hash->oword[0], FR_AB_MAC_MC_HASH_REG0);
430ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	efx_writeo(efx, &mc_hash->oword[1], FR_AB_MAC_MC_HASH_REG1);
431ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings}
432ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings
433d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchingsstatic void falcon_reset_macs(struct efx_nic *efx)
4348ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
435d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
436d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	efx_oword_t reg, mac_ctrl;
4378ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int count;
4388ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
439daeda6309e1382819a8f8bab548560742ac26cc2Ben Hutchings	if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) {
440177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings		/* It's not safe to use GLB_CTL_REG to reset the
441177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings		 * macs, so instead use the internal MAC resets
442177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings		 */
4438fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings		EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1);
4448fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings		efx_writeo(efx, &reg, FR_AB_XM_GLB_CFG);
4458fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings
4468fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings		for (count = 0; count < 10000; count++) {
4478fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings			efx_reado(efx, &reg, FR_AB_XM_GLB_CFG);
4488fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings			if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) ==
4498fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings			    0)
4508fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings				return;
4518fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings			udelay(10);
452177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings		}
4538fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings
4548fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings		netif_err(efx, hw, efx->net_dev,
4558fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings			  "timed out waiting for XMAC core reset\n");
456177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings	}
4578ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
458d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	/* Mac stats will fail whist the TX fifo is draining */
459d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	WARN_ON(nic_data->stats_disable_count == 0);
4608ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
461d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	efx_reado(efx, &mac_ctrl, FR_AB_MAC_CTRL);
462d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	EFX_SET_OWORD_FIELD(mac_ctrl, FRF_BB_TXFIFO_DRAIN_EN, 1);
463d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL);
4648ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
46512d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &reg, FR_AB_GLB_CTL);
4663e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGTX, 1);
4673e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGRX, 1);
4683e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_EM, 1);
46912d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_GLB_CTL);
4708ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
4718ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	count = 0;
4728ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	while (1) {
47312d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_reado(efx, &reg, FR_AB_GLB_CTL);
4743e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		if (!EFX_OWORD_FIELD(reg, FRF_AB_RST_XGTX) &&
4753e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		    !EFX_OWORD_FIELD(reg, FRF_AB_RST_XGRX) &&
4763e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		    !EFX_OWORD_FIELD(reg, FRF_AB_RST_EM)) {
47762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			netif_dbg(efx, hw, efx->net_dev,
47862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  "Completed MAC reset after %d loops\n",
47962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  count);
4808ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			break;
4818ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		}
4828ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		if (count > 20) {
48362776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			netif_err(efx, hw, efx->net_dev, "MAC reset failed\n");
4848ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			break;
4858ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		}
4868ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		count++;
4878ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		udelay(10);
4888ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
4898ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
490d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	/* Ensure the correct MAC is selected before statistics
491d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	 * are re-enabled by the caller */
492d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL);
493b7b40eeb0f76e73503a7e5a98d1353c2e42d9a18Steve Hodgson
494b7b40eeb0f76e73503a7e5a98d1353c2e42d9a18Steve Hodgson	falcon_setup_xaui(efx);
495177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings}
496177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings
497177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchingsvoid falcon_drain_tx_fifo(struct efx_nic *efx)
498177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings{
499177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings	efx_oword_t reg;
500177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings
501daeda6309e1382819a8f8bab548560742ac26cc2Ben Hutchings	if ((efx_nic_rev(efx) < EFX_REV_FALCON_B0) ||
502177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings	    (efx->loopback_mode != LOOPBACK_NONE))
503177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings		return;
504177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings
50512d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &reg, FR_AB_MAC_CTRL);
506177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings	/* There is no point in draining more than once */
5073e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	if (EFX_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN))
508177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings		return;
509177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings
510177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings	falcon_reset_macs(efx);
5118ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
5128ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
513d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchingsstatic void falcon_deconfigure_mac_wrapper(struct efx_nic *efx)
5148ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
515177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings	efx_oword_t reg;
5168ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
517daeda6309e1382819a8f8bab548560742ac26cc2Ben Hutchings	if (efx_nic_rev(efx) < EFX_REV_FALCON_B0)
5188ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		return;
5198ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
5208ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Isolate the MAC -> RX */
52112d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &reg, FR_AZ_RX_CFG);
5223e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 0);
52312d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AZ_RX_CFG);
5248ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
525d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	/* Isolate TX -> MAC */
526d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	falcon_drain_tx_fifo(efx);
5278ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
5288ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
5298ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchingsvoid falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
5308ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
531eb50c0d67fe3c5513c717c2dee6d9771c51be703Ben Hutchings	struct efx_link_state *link_state = &efx->link_state;
5328ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_oword_t reg;
533fd371e32fe53f137a0f940d61772bda92180007bSteve Hodgson	int link_speed, isolate;
534fd371e32fe53f137a0f940d61772bda92180007bSteve Hodgson
535a7d529ae2158b5300e4aa16c21f1828bc864449bBen Hutchings	isolate = !!ACCESS_ONCE(efx->reset_pending);
5368ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
537eb50c0d67fe3c5513c717c2dee6d9771c51be703Ben Hutchings	switch (link_state->speed) {
538f31a45d2f45a7667acd6e85ab6613b0910c55ea9Ben Hutchings	case 10000: link_speed = 3; break;
539f31a45d2f45a7667acd6e85ab6613b0910c55ea9Ben Hutchings	case 1000:  link_speed = 2; break;
540f31a45d2f45a7667acd6e85ab6613b0910c55ea9Ben Hutchings	case 100:   link_speed = 1; break;
541f31a45d2f45a7667acd6e85ab6613b0910c55ea9Ben Hutchings	default:    link_speed = 0; break;
542f31a45d2f45a7667acd6e85ab6613b0910c55ea9Ben Hutchings	}
5438ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* MAC_LINK_STATUS controls MAC backpressure but doesn't work
5448ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 * as advertised.  Disable to ensure packets are not
5458ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 * indefinitely held and TX queue can be flushed at any point
5468ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 * while the link is down. */
5478ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	EFX_POPULATE_OWORD_5(reg,
5483e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_MAC_XOFF_VAL, 0xffff /* max pause time */,
5493e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_MAC_BCAD_ACPT, 1,
5503e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_MAC_UC_PROM, efx->promiscuous,
5513e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_MAC_LINK_STATUS, 1, /* always set */
5523e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_MAC_SPEED, link_speed);
5538ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* On B0, MAC backpressure can be disabled and packets get
5548ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 * discarded. */
555daeda6309e1382819a8f8bab548560742ac26cc2Ben Hutchings	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
5563e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN,
557fd371e32fe53f137a0f940d61772bda92180007bSteve Hodgson				    !link_state->up || isolate);
5588ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
5598ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
56012d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_MAC_CTRL);
5618ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
5628ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Restore the multicast hash registers. */
5638be4f3e6f7b670529bd67aa1f0319bec1e29ebcfBen Hutchings	falcon_push_multicast_hash(efx);
5648ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
56512d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &reg, FR_AZ_RX_CFG);
5664b0d29dcfca9eafbf6e940862ab022df3ef2dd6fBen Hutchings	/* Enable XOFF signal from RX FIFO (we enabled it during NIC
5674b0d29dcfca9eafbf6e940862ab022df3ef2dd6fBen Hutchings	 * initialisation but it may read back as 0) */
5684b0d29dcfca9eafbf6e940862ab022df3ef2dd6fBen Hutchings	EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, 1);
5698ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Unisolate the MAC -> RX */
570daeda6309e1382819a8f8bab548560742ac26cc2Ben Hutchings	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0)
571fd371e32fe53f137a0f940d61772bda92180007bSteve Hodgson		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, !isolate);
57212d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AZ_RX_CFG);
5738ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
5748ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
57555edc6e6ff728681ebc10d418222740705376664Ben Hutchingsstatic void falcon_stats_request(struct efx_nic *efx)
5768ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
57755edc6e6ff728681ebc10d418222740705376664Ben Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
5788ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_oword_t reg;
5798ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
58055edc6e6ff728681ebc10d418222740705376664Ben Hutchings	WARN_ON(nic_data->stats_pending);
58155edc6e6ff728681ebc10d418222740705376664Ben Hutchings	WARN_ON(nic_data->stats_disable_count);
5828ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
58355edc6e6ff728681ebc10d418222740705376664Ben Hutchings	if (nic_data->stats_dma_done == NULL)
58455edc6e6ff728681ebc10d418222740705376664Ben Hutchings		return;	/* no mac selected */
5858ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
58655edc6e6ff728681ebc10d418222740705376664Ben Hutchings	*nic_data->stats_dma_done = FALCON_STATS_NOT_DONE;
58755edc6e6ff728681ebc10d418222740705376664Ben Hutchings	nic_data->stats_pending = true;
5888ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	wmb(); /* ensure done flag is clear */
5898ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
5908ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Initiate DMA transfer of stats */
5918ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	EFX_POPULATE_OWORD_2(reg,
5923e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_MAC_STAT_DMA_CMD, 1,
5933e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_MAC_STAT_DMA_ADR,
5948ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			     efx->stats_buffer.dma_addr);
59512d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_MAC_STAT_DMA);
5968ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
59755edc6e6ff728681ebc10d418222740705376664Ben Hutchings	mod_timer(&nic_data->stats_timer, round_jiffies_up(jiffies + HZ / 2));
59855edc6e6ff728681ebc10d418222740705376664Ben Hutchings}
59955edc6e6ff728681ebc10d418222740705376664Ben Hutchings
60055edc6e6ff728681ebc10d418222740705376664Ben Hutchingsstatic void falcon_stats_complete(struct efx_nic *efx)
60155edc6e6ff728681ebc10d418222740705376664Ben Hutchings{
60255edc6e6ff728681ebc10d418222740705376664Ben Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
60355edc6e6ff728681ebc10d418222740705376664Ben Hutchings
60455edc6e6ff728681ebc10d418222740705376664Ben Hutchings	if (!nic_data->stats_pending)
60555edc6e6ff728681ebc10d418222740705376664Ben Hutchings		return;
60655edc6e6ff728681ebc10d418222740705376664Ben Hutchings
6073db1cd5c05f35fb43eb134df6f321de4e63141f2Rusty Russell	nic_data->stats_pending = false;
60855edc6e6ff728681ebc10d418222740705376664Ben Hutchings	if (*nic_data->stats_dma_done == FALCON_STATS_DONE) {
60955edc6e6ff728681ebc10d418222740705376664Ben Hutchings		rmb(); /* read the done flag before the stats */
610710b208dc2687fdb3370110d54a67fb2288835ebBen Hutchings		falcon_update_stats_xmac(efx);
61155edc6e6ff728681ebc10d418222740705376664Ben Hutchings	} else {
61262776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_err(efx, hw, efx->net_dev,
61362776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "timed out waiting for statistics\n");
6148ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
61555edc6e6ff728681ebc10d418222740705376664Ben Hutchings}
6168ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
61755edc6e6ff728681ebc10d418222740705376664Ben Hutchingsstatic void falcon_stats_timer_func(unsigned long context)
61855edc6e6ff728681ebc10d418222740705376664Ben Hutchings{
61955edc6e6ff728681ebc10d418222740705376664Ben Hutchings	struct efx_nic *efx = (struct efx_nic *)context;
62055edc6e6ff728681ebc10d418222740705376664Ben Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
62155edc6e6ff728681ebc10d418222740705376664Ben Hutchings
62255edc6e6ff728681ebc10d418222740705376664Ben Hutchings	spin_lock(&efx->stats_lock);
62355edc6e6ff728681ebc10d418222740705376664Ben Hutchings
62455edc6e6ff728681ebc10d418222740705376664Ben Hutchings	falcon_stats_complete(efx);
62555edc6e6ff728681ebc10d418222740705376664Ben Hutchings	if (nic_data->stats_disable_count == 0)
62655edc6e6ff728681ebc10d418222740705376664Ben Hutchings		falcon_stats_request(efx);
62755edc6e6ff728681ebc10d418222740705376664Ben Hutchings
62855edc6e6ff728681ebc10d418222740705376664Ben Hutchings	spin_unlock(&efx->stats_lock);
6298ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
6308ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
631fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgsonstatic bool falcon_loopback_link_poll(struct efx_nic *efx)
632fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson{
633fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	struct efx_link_state old_state = efx->link_state;
634fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
635fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	WARN_ON(!mutex_is_locked(&efx->mac_lock));
636fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	WARN_ON(!LOOPBACK_INTERNAL(efx));
637fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
638fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	efx->link_state.fd = true;
639fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	efx->link_state.fc = efx->wanted_fc;
640fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	efx->link_state.up = true;
6418fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx->link_state.speed = 10000;
642fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
643fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	return !efx_link_state_equal(&efx->link_state, &old_state);
644fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson}
645fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
646d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchingsstatic int falcon_reconfigure_port(struct efx_nic *efx)
647d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings{
648d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	int rc;
649d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
650d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	WARN_ON(efx_nic_rev(efx) > EFX_REV_FALCON_B0);
651d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
652d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	/* Poll the PHY link state *before* reconfiguring it. This means we
653d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	 * will pick up the correct speed (in loopback) to select the correct
654d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	 * MAC.
655d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	 */
656d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	if (LOOPBACK_INTERNAL(efx))
657d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings		falcon_loopback_link_poll(efx);
658d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	else
659d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings		efx->phy_op->poll(efx);
660d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
661d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	falcon_stop_nic_stats(efx);
662d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	falcon_deconfigure_mac_wrapper(efx);
663d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
6648fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	falcon_reset_macs(efx);
665d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
666d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	efx->phy_op->reconfigure(efx);
667710b208dc2687fdb3370110d54a67fb2288835ebBen Hutchings	rc = falcon_reconfigure_xmac(efx);
668d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	BUG_ON(rc);
669d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
670d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	falcon_start_nic_stats(efx);
671d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
672d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	/* Synchronise efx->link_state with the kernel */
673d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	efx_link_status_changed(efx);
674d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
675d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	return 0;
676d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings}
677d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
6788ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/**************************************************************************
6798ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
6808ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * PHY access via GMII
6818ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
6828ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings **************************************************************************
6838ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings */
6848ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
6858ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Wait for GMII access to complete */
6868ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchingsstatic int falcon_gmii_wait(struct efx_nic *efx)
6878ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
68880cb9a0f7f381e1c0e9f6dabec6e67db0dd3a0d9Ben Hutchings	efx_oword_t md_stat;
6898ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int count;
6908ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
69125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	/* wait up to 50ms - taken max from datasheet */
692177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings	for (count = 0; count < 5000; count++) {
69380cb9a0f7f381e1c0e9f6dabec6e67db0dd3a0d9Ben Hutchings		efx_reado(efx, &md_stat, FR_AB_MD_STAT);
69480cb9a0f7f381e1c0e9f6dabec6e67db0dd3a0d9Ben Hutchings		if (EFX_OWORD_FIELD(md_stat, FRF_AB_MD_BSY) == 0) {
69580cb9a0f7f381e1c0e9f6dabec6e67db0dd3a0d9Ben Hutchings			if (EFX_OWORD_FIELD(md_stat, FRF_AB_MD_LNFL) != 0 ||
69680cb9a0f7f381e1c0e9f6dabec6e67db0dd3a0d9Ben Hutchings			    EFX_OWORD_FIELD(md_stat, FRF_AB_MD_BSERR) != 0) {
69762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				netif_err(efx, hw, efx->net_dev,
69862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings					  "error from GMII access "
69962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings					  EFX_OWORD_FMT"\n",
70062776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings					  EFX_OWORD_VAL(md_stat));
7018ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings				return -EIO;
7028ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			}
7038ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			return 0;
7048ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		}
7058ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		udelay(10);
7068ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
70762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings	netif_err(efx, hw, efx->net_dev, "timed out waiting for GMII\n");
7088ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return -ETIMEDOUT;
7098ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
7108ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
71168e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings/* Write an MDIO register of a PHY connected to Falcon. */
71268e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchingsstatic int falcon_mdio_write(struct net_device *net_dev,
71368e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings			     int prtad, int devad, u16 addr, u16 value)
7148ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
715767e468c06fc0e88f95881c1056437688b37c7c6Ben Hutchings	struct efx_nic *efx = netdev_priv(net_dev);
7164833f02a2972b7da4c8a15e1e329db0f984a75d9Ben Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
7178ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_oword_t reg;
71868e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	int rc;
7198ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
72062776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings	netif_vdbg(efx, hw, efx->net_dev,
72162776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		   "writing MDIO %d register %d.%d with 0x%04x\n",
72268e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings		    prtad, devad, addr, value);
7238ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
7244833f02a2972b7da4c8a15e1e329db0f984a75d9Ben Hutchings	mutex_lock(&nic_data->mdio_lock);
7258ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
72668e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	/* Check MDIO not currently being accessed */
72768e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	rc = falcon_gmii_wait(efx);
72868e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	if (rc)
7298ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		goto out;
7308ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
7318ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Write the address/ID register */
7323e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_PHY_ADR, addr);
73312d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_MD_PHY_ADR);
7348ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
7353e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_PRT_ADR, prtad,
7363e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_MD_DEV_ADR, devad);
73712d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_MD_ID);
7388ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
7398ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Write data */
7403e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_TXD, value);
74112d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_MD_TXD);
7428ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
7438ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	EFX_POPULATE_OWORD_2(reg,
7443e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_MD_WRC, 1,
7453e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_MD_GC, 0);
74612d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_MD_CS);
7478ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
7488ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Wait for data to be written */
74968e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	rc = falcon_gmii_wait(efx);
75068e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	if (rc) {
7518ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		/* Abort the write operation */
7528ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		EFX_POPULATE_OWORD_2(reg,
7533e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_MD_WRC, 0,
7543e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_MD_GC, 1);
75512d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_writeo(efx, &reg, FR_AB_MD_CS);
7568ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		udelay(10);
7578ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
7588ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
759ab86746175a5e1379abb9c7c38522af4d3176f57Steve Hodgsonout:
7604833f02a2972b7da4c8a15e1e329db0f984a75d9Ben Hutchings	mutex_unlock(&nic_data->mdio_lock);
76168e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	return rc;
7628ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
7638ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
76468e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings/* Read an MDIO register of a PHY connected to Falcon. */
76568e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchingsstatic int falcon_mdio_read(struct net_device *net_dev,
76668e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings			    int prtad, int devad, u16 addr)
7678ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
768767e468c06fc0e88f95881c1056437688b37c7c6Ben Hutchings	struct efx_nic *efx = netdev_priv(net_dev);
7694833f02a2972b7da4c8a15e1e329db0f984a75d9Ben Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
7708ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_oword_t reg;
77168e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	int rc;
7728ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
7734833f02a2972b7da4c8a15e1e329db0f984a75d9Ben Hutchings	mutex_lock(&nic_data->mdio_lock);
7748ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
77568e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	/* Check MDIO not currently being accessed */
77668e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	rc = falcon_gmii_wait(efx);
77768e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	if (rc)
7788ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		goto out;
7798ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
7803e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_PHY_ADR, addr);
78112d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_MD_PHY_ADR);
7828ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
7833e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_PRT_ADR, prtad,
7843e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AB_MD_DEV_ADR, devad);
78512d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_MD_ID);
7868ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
7878ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Request data to be read */
7883e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_RDC, 1, FRF_AB_MD_GC, 0);
78912d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AB_MD_CS);
7908ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
7918ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Wait for data to become available */
79268e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	rc = falcon_gmii_wait(efx);
79368e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	if (rc == 0) {
79412d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_reado(efx, &reg, FR_AB_MD_RXD);
7953e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		rc = EFX_OWORD_FIELD(reg, FRF_AB_MD_RXD);
79662776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_vdbg(efx, hw, efx->net_dev,
79762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			   "read from MDIO %d register %d.%d, got %04x\n",
79862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			   prtad, devad, addr, rc);
7998ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	} else {
8008ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		/* Abort the read operation */
8018ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		EFX_POPULATE_OWORD_2(reg,
8023e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_MD_RIC, 0,
8033e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_MD_GC, 1);
80412d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_writeo(efx, &reg, FR_AB_MD_CS);
8058ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
80662776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_dbg(efx, hw, efx->net_dev,
80762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "read from MDIO %d register %d.%d, got error %d\n",
80862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  prtad, devad, addr, rc);
8098ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
8108ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
811ab86746175a5e1379abb9c7c38522af4d3176f57Steve Hodgsonout:
8124833f02a2972b7da4c8a15e1e329db0f984a75d9Ben Hutchings	mutex_unlock(&nic_data->mdio_lock);
81368e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	return rc;
8148ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
8158ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
8168ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* This call is responsible for hooking in the MAC and PHY operations */
817ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchingsstatic int falcon_probe_port(struct efx_nic *efx)
8188ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
8198fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
8208ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int rc;
8218ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
82296c45726c7dd5ee11b8773810208c41e40a93ffdBen Hutchings	switch (efx->phy_type) {
82396c45726c7dd5ee11b8773810208c41e40a93ffdBen Hutchings	case PHY_TYPE_SFX7101:
82496c45726c7dd5ee11b8773810208c41e40a93ffdBen Hutchings		efx->phy_op = &falcon_sfx7101_phy_ops;
82596c45726c7dd5ee11b8773810208c41e40a93ffdBen Hutchings		break;
82696c45726c7dd5ee11b8773810208c41e40a93ffdBen Hutchings	case PHY_TYPE_QT2022C2:
82796c45726c7dd5ee11b8773810208c41e40a93ffdBen Hutchings	case PHY_TYPE_QT2025C:
828b37b62fea1d1bf68ca51818f8eb1035188efd030Ben Hutchings		efx->phy_op = &falcon_qt202x_phy_ops;
82996c45726c7dd5ee11b8773810208c41e40a93ffdBen Hutchings		break;
8307e51b439f147670c4ddd2bf6ca4567592b5312deBen Hutchings	case PHY_TYPE_TXC43128:
8317e51b439f147670c4ddd2bf6ca4567592b5312deBen Hutchings		efx->phy_op = &falcon_txc_phy_ops;
8327e51b439f147670c4ddd2bf6ca4567592b5312deBen Hutchings		break;
83396c45726c7dd5ee11b8773810208c41e40a93ffdBen Hutchings	default:
83462776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_err(efx, probe, efx->net_dev, "Unknown PHY type %d\n",
83562776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  efx->phy_type);
83696c45726c7dd5ee11b8773810208c41e40a93ffdBen Hutchings		return -ENODEV;
83796c45726c7dd5ee11b8773810208c41e40a93ffdBen Hutchings	}
83896c45726c7dd5ee11b8773810208c41e40a93ffdBen Hutchings
839c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings	/* Fill out MDIO structure and loopback modes */
8404833f02a2972b7da4c8a15e1e329db0f984a75d9Ben Hutchings	mutex_init(&nic_data->mdio_lock);
84168e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	efx->mdio.mdio_read = falcon_mdio_read;
84268e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	efx->mdio.mdio_write = falcon_mdio_write;
843c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings	rc = efx->phy_op->probe(efx);
844c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings	if (rc != 0)
845c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings		return rc;
8468ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
847b895d73e9836fccc402e48a8f63e6805d2edc87bSteve Hodgson	/* Initial assumption */
848b895d73e9836fccc402e48a8f63e6805d2edc87bSteve Hodgson	efx->link_state.speed = 10000;
849b895d73e9836fccc402e48a8f63e6805d2edc87bSteve Hodgson	efx->link_state.fd = true;
850b895d73e9836fccc402e48a8f63e6805d2edc87bSteve Hodgson
8518ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */
852daeda6309e1382819a8f8bab548560742ac26cc2Ben Hutchings	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0)
85304cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings		efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
8548ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	else
85504cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings		efx->wanted_fc = EFX_FC_RX;
8567a6b8f6f7f74085a1330b0f9765d81bcea8c58b7Steve Hodgson	if (efx->mdio.mmds & MDIO_DEVS_AN)
8577a6b8f6f7f74085a1330b0f9765d81bcea8c58b7Steve Hodgson		efx->wanted_fc |= EFX_FC_AUTO;
8588ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
8598ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Allocate buffer for stats */
860152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
861152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings				  FALCON_MAC_STATS_SIZE);
8628ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (rc)
8638ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		return rc;
86462776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings	netif_dbg(efx, probe, efx->net_dev,
86562776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		  "stats buffer at %llx (virt %p phys %llx)\n",
86662776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		  (u64)efx->stats_buffer.dma_addr,
86762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		  efx->stats_buffer.addr,
86862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		  (u64)virt_to_phys(efx->stats_buffer.addr));
8698fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	nic_data->stats_dma_done = efx->stats_buffer.addr + XgDmaDone_offset;
8708ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
8718ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return 0;
8728ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
8738ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
874ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchingsstatic void falcon_remove_port(struct efx_nic *efx)
8758ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
876ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	efx->phy_op->remove(efx);
877152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	efx_nic_free_buffer(efx, &efx->stats_buffer);
8788ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
8798ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
88040641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings/* Global events are basically PHY events */
88140641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchingsstatic bool
88240641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchingsfalcon_handle_global_event(struct efx_channel *channel, efx_qword_t *event)
88340641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings{
88440641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	struct efx_nic *efx = channel->efx;
885cef68bde74f083d83c18ce870ed834e82ee0ae5aBen Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
88640641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings
88740641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) ||
88840641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	    EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) ||
88940641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	    EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR))
89040641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings		/* Ignored */
89140641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings		return true;
89240641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings
89340641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	if ((efx_nic_rev(efx) == EFX_REV_FALCON_B0) &&
89440641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	    EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) {
895cef68bde74f083d83c18ce870ed834e82ee0ae5aBen Hutchings		nic_data->xmac_poll_required = true;
89640641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings		return true;
89740641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	}
89840641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings
89940641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1 ?
90040641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	    EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) :
90140641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	    EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) {
90240641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings		netif_err(efx, rx_err, efx->net_dev,
90340641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings			  "channel %d seen global RX_RESET event. Resetting.\n",
90440641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings			  channel->channel);
90540641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings
90640641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings		atomic_inc(&efx->rx_reset);
90740641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings		efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ?
90840641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings				   RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE);
90940641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings		return true;
91040641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	}
91140641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings
91240641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	return false;
91340641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings}
91440641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings
9158ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/**************************************************************************
9168ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
9178c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings * Falcon test code
9188c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings *
9198c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings **************************************************************************/
9208c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
9210aa3fbaa3f2d29a14231ebb0c8e521c23701d41fBen Hutchingsstatic int
9220aa3fbaa3f2d29a14231ebb0c8e521c23701d41fBen Hutchingsfalcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out)
9238c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings{
9244de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
9258c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	struct falcon_nvconfig *nvconfig;
9268c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	struct efx_spi_device *spi;
9278c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	void *region;
9288c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	int rc, magic_num, struct_ver;
9298c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	__le16 *word, *limit;
9308c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	u32 csum;
9318c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
9324de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	if (efx_spi_present(&nic_data->spi_flash))
9334de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings		spi = &nic_data->spi_flash;
9344de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	else if (efx_spi_present(&nic_data->spi_eeprom))
9354de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings		spi = &nic_data->spi_eeprom;
9364de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	else
9372f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings		return -EINVAL;
9382f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings
9390a95f56323ce93dac354c1b2d54bf959a985cf7dBen Hutchings	region = kmalloc(FALCON_NVCONFIG_END, GFP_KERNEL);
9408c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	if (!region)
9418c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings		return -ENOMEM;
9423e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	nvconfig = region + FALCON_NVCONFIG_OFFSET;
9438c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
9444de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	mutex_lock(&nic_data->spi_lock);
94576884835684411264cda2f15585261eb02183541Ben Hutchings	rc = falcon_spi_read(efx, spi, 0, FALCON_NVCONFIG_END, NULL, region);
9464de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	mutex_unlock(&nic_data->spi_lock);
9478c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	if (rc) {
94862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_err(efx, hw, efx->net_dev, "Failed to read %s\n",
9494de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings			  efx_spi_present(&nic_data->spi_flash) ?
9504de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings			  "flash" : "EEPROM");
9518c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings		rc = -EIO;
9528c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings		goto out;
9538c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	}
9548c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
9558c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	magic_num = le16_to_cpu(nvconfig->board_magic_num);
9568c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	struct_ver = le16_to_cpu(nvconfig->board_struct_ver);
9578c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
9588c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	rc = -EINVAL;
9593e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	if (magic_num != FALCON_NVCONFIG_BOARD_MAGIC_NUM) {
96062776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_err(efx, hw, efx->net_dev,
96162776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "NVRAM bad magic 0x%x\n", magic_num);
9628c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings		goto out;
9638c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	}
9648c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	if (struct_ver < 2) {
96562776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_err(efx, hw, efx->net_dev,
96662776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "NVRAM has ancient version 0x%x\n", struct_ver);
9678c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings		goto out;
9688c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	} else if (struct_ver < 4) {
9698c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings		word = &nvconfig->board_magic_num;
9708c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings		limit = (__le16 *) (nvconfig + 1);
9718c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	} else {
9728c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings		word = region;
9730a95f56323ce93dac354c1b2d54bf959a985cf7dBen Hutchings		limit = region + FALCON_NVCONFIG_END;
9748c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	}
9758c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	for (csum = 0; word < limit; ++word)
9768c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings		csum += le16_to_cpu(*word);
9778c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
9788c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	if (~csum & 0xffff) {
97962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_err(efx, hw, efx->net_dev,
98062776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "NVRAM has incorrect checksum\n");
9818c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings		goto out;
9828c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	}
9838c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
9848c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	rc = 0;
9858c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	if (nvconfig_out)
9868c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings		memcpy(nvconfig_out, nvconfig, sizeof(*nvconfig));
9878c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
9888c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings out:
9898c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	kfree(region);
9908c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	return rc;
9918c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings}
9928c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
9930aa3fbaa3f2d29a14231ebb0c8e521c23701d41fBen Hutchingsstatic int falcon_test_nvram(struct efx_nic *efx)
9940aa3fbaa3f2d29a14231ebb0c8e521c23701d41fBen Hutchings{
9950aa3fbaa3f2d29a14231ebb0c8e521c23701d41fBen Hutchings	return falcon_read_nvram(efx, NULL);
9960aa3fbaa3f2d29a14231ebb0c8e521c23701d41fBen Hutchings}
9970aa3fbaa3f2d29a14231ebb0c8e521c23701d41fBen Hutchings
998152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchingsstatic const struct efx_nic_register_test falcon_b0_register_tests[] = {
9993e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AZ_ADR_REGION,
10004cddca5484e047fa77ce090bec96fbfb92a6eb19Steve Hodgson	  EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) },
10013e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AZ_RX_CFG,
10028c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0xFFFFFFFE, 0x00017FFF, 0x00000000, 0x00000000) },
10033e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AZ_TX_CFG,
10048c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0x7FFF0037, 0x00000000, 0x00000000, 0x00000000) },
10053e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AZ_TX_RESERVED,
10068c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF) },
10073e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AB_MAC_CTRL,
10088c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0xFFFF0000, 0x00000000, 0x00000000, 0x00000000) },
10093e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AZ_SRM_TX_DC_CFG,
10108c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0x001FFFFF, 0x00000000, 0x00000000, 0x00000000) },
10113e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AZ_RX_DC_CFG,
10128c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0x0000000F, 0x00000000, 0x00000000, 0x00000000) },
10133e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AZ_RX_DC_PF_WM,
10148c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) },
10153e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_BZ_DP_CTRL,
10168c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) },
10173e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AB_GM_CFG2,
1018177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings	  EFX_OWORD32(0x00007337, 0x00000000, 0x00000000, 0x00000000) },
10193e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AB_GMF_CFG0,
1020177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings	  EFX_OWORD32(0x00001F1F, 0x00000000, 0x00000000, 0x00000000) },
10213e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AB_XM_GLB_CFG,
10228c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0x00000C68, 0x00000000, 0x00000000, 0x00000000) },
10233e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AB_XM_TX_CFG,
10248c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0x00080164, 0x00000000, 0x00000000, 0x00000000) },
10253e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AB_XM_RX_CFG,
10268c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0x07100A0C, 0x00000000, 0x00000000, 0x00000000) },
10273e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AB_XM_RX_PARAM,
10288c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0x00001FF8, 0x00000000, 0x00000000, 0x00000000) },
10293e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AB_XM_FC,
10308c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0xFFFF0001, 0x00000000, 0x00000000, 0x00000000) },
10313e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AB_XM_ADR_LO,
10328c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000) },
10333e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	{ FR_AB_XX_SD_CTL,
10348c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	  EFX_OWORD32(0x0003FF0F, 0x00000000, 0x00000000, 0x00000000) },
10358c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings};
10368c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
1037152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchingsstatic int falcon_b0_test_registers(struct efx_nic *efx)
1038152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings{
1039152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	return efx_nic_test_registers(efx, falcon_b0_register_tests,
1040152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings				      ARRAY_SIZE(falcon_b0_register_tests));
1041152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings}
1042152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings
10438ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/**************************************************************************
10448ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
10458ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * Device reset
10468ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
10478ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings **************************************************************************
10488ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings */
10498ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
10500e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchingsstatic enum reset_type falcon_map_reset_reason(enum reset_type reason)
10510e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings{
10520e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	switch (reason) {
10530e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	case RESET_TYPE_RX_RECOVERY:
10540e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	case RESET_TYPE_RX_DESC_FETCH:
10550e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	case RESET_TYPE_TX_DESC_FETCH:
10560e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	case RESET_TYPE_TX_SKIP:
10570e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		/* These can occasionally occur due to hardware bugs.
10580e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		 * We try to reset without disrupting the link.
10590e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		 */
10600e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		return RESET_TYPE_INVISIBLE;
10610e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	default:
10620e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		return RESET_TYPE_ALL;
10630e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	}
10640e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings}
10650e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings
10660e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchingsstatic int falcon_map_reset_flags(u32 *flags)
10670e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings{
10680e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	enum {
10690e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		FALCON_RESET_INVISIBLE = (ETH_RESET_DMA | ETH_RESET_FILTER |
10700e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings					  ETH_RESET_OFFLOAD | ETH_RESET_MAC),
10710e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		FALCON_RESET_ALL = FALCON_RESET_INVISIBLE | ETH_RESET_PHY,
10720e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		FALCON_RESET_WORLD = FALCON_RESET_ALL | ETH_RESET_IRQ,
10730e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	};
10740e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings
10750e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	if ((*flags & FALCON_RESET_WORLD) == FALCON_RESET_WORLD) {
10760e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		*flags &= ~FALCON_RESET_WORLD;
10770e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		return RESET_TYPE_WORLD;
10780e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	}
10790e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings
10800e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	if ((*flags & FALCON_RESET_ALL) == FALCON_RESET_ALL) {
10810e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		*flags &= ~FALCON_RESET_ALL;
10820e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		return RESET_TYPE_ALL;
10830e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	}
10840e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings
10850e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	if ((*flags & FALCON_RESET_INVISIBLE) == FALCON_RESET_INVISIBLE) {
10860e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		*flags &= ~FALCON_RESET_INVISIBLE;
10870e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings		return RESET_TYPE_INVISIBLE;
10880e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	}
10890e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings
10900e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	return -EINVAL;
10910e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings}
10920e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings
10938ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Resets NIC to known state.  This routine must be called in process
10948ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * context and is allowed to sleep. */
10954de92180258ac661bbce0f0065c9c81633ac862bBen Hutchingsstatic int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
10968ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
10978ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
10988ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_oword_t glb_ctl_reg_ker;
10998ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int rc;
11008ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
110162776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings	netif_dbg(efx, hw, efx->net_dev, "performing %s hardware reset\n",
110262776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		  RESET_TYPE(method));
11038ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
11048ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Initiate device reset */
11058ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (method == RESET_TYPE_WORLD) {
11068ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		rc = pci_save_state(efx->pci_dev);
11078ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		if (rc) {
110862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			netif_err(efx, drv, efx->net_dev,
110962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  "failed to backup PCI state of primary "
111062776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  "function prior to hardware reset\n");
11118ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			goto fail1;
11128ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		}
1113152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings		if (efx_nic_is_dual_func(efx)) {
11148ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			rc = pci_save_state(nic_data->pci_dev2);
11158ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			if (rc) {
111662776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				netif_err(efx, drv, efx->net_dev,
111762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings					  "failed to backup PCI state of "
111862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings					  "secondary function prior to "
111962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings					  "hardware reset\n");
11208ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings				goto fail2;
11218ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			}
11228ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		}
11238ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
11248ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		EFX_POPULATE_OWORD_2(glb_ctl_reg_ker,
11253e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_EXT_PHY_RST_DUR,
11263e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FFE_AB_EXT_PHY_RST_DUR_10240US,
11273e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_SWRST, 1);
11288ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	} else {
11298ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		EFX_POPULATE_OWORD_7(glb_ctl_reg_ker,
11303e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     /* exclude PHY from "invisible" reset */
11313e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_EXT_PHY_RST_CTL,
11323e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     method == RESET_TYPE_INVISIBLE,
11333e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     /* exclude EEPROM/flash and PCIe */
11343e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_PCIE_CORE_RST_CTL, 1,
11353e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_PCIE_NSTKY_RST_CTL, 1,
11363e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_PCIE_SD_RST_CTL, 1,
11373e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_EE_RST_CTL, 1,
11383e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_EXT_PHY_RST_DUR,
11393e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FFE_AB_EXT_PHY_RST_DUR_10240US,
11403e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_SWRST, 1);
11413e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	}
114212d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL);
11438ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
114462776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings	netif_dbg(efx, hw, efx->net_dev, "waiting for hardware reset\n");
11458ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	schedule_timeout_uninterruptible(HZ / 20);
11468ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
11478ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Restore PCI configuration if needed */
11488ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (method == RESET_TYPE_WORLD) {
11491d3c16a818e992c199844954d95c17fd7ce6cbbaJon Mason		if (efx_nic_is_dual_func(efx))
11501d3c16a818e992c199844954d95c17fd7ce6cbbaJon Mason			pci_restore_state(nic_data->pci_dev2);
11511d3c16a818e992c199844954d95c17fd7ce6cbbaJon Mason		pci_restore_state(efx->pci_dev);
115262776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_dbg(efx, drv, efx->net_dev,
115362776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "successfully restored PCI config\n");
11548ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
11558ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
11568ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Assert that reset complete */
115712d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL);
11583e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	if (EFX_OWORD_FIELD(glb_ctl_reg_ker, FRF_AB_SWRST) != 0) {
11598ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		rc = -ETIMEDOUT;
116062776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_err(efx, hw, efx->net_dev,
116162776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "timed out waiting for hardware reset\n");
11621d3c16a818e992c199844954d95c17fd7ce6cbbaJon Mason		goto fail3;
11638ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
116462776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings	netif_dbg(efx, hw, efx->net_dev, "hardware reset complete\n");
11658ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
11668ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return 0;
11678ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
11688ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* pci_save_state() and pci_restore_state() MUST be called in pairs */
11698ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchingsfail2:
11708ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	pci_restore_state(efx->pci_dev);
11718ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchingsfail1:
11721d3c16a818e992c199844954d95c17fd7ce6cbbaJon Masonfail3:
11738ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return rc;
11748ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
11758ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
11764de92180258ac661bbce0f0065c9c81633ac862bBen Hutchingsstatic int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
11774de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings{
11784de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
11794de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	int rc;
11804de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings
11814de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	mutex_lock(&nic_data->spi_lock);
11824de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	rc = __falcon_reset_hw(efx, method);
11834de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	mutex_unlock(&nic_data->spi_lock);
11844de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings
11854de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	return rc;
11864de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings}
11874de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings
1188ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchingsstatic void falcon_monitor(struct efx_nic *efx)
1189fe75820b99ff2de713de23252432f0f9d0ca1d35Ben Hutchings{
1190fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	bool link_changed;
1191fe75820b99ff2de713de23252432f0f9d0ca1d35Ben Hutchings	int rc;
1192fe75820b99ff2de713de23252432f0f9d0ca1d35Ben Hutchings
1193fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	BUG_ON(!mutex_is_locked(&efx->mac_lock));
1194fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
1195fe75820b99ff2de713de23252432f0f9d0ca1d35Ben Hutchings	rc = falcon_board(efx)->type->monitor(efx);
1196fe75820b99ff2de713de23252432f0f9d0ca1d35Ben Hutchings	if (rc) {
119762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_err(efx, hw, efx->net_dev,
119862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "Board sensor %s; shutting down PHY\n",
119962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  (rc == -ERANGE) ? "reported fault" : "failed");
1200fe75820b99ff2de713de23252432f0f9d0ca1d35Ben Hutchings		efx->phy_mode |= PHY_MODE_LOW_POWER;
1201d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings		rc = __efx_reconfigure_port(efx);
1202d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings		WARN_ON(rc);
1203fe75820b99ff2de713de23252432f0f9d0ca1d35Ben Hutchings	}
1204fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
1205fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	if (LOOPBACK_INTERNAL(efx))
1206fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson		link_changed = falcon_loopback_link_poll(efx);
1207fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	else
1208fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson		link_changed = efx->phy_op->poll(efx);
1209fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
1210fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	if (link_changed) {
1211fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson		falcon_stop_nic_stats(efx);
1212fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson		falcon_deconfigure_mac_wrapper(efx);
1213fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
12148fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings		falcon_reset_macs(efx);
1215710b208dc2687fdb3370110d54a67fb2288835ebBen Hutchings		rc = falcon_reconfigure_xmac(efx);
1216d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings		BUG_ON(rc);
1217fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
1218fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson		falcon_start_nic_stats(efx);
1219fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
1220fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson		efx_link_status_changed(efx);
1221fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	}
1222fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
12238fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	falcon_poll_xmac(efx);
1224fe75820b99ff2de713de23252432f0f9d0ca1d35Ben Hutchings}
1225fe75820b99ff2de713de23252432f0f9d0ca1d35Ben Hutchings
12268ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Zeroes out the SRAM contents.  This routine must be called in
12278ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * process context and is allowed to sleep.
12288ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings */
12298ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchingsstatic int falcon_reset_sram(struct efx_nic *efx)
12308ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
12318ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_oword_t srm_cfg_reg_ker, gpio_cfg_reg_ker;
12328ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int count;
12338ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
12348ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Set the SRAM wake/sleep GPIO appropriately. */
123512d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL);
12363e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, FRF_AB_GPIO1_OEN, 1);
12373e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, FRF_AB_GPIO1_OUT, 1);
123812d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL);
12398ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
12408ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Initiate SRAM reset */
12418ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	EFX_POPULATE_OWORD_2(srm_cfg_reg_ker,
12423e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AZ_SRM_INIT_EN, 1,
12433e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			     FRF_AZ_SRM_NB_SZ, 0);
124412d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG);
12458ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
12468ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Wait for SRAM reset to complete */
12478ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	count = 0;
12488ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	do {
124962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_dbg(efx, hw, efx->net_dev,
125062776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "waiting for SRAM reset (attempt %d)...\n", count);
12518ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
12528ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		/* SRAM reset is slow; expect around 16ms */
12538ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		schedule_timeout_uninterruptible(HZ / 50);
12548ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
12558ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		/* Check for reset complete */
125612d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_reado(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG);
12573e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		if (!EFX_OWORD_FIELD(srm_cfg_reg_ker, FRF_AZ_SRM_INIT_EN)) {
125862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			netif_dbg(efx, hw, efx->net_dev,
125962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  "SRAM reset complete\n");
12608ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
12618ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			return 0;
12628ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		}
126325985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	} while (++count < 20);	/* wait up to 0.4 sec */
12648ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
126562776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings	netif_err(efx, hw, efx->net_dev, "timed out waiting for SRAM reset\n");
12668ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return -ETIMEDOUT;
12678ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
12688ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
12694de92180258ac661bbce0f0065c9c81633ac862bBen Hutchingsstatic void falcon_spi_device_init(struct efx_nic *efx,
12704de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings				  struct efx_spi_device *spi_device,
12714a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings				  unsigned int device_id, u32 device_type)
12724a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings{
12734a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	if (device_type != 0) {
12744a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		spi_device->device_id = device_id;
12754a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		spi_device->size =
12764a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			1 << SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_SIZE);
12774a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		spi_device->addr_len =
12784a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_ADDR_LEN);
12794a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		spi_device->munge_address = (spi_device->size == 1 << 9 &&
12804a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings					     spi_device->addr_len == 1);
1281f41507245ef8b079685aba8da5b5b2b5e87e70bcBen Hutchings		spi_device->erase_command =
1282f41507245ef8b079685aba8da5b5b2b5e87e70bcBen Hutchings			SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_ERASE_CMD);
1283f41507245ef8b079685aba8da5b5b2b5e87e70bcBen Hutchings		spi_device->erase_size =
1284f41507245ef8b079685aba8da5b5b2b5e87e70bcBen Hutchings			1 << SPI_DEV_TYPE_FIELD(device_type,
1285f41507245ef8b079685aba8da5b5b2b5e87e70bcBen Hutchings						SPI_DEV_TYPE_ERASE_SIZE);
12864a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		spi_device->block_size =
12874a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings			1 << SPI_DEV_TYPE_FIELD(device_type,
12884a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings						SPI_DEV_TYPE_BLOCK_SIZE);
12894a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	} else {
12904de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings		spi_device->size = 0;
12914a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	}
12924a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings}
12934a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
12948ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Extract non-volatile configuration */
12958ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchingsstatic int falcon_probe_nvconfig(struct efx_nic *efx)
12968ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
12974de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
12988ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	struct falcon_nvconfig *nvconfig;
12998ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int rc;
13008ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
13018ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	nvconfig = kmalloc(sizeof(*nvconfig), GFP_KERNEL);
13024a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	if (!nvconfig)
13034a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings		return -ENOMEM;
13048ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
13058c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	rc = falcon_read_nvram(efx, nvconfig);
13066c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings	if (rc)
13074de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings		goto out;
13086c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings
13096c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings	efx->phy_type = nvconfig->board_v2.port0_phy_type;
13106c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings	efx->mdio.prtad = nvconfig->board_v2.port0_phy_addr;
13116c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings
13126c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings	if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) {
13134de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings		falcon_spi_device_init(
13144de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings			efx, &nic_data->spi_flash, FFE_AB_SPI_DEVICE_FLASH,
13156c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings			le32_to_cpu(nvconfig->board_v3
13166c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings				    .spi_device_type[FFE_AB_SPI_DEVICE_FLASH]));
13174de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings		falcon_spi_device_init(
13184de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings			efx, &nic_data->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM,
13196c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings			le32_to_cpu(nvconfig->board_v3
13206c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings				    .spi_device_type[FFE_AB_SPI_DEVICE_EEPROM]));
13218ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
13228ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
13238c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	/* Read the MAC addresses */
13247e300bc8e6736d41e7b92978f415572ac60fd59bBen Hutchings	memcpy(efx->net_dev->perm_addr, nvconfig->mac_address[0], ETH_ALEN);
13258c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
132662776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings	netif_dbg(efx, probe, efx->net_dev, "PHY is %d phy_id %d\n",
132762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		  efx->phy_type, efx->mdio.prtad);
13288ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
13296c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings	rc = falcon_probe_board(efx,
13306c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings				le16_to_cpu(nvconfig->board_v2.board_revision));
13314de92180258ac661bbce0f0065c9c81633ac862bBen Hutchingsout:
13328ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	kfree(nvconfig);
13338ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return rc;
13348ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
13358ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
133628e47c498a931200125e299e9d60d22e27b4ab0dBen Hutchingsstatic void falcon_dimension_resources(struct efx_nic *efx)
133728e47c498a931200125e299e9d60d22e27b4ab0dBen Hutchings{
133828e47c498a931200125e299e9d60d22e27b4ab0dBen Hutchings	efx->rx_dc_base = 0x20000;
133928e47c498a931200125e299e9d60d22e27b4ab0dBen Hutchings	efx->tx_dc_base = 0x26000;
134028e47c498a931200125e299e9d60d22e27b4ab0dBen Hutchings}
134128e47c498a931200125e299e9d60d22e27b4ab0dBen Hutchings
13424a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings/* Probe all SPI devices on the NIC */
13434a5b504d0c582db80813b70359b616ea30e91743Ben Hutchingsstatic void falcon_probe_spi_devices(struct efx_nic *efx)
13444a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings{
13454de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
13464a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	efx_oword_t nic_stat, gpio_ctl, ee_vpd_cfg;
13472f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings	int boot_dev;
13484a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
134912d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &gpio_ctl, FR_AB_GPIO_CTL);
135012d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &nic_stat, FR_AB_NIC_STAT);
135112d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0);
13524a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
13533e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	if (EFX_OWORD_FIELD(gpio_ctl, FRF_AB_GPIO3_PWRUP_VALUE)) {
13543e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		boot_dev = (EFX_OWORD_FIELD(nic_stat, FRF_AB_SF_PRST) ?
13553e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			    FFE_AB_SPI_DEVICE_FLASH : FFE_AB_SPI_DEVICE_EEPROM);
135662776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_dbg(efx, probe, efx->net_dev, "Booted from %s\n",
135762776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  boot_dev == FFE_AB_SPI_DEVICE_FLASH ?
135862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "flash" : "EEPROM");
13592f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings	} else {
13602f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings		/* Disable VPD and set clock dividers to safe
13612f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings		 * values for initial programming. */
13622f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings		boot_dev = -1;
136362776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_dbg(efx, probe, efx->net_dev,
136462776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "Booted from internal ASIC settings;"
136562776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  " setting SPI config\n");
13663e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_POPULATE_OWORD_3(ee_vpd_cfg, FRF_AB_EE_VPD_EN, 0,
13672f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings				     /* 125 MHz / 7 ~= 20 MHz */
13683e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_EE_SF_CLOCK_DIV, 7,
13692f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings				     /* 125 MHz / 63 ~= 2 MHz */
13703e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				     FRF_AB_EE_EE_CLOCK_DIV, 63);
137112d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_writeo(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0);
13724a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	}
13734a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
13744de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	mutex_init(&nic_data->spi_lock);
13754de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings
13763e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	if (boot_dev == FFE_AB_SPI_DEVICE_FLASH)
13774de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings		falcon_spi_device_init(efx, &nic_data->spi_flash,
13783e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				       FFE_AB_SPI_DEVICE_FLASH,
13792f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings				       default_flash_type);
13803e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	if (boot_dev == FFE_AB_SPI_DEVICE_EEPROM)
13814de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings		falcon_spi_device_init(efx, &nic_data->spi_eeprom,
13823e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				       FFE_AB_SPI_DEVICE_EEPROM,
13832f7f573095132240916a8780cd5ef648c0ad7281Ben Hutchings				       large_eeprom_type);
13844a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings}
13854a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
1386ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchingsstatic int falcon_probe_nic(struct efx_nic *efx)
13878ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
13888ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	struct falcon_nic_data *nic_data;
1389e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	struct falcon_board *board;
13908ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int rc;
13918ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
13928ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Allocate storage for hardware specific data */
13938ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL);
139488c59425139c0cd9984ca8f1ef577959326446d3Ben Hutchings	if (!nic_data)
139588c59425139c0cd9984ca8f1ef577959326446d3Ben Hutchings		return -ENOMEM;
13965daab96d873721cb84f4583f232b88fcd67c51fbBen Hutchings	efx->nic_data = nic_data;
13978ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
13985784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings	rc = -ENODEV;
13995784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings
14005784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings	if (efx_nic_fpga_ver(efx) != 0) {
140162776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_err(efx, probe, efx->net_dev,
140262776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "Falcon FPGA not supported\n");
14038ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		goto fail1;
14045784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings	}
14055784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings
14065784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings	if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) {
14075784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings		efx_oword_t nic_stat;
14085784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings		struct pci_dev *dev;
14095784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings		u8 pci_rev = efx->pci_dev->revision;
14108ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
14115784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings		if ((pci_rev == 0xff) || (pci_rev == 0)) {
141262776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			netif_err(efx, probe, efx->net_dev,
141362776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  "Falcon rev A0 not supported\n");
14145784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings			goto fail1;
14155784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings		}
14165784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings		efx_reado(efx, &nic_stat, FR_AB_NIC_STAT);
14175784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings		if (EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) == 0) {
141862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			netif_err(efx, probe, efx->net_dev,
141962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  "Falcon rev A1 1G not supported\n");
14205784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings			goto fail1;
14215784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings		}
14225784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings		if (EFX_OWORD_FIELD(nic_stat, FRF_AA_STRAP_PCIE) == 0) {
142362776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			netif_err(efx, probe, efx->net_dev,
142462776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  "Falcon rev A1 PCI-X not supported\n");
14255784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings			goto fail1;
14265784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings		}
14278ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
14285784946068f81c5f1cce2906a7655652e34f44f3Ben Hutchings		dev = pci_dev_get(efx->pci_dev);
1429937383a58e47154d3098783df739e8fa8984a434Ben Hutchings		while ((dev = pci_get_device(PCI_VENDOR_ID_SOLARFLARE,
1430937383a58e47154d3098783df739e8fa8984a434Ben Hutchings					     PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1,
14318ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings					     dev))) {
14328ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			if (dev->bus == efx->pci_dev->bus &&
14338ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			    dev->devfn == efx->pci_dev->devfn + 1) {
14348ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings				nic_data->pci_dev2 = dev;
14358ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings				break;
14368ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			}
14378ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		}
14388ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		if (!nic_data->pci_dev2) {
143962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			netif_err(efx, probe, efx->net_dev,
144062776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  "failed to find secondary function\n");
14418ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			rc = -ENODEV;
14428ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings			goto fail2;
14438ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		}
14448ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
14458ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
14468ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Now we can reset the NIC */
14474de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	rc = __falcon_reset_hw(efx, RESET_TYPE_ALL);
14488ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (rc) {
144962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_err(efx, probe, efx->net_dev, "failed to reset NIC\n");
14508ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		goto fail3;
14518ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
14528ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
14538ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Allocate memory for INT_KER */
1454152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t));
14558ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (rc)
14568ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		goto fail4;
14578ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	BUG_ON(efx->irq_status.dma_addr & 0x0f);
14588ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
145962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings	netif_dbg(efx, probe, efx->net_dev,
146062776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		  "INT_KER at %llx (virt %p phys %llx)\n",
146162776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		  (u64)efx->irq_status.dma_addr,
146262776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		  efx->irq_status.addr,
146362776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		  (u64)virt_to_phys(efx->irq_status.addr));
14648ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
14654a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings	falcon_probe_spi_devices(efx);
14664a5b504d0c582db80813b70359b616ea30e91743Ben Hutchings
14678ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Read in the non-volatile configuration */
14688ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	rc = falcon_probe_nvconfig(efx);
14696c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings	if (rc) {
14706c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings		if (rc == -EINVAL)
14716c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings			netif_err(efx, probe, efx->net_dev, "NVRAM is invalid\n");
14728ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		goto fail5;
14736c88b0b6dc886e49c0e6ee21d677c2e380bde688Ben Hutchings	}
14748ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1475cc180b69c009ec52f67a56d96b9073b9f774b323Ben Hutchings	efx->timer_quantum_ns = 4968; /* 621 cycles */
1476cc180b69c009ec52f67a56d96b9073b9f774b323Ben Hutchings
147737b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings	/* Initialise I2C adapter */
1478e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	board = falcon_board(efx);
1479e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	board->i2c_adap.owner = THIS_MODULE;
1480e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	board->i2c_data = falcon_i2c_bit_operations;
1481e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	board->i2c_data.data = efx;
1482e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	board->i2c_adap.algo_data = &board->i2c_data;
1483e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	board->i2c_adap.dev.parent = &efx->pci_dev->dev;
1484e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	strlcpy(board->i2c_adap.name, "SFC4000 GPIO",
1485e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings		sizeof(board->i2c_adap.name));
1486e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	rc = i2c_bit_add_bus(&board->i2c_adap);
148737b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings	if (rc)
148837b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings		goto fail5;
148937b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings
149044838a447de3b1541cbf845853c4f8999310b0ddBen Hutchings	rc = falcon_board(efx)->type->init(efx);
1491278c0621fbc4ef52177969edb6f07352da816fdbBen Hutchings	if (rc) {
149262776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings		netif_err(efx, probe, efx->net_dev,
149362776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			  "failed to initialise board\n");
1494278c0621fbc4ef52177969edb6f07352da816fdbBen Hutchings		goto fail6;
1495278c0621fbc4ef52177969edb6f07352da816fdbBen Hutchings	}
1496278c0621fbc4ef52177969edb6f07352da816fdbBen Hutchings
149755edc6e6ff728681ebc10d418222740705376664Ben Hutchings	nic_data->stats_disable_count = 1;
149855edc6e6ff728681ebc10d418222740705376664Ben Hutchings	setup_timer(&nic_data->stats_timer, &falcon_stats_timer_func,
149955edc6e6ff728681ebc10d418222740705376664Ben Hutchings		    (unsigned long)efx);
150055edc6e6ff728681ebc10d418222740705376664Ben Hutchings
15018ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return 0;
15028ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1503278c0621fbc4ef52177969edb6f07352da816fdbBen Hutchings fail6:
1504e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	BUG_ON(i2c_del_adapter(&board->i2c_adap));
1505e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	memset(&board->i2c_adap, 0, sizeof(board->i2c_adap));
15068ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings fail5:
1507152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	efx_nic_free_buffer(efx, &efx->irq_status);
15088ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings fail4:
15098ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings fail3:
15108ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (nic_data->pci_dev2) {
15118ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		pci_dev_put(nic_data->pci_dev2);
15128ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		nic_data->pci_dev2 = NULL;
15138ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
15148ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings fail2:
15158ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings fail1:
15168ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	kfree(efx->nic_data);
15178ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return rc;
15188ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
15198ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
152056241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchingsstatic void falcon_init_rx_cfg(struct efx_nic *efx)
152156241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings{
152256241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings	/* Prior to Siena the RX DMA engine will split each frame at
152356241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings	 * intervals of RX_USR_BUF_SIZE (32-byte units). We set it to
152456241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings	 * be so large that that never happens. */
152556241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings	const unsigned huge_buf_size = (3 * 4096) >> 5;
152656241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings	/* RX control FIFO thresholds (32 entries) */
152756241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings	const unsigned ctrl_xon_thr = 20;
152856241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings	const unsigned ctrl_xoff_thr = 25;
152956241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings	efx_oword_t reg;
153056241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings
153112d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &reg, FR_AZ_RX_CFG);
1532daeda6309e1382819a8f8bab548560742ac26cc2Ben Hutchings	if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) {
1533625b451455cebb7120492766c8425b6e808fc209Ben Hutchings		/* Data FIFO size is 5.5K */
15343e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_DESC_PUSH_EN, 0);
15353e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_USR_BUF_SIZE,
15363e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				    huge_buf_size);
15375fb6b06d4eda2167eab662ad5e30058cecd67b8bBen Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XON_MAC_TH, 512 >> 8);
15385fb6b06d4eda2167eab662ad5e30058cecd67b8bBen Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XOFF_MAC_TH, 2048 >> 8);
15393e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XON_TX_TH, ctrl_xon_thr);
15403e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XOFF_TX_TH, ctrl_xoff_thr);
154156241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings	} else {
1542625b451455cebb7120492766c8425b6e808fc209Ben Hutchings		/* Data FIFO size is 80K; register fields moved */
15433e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_DESC_PUSH_EN, 0);
15443e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_USR_BUF_SIZE,
15453e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings				    huge_buf_size);
15465fb6b06d4eda2167eab662ad5e30058cecd67b8bBen Hutchings		/* Send XON and XOFF at ~3 * max MTU away from empty/full */
15475fb6b06d4eda2167eab662ad5e30058cecd67b8bBen Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XON_MAC_TH, 27648 >> 8);
15485fb6b06d4eda2167eab662ad5e30058cecd67b8bBen Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_MAC_TH, 54272 >> 8);
15493e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XON_TX_TH, ctrl_xon_thr);
15503e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_TX_TH, ctrl_xoff_thr);
15513e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1);
1552477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings
1553477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings		/* Enable hash insertion. This is broken for the
1554477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings		 * 'Falcon' hash so also select Toeplitz TCP/IPv4 and
1555477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings		 * IPv4 hashes. */
1556477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_HASH_INSRT_HDR, 1);
1557477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_HASH_ALG, 1);
1558477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_IP_HASH, 1);
155956241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings	}
15604b0d29dcfca9eafbf6e940862ab022df3ef2dd6fBen Hutchings	/* Always enable XOFF signal from RX FIFO.  We enable
15614b0d29dcfca9eafbf6e940862ab022df3ef2dd6fBen Hutchings	 * or disable transmission of pause frames at the MAC. */
15624b0d29dcfca9eafbf6e940862ab022df3ef2dd6fBen Hutchings	EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, 1);
156312d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &reg, FR_AZ_RX_CFG);
156456241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings}
156556241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings
1566152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings/* This call performs hardware-specific global initialisation, such as
1567152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings * defining the descriptor cache sizes and number of RSS channels.
1568152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings * It does not set up any buffers, descriptor rings or event queues.
1569152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings */
1570152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchingsstatic int falcon_init_nic(struct efx_nic *efx)
1571152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings{
1572152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	efx_oword_t temp;
1573152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	int rc;
1574152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings
1575152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	/* Use on-chip SRAM */
1576152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	efx_reado(efx, &temp, FR_AB_NIC_STAT);
1577152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	EFX_SET_OWORD_FIELD(temp, FRF_AB_ONCHIP_SRAM, 1);
1578152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	efx_writeo(efx, &temp, FR_AB_NIC_STAT);
1579152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings
1580152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	rc = falcon_reset_sram(efx);
1581152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	if (rc)
1582152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings		return rc;
1583152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings
1584152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	/* Clear the parity enables on the TX data fifos as
1585152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	 * they produce false parity errors because of timing issues
1586152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	 */
1587152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	if (EFX_WORKAROUND_5129(efx)) {
1588152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings		efx_reado(efx, &temp, FR_AZ_CSR_SPARE);
1589152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings		EFX_SET_OWORD_FIELD(temp, FRF_AB_MEM_PERR_EN_TX_DATA, 0);
1590152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings		efx_writeo(efx, &temp, FR_AZ_CSR_SPARE);
1591152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	}
1592152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings
15938ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (EFX_WORKAROUND_7244(efx)) {
159412d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_reado(efx, &temp, FR_BZ_RX_FILTER_CTL);
15953e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(temp, FRF_BZ_UDP_FULL_SRCH_LIMIT, 8);
15963e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(temp, FRF_BZ_UDP_WILD_SRCH_LIMIT, 8);
15973e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(temp, FRF_BZ_TCP_FULL_SRCH_LIMIT, 8);
15983e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(temp, FRF_BZ_TCP_WILD_SRCH_LIMIT, 8);
159912d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_writeo(efx, &temp, FR_BZ_RX_FILTER_CTL);
16008ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
16018ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
16023e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	/* XXX This is documented only for Falcon A0/A1 */
16038ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Setup RX.  Wait for descriptor is broken and must
16048ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 * be disabled.  RXDP recovery shouldn't be needed, but is.
16058ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 */
160612d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &temp, FR_AA_RX_SELF_RST);
16073e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_NODESC_WAIT_DIS, 1);
16083e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_SELF_RST_EN, 1);
16098ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (EFX_WORKAROUND_5583(efx))
16103e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_ISCSI_DIS, 1);
161112d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &temp, FR_AA_RX_SELF_RST);
16128ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
16138ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Do not enable TX_NO_EOP_DISC_EN, since it limits packets to 16
16148ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 * descriptors (which is bad).
16158ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 */
161612d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &temp, FR_AZ_TX_CFG);
16173e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_NO_EOP_DISC_EN, 0);
161812d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_writeo(efx, &temp, FR_AZ_TX_CFG);
16198ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
162056241ceb9e75fc1a5fb142a754096ad6c6ab19eeBen Hutchings	falcon_init_rx_cfg(efx);
16218ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1622daeda6309e1382819a8f8bab548560742ac26cc2Ben Hutchings	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
1623477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings		/* Set hash key for IPv4 */
1624477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings		memcpy(&temp, efx->rx_hash_key, sizeof(temp));
1625477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings		efx_writeo(efx, &temp, FR_BZ_RX_RSS_TKEY);
1626477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings
1627477e54eba4fd092704e50e65ade79463bd17fa85Ben Hutchings		/* Set destination of both TX and RX Flush events */
16283e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_POPULATE_OWORD_1(temp, FRF_BZ_FLS_EVQ_ID, 0);
162912d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings		efx_writeo(efx, &temp, FR_BZ_DP_CTRL);
16308ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
16318ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1632152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	efx_nic_init_common(efx);
1633152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings
16348ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return 0;
16358ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
16368ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1637ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchingsstatic void falcon_remove_nic(struct efx_nic *efx)
16388ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
16398ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
1640e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	struct falcon_board *board = falcon_board(efx);
164137b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings	int rc;
164237b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings
164344838a447de3b1541cbf845853c4f8999310b0ddBen Hutchings	board->type->fini(efx);
1644278c0621fbc4ef52177969edb6f07352da816fdbBen Hutchings
16458c870379d2db81a11ede65e9fd9774e4e6efe84aBen Hutchings	/* Remove I2C adapter and clear it in preparation for a retry */
1646e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	rc = i2c_del_adapter(&board->i2c_adap);
164737b5a60335305e46be93c2eb904c8b5be7aba5f6Ben Hutchings	BUG_ON(rc);
1648e775fb93a880d218ce0b3fd405278dd78f86c405Ben Hutchings	memset(&board->i2c_adap, 0, sizeof(board->i2c_adap));
16498ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1650152b6a62aea2d43359dd37004e9c218bf7bdeb3bBen Hutchings	efx_nic_free_buffer(efx, &efx->irq_status);
16518ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
16524de92180258ac661bbce0f0065c9c81633ac862bBen Hutchings	__falcon_reset_hw(efx, RESET_TYPE_ALL);
16538ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
16548ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Release the second function after the reset */
16558ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (nic_data->pci_dev2) {
16568ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		pci_dev_put(nic_data->pci_dev2);
16578ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		nic_data->pci_dev2 = NULL;
16588ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
16598ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
16608ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Tear down the private nic state */
16618ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	kfree(efx->nic_data);
16628ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx->nic_data = NULL;
16638ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
16648ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1665ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchingsstatic void falcon_update_nic_stats(struct efx_nic *efx)
16668ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
166755edc6e6ff728681ebc10d418222740705376664Ben Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
16688ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx_oword_t cnt;
16698ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
167055edc6e6ff728681ebc10d418222740705376664Ben Hutchings	if (nic_data->stats_disable_count)
167155edc6e6ff728681ebc10d418222740705376664Ben Hutchings		return;
167255edc6e6ff728681ebc10d418222740705376664Ben Hutchings
167312d00cadcc45382fc127712aa35bd0c96cbf81d9Ben Hutchings	efx_reado(efx, &cnt, FR_AZ_RX_NODESC_DROP);
16743e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	efx->n_rx_nodesc_drop_cnt +=
16753e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings		EFX_OWORD_FIELD(cnt, FRF_AB_RX_NODESC_DROP_CNT);
167655edc6e6ff728681ebc10d418222740705376664Ben Hutchings
167755edc6e6ff728681ebc10d418222740705376664Ben Hutchings	if (nic_data->stats_pending &&
167855edc6e6ff728681ebc10d418222740705376664Ben Hutchings	    *nic_data->stats_dma_done == FALCON_STATS_DONE) {
167955edc6e6ff728681ebc10d418222740705376664Ben Hutchings		nic_data->stats_pending = false;
168055edc6e6ff728681ebc10d418222740705376664Ben Hutchings		rmb(); /* read the done flag before the stats */
1681710b208dc2687fdb3370110d54a67fb2288835ebBen Hutchings		falcon_update_stats_xmac(efx);
168255edc6e6ff728681ebc10d418222740705376664Ben Hutchings	}
168355edc6e6ff728681ebc10d418222740705376664Ben Hutchings}
168455edc6e6ff728681ebc10d418222740705376664Ben Hutchings
168555edc6e6ff728681ebc10d418222740705376664Ben Hutchingsvoid falcon_start_nic_stats(struct efx_nic *efx)
168655edc6e6ff728681ebc10d418222740705376664Ben Hutchings{
168755edc6e6ff728681ebc10d418222740705376664Ben Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
168855edc6e6ff728681ebc10d418222740705376664Ben Hutchings
168955edc6e6ff728681ebc10d418222740705376664Ben Hutchings	spin_lock_bh(&efx->stats_lock);
169055edc6e6ff728681ebc10d418222740705376664Ben Hutchings	if (--nic_data->stats_disable_count == 0)
169155edc6e6ff728681ebc10d418222740705376664Ben Hutchings		falcon_stats_request(efx);
169255edc6e6ff728681ebc10d418222740705376664Ben Hutchings	spin_unlock_bh(&efx->stats_lock);
169355edc6e6ff728681ebc10d418222740705376664Ben Hutchings}
169455edc6e6ff728681ebc10d418222740705376664Ben Hutchings
169555edc6e6ff728681ebc10d418222740705376664Ben Hutchingsvoid falcon_stop_nic_stats(struct efx_nic *efx)
169655edc6e6ff728681ebc10d418222740705376664Ben Hutchings{
169755edc6e6ff728681ebc10d418222740705376664Ben Hutchings	struct falcon_nic_data *nic_data = efx->nic_data;
169855edc6e6ff728681ebc10d418222740705376664Ben Hutchings	int i;
169955edc6e6ff728681ebc10d418222740705376664Ben Hutchings
170055edc6e6ff728681ebc10d418222740705376664Ben Hutchings	might_sleep();
170155edc6e6ff728681ebc10d418222740705376664Ben Hutchings
170255edc6e6ff728681ebc10d418222740705376664Ben Hutchings	spin_lock_bh(&efx->stats_lock);
170355edc6e6ff728681ebc10d418222740705376664Ben Hutchings	++nic_data->stats_disable_count;
170455edc6e6ff728681ebc10d418222740705376664Ben Hutchings	spin_unlock_bh(&efx->stats_lock);
170555edc6e6ff728681ebc10d418222740705376664Ben Hutchings
170655edc6e6ff728681ebc10d418222740705376664Ben Hutchings	del_timer_sync(&nic_data->stats_timer);
170755edc6e6ff728681ebc10d418222740705376664Ben Hutchings
170855edc6e6ff728681ebc10d418222740705376664Ben Hutchings	/* Wait enough time for the most recent transfer to
170955edc6e6ff728681ebc10d418222740705376664Ben Hutchings	 * complete. */
171055edc6e6ff728681ebc10d418222740705376664Ben Hutchings	for (i = 0; i < 4 && nic_data->stats_pending; i++) {
171155edc6e6ff728681ebc10d418222740705376664Ben Hutchings		if (*nic_data->stats_dma_done == FALCON_STATS_DONE)
171255edc6e6ff728681ebc10d418222740705376664Ben Hutchings			break;
171355edc6e6ff728681ebc10d418222740705376664Ben Hutchings		msleep(1);
171455edc6e6ff728681ebc10d418222740705376664Ben Hutchings	}
171555edc6e6ff728681ebc10d418222740705376664Ben Hutchings
171655edc6e6ff728681ebc10d418222740705376664Ben Hutchings	spin_lock_bh(&efx->stats_lock);
171755edc6e6ff728681ebc10d418222740705376664Ben Hutchings	falcon_stats_complete(efx);
171855edc6e6ff728681ebc10d418222740705376664Ben Hutchings	spin_unlock_bh(&efx->stats_lock);
17198ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
17208ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
172106629f07248b259e08a6e4089fbe6aa3f98dfbe6Ben Hutchingsstatic void falcon_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
172206629f07248b259e08a6e4089fbe6aa3f98dfbe6Ben Hutchings{
172306629f07248b259e08a6e4089fbe6aa3f98dfbe6Ben Hutchings	falcon_board(efx)->type->set_id_led(efx, mode);
172406629f07248b259e08a6e4089fbe6aa3f98dfbe6Ben Hutchings}
172506629f07248b259e08a6e4089fbe6aa3f98dfbe6Ben Hutchings
17268ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/**************************************************************************
17278ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
172889c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings * Wake on LAN
172989c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings *
173089c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings **************************************************************************
173189c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings */
173289c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings
173389c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchingsstatic void falcon_get_wol(struct efx_nic *efx, struct ethtool_wolinfo *wol)
173489c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings{
173589c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings	wol->supported = 0;
173689c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings	wol->wolopts = 0;
173789c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings	memset(&wol->sopass, 0, sizeof(wol->sopass));
173889c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings}
173989c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings
174089c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchingsstatic int falcon_set_wol(struct efx_nic *efx, u32 type)
174189c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings{
174289c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings	if (type != 0)
174389c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings		return -EINVAL;
174489c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings	return 0;
174589c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings}
174689c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings
174789c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings/**************************************************************************
174889c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings *
1749754c653a4e62bfa19b4e015c45198863c4211947Ben Hutchings * Revision-dependent attributes used by efx.c and nic.c
17508ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
17518ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings **************************************************************************
17528ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings */
17538ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
17546c8c2513c86c589a819c161c9abbdea2a3d56f5estephen hemmingerconst struct efx_nic_type falcon_a1_nic_type = {
1755ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.probe = falcon_probe_nic,
1756ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.remove = falcon_remove_nic,
1757ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.init = falcon_init_nic,
175828e47c498a931200125e299e9d60d22e27b4ab0dBen Hutchings	.dimension_resources = falcon_dimension_resources,
1759ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.fini = efx_port_dummy_op_void,
1760ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.monitor = falcon_monitor,
17610e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	.map_reset_reason = falcon_map_reset_reason,
17620e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	.map_reset_flags = falcon_map_reset_flags,
1763ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.reset = falcon_reset_hw,
1764ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.probe_port = falcon_probe_port,
1765ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.remove_port = falcon_remove_port,
176640641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	.handle_global_event = falcon_handle_global_event,
1767ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.prepare_flush = falcon_prepare_flush,
1768ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.update_stats = falcon_update_nic_stats,
1769ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.start_stats = falcon_start_nic_stats,
1770ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.stop_stats = falcon_stop_nic_stats,
177106629f07248b259e08a6e4089fbe6aa3f98dfbe6Ben Hutchings	.set_id_led = falcon_set_id_led,
1772ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.push_irq_moderation = falcon_push_irq_moderation,
1773d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	.reconfigure_port = falcon_reconfigure_port,
1774710b208dc2687fdb3370110d54a67fb2288835ebBen Hutchings	.reconfigure_mac = falcon_reconfigure_xmac,
1775710b208dc2687fdb3370110d54a67fb2288835ebBen Hutchings	.check_mac_fault = falcon_xmac_check_fault,
177689c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings	.get_wol = falcon_get_wol,
177789c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings	.set_wol = falcon_set_wol,
177889c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings	.resume_wol = efx_port_dummy_op_void,
17790aa3fbaa3f2d29a14231ebb0c8e521c23701d41fBen Hutchings	.test_nvram = falcon_test_nvram,
1780b895d73e9836fccc402e48a8f63e6805d2edc87bSteve Hodgson
1781daeda6309e1382819a8f8bab548560742ac26cc2Ben Hutchings	.revision = EFX_REV_FALCON_A1,
17828ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	.mem_map_size = 0x20000,
17833e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	.txd_ptr_tbl_base = FR_AA_TX_DESC_PTR_TBL_KER,
17843e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	.rxd_ptr_tbl_base = FR_AA_RX_DESC_PTR_TBL_KER,
17853e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	.buf_tbl_base = FR_AA_BUF_FULL_TBL_KER,
17863e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	.evq_ptr_tbl_base = FR_AA_EVQ_PTR_TBL_KER,
17873e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	.evq_rptr_tbl_base = FR_AA_EVQ_RPTR_KER,
17886d51d307509f98f070688b4bff1d0f7462c4d3ecBen Hutchings	.max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH),
17898ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	.rx_buffer_padding = 0x24,
17908ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	.max_interrupt_mode = EFX_INT_MODE_MSI,
17918ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	.phys_addr_channels = 4,
1792cc180b69c009ec52f67a56d96b9073b9f774b323Ben Hutchings	.timer_period_max =  1 << FRF_AB_TC_TIMER_VAL_WIDTH,
1793c383b53729a9bbbceee132a85955d084ba00ca3aBen Hutchings	.offload_features = NETIF_F_IP_CSUM,
17948ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings};
17958ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
17966c8c2513c86c589a819c161c9abbdea2a3d56f5estephen hemmingerconst struct efx_nic_type falcon_b0_nic_type = {
1797ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.probe = falcon_probe_nic,
1798ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.remove = falcon_remove_nic,
1799ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.init = falcon_init_nic,
180028e47c498a931200125e299e9d60d22e27b4ab0dBen Hutchings	.dimension_resources = falcon_dimension_resources,
1801ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.fini = efx_port_dummy_op_void,
1802ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.monitor = falcon_monitor,
18030e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	.map_reset_reason = falcon_map_reset_reason,
18040e2a9c7cb941db993f481cdd6a99d70a302053e0Ben Hutchings	.map_reset_flags = falcon_map_reset_flags,
1805ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.reset = falcon_reset_hw,
1806ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.probe_port = falcon_probe_port,
1807ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.remove_port = falcon_remove_port,
180840641ed93cd53561f7d53b5fd5ed656b35f3aabdBen Hutchings	.handle_global_event = falcon_handle_global_event,
1809ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.prepare_flush = falcon_prepare_flush,
1810ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.update_stats = falcon_update_nic_stats,
1811ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.start_stats = falcon_start_nic_stats,
1812ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.stop_stats = falcon_stop_nic_stats,
181306629f07248b259e08a6e4089fbe6aa3f98dfbe6Ben Hutchings	.set_id_led = falcon_set_id_led,
1814ef2b90ee4dba7a3d9001f1f0003b860b39a4aaaeBen Hutchings	.push_irq_moderation = falcon_push_irq_moderation,
1815d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	.reconfigure_port = falcon_reconfigure_port,
1816710b208dc2687fdb3370110d54a67fb2288835ebBen Hutchings	.reconfigure_mac = falcon_reconfigure_xmac,
1817710b208dc2687fdb3370110d54a67fb2288835ebBen Hutchings	.check_mac_fault = falcon_xmac_check_fault,
181889c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings	.get_wol = falcon_get_wol,
181989c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings	.set_wol = falcon_set_wol,
182089c758fa47b54d8ce10d2b39ed09de6da0ba4324Ben Hutchings	.resume_wol = efx_port_dummy_op_void,
18219bfc4bb1f9b5863b177752b88e8bfa364e83a4faBen Hutchings	.test_registers = falcon_b0_test_registers,
18220aa3fbaa3f2d29a14231ebb0c8e521c23701d41fBen Hutchings	.test_nvram = falcon_test_nvram,
1823b895d73e9836fccc402e48a8f63e6805d2edc87bSteve Hodgson
1824daeda6309e1382819a8f8bab548560742ac26cc2Ben Hutchings	.revision = EFX_REV_FALCON_B0,
18258ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Map everything up to and including the RSS indirection
18268ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 * table.  Don't map MSI-X table, MSI-X PBA since Linux
18278ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	 * requires that they not be mapped.  */
18283e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	.mem_map_size = (FR_BZ_RX_INDIRECTION_TBL +
18293e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			 FR_BZ_RX_INDIRECTION_TBL_STEP *
18303e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings			 FR_BZ_RX_INDIRECTION_TBL_ROWS),
18313e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	.txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL,
18323e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	.rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL,
18333e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	.buf_tbl_base = FR_BZ_BUF_FULL_TBL,
18343e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	.evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL,
18353e6c4538542ab2103ab7c01f4458bc2e21b672a1Ben Hutchings	.evq_rptr_tbl_base = FR_BZ_EVQ_RPTR,
18366d51d307509f98f070688b4bff1d0f7462c4d3ecBen Hutchings	.max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH),
183739c9cf07077146b14ab077a0e27c869c6f0e6199Ben Hutchings	.rx_buffer_hash_size = 0x10,
18388ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	.rx_buffer_padding = 0,
18398ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	.max_interrupt_mode = EFX_INT_MODE_MSIX,
18408ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	.phys_addr_channels = 32, /* Hardware limit is 64, but the legacy
18418ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings				   * interrupt handler only supports 32
18428ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings				   * channels */
1843cc180b69c009ec52f67a56d96b9073b9f774b323Ben Hutchings	.timer_period_max =  1 << FRF_AB_TC_TIMER_VAL_WIDTH,
1844b4187e4277b13d7bc4acc3c953b3cab0137b14b2Ben Hutchings	.offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE,
18458ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings};
18468ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1847