From 19e71cf6910defed10c5d22af9f4591bbcd6a0fe Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:28:53 +0000 Subject: sfc: Remove redundant hardware initialisation Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index c049364aec46..57898fd5298c 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2933,10 +2933,6 @@ int falcon_init_nic(struct efx_nic *efx) falcon_write(efx, &temp, GPIO_CTL_REG_KER); } - /* Set buffer table mode */ - EFX_POPULATE_OWORD_1(temp, BUF_TBL_MODE, BUF_TBL_MODE_FULL); - falcon_write(efx, &temp, BUF_TBL_CFG_REG_KER); - rc = falcon_reset_sram(efx); if (rc) return rc; -- cgit v1.2.2 From 3473a5b11827fa0f84f18b79373a26290798f54a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:29:16 +0000 Subject: sfc: Rename Falcon-specific board code and types Siena will require entirely different board code. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 57898fd5298c..abc6b632df9f 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2732,7 +2732,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad); - efx_set_board_info(efx, board_rev); + falcon_probe_board(efx, board_rev); kfree(nvconfig); return 0; -- cgit v1.2.2 From 5087b54ddc4f3a1007c0984177934c016d884639 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:29:51 +0000 Subject: sfc: Remove boards.h, moving last remaining declaration to falcon.h Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index abc6b632df9f..eed8d1f98dd0 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -26,7 +26,6 @@ #include "falcon_io.h" #include "mdio_10g.h" #include "phy.h" -#include "boards.h" #include "workarounds.h" /* Falcon hardware control. -- cgit v1.2.2 From 56241ceb9e75fc1a5fb142a754096ad6c6ab19ee Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:30:06 +0000 Subject: sfc: Remove versioned bitfield macros These macros are not extensible to more than two NIC types without repetition of register definitions, and they are only used to deal with a few fields in RX_CFG_REG and global events which moved between Falcon rev A1 and B0. Therefore: - Move RX_CFG_REG initialisation into its own function which tests the NIC revision just once - Explicitly test the NIC revision when checking the RX_RECOVERY flag in global events - Merge definitions of RX_XOFF_MAC_EN flag, which did not move - Remove the macro definitions Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 67 +++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 23 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index eed8d1f98dd0..4cb98d473c4d 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -929,7 +929,9 @@ static void falcon_handle_global_event(struct efx_channel *channel, handled = true; } - if (EFX_QWORD_FIELD_VER(efx, *event, RX_RECOVERY)) { + if (falcon_rev(efx) <= FALCON_REV_A1 ? + EFX_QWORD_FIELD(*event, RX_RECOVERY_A1) : + EFX_QWORD_FIELD(*event, RX_RECOVERY_B0)) { EFX_ERR(efx, "channel %d seen global RX_RESET " "event. Resetting.\n", channel->channel); @@ -2006,7 +2008,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) * Action on receipt of pause frames is controller by XM_DIS_FCNTL */ tx_fc = !!(efx->link_fc & EFX_FC_TX); falcon_read(efx, ®, RX_CFG_REG_KER); - EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc); + EFX_SET_OWORD_FIELD(reg, RX_XOFF_MAC_EN, tx_fc); /* Unisolate the MAC -> RX */ if (falcon_rev(efx) >= FALCON_REV_B0) @@ -2910,6 +2912,45 @@ int falcon_probe_nic(struct efx_nic *efx) return rc; } +static void falcon_init_rx_cfg(struct efx_nic *efx) +{ + /* Prior to Siena the RX DMA engine will split each frame at + * intervals of RX_USR_BUF_SIZE (32-byte units). We set it to + * be so large that that never happens. */ + const unsigned huge_buf_size = (3 * 4096) >> 5; + /* RX control FIFO thresholds (32 entries) */ + const unsigned ctrl_xon_thr = 20; + const unsigned ctrl_xoff_thr = 25; + /* RX data FIFO thresholds (256-byte units; size varies) */ + unsigned data_xon_thr = + ((rx_xon_thresh_bytes >= 0) ? + rx_xon_thresh_bytes : efx->type->rx_xon_thresh) >> 8; + unsigned data_xoff_thr = + ((rx_xoff_thresh_bytes >= 0) ? + rx_xoff_thresh_bytes : efx->type->rx_xoff_thresh) >> 8; + efx_oword_t reg; + + falcon_read(efx, ®, RX_CFG_REG_KER); + if (falcon_rev(efx) <= FALCON_REV_A1) { + EFX_SET_OWORD_FIELD(reg, RX_DESC_PUSH_EN_A1, 0); + EFX_SET_OWORD_FIELD(reg, RX_USR_BUF_SIZE_A1, huge_buf_size); + EFX_SET_OWORD_FIELD(reg, RX_XON_MAC_TH_A1, data_xon_thr); + EFX_SET_OWORD_FIELD(reg, RX_XOFF_MAC_TH_A1, data_xoff_thr); + EFX_SET_OWORD_FIELD(reg, RX_XON_TX_TH_A1, ctrl_xon_thr); + EFX_SET_OWORD_FIELD(reg, RX_XOFF_TX_TH_A1, ctrl_xoff_thr); + } else { + /* Register fields moved */ + EFX_SET_OWORD_FIELD(reg, RX_DESC_PUSH_EN_B0, 0); + EFX_SET_OWORD_FIELD(reg, RX_USR_BUF_SIZE_B0, huge_buf_size); + EFX_SET_OWORD_FIELD(reg, RX_XON_MAC_TH_B0, data_xon_thr); + EFX_SET_OWORD_FIELD(reg, RX_XOFF_MAC_TH_B0, data_xoff_thr); + EFX_SET_OWORD_FIELD(reg, RX_XON_TX_TH_B0, ctrl_xon_thr); + EFX_SET_OWORD_FIELD(reg, RX_XOFF_TX_TH_B0, ctrl_xoff_thr); + EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 1); + } + falcon_write(efx, ®, RX_CFG_REG_KER); +} + /* This call performs hardware-specific global initialisation, such as * defining the descriptor cache sizes and number of RSS channels. * It does not set up any buffers, descriptor rings or event queues. @@ -2917,7 +2958,6 @@ int falcon_probe_nic(struct efx_nic *efx) int falcon_init_nic(struct efx_nic *efx) { efx_oword_t temp; - unsigned thresh; int rc; /* Use on-chip SRAM */ @@ -3024,26 +3064,7 @@ int falcon_init_nic(struct efx_nic *efx) EFX_SET_OWORD_FIELD(temp, TX_NO_EOP_DISC_EN, 0); falcon_write(efx, &temp, TX_CFG_REG_KER); - /* RX config */ - falcon_read(efx, &temp, RX_CFG_REG_KER); - EFX_SET_OWORD_FIELD_VER(efx, temp, RX_DESC_PUSH_EN, 0); - if (EFX_WORKAROUND_7575(efx)) - EFX_SET_OWORD_FIELD_VER(efx, temp, RX_USR_BUF_SIZE, - (3 * 4096) / 32); - if (falcon_rev(efx) >= FALCON_REV_B0) - EFX_SET_OWORD_FIELD(temp, RX_INGR_EN_B0, 1); - - /* RX FIFO flow control thresholds */ - thresh = ((rx_xon_thresh_bytes >= 0) ? - rx_xon_thresh_bytes : efx->type->rx_xon_thresh); - EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XON_MAC_TH, thresh / 256); - thresh = ((rx_xoff_thresh_bytes >= 0) ? - rx_xoff_thresh_bytes : efx->type->rx_xoff_thresh); - EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XOFF_MAC_TH, thresh / 256); - /* RX control FIFO thresholds [32 entries] */ - EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XON_TX_TH, 20); - EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XOFF_TX_TH, 25); - falcon_write(efx, &temp, RX_CFG_REG_KER); + falcon_init_rx_cfg(efx); /* Set destination of both TX and RX Flush events */ if (falcon_rev(efx) >= FALCON_REV_B0) { -- cgit v1.2.2 From 625b451455cebb7120492766c8425b6e808fc209 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:30:17 +0000 Subject: sfc: Move RX data FIFO thresholds out of struct efx_nic_type Since there are now separate blocks of code to set the thresholds for each NIC type, it is no longer useful to include them in the NIC type description. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 4cb98d473c4d..c23e8e2b094a 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2922,16 +2922,17 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) const unsigned ctrl_xon_thr = 20; const unsigned ctrl_xoff_thr = 25; /* RX data FIFO thresholds (256-byte units; size varies) */ - unsigned data_xon_thr = - ((rx_xon_thresh_bytes >= 0) ? - rx_xon_thresh_bytes : efx->type->rx_xon_thresh) >> 8; - unsigned data_xoff_thr = - ((rx_xoff_thresh_bytes >= 0) ? - rx_xoff_thresh_bytes : efx->type->rx_xoff_thresh) >> 8; + int data_xon_thr = rx_xon_thresh_bytes >> 8; + int data_xoff_thr = rx_xoff_thresh_bytes >> 8; efx_oword_t reg; falcon_read(efx, ®, RX_CFG_REG_KER); if (falcon_rev(efx) <= FALCON_REV_A1) { + /* Data FIFO size is 5.5K */ + if (data_xon_thr < 0) + data_xon_thr = 512 >> 8; + if (data_xoff_thr < 0) + data_xoff_thr = 2048 >> 8; EFX_SET_OWORD_FIELD(reg, RX_DESC_PUSH_EN_A1, 0); EFX_SET_OWORD_FIELD(reg, RX_USR_BUF_SIZE_A1, huge_buf_size); EFX_SET_OWORD_FIELD(reg, RX_XON_MAC_TH_A1, data_xon_thr); @@ -2939,7 +2940,11 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) EFX_SET_OWORD_FIELD(reg, RX_XON_TX_TH_A1, ctrl_xon_thr); EFX_SET_OWORD_FIELD(reg, RX_XOFF_TX_TH_A1, ctrl_xoff_thr); } else { - /* Register fields moved */ + /* Data FIFO size is 80K; register fields moved */ + if (data_xon_thr < 0) + data_xon_thr = 27648 >> 8; /* ~3*max MTU */ + if (data_xoff_thr < 0) + data_xoff_thr = 54272 >> 8; /* ~80Kb - 3*max MTU */ EFX_SET_OWORD_FIELD(reg, RX_DESC_PUSH_EN_B0, 0); EFX_SET_OWORD_FIELD(reg, RX_USR_BUF_SIZE_B0, huge_buf_size); EFX_SET_OWORD_FIELD(reg, RX_XON_MAC_TH_B0, data_xon_thr); @@ -3130,8 +3135,6 @@ struct efx_nic_type falcon_a_nic_type = { .max_dma_mask = FALCON_DMA_MASK, .tx_dma_mask = FALCON_TX_DMA_MASK, .bug5391_mask = 0xf, - .rx_xoff_thresh = 2048, - .rx_xon_thresh = 512, .rx_buffer_padding = 0x24, .max_interrupt_mode = EFX_INT_MODE_MSI, .phys_addr_channels = 4, @@ -3154,8 +3157,6 @@ struct efx_nic_type falcon_b_nic_type = { .max_dma_mask = FALCON_DMA_MASK, .tx_dma_mask = FALCON_TX_DMA_MASK, .bug5391_mask = 0, - .rx_xoff_thresh = 54272, /* ~80Kb - 3*max MTU */ - .rx_xon_thresh = 27648, /* ~3*max MTU */ .rx_buffer_padding = 0, .max_interrupt_mode = EFX_INT_MODE_MSIX, .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy -- cgit v1.2.2 From 3e6c4538542ab2103ab7c01f4458bc2e21b672a1 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:30:36 +0000 Subject: sfc: Update hardware definitions for Siena Siena is still based on the Falcon hardware architecture and will share many of these definitions, so replace falcon_hwdefs.h with regs.h. The new definitions have been generated according to a naming convention which incorporates the type and revision information. Update the code accordingly. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 848 ++++++++++++++++++++++++----------------------- 1 file changed, 437 insertions(+), 411 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index c23e8e2b094a..b35e01031e23 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -22,7 +22,7 @@ #include "mac.h" #include "spi.h" #include "falcon.h" -#include "falcon_hwdefs.h" +#include "regs.h" #include "falcon_io.h" #include "mdio_10g.h" #include "phy.h" @@ -109,17 +109,17 @@ module_param(rx_xon_thresh_bytes, int, 0644); MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); /* TX descriptor ring size - min 512 max 4k */ -#define FALCON_TXD_RING_ORDER TX_DESCQ_SIZE_1K +#define FALCON_TXD_RING_ORDER FFE_AZ_TX_DESCQ_SIZE_1K #define FALCON_TXD_RING_SIZE 1024 #define FALCON_TXD_RING_MASK (FALCON_TXD_RING_SIZE - 1) /* RX descriptor ring size - min 512 max 4k */ -#define FALCON_RXD_RING_ORDER RX_DESCQ_SIZE_1K +#define FALCON_RXD_RING_ORDER FFE_AZ_RX_DESCQ_SIZE_1K #define FALCON_RXD_RING_SIZE 1024 #define FALCON_RXD_RING_MASK (FALCON_RXD_RING_SIZE - 1) /* Event queue size - max 32k */ -#define FALCON_EVQ_ORDER EVQ_SIZE_4K +#define FALCON_EVQ_ORDER FFE_AZ_EVQ_SIZE_4K #define FALCON_EVQ_SIZE 4096 #define FALCON_EVQ_MASK (FALCON_EVQ_SIZE - 1) @@ -199,9 +199,9 @@ static void falcon_setsda(void *data, int state) struct efx_nic *efx = (struct efx_nic *)data; efx_oword_t reg; - falcon_read(efx, ®, GPIO_CTL_REG_KER); - EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, !state); - falcon_write(efx, ®, GPIO_CTL_REG_KER); + falcon_read(efx, ®, FR_AB_GPIO_CTL); + EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO3_OEN, !state); + falcon_write(efx, ®, FR_AB_GPIO_CTL); } static void falcon_setscl(void *data, int state) @@ -209,9 +209,9 @@ static void falcon_setscl(void *data, int state) struct efx_nic *efx = (struct efx_nic *)data; efx_oword_t reg; - falcon_read(efx, ®, GPIO_CTL_REG_KER); - EFX_SET_OWORD_FIELD(reg, GPIO0_OEN, !state); - falcon_write(efx, ®, GPIO_CTL_REG_KER); + falcon_read(efx, ®, FR_AB_GPIO_CTL); + EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO0_OEN, !state); + falcon_write(efx, ®, FR_AB_GPIO_CTL); } static int falcon_getsda(void *data) @@ -219,8 +219,8 @@ static int falcon_getsda(void *data) struct efx_nic *efx = (struct efx_nic *)data; efx_oword_t reg; - falcon_read(efx, ®, GPIO_CTL_REG_KER); - return EFX_OWORD_FIELD(reg, GPIO3_IN); + falcon_read(efx, ®, FR_AB_GPIO_CTL); + return EFX_OWORD_FIELD(reg, FRF_AB_GPIO3_IN); } static int falcon_getscl(void *data) @@ -228,8 +228,8 @@ static int falcon_getscl(void *data) struct efx_nic *efx = (struct efx_nic *)data; efx_oword_t reg; - falcon_read(efx, ®, GPIO_CTL_REG_KER); - return EFX_OWORD_FIELD(reg, GPIO0_IN); + falcon_read(efx, ®, FR_AB_GPIO_CTL); + return EFX_OWORD_FIELD(reg, FRF_AB_GPIO0_IN); } static struct i2c_algo_bit_data falcon_i2c_bit_operations = { @@ -274,11 +274,10 @@ falcon_init_special_buffer(struct efx_nic *efx, dma_addr = buffer->dma_addr + (i * 4096); EFX_LOG(efx, "mapping special buffer %d at %llx\n", index, (unsigned long long)dma_addr); - EFX_POPULATE_QWORD_4(buf_desc, - IP_DAT_BUF_SIZE, IP_DAT_BUF_SIZE_4K, - BUF_ADR_REGION, 0, - BUF_ADR_FBUF, (dma_addr >> 12), - BUF_OWNER_ID_FBUF, 0); + EFX_POPULATE_QWORD_3(buf_desc, + FRF_AZ_BUF_ADR_REGION, 0, + FRF_AZ_BUF_ADR_FBUF, dma_addr >> 12, + FRF_AZ_BUF_OWNER_ID_FBUF, 0); falcon_write_sram(efx, &buf_desc, index); } } @@ -299,11 +298,11 @@ falcon_fini_special_buffer(struct efx_nic *efx, buffer->index, buffer->index + buffer->entries - 1); EFX_POPULATE_OWORD_4(buf_tbl_upd, - BUF_UPD_CMD, 0, - BUF_CLR_CMD, 1, - BUF_CLR_END_ID, end, - BUF_CLR_START_ID, start); - falcon_write(efx, &buf_tbl_upd, BUF_TBL_UPD_REG_KER); + FRF_AZ_BUF_UPD_CMD, 0, + FRF_AZ_BUF_CLR_CMD, 1, + FRF_AZ_BUF_CLR_END_ID, end, + FRF_AZ_BUF_CLR_START_ID, start); + falcon_write(efx, &buf_tbl_upd, FR_AZ_BUF_TBL_UPD); } /* @@ -415,9 +414,9 @@ static inline void falcon_notify_tx_desc(struct efx_tx_queue *tx_queue) efx_dword_t reg; write_ptr = tx_queue->write_count & FALCON_TXD_RING_MASK; - EFX_POPULATE_DWORD_1(reg, TX_DESC_WPTR_DWORD, write_ptr); + EFX_POPULATE_DWORD_1(reg, FRF_AZ_TX_DESC_WPTR_DWORD, write_ptr); falcon_writel_page(tx_queue->efx, ®, - TX_DESC_UPD_REG_KER_DWORD, tx_queue->queue); + FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue); } @@ -441,12 +440,11 @@ void falcon_push_buffers(struct efx_tx_queue *tx_queue) ++tx_queue->write_count; /* Create TX descriptor ring entry */ - EFX_POPULATE_QWORD_5(*txd, - TX_KER_PORT, 0, - TX_KER_CONT, buffer->continuation, - TX_KER_BYTE_CNT, buffer->len, - TX_KER_BUF_REGION, 0, - TX_KER_BUF_ADR, buffer->dma_addr); + EFX_POPULATE_QWORD_4(*txd, + FSF_AZ_TX_KER_CONT, buffer->continuation, + FSF_AZ_TX_KER_BYTE_COUNT, buffer->len, + FSF_AZ_TX_KER_BUF_REGION, 0, + FSF_AZ_TX_KER_BUF_ADDR, buffer->dma_addr); } while (tx_queue->write_count != tx_queue->insert_count); wmb(); /* Ensure descriptors are written before they are fetched */ @@ -474,21 +472,23 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) /* Push TX descriptor ring to card */ EFX_POPULATE_OWORD_10(tx_desc_ptr, - TX_DESCQ_EN, 1, - TX_ISCSI_DDIG_EN, 0, - TX_ISCSI_HDIG_EN, 0, - TX_DESCQ_BUF_BASE_ID, tx_queue->txd.index, - TX_DESCQ_EVQ_ID, tx_queue->channel->channel, - TX_DESCQ_OWNER_ID, 0, - TX_DESCQ_LABEL, tx_queue->queue, - TX_DESCQ_SIZE, FALCON_TXD_RING_ORDER, - TX_DESCQ_TYPE, 0, - TX_NON_IP_DROP_DIS_B0, 1); + FRF_AZ_TX_DESCQ_EN, 1, + FRF_AZ_TX_ISCSI_DDIG_EN, 0, + FRF_AZ_TX_ISCSI_HDIG_EN, 0, + FRF_AZ_TX_DESCQ_BUF_BASE_ID, tx_queue->txd.index, + FRF_AZ_TX_DESCQ_EVQ_ID, + tx_queue->channel->channel, + FRF_AZ_TX_DESCQ_OWNER_ID, 0, + FRF_AZ_TX_DESCQ_LABEL, tx_queue->queue, + FRF_AZ_TX_DESCQ_SIZE, FALCON_TXD_RING_ORDER, + FRF_AZ_TX_DESCQ_TYPE, 0, + FRF_BZ_TX_NON_IP_DROP_DIS, 1); if (falcon_rev(efx) >= FALCON_REV_B0) { int csum = tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM; - EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, !csum); - EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, !csum); + EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_IP_CHKSM_DIS, !csum); + EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_TCP_CHKSM_DIS, + !csum); } falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, @@ -500,12 +500,12 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) /* Only 128 bits in this register */ BUILD_BUG_ON(EFX_TX_QUEUE_COUNT >= 128); - falcon_read(efx, ®, TX_CHKSM_CFG_REG_KER_A1); + falcon_read(efx, ®, FR_AA_TX_CHKSM_CFG); if (tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM) clear_bit_le(tx_queue->queue, (void *)®); else set_bit_le(tx_queue->queue, (void *)®); - falcon_write(efx, ®, TX_CHKSM_CFG_REG_KER_A1); + falcon_write(efx, ®, FR_AA_TX_CHKSM_CFG); } } @@ -516,9 +516,9 @@ static void falcon_flush_tx_queue(struct efx_tx_queue *tx_queue) /* Post a flush command */ EFX_POPULATE_OWORD_2(tx_flush_descq, - TX_FLUSH_DESCQ_CMD, 1, - TX_FLUSH_DESCQ, tx_queue->queue); - falcon_write(efx, &tx_flush_descq, TX_FLUSH_DESCQ_REG_KER); + FRF_AZ_TX_FLUSH_DESCQ_CMD, 1, + FRF_AZ_TX_FLUSH_DESCQ, tx_queue->queue); + falcon_write(efx, &tx_flush_descq, FR_AZ_TX_FLUSH_DESCQ); } void falcon_fini_tx(struct efx_tx_queue *tx_queue) @@ -567,11 +567,11 @@ static inline void falcon_build_rx_desc(struct efx_rx_queue *rx_queue, rxd = falcon_rx_desc(rx_queue, index); rx_buf = efx_rx_buffer(rx_queue, index); EFX_POPULATE_QWORD_3(*rxd, - RX_KER_BUF_SIZE, + FSF_AZ_RX_KER_BUF_SIZE, rx_buf->len - rx_queue->efx->type->rx_buffer_padding, - RX_KER_BUF_REGION, 0, - RX_KER_BUF_ADR, rx_buf->dma_addr); + FSF_AZ_RX_KER_BUF_REGION, 0, + FSF_AZ_RX_KER_BUF_ADDR, rx_buf->dma_addr); } /* This writes to the RX_DESC_WPTR register for the specified receive @@ -591,9 +591,9 @@ void falcon_notify_rx_desc(struct efx_rx_queue *rx_queue) wmb(); write_ptr = rx_queue->added_count & FALCON_RXD_RING_MASK; - EFX_POPULATE_DWORD_1(reg, RX_DESC_WPTR_DWORD, write_ptr); + EFX_POPULATE_DWORD_1(reg, FRF_AZ_RX_DESC_WPTR_DWORD, write_ptr); falcon_writel_page(rx_queue->efx, ®, - RX_DESC_UPD_REG_KER_DWORD, rx_queue->queue); + FR_AZ_RX_DESC_UPD_DWORD_P0, rx_queue->queue); } int falcon_probe_rx(struct efx_rx_queue *rx_queue) @@ -622,17 +622,18 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue) /* Push RX descriptor ring to card */ EFX_POPULATE_OWORD_10(rx_desc_ptr, - RX_ISCSI_DDIG_EN, iscsi_digest_en, - RX_ISCSI_HDIG_EN, iscsi_digest_en, - RX_DESCQ_BUF_BASE_ID, rx_queue->rxd.index, - RX_DESCQ_EVQ_ID, rx_queue->channel->channel, - RX_DESCQ_OWNER_ID, 0, - RX_DESCQ_LABEL, rx_queue->queue, - RX_DESCQ_SIZE, FALCON_RXD_RING_ORDER, - RX_DESCQ_TYPE, 0 /* kernel queue */ , + FRF_AZ_RX_ISCSI_DDIG_EN, iscsi_digest_en, + FRF_AZ_RX_ISCSI_HDIG_EN, iscsi_digest_en, + FRF_AZ_RX_DESCQ_BUF_BASE_ID, rx_queue->rxd.index, + FRF_AZ_RX_DESCQ_EVQ_ID, + rx_queue->channel->channel, + FRF_AZ_RX_DESCQ_OWNER_ID, 0, + FRF_AZ_RX_DESCQ_LABEL, rx_queue->queue, + FRF_AZ_RX_DESCQ_SIZE, FALCON_RXD_RING_ORDER, + FRF_AZ_RX_DESCQ_TYPE, 0 /* kernel queue */ , /* For >=B0 this is scatter so disable */ - RX_DESCQ_JUMBO, !is_b0, - RX_DESCQ_EN, 1); + FRF_AZ_RX_DESCQ_JUMBO, !is_b0, + FRF_AZ_RX_DESCQ_EN, 1); falcon_write_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, rx_queue->queue); } @@ -644,9 +645,9 @@ static void falcon_flush_rx_queue(struct efx_rx_queue *rx_queue) /* Post a flush command */ EFX_POPULATE_OWORD_2(rx_flush_descq, - RX_FLUSH_DESCQ_CMD, 1, - RX_FLUSH_DESCQ, rx_queue->queue); - falcon_write(efx, &rx_flush_descq, RX_FLUSH_DESCQ_REG_KER); + FRF_AZ_RX_FLUSH_DESCQ_CMD, 1, + FRF_AZ_RX_FLUSH_DESCQ, rx_queue->queue); + falcon_write(efx, &rx_flush_descq, FR_AZ_RX_FLUSH_DESCQ); } void falcon_fini_rx(struct efx_rx_queue *rx_queue) @@ -693,7 +694,7 @@ void falcon_eventq_read_ack(struct efx_channel *channel) efx_dword_t reg; struct efx_nic *efx = channel->efx; - EFX_POPULATE_DWORD_1(reg, EVQ_RPTR_DWORD, channel->eventq_read_ptr); + EFX_POPULATE_DWORD_1(reg, FRF_AZ_EVQ_RPTR, channel->eventq_read_ptr); falcon_writel_table(efx, ®, efx->type->evq_rptr_tbl_base, channel->channel); } @@ -703,11 +704,14 @@ void falcon_generate_event(struct efx_channel *channel, efx_qword_t *event) { efx_oword_t drv_ev_reg; - EFX_POPULATE_OWORD_2(drv_ev_reg, - DRV_EV_QID, channel->channel, - DRV_EV_DATA, - EFX_QWORD_FIELD64(*event, WHOLE_EVENT)); - falcon_write(channel->efx, &drv_ev_reg, DRV_EV_REG_KER); + BUILD_BUG_ON(FRF_AZ_DRV_EV_DATA_LBN != 0 || + FRF_AZ_DRV_EV_DATA_WIDTH != 64); + drv_ev_reg.u32[0] = event->u32[0]; + drv_ev_reg.u32[1] = event->u32[1]; + drv_ev_reg.u32[2] = 0; + drv_ev_reg.u32[3] = 0; + EFX_SET_OWORD_FIELD(drv_ev_reg, FRF_AZ_DRV_EV_QID, channel->channel); + falcon_write(channel->efx, &drv_ev_reg, FR_AZ_DRV_EV); } /* Handle a transmit completion event @@ -723,18 +727,18 @@ static void falcon_handle_tx_event(struct efx_channel *channel, struct efx_tx_queue *tx_queue; struct efx_nic *efx = channel->efx; - if (likely(EFX_QWORD_FIELD(*event, TX_EV_COMP))) { + if (likely(EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_COMP))) { /* Transmit completion */ - tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, TX_EV_DESC_PTR); - tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL); + tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR); + tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); tx_queue = &efx->tx_queue[tx_ev_q_label]; channel->irq_mod_score += (tx_ev_desc_ptr - tx_queue->read_count) & efx->type->txd_ring_mask; efx_xmit_done(tx_queue, tx_ev_desc_ptr); - } else if (EFX_QWORD_FIELD(*event, TX_EV_WQ_FF_FULL)) { + } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) { /* Rewrite the FIFO write pointer */ - tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL); + tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); tx_queue = &efx->tx_queue[tx_ev_q_label]; if (efx_dev_registered(efx)) @@ -742,7 +746,7 @@ static void falcon_handle_tx_event(struct efx_channel *channel, falcon_notify_tx_desc(tx_queue); if (efx_dev_registered(efx)) netif_tx_unlock(efx->net_dev); - } else if (EFX_QWORD_FIELD(*event, TX_EV_PKT_ERR) && + } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_PKT_ERR) && EFX_WORKAROUND_10727(efx)) { efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH); } else { @@ -766,22 +770,22 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, bool rx_ev_ip_frag_err, rx_ev_hdr_type, rx_ev_mcast_pkt; unsigned rx_ev_pkt_type; - rx_ev_hdr_type = EFX_QWORD_FIELD(*event, RX_EV_HDR_TYPE); - rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, RX_EV_MCAST_PKT); - rx_ev_tobe_disc = EFX_QWORD_FIELD(*event, RX_EV_TOBE_DISC); - rx_ev_pkt_type = EFX_QWORD_FIELD(*event, RX_EV_PKT_TYPE); + rx_ev_hdr_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE); + rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_PKT); + rx_ev_tobe_disc = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_TOBE_DISC); + rx_ev_pkt_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_TYPE); rx_ev_buf_owner_id_err = EFX_QWORD_FIELD(*event, - RX_EV_BUF_OWNER_ID_ERR); - rx_ev_ip_frag_err = EFX_QWORD_FIELD(*event, RX_EV_IF_FRAG_ERR); + FSF_AZ_RX_EV_BUF_OWNER_ID_ERR); + rx_ev_ip_frag_err = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_IP_FRAG_ERR); rx_ev_ip_hdr_chksum_err = EFX_QWORD_FIELD(*event, - RX_EV_IP_HDR_CHKSUM_ERR); + FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR); rx_ev_tcp_udp_chksum_err = EFX_QWORD_FIELD(*event, - RX_EV_TCP_UDP_CHKSUM_ERR); - rx_ev_eth_crc_err = EFX_QWORD_FIELD(*event, RX_EV_ETH_CRC_ERR); - rx_ev_frm_trunc = EFX_QWORD_FIELD(*event, RX_EV_FRM_TRUNC); + FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR); + rx_ev_eth_crc_err = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_ETH_CRC_ERR); + rx_ev_frm_trunc = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_FRM_TRUNC); rx_ev_drib_nib = ((falcon_rev(efx) >= FALCON_REV_B0) ? - 0 : EFX_QWORD_FIELD(*event, RX_EV_DRIB_NIB)); - rx_ev_pause_frm = EFX_QWORD_FIELD(*event, RX_EV_PAUSE_FRM_ERR); + 0 : EFX_QWORD_FIELD(*event, FSF_AA_RX_EV_DRIB_NIB)); + rx_ev_pause_frm = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PAUSE_FRM_ERR); /* Every error apart from tobe_disc and pause_frm */ rx_ev_other_err = (rx_ev_drib_nib | rx_ev_tcp_udp_chksum_err | @@ -865,16 +869,17 @@ static void falcon_handle_rx_event(struct efx_channel *channel, struct efx_nic *efx = channel->efx; /* Basic packet information */ - rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, RX_EV_BYTE_CNT); - rx_ev_pkt_ok = EFX_QWORD_FIELD(*event, RX_EV_PKT_OK); - rx_ev_hdr_type = EFX_QWORD_FIELD(*event, RX_EV_HDR_TYPE); - WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_JUMBO_CONT)); - WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_SOP) != 1); - WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_Q_LABEL) != channel->channel); + rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_BYTE_CNT); + rx_ev_pkt_ok = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_OK); + rx_ev_hdr_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE); + WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_JUMBO_CONT)); + WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_SOP) != 1); + WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_Q_LABEL) != + channel->channel); rx_queue = &efx->rx_queue[channel->channel]; - rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, RX_EV_DESC_PTR); + rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR); expected_ptr = rx_queue->removed_count & FALCON_RXD_RING_MASK; if (unlikely(rx_ev_desc_ptr != expected_ptr)) falcon_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr); @@ -883,7 +888,9 @@ static void falcon_handle_rx_event(struct efx_channel *channel, /* If packet is marked as OK and packet type is TCP/IPv4 or * UDP/IPv4, then we can rely on the hardware checksum. */ - checksummed = RX_EV_HDR_TYPE_HAS_CHECKSUMS(rx_ev_hdr_type); + checksummed = + rx_ev_hdr_type == FSE_AB_RX_EV_HDR_TYPE_IPV4_TCP || + rx_ev_hdr_type == FSE_AB_RX_EV_HDR_TYPE_IPV4_UDP; } else { falcon_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard); @@ -891,10 +898,10 @@ static void falcon_handle_rx_event(struct efx_channel *channel, } /* Detect multicast packets that didn't match the filter */ - rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, RX_EV_MCAST_PKT); + rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_PKT); if (rx_ev_mcast_pkt) { unsigned int rx_ev_mcast_hash_match = - EFX_QWORD_FIELD(*event, RX_EV_MCAST_HASH_MATCH); + EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_HASH_MATCH); if (unlikely(!rx_ev_mcast_hash_match)) discard = true; @@ -914,24 +921,23 @@ static void falcon_handle_global_event(struct efx_channel *channel, struct efx_nic *efx = channel->efx; bool handled = false; - if (EFX_QWORD_FIELD(*event, G_PHY0_INTR) || - EFX_QWORD_FIELD(*event, G_PHY1_INTR) || - EFX_QWORD_FIELD(*event, XG_PHY_INTR) || - EFX_QWORD_FIELD(*event, XFP_PHY_INTR)) { + if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) || + EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) || + EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR)) { efx->phy_op->clear_interrupt(efx); queue_work(efx->workqueue, &efx->phy_work); handled = true; } if ((falcon_rev(efx) >= FALCON_REV_B0) && - EFX_QWORD_FIELD(*event, XG_MNT_INTR_B0)) { + EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) { queue_work(efx->workqueue, &efx->mac_work); handled = true; } if (falcon_rev(efx) <= FALCON_REV_A1 ? - EFX_QWORD_FIELD(*event, RX_RECOVERY_A1) : - EFX_QWORD_FIELD(*event, RX_RECOVERY_B0)) { + EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) : + EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) { EFX_ERR(efx, "channel %d seen global RX_RESET " "event. Resetting.\n", channel->channel); @@ -954,35 +960,35 @@ static void falcon_handle_driver_event(struct efx_channel *channel, unsigned int ev_sub_code; unsigned int ev_sub_data; - ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE); - ev_sub_data = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_DATA); + ev_sub_code = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBCODE); + ev_sub_data = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBDATA); switch (ev_sub_code) { - case TX_DESCQ_FLS_DONE_EV_DECODE: + case FSE_AZ_TX_DESCQ_FLS_DONE_EV: EFX_TRACE(efx, "channel %d TXQ %d flushed\n", channel->channel, ev_sub_data); break; - case RX_DESCQ_FLS_DONE_EV_DECODE: + case FSE_AZ_RX_DESCQ_FLS_DONE_EV: EFX_TRACE(efx, "channel %d RXQ %d flushed\n", channel->channel, ev_sub_data); break; - case EVQ_INIT_DONE_EV_DECODE: + case FSE_AZ_EVQ_INIT_DONE_EV: EFX_LOG(efx, "channel %d EVQ %d initialised\n", channel->channel, ev_sub_data); break; - case SRM_UPD_DONE_EV_DECODE: + case FSE_AZ_SRM_UPD_DONE_EV: EFX_TRACE(efx, "channel %d SRAM update done\n", channel->channel); break; - case WAKE_UP_EV_DECODE: + case FSE_AZ_WAKE_UP_EV: EFX_TRACE(efx, "channel %d RXQ %d wakeup event\n", channel->channel, ev_sub_data); break; - case TIMER_EV_DECODE: + case FSE_AZ_TIMER_EV: EFX_TRACE(efx, "channel %d RX queue %d timer expired\n", channel->channel, ev_sub_data); break; - case RX_RECOVERY_EV_DECODE: + case FSE_AA_RX_RECOVER_EV: EFX_ERR(efx, "channel %d seen DRIVER RX_RESET event. " "Resetting.\n", channel->channel); atomic_inc(&efx->rx_reset); @@ -991,12 +997,12 @@ static void falcon_handle_driver_event(struct efx_channel *channel, RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE); break; - case RX_DSC_ERROR_EV_DECODE: + case FSE_BZ_RX_DSC_ERROR_EV: EFX_ERR(efx, "RX DMA Q %d reports descriptor fetch error." " RX Q %d is disabled.\n", ev_sub_data, ev_sub_data); efx_schedule_reset(efx, RESET_TYPE_RX_DESC_FETCH); break; - case TX_DSC_ERROR_EV_DECODE: + case FSE_BZ_TX_DSC_ERROR_EV: EFX_ERR(efx, "TX DMA Q %d reports descriptor fetch error." " TX Q %d is disabled.\n", ev_sub_data, ev_sub_data); efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH); @@ -1032,27 +1038,27 @@ int falcon_process_eventq(struct efx_channel *channel, int rx_quota) /* Clear this event by marking it all ones */ EFX_SET_QWORD(*p_event); - ev_code = EFX_QWORD_FIELD(event, EV_CODE); + ev_code = EFX_QWORD_FIELD(event, FSF_AZ_EV_CODE); switch (ev_code) { - case RX_IP_EV_DECODE: + case FSE_AZ_EV_CODE_RX_EV: falcon_handle_rx_event(channel, &event); ++rx_packets; break; - case TX_IP_EV_DECODE: + case FSE_AZ_EV_CODE_TX_EV: falcon_handle_tx_event(channel, &event); break; - case DRV_GEN_EV_DECODE: - channel->eventq_magic - = EFX_QWORD_FIELD(event, EVQ_MAGIC); + case FSE_AZ_EV_CODE_DRV_GEN_EV: + channel->eventq_magic = EFX_QWORD_FIELD( + event, FSF_AZ_DRV_GEN_EV_MAGIC); EFX_LOG(channel->efx, "channel %d received generated " "event "EFX_QWORD_FMT"\n", channel->channel, EFX_QWORD_VAL(event)); break; - case GLOBAL_EV_DECODE: + case FSE_AZ_EV_CODE_GLOBAL_EV: falcon_handle_global_event(channel, &event); break; - case DRIVER_EV_DECODE: + case FSE_AZ_EV_CODE_DRIVER_EV: falcon_handle_driver_event(channel, &event); break; default: @@ -1086,16 +1092,19 @@ void falcon_set_int_moderation(struct efx_channel *channel) if (channel->irq_moderation < FALCON_IRQ_MOD_RESOLUTION) channel->irq_moderation = FALCON_IRQ_MOD_RESOLUTION; EFX_POPULATE_DWORD_2(timer_cmd, - TIMER_MODE, TIMER_MODE_INT_HLDOFF, - TIMER_VAL, + FRF_AB_TC_TIMER_MODE, + FFE_BB_TIMER_MODE_INT_HLDOFF, + FRF_AB_TC_TIMER_VAL, channel->irq_moderation / FALCON_IRQ_MOD_RESOLUTION - 1); } else { EFX_POPULATE_DWORD_2(timer_cmd, - TIMER_MODE, TIMER_MODE_DIS, - TIMER_VAL, 0); + FRF_AB_TC_TIMER_MODE, + FFE_BB_TIMER_MODE_DIS, + FRF_AB_TC_TIMER_VAL, 0); } - falcon_writel_page_locked(efx, &timer_cmd, TIMER_CMD_REG_KER, + BUILD_BUG_ON(FR_AA_TIMER_COMMAND_KER != FR_BZ_TIMER_COMMAND_P0); + falcon_writel_page_locked(efx, &timer_cmd, FR_BZ_TIMER_COMMAND_P0, channel->channel); } @@ -1127,9 +1136,9 @@ void falcon_init_eventq(struct efx_channel *channel) /* Push event queue to card */ EFX_POPULATE_OWORD_3(evq_ptr, - EVQ_EN, 1, - EVQ_SIZE, FALCON_EVQ_ORDER, - EVQ_BUF_BASE_ID, channel->eventq.index); + FRF_AZ_EVQ_EN, 1, + FRF_AZ_EVQ_SIZE, FALCON_EVQ_ORDER, + FRF_AZ_EVQ_BUF_BASE_ID, channel->eventq.index); falcon_write_table(efx, &evq_ptr, efx->type->evq_ptr_tbl_base, channel->channel); @@ -1165,9 +1174,9 @@ void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic) { efx_qword_t test_event; - EFX_POPULATE_QWORD_2(test_event, - EV_CODE, DRV_GEN_EV_DECODE, - EVQ_MAGIC, magic); + EFX_POPULATE_QWORD_2(test_event, FSF_AZ_EV_CODE, + FSE_AZ_EV_CODE_DRV_GEN_EV, + FSF_AZ_DRV_GEN_EV_MAGIC, magic); falcon_generate_event(channel, &test_event); } @@ -1175,11 +1184,12 @@ void falcon_sim_phy_event(struct efx_nic *efx) { efx_qword_t phy_event; - EFX_POPULATE_QWORD_1(phy_event, EV_CODE, GLOBAL_EV_DECODE); + EFX_POPULATE_QWORD_1(phy_event, FSF_AZ_EV_CODE, + FSE_AZ_EV_CODE_GLOBAL_EV); if (EFX_IS10G(efx)) - EFX_SET_QWORD_FIELD(phy_event, XG_PHY_INTR, 1); + EFX_SET_QWORD_FIELD(phy_event, FSF_AB_GLB_EV_XG_PHY0_INTR, 1); else - EFX_SET_QWORD_FIELD(phy_event, G_PHY0_INTR, 1); + EFX_SET_QWORD_FIELD(phy_event, FSF_AB_GLB_EV_G_PHY0_INTR, 1); falcon_generate_event(&efx->channel[0], &phy_event); } @@ -1207,22 +1217,23 @@ static void falcon_poll_flush_events(struct efx_nic *efx) if (!falcon_event_present(event)) break; - ev_code = EFX_QWORD_FIELD(*event, EV_CODE); - ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE); - if (ev_code == DRIVER_EV_DECODE && - ev_sub_code == TX_DESCQ_FLS_DONE_EV_DECODE) { + ev_code = EFX_QWORD_FIELD(*event, FSF_AZ_EV_CODE); + ev_sub_code = EFX_QWORD_FIELD(*event, + FSF_AZ_DRIVER_EV_SUBCODE); + if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV && + ev_sub_code == FSE_AZ_TX_DESCQ_FLS_DONE_EV) { ev_queue = EFX_QWORD_FIELD(*event, - DRIVER_EV_TX_DESCQ_ID); + FSF_AZ_DRIVER_EV_SUBDATA); if (ev_queue < EFX_TX_QUEUE_COUNT) { tx_queue = efx->tx_queue + ev_queue; tx_queue->flushed = true; } - } else if (ev_code == DRIVER_EV_DECODE && - ev_sub_code == RX_DESCQ_FLS_DONE_EV_DECODE) { - ev_queue = EFX_QWORD_FIELD(*event, - DRIVER_EV_RX_DESCQ_ID); - ev_failed = EFX_QWORD_FIELD(*event, - DRIVER_EV_RX_FLUSH_FAIL); + } else if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV && + ev_sub_code == FSE_AZ_RX_DESCQ_FLS_DONE_EV) { + ev_queue = EFX_QWORD_FIELD( + *event, FSF_AZ_DRIVER_EV_RX_DESCQ_ID); + ev_failed = EFX_QWORD_FIELD( + *event, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL); if (ev_queue < efx->n_rx_queues) { rx_queue = efx->rx_queue + ev_queue; @@ -1312,9 +1323,9 @@ static inline void falcon_interrupts(struct efx_nic *efx, int enabled, efx_oword_t int_en_reg_ker; EFX_POPULATE_OWORD_2(int_en_reg_ker, - KER_INT_KER, force, - DRV_INT_EN_KER, enabled); - falcon_write(efx, &int_en_reg_ker, INT_EN_REG_KER); + FRF_AZ_KER_INT_KER, force, + FRF_AZ_DRV_INT_EN_KER, enabled); + falcon_write(efx, &int_en_reg_ker, FR_AZ_INT_EN_KER); } void falcon_enable_interrupts(struct efx_nic *efx) @@ -1327,9 +1338,10 @@ void falcon_enable_interrupts(struct efx_nic *efx) /* Program address */ EFX_POPULATE_OWORD_2(int_adr_reg_ker, - NORM_INT_VEC_DIS_KER, EFX_INT_MODE_USE_MSI(efx), - INT_ADR_KER, efx->irq_status.dma_addr); - falcon_write(efx, &int_adr_reg_ker, INT_ADR_REG_KER); + FRF_AZ_NORM_INT_VEC_DIS_KER, + EFX_INT_MODE_USE_MSI(efx), + FRF_AZ_INT_ADR_KER, efx->irq_status.dma_addr); + falcon_write(efx, &int_adr_reg_ker, FR_AZ_INT_ADR_KER); /* Enable interrupts */ falcon_interrupts(efx, 1, 0); @@ -1369,9 +1381,9 @@ static inline void falcon_irq_ack_a1(struct efx_nic *efx) { efx_dword_t reg; - EFX_POPULATE_DWORD_1(reg, INT_ACK_DUMMY_DATA, 0xb7eb7e); - falcon_writel(efx, ®, INT_ACK_REG_KER_A1); - falcon_readl(efx, ®, WORK_AROUND_BROKEN_PCI_READS_REG_KER_A1); + EFX_POPULATE_DWORD_1(reg, FRF_AA_INT_ACK_KER_FIELD, 0xb7eb7e); + falcon_writel(efx, ®, FR_AA_INT_ACK_KER); + falcon_readl(efx, ®, FR_AA_WORK_AROUND_BROKEN_PCI_READS); } /* Process a fatal interrupt @@ -1384,8 +1396,8 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) efx_oword_t fatal_intr; int error, mem_perr; - falcon_read(efx, &fatal_intr, FATAL_INTR_REG_KER); - error = EFX_OWORD_FIELD(fatal_intr, INT_KER_ERROR); + falcon_read(efx, &fatal_intr, FR_AZ_FATAL_INTR_KER); + error = EFX_OWORD_FIELD(fatal_intr, FRF_AZ_FATAL_INTR); EFX_ERR(efx, "SYSTEM ERROR " EFX_OWORD_FMT " status " EFX_OWORD_FMT ": %s\n", EFX_OWORD_VAL(*int_ker), @@ -1395,10 +1407,10 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) goto out; /* If this is a memory parity error dump which blocks are offending */ - mem_perr = EFX_OWORD_FIELD(fatal_intr, MEM_PERR_INT_KER); + mem_perr = EFX_OWORD_FIELD(fatal_intr, FRF_AZ_MEM_PERR_INT_KER); if (mem_perr) { efx_oword_t reg; - falcon_read(efx, ®, MEM_STAT_REG_KER); + falcon_read(efx, ®, FR_AZ_MEM_STAT); EFX_ERR(efx, "SYSTEM ERROR: memory parity error " EFX_OWORD_FMT "\n", EFX_OWORD_VAL(reg)); } @@ -1442,11 +1454,11 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) int syserr; /* Read the ISR which also ACKs the interrupts */ - falcon_readl(efx, ®, INT_ISR0_B0); + falcon_readl(efx, ®, FR_BZ_INT_ISR0); queues = EFX_EXTRACT_DWORD(reg, 0, 31); /* Check to see if we have a serious error condition */ - syserr = EFX_OWORD_FIELD(*int_ker, FATAL_INT); + syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); if (unlikely(syserr)) return falcon_fatal_interrupt(efx); @@ -1492,7 +1504,7 @@ static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker)); /* Check to see if we have a serious error condition */ - syserr = EFX_OWORD_FIELD(*int_ker, FATAL_INT); + syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); if (unlikely(syserr)) return falcon_fatal_interrupt(efx); @@ -1559,10 +1571,10 @@ static void falcon_setup_rss_indir_table(struct efx_nic *efx) if (falcon_rev(efx) < FALCON_REV_B0) return; - for (offset = RX_RSS_INDIR_TBL_B0; - offset < RX_RSS_INDIR_TBL_B0 + 0x800; + for (offset = FR_BZ_RX_INDIRECTION_TBL; + offset < FR_BZ_RX_INDIRECTION_TBL + 0x800; offset += 0x10) { - EFX_POPULATE_DWORD_1(dword, RX_RSS_INDIR_ENT_B0, + EFX_POPULATE_DWORD_1(dword, FRF_BZ_IT_QUEUE, i % efx->n_rx_queues); falcon_writel(efx, &dword, offset); i++; @@ -1627,7 +1639,7 @@ void falcon_fini_interrupt(struct efx_nic *efx) /* ACK legacy interrupt */ if (falcon_rev(efx) >= FALCON_REV_B0) - falcon_read(efx, ®, INT_ISR0_B0); + falcon_read(efx, ®, FR_BZ_INT_ISR0); else falcon_irq_ack_a1(efx); @@ -1648,8 +1660,8 @@ void falcon_fini_interrupt(struct efx_nic *efx) static int falcon_spi_poll(struct efx_nic *efx) { efx_oword_t reg; - falcon_read(efx, ®, EE_SPI_HCMD_REG_KER); - return EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN) ? -EBUSY : 0; + falcon_read(efx, ®, FR_AB_EE_SPI_HCMD); + return EFX_OWORD_FIELD(reg, FRF_AB_EE_SPI_HCMD_CMD_EN) ? -EBUSY : 0; } /* Wait for SPI command completion */ @@ -1701,27 +1713,27 @@ int falcon_spi_cmd(const struct efx_spi_device *spi, /* Program address register, if we have an address */ if (addressed) { - EFX_POPULATE_OWORD_1(reg, EE_SPI_HADR_ADR, address); - falcon_write(efx, ®, EE_SPI_HADR_REG_KER); + EFX_POPULATE_OWORD_1(reg, FRF_AB_EE_SPI_HADR_ADR, address); + falcon_write(efx, ®, FR_AB_EE_SPI_HADR); } /* Program data register, if we have data */ if (in != NULL) { memcpy(®, in, len); - falcon_write(efx, ®, EE_SPI_HDATA_REG_KER); + falcon_write(efx, ®, FR_AB_EE_SPI_HDATA); } /* Issue read/write command */ EFX_POPULATE_OWORD_7(reg, - EE_SPI_HCMD_CMD_EN, 1, - EE_SPI_HCMD_SF_SEL, spi->device_id, - EE_SPI_HCMD_DABCNT, len, - EE_SPI_HCMD_READ, reading, - EE_SPI_HCMD_DUBCNT, 0, - EE_SPI_HCMD_ADBCNT, + FRF_AB_EE_SPI_HCMD_CMD_EN, 1, + FRF_AB_EE_SPI_HCMD_SF_SEL, spi->device_id, + FRF_AB_EE_SPI_HCMD_DABCNT, len, + FRF_AB_EE_SPI_HCMD_READ, reading, + FRF_AB_EE_SPI_HCMD_DUBCNT, 0, + FRF_AB_EE_SPI_HCMD_ADBCNT, (addressed ? spi->addr_len : 0), - EE_SPI_HCMD_ENC, command); - falcon_write(efx, ®, EE_SPI_HCMD_REG_KER); + FRF_AB_EE_SPI_HCMD_ENC, command); + falcon_write(efx, ®, FR_AB_EE_SPI_HCMD); /* Wait for read/write to complete */ rc = falcon_spi_wait(efx); @@ -1730,7 +1742,7 @@ int falcon_spi_cmd(const struct efx_spi_device *spi, /* Read data */ if (out != NULL) { - falcon_read(efx, ®, EE_SPI_HDATA_REG_KER); + falcon_read(efx, ®, FR_AB_EE_SPI_HDATA); memcpy(out, ®, len); } @@ -1871,21 +1883,22 @@ static int falcon_reset_macs(struct efx_nic *efx) * macs, so instead use the internal MAC resets */ if (!EFX_IS10G(efx)) { - EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 1); - falcon_write(efx, ®, GM_CFG1_REG); + EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 1); + falcon_write(efx, ®, FR_AB_GM_CFG1); udelay(1000); - EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 0); - falcon_write(efx, ®, GM_CFG1_REG); + EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 0); + falcon_write(efx, ®, FR_AB_GM_CFG1); udelay(1000); return 0; } else { - EFX_POPULATE_OWORD_1(reg, XM_CORE_RST, 1); - falcon_write(efx, ®, XM_GLB_CFG_REG); + EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1); + falcon_write(efx, ®, FR_AB_XM_GLB_CFG); for (count = 0; count < 10000; count++) { - falcon_read(efx, ®, XM_GLB_CFG_REG); - if (EFX_OWORD_FIELD(reg, XM_CORE_RST) == 0) + falcon_read(efx, ®, FR_AB_XM_GLB_CFG); + if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) == + 0) return 0; udelay(10); } @@ -1899,22 +1912,22 @@ static int falcon_reset_macs(struct efx_nic *efx) * the drain sequence with the statistics fetch */ efx_stats_disable(efx); - falcon_read(efx, ®, MAC0_CTRL_REG_KER); - EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1); - falcon_write(efx, ®, MAC0_CTRL_REG_KER); + falcon_read(efx, ®, FR_AB_MAC_CTRL); + EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, 1); + falcon_write(efx, ®, FR_AB_MAC_CTRL); - falcon_read(efx, ®, GLB_CTL_REG_KER); - EFX_SET_OWORD_FIELD(reg, RST_XGTX, 1); - EFX_SET_OWORD_FIELD(reg, RST_XGRX, 1); - EFX_SET_OWORD_FIELD(reg, RST_EM, 1); - falcon_write(efx, ®, GLB_CTL_REG_KER); + falcon_read(efx, ®, FR_AB_GLB_CTL); + EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGTX, 1); + EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGRX, 1); + EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_EM, 1); + falcon_write(efx, ®, FR_AB_GLB_CTL); count = 0; while (1) { - falcon_read(efx, ®, GLB_CTL_REG_KER); - if (!EFX_OWORD_FIELD(reg, RST_XGTX) && - !EFX_OWORD_FIELD(reg, RST_XGRX) && - !EFX_OWORD_FIELD(reg, RST_EM)) { + falcon_read(efx, ®, FR_AB_GLB_CTL); + if (!EFX_OWORD_FIELD(reg, FRF_AB_RST_XGTX) && + !EFX_OWORD_FIELD(reg, FRF_AB_RST_XGRX) && + !EFX_OWORD_FIELD(reg, FRF_AB_RST_EM)) { EFX_LOG(efx, "Completed MAC reset after %d loops\n", count); break; @@ -1945,9 +1958,9 @@ void falcon_drain_tx_fifo(struct efx_nic *efx) (efx->loopback_mode != LOOPBACK_NONE)) return; - falcon_read(efx, ®, MAC0_CTRL_REG_KER); + falcon_read(efx, ®, FR_AB_MAC_CTRL); /* There is no point in draining more than once */ - if (EFX_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0)) + if (EFX_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN)) return; falcon_reset_macs(efx); @@ -1961,9 +1974,9 @@ void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) return; /* Isolate the MAC -> RX */ - falcon_read(efx, ®, RX_CFG_REG_KER); - EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 0); - falcon_write(efx, ®, RX_CFG_REG_KER); + falcon_read(efx, ®, FR_AZ_RX_CFG); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 0); + falcon_write(efx, ®, FR_AZ_RX_CFG); if (!efx->link_up) falcon_drain_tx_fifo(efx); @@ -1986,19 +1999,19 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) * indefinitely held and TX queue can be flushed at any point * while the link is down. */ EFX_POPULATE_OWORD_5(reg, - MAC_XOFF_VAL, 0xffff /* max pause time */, - MAC_BCAD_ACPT, 1, - MAC_UC_PROM, efx->promiscuous, - MAC_LINK_STATUS, 1, /* always set */ - MAC_SPEED, link_speed); + FRF_AB_MAC_XOFF_VAL, 0xffff /* max pause time */, + FRF_AB_MAC_BCAD_ACPT, 1, + FRF_AB_MAC_UC_PROM, efx->promiscuous, + FRF_AB_MAC_LINK_STATUS, 1, /* always set */ + FRF_AB_MAC_SPEED, link_speed); /* On B0, MAC backpressure can be disabled and packets get * discarded. */ if (falcon_rev(efx) >= FALCON_REV_B0) { - EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, + EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, !efx->link_up); } - falcon_write(efx, ®, MAC0_CTRL_REG_KER); + falcon_write(efx, ®, FR_AB_MAC_CTRL); /* Restore the multicast hash registers. */ falcon_set_multicast_hash(efx); @@ -2007,13 +2020,13 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL. * Action on receipt of pause frames is controller by XM_DIS_FCNTL */ tx_fc = !!(efx->link_fc & EFX_FC_TX); - falcon_read(efx, ®, RX_CFG_REG_KER); - EFX_SET_OWORD_FIELD(reg, RX_XOFF_MAC_EN, tx_fc); + falcon_read(efx, ®, FR_AZ_RX_CFG); + EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, tx_fc); /* Unisolate the MAC -> RX */ if (falcon_rev(efx) >= FALCON_REV_B0) - EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 1); - falcon_write(efx, ®, RX_CFG_REG_KER); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1); + falcon_write(efx, ®, FR_AZ_RX_CFG); } int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) @@ -2028,8 +2041,8 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) /* Statistics fetch will fail if the MAC is in TX drain */ if (falcon_rev(efx) >= FALCON_REV_B0) { efx_oword_t temp; - falcon_read(efx, &temp, MAC0_CTRL_REG_KER); - if (EFX_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0)) + falcon_read(efx, &temp, FR_AB_MAC_CTRL); + if (EFX_OWORD_FIELD(temp, FRF_BB_TXFIFO_DRAIN_EN)) return 0; } @@ -2039,10 +2052,10 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) /* Initiate DMA transfer of stats */ EFX_POPULATE_OWORD_2(reg, - MAC_STAT_DMA_CMD, 1, - MAC_STAT_DMA_ADR, + FRF_AB_MAC_STAT_DMA_CMD, 1, + FRF_AB_MAC_STAT_DMA_ADR, efx->stats_buffer.dma_addr); - falcon_write(efx, ®, MAC0_STAT_DMA_REG_KER); + falcon_write(efx, ®, FR_AB_MAC_STAT_DMA); /* Wait for transfer to complete */ for (i = 0; i < 400; i++) { @@ -2072,10 +2085,10 @@ static int falcon_gmii_wait(struct efx_nic *efx) /* wait upto 50ms - taken max from datasheet */ for (count = 0; count < 5000; count++) { - falcon_readl(efx, &md_stat, MD_STAT_REG_KER); - if (EFX_DWORD_FIELD(md_stat, MD_BSY) == 0) { - if (EFX_DWORD_FIELD(md_stat, MD_LNFL) != 0 || - EFX_DWORD_FIELD(md_stat, MD_BSERR) != 0) { + falcon_readl(efx, &md_stat, FR_AB_MD_STAT); + if (EFX_DWORD_FIELD(md_stat, FRF_AB_MD_BSY) == 0) { + if (EFX_DWORD_FIELD(md_stat, FRF_AB_MD_LNFL) != 0 || + EFX_DWORD_FIELD(md_stat, FRF_AB_MD_BSERR) != 0) { EFX_ERR(efx, "error from GMII access " EFX_DWORD_FMT"\n", EFX_DWORD_VAL(md_stat)); @@ -2108,29 +2121,30 @@ static int falcon_mdio_write(struct net_device *net_dev, goto out; /* Write the address/ID register */ - EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr); - falcon_write(efx, ®, MD_PHY_ADR_REG_KER); + EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_PHY_ADR, addr); + falcon_write(efx, ®, FR_AB_MD_PHY_ADR); - EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad); - falcon_write(efx, ®, MD_ID_REG_KER); + EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_PRT_ADR, prtad, + FRF_AB_MD_DEV_ADR, devad); + falcon_write(efx, ®, FR_AB_MD_ID); /* Write data */ - EFX_POPULATE_OWORD_1(reg, MD_TXD, value); - falcon_write(efx, ®, MD_TXD_REG_KER); + EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_TXD, value); + falcon_write(efx, ®, FR_AB_MD_TXD); EFX_POPULATE_OWORD_2(reg, - MD_WRC, 1, - MD_GC, 0); - falcon_write(efx, ®, MD_CS_REG_KER); + FRF_AB_MD_WRC, 1, + FRF_AB_MD_GC, 0); + falcon_write(efx, ®, FR_AB_MD_CS); /* Wait for data to be written */ rc = falcon_gmii_wait(efx); if (rc) { /* Abort the write operation */ EFX_POPULATE_OWORD_2(reg, - MD_WRC, 0, - MD_GC, 1); - falcon_write(efx, ®, MD_CS_REG_KER); + FRF_AB_MD_WRC, 0, + FRF_AB_MD_GC, 1); + falcon_write(efx, ®, FR_AB_MD_CS); udelay(10); } @@ -2154,29 +2168,30 @@ static int falcon_mdio_read(struct net_device *net_dev, if (rc) goto out; - EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr); - falcon_write(efx, ®, MD_PHY_ADR_REG_KER); + EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_PHY_ADR, addr); + falcon_write(efx, ®, FR_AB_MD_PHY_ADR); - EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad); - falcon_write(efx, ®, MD_ID_REG_KER); + EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_PRT_ADR, prtad, + FRF_AB_MD_DEV_ADR, devad); + falcon_write(efx, ®, FR_AB_MD_ID); /* Request data to be read */ - EFX_POPULATE_OWORD_2(reg, MD_RDC, 1, MD_GC, 0); - falcon_write(efx, ®, MD_CS_REG_KER); + EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_RDC, 1, FRF_AB_MD_GC, 0); + falcon_write(efx, ®, FR_AB_MD_CS); /* Wait for data to become available */ rc = falcon_gmii_wait(efx); if (rc == 0) { - falcon_read(efx, ®, MD_RXD_REG_KER); - rc = EFX_OWORD_FIELD(reg, MD_RXD); + falcon_read(efx, ®, FR_AB_MD_RXD); + rc = EFX_OWORD_FIELD(reg, FRF_AB_MD_RXD); EFX_REGDUMP(efx, "read from MDIO %d register %d.%d, got %04x\n", prtad, devad, addr, rc); } else { /* Abort the read operation */ EFX_POPULATE_OWORD_2(reg, - MD_RIC, 0, - MD_GC, 1); - falcon_write(efx, ®, MD_CS_REG_KER); + FRF_AB_MD_RIC, 0, + FRF_AB_MD_GC, 1); + falcon_write(efx, ®, FR_AB_MD_CS); EFX_LOG(efx, "read from MDIO %d register %d.%d, got error %d\n", prtad, devad, addr, rc); @@ -2243,16 +2258,17 @@ int falcon_switch_mac(struct efx_nic *efx) /* Always push the NIC_STAT_REG setting even if the mac hasn't * changed, because this function is run post online reset */ - falcon_read(efx, &nic_stat, NIC_STAT_REG); + falcon_read(efx, &nic_stat, FR_AB_NIC_STAT); strap_val = EFX_IS10G(efx) ? 5 : 3; if (falcon_rev(efx) >= FALCON_REV_B0) { - EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_EN, 1); - EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_OVR, strap_val); - falcon_write(efx, &nic_stat, NIC_STAT_REG); + EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP_EN, 1); + EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP, strap_val); + falcon_write(efx, &nic_stat, FR_AB_NIC_STAT); } else { /* Falcon A1 does not support 1G/10G speed switching * and must not be used with a PHY that does. */ - BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val); + BUG_ON(EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_PINS) != + strap_val); } if (old_mac_op == efx->mac_op) @@ -2325,8 +2341,8 @@ void falcon_set_multicast_hash(struct efx_nic *efx) */ set_bit_le(0xff, mc_hash->byte); - falcon_write(efx, &mc_hash->oword[0], MAC_MCAST_HASH_REG0_KER); - falcon_write(efx, &mc_hash->oword[1], MAC_MCAST_HASH_REG1_KER); + falcon_write(efx, &mc_hash->oword[0], FR_AB_MAC_MC_HASH_REG0); + falcon_write(efx, &mc_hash->oword[1], FR_AB_MAC_MC_HASH_REG1); } @@ -2352,7 +2368,7 @@ int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) region = kmalloc(FALCON_NVCONFIG_END, GFP_KERNEL); if (!region) return -ENOMEM; - nvconfig = region + NVCONFIG_OFFSET; + nvconfig = region + FALCON_NVCONFIG_OFFSET; mutex_lock(&efx->spi_lock); rc = falcon_spi_read(spi, 0, FALCON_NVCONFIG_END, NULL, region); @@ -2368,7 +2384,7 @@ int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) struct_ver = le16_to_cpu(nvconfig->board_struct_ver); rc = -EINVAL; - if (magic_num != NVCONFIG_BOARD_MAGIC_NUM) { + if (magic_num != FALCON_NVCONFIG_BOARD_MAGIC_NUM) { EFX_ERR(efx, "NVRAM bad magic 0x%x\n", magic_num); goto out; } @@ -2404,41 +2420,41 @@ static struct { unsigned address; efx_oword_t mask; } efx_test_registers[] = { - { ADR_REGION_REG_KER, + { FR_AZ_ADR_REGION, EFX_OWORD32(0x0001FFFF, 0x0001FFFF, 0x0001FFFF, 0x0001FFFF) }, - { RX_CFG_REG_KER, + { FR_AZ_RX_CFG, EFX_OWORD32(0xFFFFFFFE, 0x00017FFF, 0x00000000, 0x00000000) }, - { TX_CFG_REG_KER, + { FR_AZ_TX_CFG, EFX_OWORD32(0x7FFF0037, 0x00000000, 0x00000000, 0x00000000) }, - { TX_CFG2_REG_KER, + { FR_AZ_TX_RESERVED, EFX_OWORD32(0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF) }, - { MAC0_CTRL_REG_KER, + { FR_AB_MAC_CTRL, EFX_OWORD32(0xFFFF0000, 0x00000000, 0x00000000, 0x00000000) }, - { SRM_TX_DC_CFG_REG_KER, + { FR_AZ_SRM_TX_DC_CFG, EFX_OWORD32(0x001FFFFF, 0x00000000, 0x00000000, 0x00000000) }, - { RX_DC_CFG_REG_KER, + { FR_AZ_RX_DC_CFG, EFX_OWORD32(0x0000000F, 0x00000000, 0x00000000, 0x00000000) }, - { RX_DC_PF_WM_REG_KER, + { FR_AZ_RX_DC_PF_WM, EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) }, - { DP_CTRL_REG, + { FR_BZ_DP_CTRL, EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) }, - { GM_CFG2_REG, + { FR_AB_GM_CFG2, EFX_OWORD32(0x00007337, 0x00000000, 0x00000000, 0x00000000) }, - { GMF_CFG0_REG, + { FR_AB_GMF_CFG0, EFX_OWORD32(0x00001F1F, 0x00000000, 0x00000000, 0x00000000) }, - { XM_GLB_CFG_REG, + { FR_AB_XM_GLB_CFG, EFX_OWORD32(0x00000C68, 0x00000000, 0x00000000, 0x00000000) }, - { XM_TX_CFG_REG, + { FR_AB_XM_TX_CFG, EFX_OWORD32(0x00080164, 0x00000000, 0x00000000, 0x00000000) }, - { XM_RX_CFG_REG, + { FR_AB_XM_RX_CFG, EFX_OWORD32(0x07100A0C, 0x00000000, 0x00000000, 0x00000000) }, - { XM_RX_PARAM_REG, + { FR_AB_XM_RX_PARAM, EFX_OWORD32(0x00001FF8, 0x00000000, 0x00000000, 0x00000000) }, - { XM_FC_REG, + { FR_AB_XM_FC, EFX_OWORD32(0xFFFF0001, 0x00000000, 0x00000000, 0x00000000) }, - { XM_ADR_LO_REG, + { FR_AB_XM_ADR_LO, EFX_OWORD32(0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000) }, - { XX_SD_CTL_REG, + { FR_AB_XX_SD_CTL, EFX_OWORD32(0x0003FF0F, 0x00000000, 0x00000000, 0x00000000) }, }; @@ -2538,22 +2554,24 @@ int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) } EFX_POPULATE_OWORD_2(glb_ctl_reg_ker, - EXT_PHY_RST_DUR, 0x7, - SWRST, 1); + FRF_AB_EXT_PHY_RST_DUR, + FFE_AB_EXT_PHY_RST_DUR_10240US, + FRF_AB_SWRST, 1); } else { - int reset_phy = (method == RESET_TYPE_INVISIBLE ? - EXCLUDE_FROM_RESET : 0); - EFX_POPULATE_OWORD_7(glb_ctl_reg_ker, - EXT_PHY_RST_CTL, reset_phy, - PCIE_CORE_RST_CTL, EXCLUDE_FROM_RESET, - PCIE_NSTCK_RST_CTL, EXCLUDE_FROM_RESET, - PCIE_SD_RST_CTL, EXCLUDE_FROM_RESET, - EE_RST_CTL, EXCLUDE_FROM_RESET, - EXT_PHY_RST_DUR, 0x7 /* 10ms */, - SWRST, 1); - } - falcon_write(efx, &glb_ctl_reg_ker, GLB_CTL_REG_KER); + /* exclude PHY from "invisible" reset */ + FRF_AB_EXT_PHY_RST_CTL, + method == RESET_TYPE_INVISIBLE, + /* exclude EEPROM/flash and PCIe */ + FRF_AB_PCIE_CORE_RST_CTL, 1, + FRF_AB_PCIE_NSTKY_RST_CTL, 1, + FRF_AB_PCIE_SD_RST_CTL, 1, + FRF_AB_EE_RST_CTL, 1, + FRF_AB_EXT_PHY_RST_DUR, + FFE_AB_EXT_PHY_RST_DUR_10240US, + FRF_AB_SWRST, 1); + } + falcon_write(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL); EFX_LOG(efx, "waiting for hardware reset\n"); schedule_timeout_uninterruptible(HZ / 20); @@ -2578,8 +2596,8 @@ int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) } /* Assert that reset complete */ - falcon_read(efx, &glb_ctl_reg_ker, GLB_CTL_REG_KER); - if (EFX_OWORD_FIELD(glb_ctl_reg_ker, SWRST) != 0) { + falcon_read(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL); + if (EFX_OWORD_FIELD(glb_ctl_reg_ker, FRF_AB_SWRST) != 0) { rc = -ETIMEDOUT; EFX_ERR(efx, "timed out waiting for hardware reset\n"); goto fail5; @@ -2607,16 +2625,16 @@ static int falcon_reset_sram(struct efx_nic *efx) int count; /* Set the SRAM wake/sleep GPIO appropriately. */ - falcon_read(efx, &gpio_cfg_reg_ker, GPIO_CTL_REG_KER); - EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, GPIO1_OEN, 1); - EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, GPIO1_OUT, 1); - falcon_write(efx, &gpio_cfg_reg_ker, GPIO_CTL_REG_KER); + falcon_read(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL); + EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, FRF_AB_GPIO1_OEN, 1); + EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, FRF_AB_GPIO1_OUT, 1); + falcon_write(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL); /* Initiate SRAM reset */ EFX_POPULATE_OWORD_2(srm_cfg_reg_ker, - SRAM_OOB_BT_INIT_EN, 1, - SRM_NUM_BANKS_AND_BANK_SIZE, 0); - falcon_write(efx, &srm_cfg_reg_ker, SRM_CFG_REG_KER); + FRF_AZ_SRM_INIT_EN, 1, + FRF_AZ_SRM_NB_SZ, 0); + falcon_write(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG); /* Wait for SRAM reset to complete */ count = 0; @@ -2627,8 +2645,8 @@ static int falcon_reset_sram(struct efx_nic *efx) schedule_timeout_uninterruptible(HZ / 50); /* Check for reset complete */ - falcon_read(efx, &srm_cfg_reg_ker, SRM_CFG_REG_KER); - if (!EFX_OWORD_FIELD(srm_cfg_reg_ker, SRAM_OOB_BT_INIT_EN)) { + falcon_read(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG); + if (!EFX_OWORD_FIELD(srm_cfg_reg_ker, FRF_AZ_SRM_INIT_EN)) { EFX_LOG(efx, "SRAM reset complete\n"); return 0; @@ -2713,16 +2731,16 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) board_rev = le16_to_cpu(v2->board_revision); if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) { - __le32 fl = v3->spi_device_type[EE_SPI_FLASH]; - __le32 ee = v3->spi_device_type[EE_SPI_EEPROM]; - rc = falcon_spi_device_init(efx, &efx->spi_flash, - EE_SPI_FLASH, - le32_to_cpu(fl)); + rc = falcon_spi_device_init( + efx, &efx->spi_flash, FFE_AB_SPI_DEVICE_FLASH, + le32_to_cpu(v3->spi_device_type + [FFE_AB_SPI_DEVICE_FLASH])); if (rc) goto fail2; - rc = falcon_spi_device_init(efx, &efx->spi_eeprom, - EE_SPI_EEPROM, - le32_to_cpu(ee)); + rc = falcon_spi_device_init( + efx, &efx->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM, + le32_to_cpu(v3->spi_device_type + [FFE_AB_SPI_DEVICE_EEPROM])); if (rc) goto fail2; } @@ -2753,13 +2771,13 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) efx_oword_t altera_build; efx_oword_t nic_stat; - falcon_read(efx, &altera_build, ALTERA_BUILD_REG_KER); - if (EFX_OWORD_FIELD(altera_build, VER_ALL)) { + falcon_read(efx, &altera_build, FR_AZ_ALTERA_BUILD); + if (EFX_OWORD_FIELD(altera_build, FRF_AZ_ALTERA_BUILD_VER)) { EFX_ERR(efx, "Falcon FPGA not supported\n"); return -ENODEV; } - falcon_read(efx, &nic_stat, NIC_STAT_REG); + falcon_read(efx, &nic_stat, FR_AB_NIC_STAT); switch (falcon_rev(efx)) { case FALCON_REV_A0: @@ -2768,7 +2786,7 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) return -ENODEV; case FALCON_REV_A1: - if (EFX_OWORD_FIELD(nic_stat, STRAP_PCIE) == 0) { + if (EFX_OWORD_FIELD(nic_stat, FRF_AA_STRAP_PCIE) == 0) { EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); return -ENODEV; } @@ -2783,7 +2801,7 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) } /* Initial assumed speed */ - efx->link_speed = EFX_OWORD_FIELD(nic_stat, STRAP_10G) ? 10000 : 1000; + efx->link_speed = EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) ? 10000 : 1000; return 0; } @@ -2794,34 +2812,36 @@ static void falcon_probe_spi_devices(struct efx_nic *efx) efx_oword_t nic_stat, gpio_ctl, ee_vpd_cfg; int boot_dev; - falcon_read(efx, &gpio_ctl, GPIO_CTL_REG_KER); - falcon_read(efx, &nic_stat, NIC_STAT_REG); - falcon_read(efx, &ee_vpd_cfg, EE_VPD_CFG_REG_KER); + falcon_read(efx, &gpio_ctl, FR_AB_GPIO_CTL); + falcon_read(efx, &nic_stat, FR_AB_NIC_STAT); + falcon_read(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0); - if (EFX_OWORD_FIELD(gpio_ctl, BOOTED_USING_NVDEVICE)) { - boot_dev = (EFX_OWORD_FIELD(nic_stat, SF_PRST) ? - EE_SPI_FLASH : EE_SPI_EEPROM); + if (EFX_OWORD_FIELD(gpio_ctl, FRF_AB_GPIO3_PWRUP_VALUE)) { + boot_dev = (EFX_OWORD_FIELD(nic_stat, FRF_AB_SF_PRST) ? + FFE_AB_SPI_DEVICE_FLASH : FFE_AB_SPI_DEVICE_EEPROM); EFX_LOG(efx, "Booted from %s\n", - boot_dev == EE_SPI_FLASH ? "flash" : "EEPROM"); + boot_dev == FFE_AB_SPI_DEVICE_FLASH ? "flash" : "EEPROM"); } else { /* Disable VPD and set clock dividers to safe * values for initial programming. */ boot_dev = -1; EFX_LOG(efx, "Booted from internal ASIC settings;" " setting SPI config\n"); - EFX_POPULATE_OWORD_3(ee_vpd_cfg, EE_VPD_EN, 0, + EFX_POPULATE_OWORD_3(ee_vpd_cfg, FRF_AB_EE_VPD_EN, 0, /* 125 MHz / 7 ~= 20 MHz */ - EE_SF_CLOCK_DIV, 7, + FRF_AB_EE_SF_CLOCK_DIV, 7, /* 125 MHz / 63 ~= 2 MHz */ - EE_EE_CLOCK_DIV, 63); - falcon_write(efx, &ee_vpd_cfg, EE_VPD_CFG_REG_KER); + FRF_AB_EE_EE_CLOCK_DIV, 63); + falcon_write(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0); } - if (boot_dev == EE_SPI_FLASH) - falcon_spi_device_init(efx, &efx->spi_flash, EE_SPI_FLASH, + if (boot_dev == FFE_AB_SPI_DEVICE_FLASH) + falcon_spi_device_init(efx, &efx->spi_flash, + FFE_AB_SPI_DEVICE_FLASH, default_flash_type); - if (boot_dev == EE_SPI_EEPROM) - falcon_spi_device_init(efx, &efx->spi_eeprom, EE_SPI_EEPROM, + if (boot_dev == FFE_AB_SPI_DEVICE_EEPROM) + falcon_spi_device_init(efx, &efx->spi_eeprom, + FFE_AB_SPI_DEVICE_EEPROM, large_eeprom_type); } @@ -2926,34 +2946,36 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) int data_xoff_thr = rx_xoff_thresh_bytes >> 8; efx_oword_t reg; - falcon_read(efx, ®, RX_CFG_REG_KER); + falcon_read(efx, ®, FR_AZ_RX_CFG); if (falcon_rev(efx) <= FALCON_REV_A1) { /* Data FIFO size is 5.5K */ if (data_xon_thr < 0) data_xon_thr = 512 >> 8; if (data_xoff_thr < 0) data_xoff_thr = 2048 >> 8; - EFX_SET_OWORD_FIELD(reg, RX_DESC_PUSH_EN_A1, 0); - EFX_SET_OWORD_FIELD(reg, RX_USR_BUF_SIZE_A1, huge_buf_size); - EFX_SET_OWORD_FIELD(reg, RX_XON_MAC_TH_A1, data_xon_thr); - EFX_SET_OWORD_FIELD(reg, RX_XOFF_MAC_TH_A1, data_xoff_thr); - EFX_SET_OWORD_FIELD(reg, RX_XON_TX_TH_A1, ctrl_xon_thr); - EFX_SET_OWORD_FIELD(reg, RX_XOFF_TX_TH_A1, ctrl_xoff_thr); + EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_DESC_PUSH_EN, 0); + EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_USR_BUF_SIZE, + huge_buf_size); + EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XON_MAC_TH, data_xon_thr); + EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XOFF_MAC_TH, data_xoff_thr); + EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XON_TX_TH, ctrl_xon_thr); + EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XOFF_TX_TH, ctrl_xoff_thr); } else { /* Data FIFO size is 80K; register fields moved */ if (data_xon_thr < 0) data_xon_thr = 27648 >> 8; /* ~3*max MTU */ if (data_xoff_thr < 0) data_xoff_thr = 54272 >> 8; /* ~80Kb - 3*max MTU */ - EFX_SET_OWORD_FIELD(reg, RX_DESC_PUSH_EN_B0, 0); - EFX_SET_OWORD_FIELD(reg, RX_USR_BUF_SIZE_B0, huge_buf_size); - EFX_SET_OWORD_FIELD(reg, RX_XON_MAC_TH_B0, data_xon_thr); - EFX_SET_OWORD_FIELD(reg, RX_XOFF_MAC_TH_B0, data_xoff_thr); - EFX_SET_OWORD_FIELD(reg, RX_XON_TX_TH_B0, ctrl_xon_thr); - EFX_SET_OWORD_FIELD(reg, RX_XOFF_TX_TH_B0, ctrl_xoff_thr); - EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 1); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_DESC_PUSH_EN, 0); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_USR_BUF_SIZE, + huge_buf_size); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XON_MAC_TH, data_xon_thr); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_MAC_TH, data_xoff_thr); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XON_TX_TH, ctrl_xon_thr); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_TX_TH, ctrl_xoff_thr); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1); } - falcon_write(efx, ®, RX_CFG_REG_KER); + falcon_write(efx, ®, FR_AZ_RX_CFG); } /* This call performs hardware-specific global initialisation, such as @@ -2966,15 +2988,15 @@ int falcon_init_nic(struct efx_nic *efx) int rc; /* Use on-chip SRAM */ - falcon_read(efx, &temp, NIC_STAT_REG); - EFX_SET_OWORD_FIELD(temp, ONCHIP_SRAM, 1); - falcon_write(efx, &temp, NIC_STAT_REG); + falcon_read(efx, &temp, FR_AB_NIC_STAT); + EFX_SET_OWORD_FIELD(temp, FRF_AB_ONCHIP_SRAM, 1); + falcon_write(efx, &temp, FR_AB_NIC_STAT); /* Set the source of the GMAC clock */ if (falcon_rev(efx) == FALCON_REV_B0) { - falcon_read(efx, &temp, GPIO_CTL_REG_KER); - EFX_SET_OWORD_FIELD(temp, GPIO_USE_NIC_CLK, true); - falcon_write(efx, &temp, GPIO_CTL_REG_KER); + falcon_read(efx, &temp, FR_AB_GPIO_CTL); + EFX_SET_OWORD_FIELD(temp, FRF_AB_USE_NIC_CLK, true); + falcon_write(efx, &temp, FR_AB_GPIO_CTL); } rc = falcon_reset_sram(efx); @@ -2982,32 +3004,32 @@ int falcon_init_nic(struct efx_nic *efx) return rc; /* Set positions of descriptor caches in SRAM. */ - EFX_POPULATE_OWORD_1(temp, SRM_TX_DC_BASE_ADR, TX_DC_BASE / 8); - falcon_write(efx, &temp, SRM_TX_DC_CFG_REG_KER); - EFX_POPULATE_OWORD_1(temp, SRM_RX_DC_BASE_ADR, RX_DC_BASE / 8); - falcon_write(efx, &temp, SRM_RX_DC_CFG_REG_KER); + EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_TX_DC_BASE_ADR, TX_DC_BASE / 8); + falcon_write(efx, &temp, FR_AZ_SRM_TX_DC_CFG); + EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_RX_DC_BASE_ADR, RX_DC_BASE / 8); + falcon_write(efx, &temp, FR_AZ_SRM_RX_DC_CFG); /* Set TX descriptor cache size. */ BUILD_BUG_ON(TX_DC_ENTRIES != (16 << TX_DC_ENTRIES_ORDER)); - EFX_POPULATE_OWORD_1(temp, TX_DC_SIZE, TX_DC_ENTRIES_ORDER); - falcon_write(efx, &temp, TX_DC_CFG_REG_KER); + EFX_POPULATE_OWORD_1(temp, FRF_AZ_TX_DC_SIZE, TX_DC_ENTRIES_ORDER); + falcon_write(efx, &temp, FR_AZ_TX_DC_CFG); /* Set RX descriptor cache size. Set low watermark to size-8, as * this allows most efficient prefetching. */ BUILD_BUG_ON(RX_DC_ENTRIES != (16 << RX_DC_ENTRIES_ORDER)); - EFX_POPULATE_OWORD_1(temp, RX_DC_SIZE, RX_DC_ENTRIES_ORDER); - falcon_write(efx, &temp, RX_DC_CFG_REG_KER); - EFX_POPULATE_OWORD_1(temp, RX_DC_PF_LWM, RX_DC_ENTRIES - 8); - falcon_write(efx, &temp, RX_DC_PF_WM_REG_KER); + EFX_POPULATE_OWORD_1(temp, FRF_AZ_RX_DC_SIZE, RX_DC_ENTRIES_ORDER); + falcon_write(efx, &temp, FR_AZ_RX_DC_CFG); + EFX_POPULATE_OWORD_1(temp, FRF_AZ_RX_DC_PF_LWM, RX_DC_ENTRIES - 8); + falcon_write(efx, &temp, FR_AZ_RX_DC_PF_WM); /* Clear the parity enables on the TX data fifos as * they produce false parity errors because of timing issues */ if (EFX_WORKAROUND_5129(efx)) { - falcon_read(efx, &temp, SPARE_REG_KER); - EFX_SET_OWORD_FIELD(temp, MEM_PERR_EN_TX_DATA, 0); - falcon_write(efx, &temp, SPARE_REG_KER); + falcon_read(efx, &temp, FR_AZ_CSR_SPARE); + EFX_SET_OWORD_FIELD(temp, FRF_AB_MEM_PERR_EN_TX_DATA, 0); + falcon_write(efx, &temp, FR_AZ_CSR_SPARE); } /* Enable all the genuinely fatal interrupts. (They are still @@ -3017,64 +3039,65 @@ int falcon_init_nic(struct efx_nic *efx) * Note: All other fatal interrupts are enabled */ EFX_POPULATE_OWORD_3(temp, - ILL_ADR_INT_KER_EN, 1, - RBUF_OWN_INT_KER_EN, 1, - TBUF_OWN_INT_KER_EN, 1); + FRF_AZ_ILL_ADR_INT_KER_EN, 1, + FRF_AZ_RBUF_OWN_INT_KER_EN, 1, + FRF_AZ_TBUF_OWN_INT_KER_EN, 1); EFX_INVERT_OWORD(temp); - falcon_write(efx, &temp, FATAL_INTR_REG_KER); + falcon_write(efx, &temp, FR_AZ_FATAL_INTR_KER); if (EFX_WORKAROUND_7244(efx)) { - falcon_read(efx, &temp, RX_FILTER_CTL_REG); - EFX_SET_OWORD_FIELD(temp, UDP_FULL_SRCH_LIMIT, 8); - EFX_SET_OWORD_FIELD(temp, UDP_WILD_SRCH_LIMIT, 8); - EFX_SET_OWORD_FIELD(temp, TCP_FULL_SRCH_LIMIT, 8); - EFX_SET_OWORD_FIELD(temp, TCP_WILD_SRCH_LIMIT, 8); - falcon_write(efx, &temp, RX_FILTER_CTL_REG); + falcon_read(efx, &temp, FR_BZ_RX_FILTER_CTL); + EFX_SET_OWORD_FIELD(temp, FRF_BZ_UDP_FULL_SRCH_LIMIT, 8); + EFX_SET_OWORD_FIELD(temp, FRF_BZ_UDP_WILD_SRCH_LIMIT, 8); + EFX_SET_OWORD_FIELD(temp, FRF_BZ_TCP_FULL_SRCH_LIMIT, 8); + EFX_SET_OWORD_FIELD(temp, FRF_BZ_TCP_WILD_SRCH_LIMIT, 8); + falcon_write(efx, &temp, FR_BZ_RX_FILTER_CTL); } falcon_setup_rss_indir_table(efx); + /* XXX This is documented only for Falcon A0/A1 */ /* Setup RX. Wait for descriptor is broken and must * be disabled. RXDP recovery shouldn't be needed, but is. */ - falcon_read(efx, &temp, RX_SELF_RST_REG_KER); - EFX_SET_OWORD_FIELD(temp, RX_NODESC_WAIT_DIS, 1); - EFX_SET_OWORD_FIELD(temp, RX_RECOVERY_EN, 1); + falcon_read(efx, &temp, FR_AA_RX_SELF_RST); + EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_NODESC_WAIT_DIS, 1); + EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_SELF_RST_EN, 1); if (EFX_WORKAROUND_5583(efx)) - EFX_SET_OWORD_FIELD(temp, RX_ISCSI_DIS, 1); - falcon_write(efx, &temp, RX_SELF_RST_REG_KER); + EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_ISCSI_DIS, 1); + falcon_write(efx, &temp, FR_AA_RX_SELF_RST); /* Disable the ugly timer-based TX DMA backoff and allow TX DMA to be * controlled by the RX FIFO fill level. Set arbitration to one pkt/Q. */ - falcon_read(efx, &temp, TX_CFG2_REG_KER); - EFX_SET_OWORD_FIELD(temp, TX_RX_SPACER, 0xfe); - EFX_SET_OWORD_FIELD(temp, TX_RX_SPACER_EN, 1); - EFX_SET_OWORD_FIELD(temp, TX_ONE_PKT_PER_Q, 1); - EFX_SET_OWORD_FIELD(temp, TX_CSR_PUSH_EN, 0); - EFX_SET_OWORD_FIELD(temp, TX_DIS_NON_IP_EV, 1); + falcon_read(efx, &temp, FR_AZ_TX_RESERVED); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER, 0xfe); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER_EN, 1); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_ONE_PKT_PER_Q, 1); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PUSH_EN, 0); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_DIS_NON_IP_EV, 1); /* Enable SW_EV to inherit in char driver - assume harmless here */ - EFX_SET_OWORD_FIELD(temp, TX_SW_EV_EN, 1); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1); /* Prefetch threshold 2 => fetch when descriptor cache half empty */ - EFX_SET_OWORD_FIELD(temp, TX_PREF_THRESHOLD, 2); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2); /* Squash TX of packets of 16 bytes or less */ if (falcon_rev(efx) >= FALCON_REV_B0 && EFX_WORKAROUND_9141(efx)) - EFX_SET_OWORD_FIELD(temp, TX_FLUSH_MIN_LEN_EN_B0, 1); - falcon_write(efx, &temp, TX_CFG2_REG_KER); + EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); + falcon_write(efx, &temp, FR_AZ_TX_RESERVED); /* Do not enable TX_NO_EOP_DISC_EN, since it limits packets to 16 * descriptors (which is bad). */ - falcon_read(efx, &temp, TX_CFG_REG_KER); - EFX_SET_OWORD_FIELD(temp, TX_NO_EOP_DISC_EN, 0); - falcon_write(efx, &temp, TX_CFG_REG_KER); + falcon_read(efx, &temp, FR_AZ_TX_CFG); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_NO_EOP_DISC_EN, 0); + falcon_write(efx, &temp, FR_AZ_TX_CFG); falcon_init_rx_cfg(efx); /* Set destination of both TX and RX Flush events */ if (falcon_rev(efx) >= FALCON_REV_B0) { - EFX_POPULATE_OWORD_1(temp, FLS_EVQ_ID, 0); - falcon_write(efx, &temp, DP_CTRL_REG); + EFX_POPULATE_OWORD_1(temp, FRF_BZ_FLS_EVQ_ID, 0); + falcon_write(efx, &temp, FR_BZ_DP_CTRL); } return 0; @@ -3110,8 +3133,9 @@ void falcon_update_nic_stats(struct efx_nic *efx) { efx_oword_t cnt; - falcon_read(efx, &cnt, RX_NODESC_DROP_REG_KER); - efx->n_rx_nodesc_drop_cnt += EFX_OWORD_FIELD(cnt, RX_NODESC_DROP_CNT); + falcon_read(efx, &cnt, FR_AZ_RX_NODESC_DROP); + efx->n_rx_nodesc_drop_cnt += + EFX_OWORD_FIELD(cnt, FRF_AB_RX_NODESC_DROP_CNT); } /************************************************************************** @@ -3124,11 +3148,11 @@ void falcon_update_nic_stats(struct efx_nic *efx) struct efx_nic_type falcon_a_nic_type = { .mem_bar = 2, .mem_map_size = 0x20000, - .txd_ptr_tbl_base = TX_DESC_PTR_TBL_KER_A1, - .rxd_ptr_tbl_base = RX_DESC_PTR_TBL_KER_A1, - .buf_tbl_base = BUF_TBL_KER_A1, - .evq_ptr_tbl_base = EVQ_PTR_TBL_KER_A1, - .evq_rptr_tbl_base = EVQ_RPTR_REG_KER_A1, + .txd_ptr_tbl_base = FR_AA_TX_DESC_PTR_TBL_KER, + .rxd_ptr_tbl_base = FR_AA_RX_DESC_PTR_TBL_KER, + .buf_tbl_base = FR_AA_BUF_FULL_TBL_KER, + .evq_ptr_tbl_base = FR_AA_EVQ_PTR_TBL_KER, + .evq_rptr_tbl_base = FR_AA_EVQ_RPTR_KER, .txd_ring_mask = FALCON_TXD_RING_MASK, .rxd_ring_mask = FALCON_RXD_RING_MASK, .evq_size = FALCON_EVQ_SIZE, @@ -3145,12 +3169,14 @@ struct efx_nic_type falcon_b_nic_type = { /* Map everything up to and including the RSS indirection * table. Don't map MSI-X table, MSI-X PBA since Linux * requires that they not be mapped. */ - .mem_map_size = RX_RSS_INDIR_TBL_B0 + 0x800, - .txd_ptr_tbl_base = TX_DESC_PTR_TBL_KER_B0, - .rxd_ptr_tbl_base = RX_DESC_PTR_TBL_KER_B0, - .buf_tbl_base = BUF_TBL_KER_B0, - .evq_ptr_tbl_base = EVQ_PTR_TBL_KER_B0, - .evq_rptr_tbl_base = EVQ_RPTR_REG_KER_B0, + .mem_map_size = (FR_BZ_RX_INDIRECTION_TBL + + FR_BZ_RX_INDIRECTION_TBL_STEP * + FR_BZ_RX_INDIRECTION_TBL_ROWS), + .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, + .rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL, + .buf_tbl_base = FR_BZ_BUF_FULL_TBL, + .evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL, + .evq_rptr_tbl_base = FR_BZ_EVQ_RPTR, .txd_ring_mask = FALCON_TXD_RING_MASK, .rxd_ring_mask = FALCON_RXD_RING_MASK, .evq_size = FALCON_EVQ_SIZE, -- cgit v1.2.2 From 12d00cadcc45382fc127712aa35bd0c96cbf81d9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:30:46 +0000 Subject: sfc: Rename register I/O header and functions used by both Falcon and Siena While we're at it, use type suffixes of 'd', 'q' and 'o', consistent with register type names. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 249 ++++++++++++++++++++++++----------------------- 1 file changed, 128 insertions(+), 121 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index b35e01031e23..759f55ae4b83 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -23,7 +23,7 @@ #include "spi.h" #include "falcon.h" #include "regs.h" -#include "falcon_io.h" +#include "io.h" #include "mdio_10g.h" #include "phy.h" #include "workarounds.h" @@ -163,6 +163,13 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); * **************************************************************************/ +static inline void falcon_write_buf_tbl(struct efx_nic *efx, efx_qword_t *value, + unsigned int index) +{ + efx_sram_writeq(efx, efx->membase + efx->type->buf_tbl_base, + value, index); +} + /* Read the current event from the event queue */ static inline efx_qword_t *falcon_event(struct efx_channel *channel, unsigned int index) @@ -199,9 +206,9 @@ static void falcon_setsda(void *data, int state) struct efx_nic *efx = (struct efx_nic *)data; efx_oword_t reg; - falcon_read(efx, ®, FR_AB_GPIO_CTL); + efx_reado(efx, ®, FR_AB_GPIO_CTL); EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO3_OEN, !state); - falcon_write(efx, ®, FR_AB_GPIO_CTL); + efx_writeo(efx, ®, FR_AB_GPIO_CTL); } static void falcon_setscl(void *data, int state) @@ -209,9 +216,9 @@ static void falcon_setscl(void *data, int state) struct efx_nic *efx = (struct efx_nic *)data; efx_oword_t reg; - falcon_read(efx, ®, FR_AB_GPIO_CTL); + efx_reado(efx, ®, FR_AB_GPIO_CTL); EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO0_OEN, !state); - falcon_write(efx, ®, FR_AB_GPIO_CTL); + efx_writeo(efx, ®, FR_AB_GPIO_CTL); } static int falcon_getsda(void *data) @@ -219,7 +226,7 @@ static int falcon_getsda(void *data) struct efx_nic *efx = (struct efx_nic *)data; efx_oword_t reg; - falcon_read(efx, ®, FR_AB_GPIO_CTL); + efx_reado(efx, ®, FR_AB_GPIO_CTL); return EFX_OWORD_FIELD(reg, FRF_AB_GPIO3_IN); } @@ -228,7 +235,7 @@ static int falcon_getscl(void *data) struct efx_nic *efx = (struct efx_nic *)data; efx_oword_t reg; - falcon_read(efx, ®, FR_AB_GPIO_CTL); + efx_reado(efx, ®, FR_AB_GPIO_CTL); return EFX_OWORD_FIELD(reg, FRF_AB_GPIO0_IN); } @@ -278,7 +285,7 @@ falcon_init_special_buffer(struct efx_nic *efx, FRF_AZ_BUF_ADR_REGION, 0, FRF_AZ_BUF_ADR_FBUF, dma_addr >> 12, FRF_AZ_BUF_OWNER_ID_FBUF, 0); - falcon_write_sram(efx, &buf_desc, index); + falcon_write_buf_tbl(efx, &buf_desc, index); } } @@ -302,7 +309,7 @@ falcon_fini_special_buffer(struct efx_nic *efx, FRF_AZ_BUF_CLR_CMD, 1, FRF_AZ_BUF_CLR_END_ID, end, FRF_AZ_BUF_CLR_START_ID, start); - falcon_write(efx, &buf_tbl_upd, FR_AZ_BUF_TBL_UPD); + efx_writeo(efx, &buf_tbl_upd, FR_AZ_BUF_TBL_UPD); } /* @@ -415,8 +422,8 @@ static inline void falcon_notify_tx_desc(struct efx_tx_queue *tx_queue) write_ptr = tx_queue->write_count & FALCON_TXD_RING_MASK; EFX_POPULATE_DWORD_1(reg, FRF_AZ_TX_DESC_WPTR_DWORD, write_ptr); - falcon_writel_page(tx_queue->efx, ®, - FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue); + efx_writed_page(tx_queue->efx, ®, + FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue); } @@ -491,8 +498,8 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) !csum); } - falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, - tx_queue->queue); + efx_writeo_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, + tx_queue->queue); if (falcon_rev(efx) < FALCON_REV_B0) { efx_oword_t reg; @@ -500,12 +507,12 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) /* Only 128 bits in this register */ BUILD_BUG_ON(EFX_TX_QUEUE_COUNT >= 128); - falcon_read(efx, ®, FR_AA_TX_CHKSM_CFG); + efx_reado(efx, ®, FR_AA_TX_CHKSM_CFG); if (tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM) clear_bit_le(tx_queue->queue, (void *)®); else set_bit_le(tx_queue->queue, (void *)®); - falcon_write(efx, ®, FR_AA_TX_CHKSM_CFG); + efx_writeo(efx, ®, FR_AA_TX_CHKSM_CFG); } } @@ -518,7 +525,7 @@ static void falcon_flush_tx_queue(struct efx_tx_queue *tx_queue) EFX_POPULATE_OWORD_2(tx_flush_descq, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1, FRF_AZ_TX_FLUSH_DESCQ, tx_queue->queue); - falcon_write(efx, &tx_flush_descq, FR_AZ_TX_FLUSH_DESCQ); + efx_writeo(efx, &tx_flush_descq, FR_AZ_TX_FLUSH_DESCQ); } void falcon_fini_tx(struct efx_tx_queue *tx_queue) @@ -531,8 +538,8 @@ void falcon_fini_tx(struct efx_tx_queue *tx_queue) /* Remove TX descriptor ring from card */ EFX_ZERO_OWORD(tx_desc_ptr); - falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, - tx_queue->queue); + efx_writeo_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, + tx_queue->queue); /* Unpin TX descriptor ring */ falcon_fini_special_buffer(efx, &tx_queue->txd); @@ -592,8 +599,8 @@ void falcon_notify_rx_desc(struct efx_rx_queue *rx_queue) wmb(); write_ptr = rx_queue->added_count & FALCON_RXD_RING_MASK; EFX_POPULATE_DWORD_1(reg, FRF_AZ_RX_DESC_WPTR_DWORD, write_ptr); - falcon_writel_page(rx_queue->efx, ®, - FR_AZ_RX_DESC_UPD_DWORD_P0, rx_queue->queue); + efx_writed_page(rx_queue->efx, ®, + FR_AZ_RX_DESC_UPD_DWORD_P0, rx_queue->queue); } int falcon_probe_rx(struct efx_rx_queue *rx_queue) @@ -634,8 +641,8 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue) /* For >=B0 this is scatter so disable */ FRF_AZ_RX_DESCQ_JUMBO, !is_b0, FRF_AZ_RX_DESCQ_EN, 1); - falcon_write_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, - rx_queue->queue); + efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, + rx_queue->queue); } static void falcon_flush_rx_queue(struct efx_rx_queue *rx_queue) @@ -647,7 +654,7 @@ static void falcon_flush_rx_queue(struct efx_rx_queue *rx_queue) EFX_POPULATE_OWORD_2(rx_flush_descq, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1, FRF_AZ_RX_FLUSH_DESCQ, rx_queue->queue); - falcon_write(efx, &rx_flush_descq, FR_AZ_RX_FLUSH_DESCQ); + efx_writeo(efx, &rx_flush_descq, FR_AZ_RX_FLUSH_DESCQ); } void falcon_fini_rx(struct efx_rx_queue *rx_queue) @@ -660,8 +667,8 @@ void falcon_fini_rx(struct efx_rx_queue *rx_queue) /* Remove RX descriptor ring from card */ EFX_ZERO_OWORD(rx_desc_ptr); - falcon_write_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, - rx_queue->queue); + efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, + rx_queue->queue); /* Unpin RX descriptor ring */ falcon_fini_special_buffer(efx, &rx_queue->rxd); @@ -695,7 +702,7 @@ void falcon_eventq_read_ack(struct efx_channel *channel) struct efx_nic *efx = channel->efx; EFX_POPULATE_DWORD_1(reg, FRF_AZ_EVQ_RPTR, channel->eventq_read_ptr); - falcon_writel_table(efx, ®, efx->type->evq_rptr_tbl_base, + efx_writed_table(efx, ®, efx->type->evq_rptr_tbl_base, channel->channel); } @@ -711,7 +718,7 @@ void falcon_generate_event(struct efx_channel *channel, efx_qword_t *event) drv_ev_reg.u32[2] = 0; drv_ev_reg.u32[3] = 0; EFX_SET_OWORD_FIELD(drv_ev_reg, FRF_AZ_DRV_EV_QID, channel->channel); - falcon_write(channel->efx, &drv_ev_reg, FR_AZ_DRV_EV); + efx_writeo(channel->efx, &drv_ev_reg, FR_AZ_DRV_EV); } /* Handle a transmit completion event @@ -1104,8 +1111,8 @@ void falcon_set_int_moderation(struct efx_channel *channel) FRF_AB_TC_TIMER_VAL, 0); } BUILD_BUG_ON(FR_AA_TIMER_COMMAND_KER != FR_BZ_TIMER_COMMAND_P0); - falcon_writel_page_locked(efx, &timer_cmd, FR_BZ_TIMER_COMMAND_P0, - channel->channel); + efx_writed_page_locked(efx, &timer_cmd, FR_BZ_TIMER_COMMAND_P0, + channel->channel); } @@ -1139,8 +1146,8 @@ void falcon_init_eventq(struct efx_channel *channel) FRF_AZ_EVQ_EN, 1, FRF_AZ_EVQ_SIZE, FALCON_EVQ_ORDER, FRF_AZ_EVQ_BUF_BASE_ID, channel->eventq.index); - falcon_write_table(efx, &evq_ptr, efx->type->evq_ptr_tbl_base, - channel->channel); + efx_writeo_table(efx, &evq_ptr, efx->type->evq_ptr_tbl_base, + channel->channel); falcon_set_int_moderation(channel); } @@ -1152,8 +1159,8 @@ void falcon_fini_eventq(struct efx_channel *channel) /* Remove event queue from card */ EFX_ZERO_OWORD(eventq_ptr); - falcon_write_table(efx, &eventq_ptr, efx->type->evq_ptr_tbl_base, - channel->channel); + efx_writeo_table(efx, &eventq_ptr, efx->type->evq_ptr_tbl_base, + channel->channel); /* Unpin event queue */ falcon_fini_special_buffer(efx, &channel->eventq); @@ -1325,7 +1332,7 @@ static inline void falcon_interrupts(struct efx_nic *efx, int enabled, EFX_POPULATE_OWORD_2(int_en_reg_ker, FRF_AZ_KER_INT_KER, force, FRF_AZ_DRV_INT_EN_KER, enabled); - falcon_write(efx, &int_en_reg_ker, FR_AZ_INT_EN_KER); + efx_writeo(efx, &int_en_reg_ker, FR_AZ_INT_EN_KER); } void falcon_enable_interrupts(struct efx_nic *efx) @@ -1341,7 +1348,7 @@ void falcon_enable_interrupts(struct efx_nic *efx) FRF_AZ_NORM_INT_VEC_DIS_KER, EFX_INT_MODE_USE_MSI(efx), FRF_AZ_INT_ADR_KER, efx->irq_status.dma_addr); - falcon_write(efx, &int_adr_reg_ker, FR_AZ_INT_ADR_KER); + efx_writeo(efx, &int_adr_reg_ker, FR_AZ_INT_ADR_KER); /* Enable interrupts */ falcon_interrupts(efx, 1, 0); @@ -1382,8 +1389,8 @@ static inline void falcon_irq_ack_a1(struct efx_nic *efx) efx_dword_t reg; EFX_POPULATE_DWORD_1(reg, FRF_AA_INT_ACK_KER_FIELD, 0xb7eb7e); - falcon_writel(efx, ®, FR_AA_INT_ACK_KER); - falcon_readl(efx, ®, FR_AA_WORK_AROUND_BROKEN_PCI_READS); + efx_writed(efx, ®, FR_AA_INT_ACK_KER); + efx_readd(efx, ®, FR_AA_WORK_AROUND_BROKEN_PCI_READS); } /* Process a fatal interrupt @@ -1396,7 +1403,7 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) efx_oword_t fatal_intr; int error, mem_perr; - falcon_read(efx, &fatal_intr, FR_AZ_FATAL_INTR_KER); + efx_reado(efx, &fatal_intr, FR_AZ_FATAL_INTR_KER); error = EFX_OWORD_FIELD(fatal_intr, FRF_AZ_FATAL_INTR); EFX_ERR(efx, "SYSTEM ERROR " EFX_OWORD_FMT " status " @@ -1410,7 +1417,7 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) mem_perr = EFX_OWORD_FIELD(fatal_intr, FRF_AZ_MEM_PERR_INT_KER); if (mem_perr) { efx_oword_t reg; - falcon_read(efx, ®, FR_AZ_MEM_STAT); + efx_reado(efx, ®, FR_AZ_MEM_STAT); EFX_ERR(efx, "SYSTEM ERROR: memory parity error " EFX_OWORD_FMT "\n", EFX_OWORD_VAL(reg)); } @@ -1454,7 +1461,7 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) int syserr; /* Read the ISR which also ACKs the interrupts */ - falcon_readl(efx, ®, FR_BZ_INT_ISR0); + efx_readd(efx, ®, FR_BZ_INT_ISR0); queues = EFX_EXTRACT_DWORD(reg, 0, 31); /* Check to see if we have a serious error condition */ @@ -1576,7 +1583,7 @@ static void falcon_setup_rss_indir_table(struct efx_nic *efx) offset += 0x10) { EFX_POPULATE_DWORD_1(dword, FRF_BZ_IT_QUEUE, i % efx->n_rx_queues); - falcon_writel(efx, &dword, offset); + efx_writed(efx, &dword, offset); i++; } } @@ -1639,7 +1646,7 @@ void falcon_fini_interrupt(struct efx_nic *efx) /* ACK legacy interrupt */ if (falcon_rev(efx) >= FALCON_REV_B0) - falcon_read(efx, ®, FR_BZ_INT_ISR0); + efx_reado(efx, ®, FR_BZ_INT_ISR0); else falcon_irq_ack_a1(efx); @@ -1660,7 +1667,7 @@ void falcon_fini_interrupt(struct efx_nic *efx) static int falcon_spi_poll(struct efx_nic *efx) { efx_oword_t reg; - falcon_read(efx, ®, FR_AB_EE_SPI_HCMD); + efx_reado(efx, ®, FR_AB_EE_SPI_HCMD); return EFX_OWORD_FIELD(reg, FRF_AB_EE_SPI_HCMD_CMD_EN) ? -EBUSY : 0; } @@ -1714,13 +1721,13 @@ int falcon_spi_cmd(const struct efx_spi_device *spi, /* Program address register, if we have an address */ if (addressed) { EFX_POPULATE_OWORD_1(reg, FRF_AB_EE_SPI_HADR_ADR, address); - falcon_write(efx, ®, FR_AB_EE_SPI_HADR); + efx_writeo(efx, ®, FR_AB_EE_SPI_HADR); } /* Program data register, if we have data */ if (in != NULL) { memcpy(®, in, len); - falcon_write(efx, ®, FR_AB_EE_SPI_HDATA); + efx_writeo(efx, ®, FR_AB_EE_SPI_HDATA); } /* Issue read/write command */ @@ -1733,7 +1740,7 @@ int falcon_spi_cmd(const struct efx_spi_device *spi, FRF_AB_EE_SPI_HCMD_ADBCNT, (addressed ? spi->addr_len : 0), FRF_AB_EE_SPI_HCMD_ENC, command); - falcon_write(efx, ®, FR_AB_EE_SPI_HCMD); + efx_writeo(efx, ®, FR_AB_EE_SPI_HCMD); /* Wait for read/write to complete */ rc = falcon_spi_wait(efx); @@ -1742,7 +1749,7 @@ int falcon_spi_cmd(const struct efx_spi_device *spi, /* Read data */ if (out != NULL) { - falcon_read(efx, ®, FR_AB_EE_SPI_HDATA); + efx_reado(efx, ®, FR_AB_EE_SPI_HDATA); memcpy(out, ®, len); } @@ -1884,19 +1891,19 @@ static int falcon_reset_macs(struct efx_nic *efx) */ if (!EFX_IS10G(efx)) { EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 1); - falcon_write(efx, ®, FR_AB_GM_CFG1); + efx_writeo(efx, ®, FR_AB_GM_CFG1); udelay(1000); EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 0); - falcon_write(efx, ®, FR_AB_GM_CFG1); + efx_writeo(efx, ®, FR_AB_GM_CFG1); udelay(1000); return 0; } else { EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1); - falcon_write(efx, ®, FR_AB_XM_GLB_CFG); + efx_writeo(efx, ®, FR_AB_XM_GLB_CFG); for (count = 0; count < 10000; count++) { - falcon_read(efx, ®, FR_AB_XM_GLB_CFG); + efx_reado(efx, ®, FR_AB_XM_GLB_CFG); if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) == 0) return 0; @@ -1912,19 +1919,19 @@ static int falcon_reset_macs(struct efx_nic *efx) * the drain sequence with the statistics fetch */ efx_stats_disable(efx); - falcon_read(efx, ®, FR_AB_MAC_CTRL); + efx_reado(efx, ®, FR_AB_MAC_CTRL); EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, 1); - falcon_write(efx, ®, FR_AB_MAC_CTRL); + efx_writeo(efx, ®, FR_AB_MAC_CTRL); - falcon_read(efx, ®, FR_AB_GLB_CTL); + efx_reado(efx, ®, FR_AB_GLB_CTL); EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGTX, 1); EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGRX, 1); EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_EM, 1); - falcon_write(efx, ®, FR_AB_GLB_CTL); + efx_writeo(efx, ®, FR_AB_GLB_CTL); count = 0; while (1) { - falcon_read(efx, ®, FR_AB_GLB_CTL); + efx_reado(efx, ®, FR_AB_GLB_CTL); if (!EFX_OWORD_FIELD(reg, FRF_AB_RST_XGTX) && !EFX_OWORD_FIELD(reg, FRF_AB_RST_XGRX) && !EFX_OWORD_FIELD(reg, FRF_AB_RST_EM)) { @@ -1958,7 +1965,7 @@ void falcon_drain_tx_fifo(struct efx_nic *efx) (efx->loopback_mode != LOOPBACK_NONE)) return; - falcon_read(efx, ®, FR_AB_MAC_CTRL); + efx_reado(efx, ®, FR_AB_MAC_CTRL); /* There is no point in draining more than once */ if (EFX_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN)) return; @@ -1974,9 +1981,9 @@ void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) return; /* Isolate the MAC -> RX */ - falcon_read(efx, ®, FR_AZ_RX_CFG); + efx_reado(efx, ®, FR_AZ_RX_CFG); EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 0); - falcon_write(efx, ®, FR_AZ_RX_CFG); + efx_writeo(efx, ®, FR_AZ_RX_CFG); if (!efx->link_up) falcon_drain_tx_fifo(efx); @@ -2011,7 +2018,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) !efx->link_up); } - falcon_write(efx, ®, FR_AB_MAC_CTRL); + efx_writeo(efx, ®, FR_AB_MAC_CTRL); /* Restore the multicast hash registers. */ falcon_set_multicast_hash(efx); @@ -2020,13 +2027,13 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL. * Action on receipt of pause frames is controller by XM_DIS_FCNTL */ tx_fc = !!(efx->link_fc & EFX_FC_TX); - falcon_read(efx, ®, FR_AZ_RX_CFG); + efx_reado(efx, ®, FR_AZ_RX_CFG); EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, tx_fc); /* Unisolate the MAC -> RX */ if (falcon_rev(efx) >= FALCON_REV_B0) EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1); - falcon_write(efx, ®, FR_AZ_RX_CFG); + efx_writeo(efx, ®, FR_AZ_RX_CFG); } int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) @@ -2041,7 +2048,7 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) /* Statistics fetch will fail if the MAC is in TX drain */ if (falcon_rev(efx) >= FALCON_REV_B0) { efx_oword_t temp; - falcon_read(efx, &temp, FR_AB_MAC_CTRL); + efx_reado(efx, &temp, FR_AB_MAC_CTRL); if (EFX_OWORD_FIELD(temp, FRF_BB_TXFIFO_DRAIN_EN)) return 0; } @@ -2055,7 +2062,7 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) FRF_AB_MAC_STAT_DMA_CMD, 1, FRF_AB_MAC_STAT_DMA_ADR, efx->stats_buffer.dma_addr); - falcon_write(efx, ®, FR_AB_MAC_STAT_DMA); + efx_writeo(efx, ®, FR_AB_MAC_STAT_DMA); /* Wait for transfer to complete */ for (i = 0; i < 400; i++) { @@ -2085,7 +2092,7 @@ static int falcon_gmii_wait(struct efx_nic *efx) /* wait upto 50ms - taken max from datasheet */ for (count = 0; count < 5000; count++) { - falcon_readl(efx, &md_stat, FR_AB_MD_STAT); + efx_readd(efx, &md_stat, FR_AB_MD_STAT); if (EFX_DWORD_FIELD(md_stat, FRF_AB_MD_BSY) == 0) { if (EFX_DWORD_FIELD(md_stat, FRF_AB_MD_LNFL) != 0 || EFX_DWORD_FIELD(md_stat, FRF_AB_MD_BSERR) != 0) { @@ -2122,20 +2129,20 @@ static int falcon_mdio_write(struct net_device *net_dev, /* Write the address/ID register */ EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_PHY_ADR, addr); - falcon_write(efx, ®, FR_AB_MD_PHY_ADR); + efx_writeo(efx, ®, FR_AB_MD_PHY_ADR); EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_PRT_ADR, prtad, FRF_AB_MD_DEV_ADR, devad); - falcon_write(efx, ®, FR_AB_MD_ID); + efx_writeo(efx, ®, FR_AB_MD_ID); /* Write data */ EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_TXD, value); - falcon_write(efx, ®, FR_AB_MD_TXD); + efx_writeo(efx, ®, FR_AB_MD_TXD); EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_WRC, 1, FRF_AB_MD_GC, 0); - falcon_write(efx, ®, FR_AB_MD_CS); + efx_writeo(efx, ®, FR_AB_MD_CS); /* Wait for data to be written */ rc = falcon_gmii_wait(efx); @@ -2144,7 +2151,7 @@ static int falcon_mdio_write(struct net_device *net_dev, EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_WRC, 0, FRF_AB_MD_GC, 1); - falcon_write(efx, ®, FR_AB_MD_CS); + efx_writeo(efx, ®, FR_AB_MD_CS); udelay(10); } @@ -2169,20 +2176,20 @@ static int falcon_mdio_read(struct net_device *net_dev, goto out; EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_PHY_ADR, addr); - falcon_write(efx, ®, FR_AB_MD_PHY_ADR); + efx_writeo(efx, ®, FR_AB_MD_PHY_ADR); EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_PRT_ADR, prtad, FRF_AB_MD_DEV_ADR, devad); - falcon_write(efx, ®, FR_AB_MD_ID); + efx_writeo(efx, ®, FR_AB_MD_ID); /* Request data to be read */ EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_RDC, 1, FRF_AB_MD_GC, 0); - falcon_write(efx, ®, FR_AB_MD_CS); + efx_writeo(efx, ®, FR_AB_MD_CS); /* Wait for data to become available */ rc = falcon_gmii_wait(efx); if (rc == 0) { - falcon_read(efx, ®, FR_AB_MD_RXD); + efx_reado(efx, ®, FR_AB_MD_RXD); rc = EFX_OWORD_FIELD(reg, FRF_AB_MD_RXD); EFX_REGDUMP(efx, "read from MDIO %d register %d.%d, got %04x\n", prtad, devad, addr, rc); @@ -2191,7 +2198,7 @@ static int falcon_mdio_read(struct net_device *net_dev, EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_RIC, 0, FRF_AB_MD_GC, 1); - falcon_write(efx, ®, FR_AB_MD_CS); + efx_writeo(efx, ®, FR_AB_MD_CS); EFX_LOG(efx, "read from MDIO %d register %d.%d, got error %d\n", prtad, devad, addr, rc); @@ -2258,12 +2265,12 @@ int falcon_switch_mac(struct efx_nic *efx) /* Always push the NIC_STAT_REG setting even if the mac hasn't * changed, because this function is run post online reset */ - falcon_read(efx, &nic_stat, FR_AB_NIC_STAT); + efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); strap_val = EFX_IS10G(efx) ? 5 : 3; if (falcon_rev(efx) >= FALCON_REV_B0) { EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP_EN, 1); EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP, strap_val); - falcon_write(efx, &nic_stat, FR_AB_NIC_STAT); + efx_writeo(efx, &nic_stat, FR_AB_NIC_STAT); } else { /* Falcon A1 does not support 1G/10G speed switching * and must not be used with a PHY that does. */ @@ -2341,8 +2348,8 @@ void falcon_set_multicast_hash(struct efx_nic *efx) */ set_bit_le(0xff, mc_hash->byte); - falcon_write(efx, &mc_hash->oword[0], FR_AB_MAC_MC_HASH_REG0); - falcon_write(efx, &mc_hash->oword[1], FR_AB_MAC_MC_HASH_REG1); + efx_writeo(efx, &mc_hash->oword[0], FR_AB_MAC_MC_HASH_REG0); + efx_writeo(efx, &mc_hash->oword[1], FR_AB_MAC_MC_HASH_REG1); } @@ -2478,7 +2485,7 @@ int falcon_test_registers(struct efx_nic *efx) mask = imask = efx_test_registers[i].mask; EFX_INVERT_OWORD(imask); - falcon_read(efx, &original, address); + efx_reado(efx, &original, address); /* bit sweep on and off */ for (j = 0; j < 128; j++) { @@ -2489,8 +2496,8 @@ int falcon_test_registers(struct efx_nic *efx) EFX_AND_OWORD(reg, original, mask); EFX_SET_OWORD32(reg, j, j, 1); - falcon_write(efx, ®, address); - falcon_read(efx, &buf, address); + efx_writeo(efx, ®, address); + efx_reado(efx, &buf, address); if (efx_masked_compare_oword(®, &buf, &mask)) goto fail; @@ -2499,14 +2506,14 @@ int falcon_test_registers(struct efx_nic *efx) EFX_OR_OWORD(reg, original, mask); EFX_SET_OWORD32(reg, j, j, 0); - falcon_write(efx, ®, address); - falcon_read(efx, &buf, address); + efx_writeo(efx, ®, address); + efx_reado(efx, &buf, address); if (efx_masked_compare_oword(®, &buf, &mask)) goto fail; } - falcon_write(efx, &original, address); + efx_writeo(efx, &original, address); } return 0; @@ -2571,7 +2578,7 @@ int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) FFE_AB_EXT_PHY_RST_DUR_10240US, FRF_AB_SWRST, 1); } - falcon_write(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL); + efx_writeo(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL); EFX_LOG(efx, "waiting for hardware reset\n"); schedule_timeout_uninterruptible(HZ / 20); @@ -2596,7 +2603,7 @@ int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) } /* Assert that reset complete */ - falcon_read(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL); + efx_reado(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL); if (EFX_OWORD_FIELD(glb_ctl_reg_ker, FRF_AB_SWRST) != 0) { rc = -ETIMEDOUT; EFX_ERR(efx, "timed out waiting for hardware reset\n"); @@ -2625,16 +2632,16 @@ static int falcon_reset_sram(struct efx_nic *efx) int count; /* Set the SRAM wake/sleep GPIO appropriately. */ - falcon_read(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL); + efx_reado(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL); EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, FRF_AB_GPIO1_OEN, 1); EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, FRF_AB_GPIO1_OUT, 1); - falcon_write(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL); + efx_writeo(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL); /* Initiate SRAM reset */ EFX_POPULATE_OWORD_2(srm_cfg_reg_ker, FRF_AZ_SRM_INIT_EN, 1, FRF_AZ_SRM_NB_SZ, 0); - falcon_write(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG); + efx_writeo(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG); /* Wait for SRAM reset to complete */ count = 0; @@ -2645,7 +2652,7 @@ static int falcon_reset_sram(struct efx_nic *efx) schedule_timeout_uninterruptible(HZ / 50); /* Check for reset complete */ - falcon_read(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG); + efx_reado(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG); if (!EFX_OWORD_FIELD(srm_cfg_reg_ker, FRF_AZ_SRM_INIT_EN)) { EFX_LOG(efx, "SRAM reset complete\n"); @@ -2771,13 +2778,13 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) efx_oword_t altera_build; efx_oword_t nic_stat; - falcon_read(efx, &altera_build, FR_AZ_ALTERA_BUILD); + efx_reado(efx, &altera_build, FR_AZ_ALTERA_BUILD); if (EFX_OWORD_FIELD(altera_build, FRF_AZ_ALTERA_BUILD_VER)) { EFX_ERR(efx, "Falcon FPGA not supported\n"); return -ENODEV; } - falcon_read(efx, &nic_stat, FR_AB_NIC_STAT); + efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); switch (falcon_rev(efx)) { case FALCON_REV_A0: @@ -2812,9 +2819,9 @@ static void falcon_probe_spi_devices(struct efx_nic *efx) efx_oword_t nic_stat, gpio_ctl, ee_vpd_cfg; int boot_dev; - falcon_read(efx, &gpio_ctl, FR_AB_GPIO_CTL); - falcon_read(efx, &nic_stat, FR_AB_NIC_STAT); - falcon_read(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0); + efx_reado(efx, &gpio_ctl, FR_AB_GPIO_CTL); + efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); + efx_reado(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0); if (EFX_OWORD_FIELD(gpio_ctl, FRF_AB_GPIO3_PWRUP_VALUE)) { boot_dev = (EFX_OWORD_FIELD(nic_stat, FRF_AB_SF_PRST) ? @@ -2832,7 +2839,7 @@ static void falcon_probe_spi_devices(struct efx_nic *efx) FRF_AB_EE_SF_CLOCK_DIV, 7, /* 125 MHz / 63 ~= 2 MHz */ FRF_AB_EE_EE_CLOCK_DIV, 63); - falcon_write(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0); + efx_writeo(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0); } if (boot_dev == FFE_AB_SPI_DEVICE_FLASH) @@ -2946,7 +2953,7 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) int data_xoff_thr = rx_xoff_thresh_bytes >> 8; efx_oword_t reg; - falcon_read(efx, ®, FR_AZ_RX_CFG); + efx_reado(efx, ®, FR_AZ_RX_CFG); if (falcon_rev(efx) <= FALCON_REV_A1) { /* Data FIFO size is 5.5K */ if (data_xon_thr < 0) @@ -2975,7 +2982,7 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_TX_TH, ctrl_xoff_thr); EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1); } - falcon_write(efx, ®, FR_AZ_RX_CFG); + efx_writeo(efx, ®, FR_AZ_RX_CFG); } /* This call performs hardware-specific global initialisation, such as @@ -2988,15 +2995,15 @@ int falcon_init_nic(struct efx_nic *efx) int rc; /* Use on-chip SRAM */ - falcon_read(efx, &temp, FR_AB_NIC_STAT); + efx_reado(efx, &temp, FR_AB_NIC_STAT); EFX_SET_OWORD_FIELD(temp, FRF_AB_ONCHIP_SRAM, 1); - falcon_write(efx, &temp, FR_AB_NIC_STAT); + efx_writeo(efx, &temp, FR_AB_NIC_STAT); /* Set the source of the GMAC clock */ if (falcon_rev(efx) == FALCON_REV_B0) { - falcon_read(efx, &temp, FR_AB_GPIO_CTL); + efx_reado(efx, &temp, FR_AB_GPIO_CTL); EFX_SET_OWORD_FIELD(temp, FRF_AB_USE_NIC_CLK, true); - falcon_write(efx, &temp, FR_AB_GPIO_CTL); + efx_writeo(efx, &temp, FR_AB_GPIO_CTL); } rc = falcon_reset_sram(efx); @@ -3005,31 +3012,31 @@ int falcon_init_nic(struct efx_nic *efx) /* Set positions of descriptor caches in SRAM. */ EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_TX_DC_BASE_ADR, TX_DC_BASE / 8); - falcon_write(efx, &temp, FR_AZ_SRM_TX_DC_CFG); + efx_writeo(efx, &temp, FR_AZ_SRM_TX_DC_CFG); EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_RX_DC_BASE_ADR, RX_DC_BASE / 8); - falcon_write(efx, &temp, FR_AZ_SRM_RX_DC_CFG); + efx_writeo(efx, &temp, FR_AZ_SRM_RX_DC_CFG); /* Set TX descriptor cache size. */ BUILD_BUG_ON(TX_DC_ENTRIES != (16 << TX_DC_ENTRIES_ORDER)); EFX_POPULATE_OWORD_1(temp, FRF_AZ_TX_DC_SIZE, TX_DC_ENTRIES_ORDER); - falcon_write(efx, &temp, FR_AZ_TX_DC_CFG); + efx_writeo(efx, &temp, FR_AZ_TX_DC_CFG); /* Set RX descriptor cache size. Set low watermark to size-8, as * this allows most efficient prefetching. */ BUILD_BUG_ON(RX_DC_ENTRIES != (16 << RX_DC_ENTRIES_ORDER)); EFX_POPULATE_OWORD_1(temp, FRF_AZ_RX_DC_SIZE, RX_DC_ENTRIES_ORDER); - falcon_write(efx, &temp, FR_AZ_RX_DC_CFG); + efx_writeo(efx, &temp, FR_AZ_RX_DC_CFG); EFX_POPULATE_OWORD_1(temp, FRF_AZ_RX_DC_PF_LWM, RX_DC_ENTRIES - 8); - falcon_write(efx, &temp, FR_AZ_RX_DC_PF_WM); + efx_writeo(efx, &temp, FR_AZ_RX_DC_PF_WM); /* Clear the parity enables on the TX data fifos as * they produce false parity errors because of timing issues */ if (EFX_WORKAROUND_5129(efx)) { - falcon_read(efx, &temp, FR_AZ_CSR_SPARE); + efx_reado(efx, &temp, FR_AZ_CSR_SPARE); EFX_SET_OWORD_FIELD(temp, FRF_AB_MEM_PERR_EN_TX_DATA, 0); - falcon_write(efx, &temp, FR_AZ_CSR_SPARE); + efx_writeo(efx, &temp, FR_AZ_CSR_SPARE); } /* Enable all the genuinely fatal interrupts. (They are still @@ -3043,15 +3050,15 @@ int falcon_init_nic(struct efx_nic *efx) FRF_AZ_RBUF_OWN_INT_KER_EN, 1, FRF_AZ_TBUF_OWN_INT_KER_EN, 1); EFX_INVERT_OWORD(temp); - falcon_write(efx, &temp, FR_AZ_FATAL_INTR_KER); + efx_writeo(efx, &temp, FR_AZ_FATAL_INTR_KER); if (EFX_WORKAROUND_7244(efx)) { - falcon_read(efx, &temp, FR_BZ_RX_FILTER_CTL); + efx_reado(efx, &temp, FR_BZ_RX_FILTER_CTL); EFX_SET_OWORD_FIELD(temp, FRF_BZ_UDP_FULL_SRCH_LIMIT, 8); EFX_SET_OWORD_FIELD(temp, FRF_BZ_UDP_WILD_SRCH_LIMIT, 8); EFX_SET_OWORD_FIELD(temp, FRF_BZ_TCP_FULL_SRCH_LIMIT, 8); EFX_SET_OWORD_FIELD(temp, FRF_BZ_TCP_WILD_SRCH_LIMIT, 8); - falcon_write(efx, &temp, FR_BZ_RX_FILTER_CTL); + efx_writeo(efx, &temp, FR_BZ_RX_FILTER_CTL); } falcon_setup_rss_indir_table(efx); @@ -3060,17 +3067,17 @@ int falcon_init_nic(struct efx_nic *efx) /* Setup RX. Wait for descriptor is broken and must * be disabled. RXDP recovery shouldn't be needed, but is. */ - falcon_read(efx, &temp, FR_AA_RX_SELF_RST); + efx_reado(efx, &temp, FR_AA_RX_SELF_RST); EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_NODESC_WAIT_DIS, 1); EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_SELF_RST_EN, 1); if (EFX_WORKAROUND_5583(efx)) EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_ISCSI_DIS, 1); - falcon_write(efx, &temp, FR_AA_RX_SELF_RST); + efx_writeo(efx, &temp, FR_AA_RX_SELF_RST); /* Disable the ugly timer-based TX DMA backoff and allow TX DMA to be * controlled by the RX FIFO fill level. Set arbitration to one pkt/Q. */ - falcon_read(efx, &temp, FR_AZ_TX_RESERVED); + efx_reado(efx, &temp, FR_AZ_TX_RESERVED); EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER, 0xfe); EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER_EN, 1); EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_ONE_PKT_PER_Q, 1); @@ -3083,21 +3090,21 @@ int falcon_init_nic(struct efx_nic *efx) /* Squash TX of packets of 16 bytes or less */ if (falcon_rev(efx) >= FALCON_REV_B0 && EFX_WORKAROUND_9141(efx)) EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); - falcon_write(efx, &temp, FR_AZ_TX_RESERVED); + efx_writeo(efx, &temp, FR_AZ_TX_RESERVED); /* Do not enable TX_NO_EOP_DISC_EN, since it limits packets to 16 * descriptors (which is bad). */ - falcon_read(efx, &temp, FR_AZ_TX_CFG); + efx_reado(efx, &temp, FR_AZ_TX_CFG); EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_NO_EOP_DISC_EN, 0); - falcon_write(efx, &temp, FR_AZ_TX_CFG); + efx_writeo(efx, &temp, FR_AZ_TX_CFG); falcon_init_rx_cfg(efx); /* Set destination of both TX and RX Flush events */ if (falcon_rev(efx) >= FALCON_REV_B0) { EFX_POPULATE_OWORD_1(temp, FRF_BZ_FLS_EVQ_ID, 0); - falcon_write(efx, &temp, FR_BZ_DP_CTRL); + efx_writeo(efx, &temp, FR_BZ_DP_CTRL); } return 0; @@ -3133,7 +3140,7 @@ void falcon_update_nic_stats(struct efx_nic *efx) { efx_oword_t cnt; - falcon_read(efx, &cnt, FR_AZ_RX_NODESC_DROP); + efx_reado(efx, &cnt, FR_AZ_RX_NODESC_DROP); efx->n_rx_nodesc_drop_cnt += EFX_OWORD_FIELD(cnt, FRF_AB_RX_NODESC_DROP_CNT); } -- cgit v1.2.2 From 3ffeabdd2bc62e0ebcb1a51a5d959a86a7a915fc Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:30:58 +0000 Subject: sfc: Eliminate indirect lookups of queue size constants Move size and mask definitions into efx.h; calculate page orders in falcon.c. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 70 ++++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 44 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 759f55ae4b83..3cb7e613ab30 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -108,21 +108,6 @@ static int rx_xon_thresh_bytes = -1; module_param(rx_xon_thresh_bytes, int, 0644); MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); -/* TX descriptor ring size - min 512 max 4k */ -#define FALCON_TXD_RING_ORDER FFE_AZ_TX_DESCQ_SIZE_1K -#define FALCON_TXD_RING_SIZE 1024 -#define FALCON_TXD_RING_MASK (FALCON_TXD_RING_SIZE - 1) - -/* RX descriptor ring size - min 512 max 4k */ -#define FALCON_RXD_RING_ORDER FFE_AZ_RX_DESCQ_SIZE_1K -#define FALCON_RXD_RING_SIZE 1024 -#define FALCON_RXD_RING_MASK (FALCON_RXD_RING_SIZE - 1) - -/* Event queue size - max 32k */ -#define FALCON_EVQ_ORDER FFE_AZ_EVQ_SIZE_4K -#define FALCON_EVQ_SIZE 4096 -#define FALCON_EVQ_MASK (FALCON_EVQ_SIZE - 1) - /* If FALCON_MAX_INT_ERRORS internal errors occur within * FALCON_INT_ERROR_EXPIRE seconds, we consider the NIC broken and * disable it. @@ -420,7 +405,7 @@ static inline void falcon_notify_tx_desc(struct efx_tx_queue *tx_queue) unsigned write_ptr; efx_dword_t reg; - write_ptr = tx_queue->write_count & FALCON_TXD_RING_MASK; + write_ptr = tx_queue->write_count & EFX_TXQ_MASK; EFX_POPULATE_DWORD_1(reg, FRF_AZ_TX_DESC_WPTR_DWORD, write_ptr); efx_writed_page(tx_queue->efx, ®, FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue); @@ -441,7 +426,7 @@ void falcon_push_buffers(struct efx_tx_queue *tx_queue) BUG_ON(tx_queue->write_count == tx_queue->insert_count); do { - write_ptr = tx_queue->write_count & FALCON_TXD_RING_MASK; + write_ptr = tx_queue->write_count & EFX_TXQ_MASK; buffer = &tx_queue->buffer[write_ptr]; txd = falcon_tx_desc(tx_queue, write_ptr); ++tx_queue->write_count; @@ -462,9 +447,10 @@ void falcon_push_buffers(struct efx_tx_queue *tx_queue) int falcon_probe_tx(struct efx_tx_queue *tx_queue) { struct efx_nic *efx = tx_queue->efx; + BUILD_BUG_ON(EFX_TXQ_SIZE < 512 || EFX_TXQ_SIZE > 4096 || + EFX_TXQ_SIZE & EFX_TXQ_MASK); return falcon_alloc_special_buffer(efx, &tx_queue->txd, - FALCON_TXD_RING_SIZE * - sizeof(efx_qword_t)); + EFX_TXQ_SIZE * sizeof(efx_qword_t)); } void falcon_init_tx(struct efx_tx_queue *tx_queue) @@ -487,7 +473,8 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) tx_queue->channel->channel, FRF_AZ_TX_DESCQ_OWNER_ID, 0, FRF_AZ_TX_DESCQ_LABEL, tx_queue->queue, - FRF_AZ_TX_DESCQ_SIZE, FALCON_TXD_RING_ORDER, + FRF_AZ_TX_DESCQ_SIZE, + __ffs(tx_queue->txd.entries), FRF_AZ_TX_DESCQ_TYPE, 0, FRF_BZ_TX_NON_IP_DROP_DIS, 1); @@ -592,12 +579,12 @@ void falcon_notify_rx_desc(struct efx_rx_queue *rx_queue) while (rx_queue->notified_count != rx_queue->added_count) { falcon_build_rx_desc(rx_queue, rx_queue->notified_count & - FALCON_RXD_RING_MASK); + EFX_RXQ_MASK); ++rx_queue->notified_count; } wmb(); - write_ptr = rx_queue->added_count & FALCON_RXD_RING_MASK; + write_ptr = rx_queue->added_count & EFX_RXQ_MASK; EFX_POPULATE_DWORD_1(reg, FRF_AZ_RX_DESC_WPTR_DWORD, write_ptr); efx_writed_page(rx_queue->efx, ®, FR_AZ_RX_DESC_UPD_DWORD_P0, rx_queue->queue); @@ -606,9 +593,10 @@ void falcon_notify_rx_desc(struct efx_rx_queue *rx_queue) int falcon_probe_rx(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; + BUILD_BUG_ON(EFX_RXQ_SIZE < 512 || EFX_RXQ_SIZE > 4096 || + EFX_RXQ_SIZE & EFX_RXQ_MASK); return falcon_alloc_special_buffer(efx, &rx_queue->rxd, - FALCON_RXD_RING_SIZE * - sizeof(efx_qword_t)); + EFX_RXQ_SIZE * sizeof(efx_qword_t)); } void falcon_init_rx(struct efx_rx_queue *rx_queue) @@ -636,7 +624,8 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue) rx_queue->channel->channel, FRF_AZ_RX_DESCQ_OWNER_ID, 0, FRF_AZ_RX_DESCQ_LABEL, rx_queue->queue, - FRF_AZ_RX_DESCQ_SIZE, FALCON_RXD_RING_ORDER, + FRF_AZ_RX_DESCQ_SIZE, + __ffs(rx_queue->rxd.entries), FRF_AZ_RX_DESCQ_TYPE, 0 /* kernel queue */ , /* For >=B0 this is scatter so disable */ FRF_AZ_RX_DESCQ_JUMBO, !is_b0, @@ -741,7 +730,7 @@ static void falcon_handle_tx_event(struct efx_channel *channel, tx_queue = &efx->tx_queue[tx_ev_q_label]; channel->irq_mod_score += (tx_ev_desc_ptr - tx_queue->read_count) & - efx->type->txd_ring_mask; + EFX_TXQ_MASK; efx_xmit_done(tx_queue, tx_ev_desc_ptr); } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) { /* Rewrite the FIFO write pointer */ @@ -848,9 +837,8 @@ static void falcon_handle_rx_bad_index(struct efx_rx_queue *rx_queue, struct efx_nic *efx = rx_queue->efx; unsigned expected, dropped; - expected = rx_queue->removed_count & FALCON_RXD_RING_MASK; - dropped = ((index + FALCON_RXD_RING_SIZE - expected) & - FALCON_RXD_RING_MASK); + expected = rx_queue->removed_count & EFX_RXQ_MASK; + dropped = (index - expected) & EFX_RXQ_MASK; EFX_INFO(efx, "dropped %d events (index=%d expected=%d)\n", dropped, index, expected); @@ -887,7 +875,7 @@ static void falcon_handle_rx_event(struct efx_channel *channel, rx_queue = &efx->rx_queue[channel->channel]; rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR); - expected_ptr = rx_queue->removed_count & FALCON_RXD_RING_MASK; + expected_ptr = rx_queue->removed_count & EFX_RXQ_MASK; if (unlikely(rx_ev_desc_ptr != expected_ptr)) falcon_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr); @@ -1075,7 +1063,7 @@ int falcon_process_eventq(struct efx_channel *channel, int rx_quota) } /* Increment read pointer */ - read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK; + read_ptr = (read_ptr + 1) & EFX_EVQ_MASK; } while (rx_packets < rx_quota); @@ -1120,10 +1108,10 @@ void falcon_set_int_moderation(struct efx_channel *channel) int falcon_probe_eventq(struct efx_channel *channel) { struct efx_nic *efx = channel->efx; - unsigned int evq_size; - - evq_size = FALCON_EVQ_SIZE * sizeof(efx_qword_t); - return falcon_alloc_special_buffer(efx, &channel->eventq, evq_size); + BUILD_BUG_ON(EFX_EVQ_SIZE < 512 || EFX_EVQ_SIZE > 32768 || + EFX_EVQ_SIZE & EFX_EVQ_MASK); + return falcon_alloc_special_buffer(efx, &channel->eventq, + EFX_EVQ_SIZE * sizeof(efx_qword_t)); } void falcon_init_eventq(struct efx_channel *channel) @@ -1144,7 +1132,7 @@ void falcon_init_eventq(struct efx_channel *channel) /* Push event queue to card */ EFX_POPULATE_OWORD_3(evq_ptr, FRF_AZ_EVQ_EN, 1, - FRF_AZ_EVQ_SIZE, FALCON_EVQ_ORDER, + FRF_AZ_EVQ_SIZE, __ffs(channel->eventq.entries), FRF_AZ_EVQ_BUF_BASE_ID, channel->eventq.index); efx_writeo_table(efx, &evq_ptr, efx->type->evq_ptr_tbl_base, channel->channel); @@ -1214,7 +1202,7 @@ static void falcon_poll_flush_events(struct efx_nic *efx) struct efx_tx_queue *tx_queue; struct efx_rx_queue *rx_queue; unsigned int read_ptr = channel->eventq_read_ptr; - unsigned int end_ptr = (read_ptr - 1) & FALCON_EVQ_MASK; + unsigned int end_ptr = (read_ptr - 1) & EFX_EVQ_MASK; do { efx_qword_t *event = falcon_event(channel, read_ptr); @@ -1252,7 +1240,7 @@ static void falcon_poll_flush_events(struct efx_nic *efx) } } - read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK; + read_ptr = (read_ptr + 1) & EFX_EVQ_MASK; } while (read_ptr != end_ptr); } @@ -3160,9 +3148,6 @@ struct efx_nic_type falcon_a_nic_type = { .buf_tbl_base = FR_AA_BUF_FULL_TBL_KER, .evq_ptr_tbl_base = FR_AA_EVQ_PTR_TBL_KER, .evq_rptr_tbl_base = FR_AA_EVQ_RPTR_KER, - .txd_ring_mask = FALCON_TXD_RING_MASK, - .rxd_ring_mask = FALCON_RXD_RING_MASK, - .evq_size = FALCON_EVQ_SIZE, .max_dma_mask = FALCON_DMA_MASK, .tx_dma_mask = FALCON_TX_DMA_MASK, .bug5391_mask = 0xf, @@ -3184,9 +3169,6 @@ struct efx_nic_type falcon_b_nic_type = { .buf_tbl_base = FR_BZ_BUF_FULL_TBL, .evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL, .evq_rptr_tbl_base = FR_BZ_EVQ_RPTR, - .txd_ring_mask = FALCON_TXD_RING_MASK, - .rxd_ring_mask = FALCON_RXD_RING_MASK, - .evq_size = FALCON_EVQ_SIZE, .max_dma_mask = FALCON_DMA_MASK, .tx_dma_mask = FALCON_TX_DMA_MASK, .bug5391_mask = 0, -- cgit v1.2.2 From 6d51d307509f98f070688b4bff1d0f7462c4d3ec Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:31:07 +0000 Subject: sfc: Define DMA address mask explicitly in terms of descriptor field width Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 3cb7e613ab30..47507b67ba80 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -127,9 +127,6 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); ************************************************************************** */ -/* DMA address mask */ -#define FALCON_DMA_MASK DMA_BIT_MASK(46) - /* TX DMA length mask (13-bit) */ #define FALCON_TX_DMA_MASK (4096 - 1) @@ -3148,7 +3145,7 @@ struct efx_nic_type falcon_a_nic_type = { .buf_tbl_base = FR_AA_BUF_FULL_TBL_KER, .evq_ptr_tbl_base = FR_AA_EVQ_PTR_TBL_KER, .evq_rptr_tbl_base = FR_AA_EVQ_RPTR_KER, - .max_dma_mask = FALCON_DMA_MASK, + .max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH), .tx_dma_mask = FALCON_TX_DMA_MASK, .bug5391_mask = 0xf, .rx_buffer_padding = 0x24, @@ -3169,7 +3166,7 @@ struct efx_nic_type falcon_b_nic_type = { .buf_tbl_base = FR_BZ_BUF_FULL_TBL, .evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL, .evq_rptr_tbl_base = FR_BZ_EVQ_RPTR, - .max_dma_mask = FALCON_DMA_MASK, + .max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH), .tx_dma_mask = FALCON_TX_DMA_MASK, .bug5391_mask = 0, .rx_buffer_padding = 0, -- cgit v1.2.2 From 63f1988419ccaa544d1d31aadc1dd309f6471ffe Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:31:20 +0000 Subject: sfc: Move all TX DMA length limiting into tx.c Replace the duplicated logic in efx_enqueue_skb() and efx_tx_queue_insert() with an inline function, efx_max_tx_len(). Remove the failed attempt at abstracting hardware-specifics and put all the magic numbers in efx_max_tx_len(). Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 47507b67ba80..34b475e9b29d 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -127,9 +127,6 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); ************************************************************************** */ -/* TX DMA length mask (13-bit) */ -#define FALCON_TX_DMA_MASK (4096 - 1) - /* Size and alignment of special buffers (4KB) */ #define FALCON_BUF_SIZE 4096 @@ -3146,8 +3143,6 @@ struct efx_nic_type falcon_a_nic_type = { .evq_ptr_tbl_base = FR_AA_EVQ_PTR_TBL_KER, .evq_rptr_tbl_base = FR_AA_EVQ_RPTR_KER, .max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH), - .tx_dma_mask = FALCON_TX_DMA_MASK, - .bug5391_mask = 0xf, .rx_buffer_padding = 0x24, .max_interrupt_mode = EFX_INT_MODE_MSI, .phys_addr_channels = 4, @@ -3167,8 +3162,6 @@ struct efx_nic_type falcon_b_nic_type = { .evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL, .evq_rptr_tbl_base = FR_BZ_EVQ_RPTR, .max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH), - .tx_dma_mask = FALCON_TX_DMA_MASK, - .bug5391_mask = 0, .rx_buffer_padding = 0, .max_interrupt_mode = EFX_INT_MODE_MSIX, .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy -- cgit v1.2.2 From 0484e0db7c4293d6202cff730ee359d8a7a6b085 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:32:04 +0000 Subject: sfc: Move shared members of struct falcon_nic_data into struct efx_nic These will also be used with Siena NICs. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 34b475e9b29d..1582df7aba7b 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -35,19 +35,12 @@ /** * struct falcon_nic_data - Falcon NIC state - * @next_buffer_table: First available buffer table id * @pci_dev2: The secondary PCI device if present * @i2c_data: Operations and state for I2C bit-bashing algorithm - * @int_error_count: Number of internal errors seen recently - * @int_error_expire: Time at which error count will be expired */ struct falcon_nic_data { - unsigned next_buffer_table; struct pci_dev *pci_dev2; struct i2c_algo_bit_data i2c_data; - - unsigned int_error_count; - unsigned long int_error_expire; }; /************************************************************************** @@ -304,8 +297,6 @@ static int falcon_alloc_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer, unsigned int len) { - struct falcon_nic_data *nic_data = efx->nic_data; - len = ALIGN(len, FALCON_BUF_SIZE); buffer->addr = pci_alloc_consistent(efx->pci_dev, len, @@ -320,8 +311,8 @@ static int falcon_alloc_special_buffer(struct efx_nic *efx, memset(buffer->addr, 0xff, len); /* Select new buffer ID */ - buffer->index = nic_data->next_buffer_table; - nic_data->next_buffer_table += buffer->entries; + buffer->index = efx->next_buffer_table; + efx->next_buffer_table += buffer->entries; EFX_LOG(efx, "allocating special buffers %d-%d at %llx+%x " "(virt %p phys %llx)\n", buffer->index, @@ -1411,13 +1402,13 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) falcon_disable_interrupts(efx); /* Count errors and reset or disable the NIC accordingly */ - if (nic_data->int_error_count == 0 || - time_after(jiffies, nic_data->int_error_expire)) { - nic_data->int_error_count = 0; - nic_data->int_error_expire = + if (efx->int_error_count == 0 || + time_after(jiffies, efx->int_error_expire)) { + efx->int_error_count = 0; + efx->int_error_expire = jiffies + FALCON_INT_ERROR_EXPIRE * HZ; } - if (++nic_data->int_error_count < FALCON_MAX_INT_ERRORS) { + if (++efx->int_error_count < FALCON_MAX_INT_ERRORS) { EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n"); efx_schedule_reset(efx, RESET_TYPE_INT_ERROR); } else { -- cgit v1.2.2 From 0d86ebd815416efb4e95ca70c3b8e65b476c5f9f Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:32:13 +0000 Subject: sfc: Maintain interrupt moderation values in ticks, not microseconds This simplifies the implementation a lot. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 1582df7aba7b..e3c33fa06c86 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1063,20 +1063,11 @@ void falcon_set_int_moderation(struct efx_channel *channel) /* Set timer register */ if (channel->irq_moderation) { - /* Round to resolution supported by hardware. The value we - * program is based at 0. So actual interrupt moderation - * achieved is ((x + 1) * res). - */ - channel->irq_moderation -= (channel->irq_moderation % - FALCON_IRQ_MOD_RESOLUTION); - if (channel->irq_moderation < FALCON_IRQ_MOD_RESOLUTION) - channel->irq_moderation = FALCON_IRQ_MOD_RESOLUTION; EFX_POPULATE_DWORD_2(timer_cmd, FRF_AB_TC_TIMER_MODE, FFE_BB_TIMER_MODE_INT_HLDOFF, FRF_AB_TC_TIMER_VAL, - channel->irq_moderation / - FALCON_IRQ_MOD_RESOLUTION - 1); + channel->irq_moderation - 1); } else { EFX_POPULATE_DWORD_2(timer_cmd, FRF_AB_TC_TIMER_MODE, -- cgit v1.2.2 From dc803df8dd68a045bea4753f5300eeecb961ca2d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:32:33 +0000 Subject: sfc: Remove pointless abstraction of memory BAR number Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index e3c33fa06c86..ade27920a96c 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -3117,7 +3117,6 @@ void falcon_update_nic_stats(struct efx_nic *efx) */ struct efx_nic_type falcon_a_nic_type = { - .mem_bar = 2, .mem_map_size = 0x20000, .txd_ptr_tbl_base = FR_AA_TX_DESC_PTR_TBL_KER, .rxd_ptr_tbl_base = FR_AA_RX_DESC_PTR_TBL_KER, @@ -3131,7 +3130,6 @@ struct efx_nic_type falcon_a_nic_type = { }; struct efx_nic_type falcon_b_nic_type = { - .mem_bar = 2, /* Map everything up to and including the RSS indirection * table. Don't map MSI-X table, MSI-X PBA since Linux * requires that they not be mapped. */ -- cgit v1.2.2 From 96c45726c7dd5ee11b8773810208c41e40a93ffd Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:32:42 +0000 Subject: sfc: Merge falcon_probe_phy() into falcon_probe_port() MAC and PHY probing are bound up together, as evidenced by the initialisation of efx_nic::loopback_modes. Remove the current arbitrary separation. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 60 ++++++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 35 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index ade27920a96c..d9ce21edfa6a 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2173,37 +2173,6 @@ static int falcon_mdio_read(struct net_device *net_dev, return rc; } -static int falcon_probe_phy(struct efx_nic *efx) -{ - switch (efx->phy_type) { - case PHY_TYPE_SFX7101: - efx->phy_op = &falcon_sfx7101_phy_ops; - break; - case PHY_TYPE_SFT9001A: - case PHY_TYPE_SFT9001B: - efx->phy_op = &falcon_sft9001_phy_ops; - break; - case PHY_TYPE_QT2022C2: - case PHY_TYPE_QT2025C: - efx->phy_op = &falcon_xfp_phy_ops; - break; - default: - EFX_ERR(efx, "Unknown PHY type %d\n", - efx->phy_type); - return -1; - } - - if (efx->phy_op->macs & EFX_XMAC) - efx->loopback_modes |= ((1 << LOOPBACK_XGMII) | - (1 << LOOPBACK_XGXS) | - (1 << LOOPBACK_XAUI)); - if (efx->phy_op->macs & EFX_GMAC) - efx->loopback_modes |= (1 << LOOPBACK_GMAC); - efx->loopback_modes |= efx->phy_op->loopbacks; - - return 0; -} - int falcon_switch_mac(struct efx_nic *efx) { struct efx_mac_operations *old_mac_op = efx->mac_op; @@ -2260,10 +2229,31 @@ int falcon_probe_port(struct efx_nic *efx) { int rc; - /* Hook in PHY operations table */ - rc = falcon_probe_phy(efx); - if (rc) - return rc; + switch (efx->phy_type) { + case PHY_TYPE_SFX7101: + efx->phy_op = &falcon_sfx7101_phy_ops; + break; + case PHY_TYPE_SFT9001A: + case PHY_TYPE_SFT9001B: + efx->phy_op = &falcon_sft9001_phy_ops; + break; + case PHY_TYPE_QT2022C2: + case PHY_TYPE_QT2025C: + efx->phy_op = &falcon_xfp_phy_ops; + break; + default: + EFX_ERR(efx, "Unknown PHY type %d\n", + efx->phy_type); + return -ENODEV; + } + + if (efx->phy_op->macs & EFX_XMAC) + efx->loopback_modes |= ((1 << LOOPBACK_XGMII) | + (1 << LOOPBACK_XGXS) | + (1 << LOOPBACK_XAUI)); + if (efx->phy_op->macs & EFX_GMAC) + efx->loopback_modes |= (1 << LOOPBACK_GMAC); + efx->loopback_modes |= efx->phy_op->loopbacks; /* Set up MDIO structure for PHY */ efx->mdio.mmds = efx->phy_op->mmds; -- cgit v1.2.2 From b37b62fea1d1bf68ca51818f8eb1035188efd030 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 08:33:42 +0000 Subject: sfc: Rename 'xfp' file and functions to reflect reality The 'XFP' driver is really a driver for the QT2022C2 and QT2025C PHYs, covering both more and less than XFP. Rename its functions and constants to reflect reality and to reduce namespace pollution when sfc is a built-in driver. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index d9ce21edfa6a..8776432f683c 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2239,7 +2239,7 @@ int falcon_probe_port(struct efx_nic *efx) break; case PHY_TYPE_QT2022C2: case PHY_TYPE_QT2025C: - efx->phy_op = &falcon_xfp_phy_ops; + efx->phy_op = &falcon_qt202x_phy_ops; break; default: EFX_ERR(efx, "Unknown PHY type %d\n", -- cgit v1.2.2 From 9c1bbbaf3eef357b15c0e94085d96f18c6f1bde6 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 28 Oct 2009 02:50:44 -0700 Subject: sfc: Really allow RX checksum offload to be disabled We have never checked the efx_nic::rx_checksum_enabled flag everywhere we should, and since the switch to GRO we don't check it anywhere. It's simplest to check it in the one place where we initialise the per-packet checksummed flag. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 8776432f683c..865638b035bf 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -869,8 +869,9 @@ static void falcon_handle_rx_event(struct efx_channel *channel, * UDP/IPv4, then we can rely on the hardware checksum. */ checksummed = - rx_ev_hdr_type == FSE_AB_RX_EV_HDR_TYPE_IPV4_TCP || - rx_ev_hdr_type == FSE_AB_RX_EV_HDR_TYPE_IPV4_UDP; + efx->rx_checksum_enabled && + (rx_ev_hdr_type == FSE_AB_RX_EV_HDR_TYPE_IPV4_TCP || + rx_ev_hdr_type == FSE_AB_RX_EV_HDR_TYPE_IPV4_UDP); } else { falcon_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard); -- cgit v1.2.2 From 278c0621fbc4ef52177969edb6f07352da816fdb Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 23 Nov 2009 16:05:12 +0000 Subject: sfc: Make board information explicitly Falcon-specific Rename struct efx_board to struct falcon_board. Introduce and use inline function to look up board info from struct efx_nic, in preparation for moving it. Move board init and fini calls into NIC probe and remove functions. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 865638b035bf..29e79f77b732 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2877,8 +2877,17 @@ int falcon_probe_nic(struct efx_nic *efx) if (rc) goto fail5; + rc = falcon_board(efx)->init(efx); + if (rc) { + EFX_ERR(efx, "failed to initialise board\n"); + goto fail6; + } + return 0; + fail6: + BUG_ON(i2c_del_adapter(&efx->i2c_adap)); + memset(&efx->i2c_adap, 0, sizeof(efx->i2c_adap)); fail5: falcon_remove_spi_devices(efx); falcon_free_buffer(efx, &efx->irq_status); @@ -3070,6 +3079,8 @@ void falcon_remove_nic(struct efx_nic *efx) struct falcon_nic_data *nic_data = efx->nic_data; int rc; + falcon_board(efx)->fini(efx); + /* Remove I2C adapter and clear it in preparation for a retry */ rc = i2c_del_adapter(&efx->i2c_adap); BUG_ON(rc); -- cgit v1.2.2 From 5c16a96c4f31a0be287c5db3f36d1099dea9b2bd Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 23 Nov 2009 16:05:28 +0000 Subject: sfc: Move definition of struct falcon_nic_data into falcon.h This is preparation for moving Falcon-specific state required by other Falcon-specific code. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 29e79f77b732..490bda0d010e 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include "net_driver.h" #include "bitfield.h" @@ -33,16 +32,6 @@ * present in SFE400X evaluation boards */ -/** - * struct falcon_nic_data - Falcon NIC state - * @pci_dev2: The secondary PCI device if present - * @i2c_data: Operations and state for I2C bit-bashing algorithm - */ -struct falcon_nic_data { - struct pci_dev *pci_dev2; - struct i2c_algo_bit_data i2c_data; -}; - /************************************************************************** * * Configurable values -- cgit v1.2.2 From e775fb93a880d218ce0b3fd405278dd78f86c405 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 23 Nov 2009 16:06:02 +0000 Subject: sfc: Move all I2C stuff into struct falcon_board Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 490bda0d010e..ff15b9dd3618 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2799,6 +2799,7 @@ static void falcon_probe_spi_devices(struct efx_nic *efx) int falcon_probe_nic(struct efx_nic *efx) { struct falcon_nic_data *nic_data; + struct falcon_board *board; int rc; /* Allocate storage for hardware specific data */ @@ -2856,13 +2857,15 @@ int falcon_probe_nic(struct efx_nic *efx) goto fail5; /* Initialise I2C adapter */ - efx->i2c_adap.owner = THIS_MODULE; - nic_data->i2c_data = falcon_i2c_bit_operations; - nic_data->i2c_data.data = efx; - efx->i2c_adap.algo_data = &nic_data->i2c_data; - efx->i2c_adap.dev.parent = &efx->pci_dev->dev; - strlcpy(efx->i2c_adap.name, "SFC4000 GPIO", sizeof(efx->i2c_adap.name)); - rc = i2c_bit_add_bus(&efx->i2c_adap); + board = falcon_board(efx); + board->i2c_adap.owner = THIS_MODULE; + board->i2c_data = falcon_i2c_bit_operations; + board->i2c_data.data = efx; + board->i2c_adap.algo_data = &board->i2c_data; + board->i2c_adap.dev.parent = &efx->pci_dev->dev; + strlcpy(board->i2c_adap.name, "SFC4000 GPIO", + sizeof(board->i2c_adap.name)); + rc = i2c_bit_add_bus(&board->i2c_adap); if (rc) goto fail5; @@ -2875,8 +2878,8 @@ int falcon_probe_nic(struct efx_nic *efx) return 0; fail6: - BUG_ON(i2c_del_adapter(&efx->i2c_adap)); - memset(&efx->i2c_adap, 0, sizeof(efx->i2c_adap)); + BUG_ON(i2c_del_adapter(&board->i2c_adap)); + memset(&board->i2c_adap, 0, sizeof(board->i2c_adap)); fail5: falcon_remove_spi_devices(efx); falcon_free_buffer(efx, &efx->irq_status); @@ -3066,14 +3069,15 @@ int falcon_init_nic(struct efx_nic *efx) void falcon_remove_nic(struct efx_nic *efx) { struct falcon_nic_data *nic_data = efx->nic_data; + struct falcon_board *board = falcon_board(efx); int rc; falcon_board(efx)->fini(efx); /* Remove I2C adapter and clear it in preparation for a retry */ - rc = i2c_del_adapter(&efx->i2c_adap); + rc = i2c_del_adapter(&board->i2c_adap); BUG_ON(rc); - memset(&efx->i2c_adap, 0, sizeof(efx->i2c_adap)); + memset(&board->i2c_adap, 0, sizeof(board->i2c_adap)); falcon_remove_spi_devices(efx); falcon_free_buffer(efx, &efx->irq_status); -- cgit v1.2.2 From eb50c0d67fe3c5513c717c2dee6d9771c51be703 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 23 Nov 2009 16:06:30 +0000 Subject: sfc: Gather link state fields in struct efx_nic into new struct efx_link_state Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index ff15b9dd3618..6eee4b796c43 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1905,7 +1905,7 @@ static int falcon_reset_macs(struct efx_nic *efx) /* If we've reset the EM block and the link is up, then * we'll have to kick the XAUI link so the PHY can recover */ - if (efx->link_up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx)) + if (efx->link_state.up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx)) falcon_reset_xaui(efx); return 0; @@ -1939,17 +1939,18 @@ void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 0); efx_writeo(efx, ®, FR_AZ_RX_CFG); - if (!efx->link_up) + if (!efx->link_state.up) falcon_drain_tx_fifo(efx); } void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) { + struct efx_link_state *link_state = &efx->link_state; efx_oword_t reg; int link_speed; bool tx_fc; - switch (efx->link_speed) { + switch (link_state->speed) { case 10000: link_speed = 3; break; case 1000: link_speed = 2; break; case 100: link_speed = 1; break; @@ -1969,7 +1970,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) * discarded. */ if (falcon_rev(efx) >= FALCON_REV_B0) { EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, - !efx->link_up); + !link_state->up); } efx_writeo(efx, ®, FR_AB_MAC_CTRL); @@ -1980,7 +1981,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) /* Transmission of pause frames when RX crosses the threshold is * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL. * Action on receipt of pause frames is controller by XM_DIS_FCNTL */ - tx_fc = !!(efx->link_fc & EFX_FC_TX); + tx_fc = !!(efx->link_state.fc & EFX_FC_TX); efx_reado(efx, ®, FR_AZ_RX_CFG); EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, tx_fc); @@ -2175,11 +2176,11 @@ int falcon_switch_mac(struct efx_nic *efx) /* Internal loopbacks override the phy speed setting */ if (efx->loopback_mode == LOOPBACK_GMAC) { - efx->link_speed = 1000; - efx->link_fd = true; + efx->link_state.speed = 1000; + efx->link_state.fd = true; } else if (LOOPBACK_INTERNAL(efx)) { - efx->link_speed = 10000; - efx->link_fd = true; + efx->link_state.speed = 10000; + efx->link_state.fd = true; } WARN_ON(!mutex_is_locked(&efx->mac_lock)); @@ -2752,7 +2753,7 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) } /* Initial assumed speed */ - efx->link_speed = EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) ? 10000 : 1000; + efx->link_state.speed = EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) ? 10000 : 1000; return 0; } -- cgit v1.2.2 From c459302db655c1a7fd05fd4266b18990854e8386 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 23 Nov 2009 16:08:17 +0000 Subject: sfc: Log interrupt and reset type names, not numbers Define name tables for these enumerations in a similar way as for loopback. Move the loopback name table together with them. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 6eee4b796c43..41a321b0e8c6 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2485,7 +2485,7 @@ int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) efx_oword_t glb_ctl_reg_ker; int rc; - EFX_LOG(efx, "performing hardware reset (%d)\n", method); + EFX_LOG(efx, "performing %s hardware reset\n", RESET_TYPE(method)); /* Initiate device reset */ if (method == RESET_TYPE_WORLD) { -- cgit v1.2.2 From 46e1ac0f42c7ff20a7e47c172e4835273b0e6899 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 25 Nov 2009 16:08:30 +0000 Subject: sfc: Fix descriptor cache sizes These were accidentally undersized by a factor of 2, which limited performance. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 41a321b0e8c6..7b19686218a5 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -49,11 +49,11 @@ static int disable_dma_stats; * goes idle. */ #define TX_DC_ENTRIES 16 -#define TX_DC_ENTRIES_ORDER 0 +#define TX_DC_ENTRIES_ORDER 1 #define TX_DC_BASE 0x130000 #define RX_DC_ENTRIES 64 -#define RX_DC_ENTRIES_ORDER 2 +#define RX_DC_ENTRIES_ORDER 3 #define RX_DC_BASE 0x100000 static const unsigned int @@ -2974,14 +2974,14 @@ int falcon_init_nic(struct efx_nic *efx) efx_writeo(efx, &temp, FR_AZ_SRM_RX_DC_CFG); /* Set TX descriptor cache size. */ - BUILD_BUG_ON(TX_DC_ENTRIES != (16 << TX_DC_ENTRIES_ORDER)); + BUILD_BUG_ON(TX_DC_ENTRIES != (8 << TX_DC_ENTRIES_ORDER)); EFX_POPULATE_OWORD_1(temp, FRF_AZ_TX_DC_SIZE, TX_DC_ENTRIES_ORDER); efx_writeo(efx, &temp, FR_AZ_TX_DC_CFG); /* Set RX descriptor cache size. Set low watermark to size-8, as * this allows most efficient prefetching. */ - BUILD_BUG_ON(RX_DC_ENTRIES != (16 << RX_DC_ENTRIES_ORDER)); + BUILD_BUG_ON(RX_DC_ENTRIES != (8 << RX_DC_ENTRIES_ORDER)); EFX_POPULATE_OWORD_1(temp, FRF_AZ_RX_DC_SIZE, RX_DC_ENTRIES_ORDER); efx_writeo(efx, &temp, FR_AZ_RX_DC_CFG); EFX_POPULATE_OWORD_1(temp, FRF_AZ_RX_DC_PF_LWM, RX_DC_ENTRIES - 8); -- cgit v1.2.2 From 80cb9a0f7f381e1c0e9f6dabec6e67db0dd3a0d9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 25 Nov 2009 16:08:41 +0000 Subject: sfc: Treat all MAC registers as 128-bit Although all the defined fields in these registers are within 32 bits, they are architecturally defined as 128-bit like most other Falcon registers. In particular, we must use efx_reado() to ensure proper locking when reading MD_STAT_REG. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 7b19686218a5..f97ef3e0572f 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2042,18 +2042,18 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) /* Wait for GMII access to complete */ static int falcon_gmii_wait(struct efx_nic *efx) { - efx_dword_t md_stat; + efx_oword_t md_stat; int count; /* wait upto 50ms - taken max from datasheet */ for (count = 0; count < 5000; count++) { - efx_readd(efx, &md_stat, FR_AB_MD_STAT); - if (EFX_DWORD_FIELD(md_stat, FRF_AB_MD_BSY) == 0) { - if (EFX_DWORD_FIELD(md_stat, FRF_AB_MD_LNFL) != 0 || - EFX_DWORD_FIELD(md_stat, FRF_AB_MD_BSERR) != 0) { + efx_reado(efx, &md_stat, FR_AB_MD_STAT); + if (EFX_OWORD_FIELD(md_stat, FRF_AB_MD_BSY) == 0) { + if (EFX_OWORD_FIELD(md_stat, FRF_AB_MD_LNFL) != 0 || + EFX_OWORD_FIELD(md_stat, FRF_AB_MD_BSERR) != 0) { EFX_ERR(efx, "error from GMII access " - EFX_DWORD_FMT"\n", - EFX_DWORD_VAL(md_stat)); + EFX_OWORD_FMT"\n", + EFX_OWORD_VAL(md_stat)); return -EIO; } return 0; -- cgit v1.2.2 From 8986352a32485f9dd9069e370ffa6d5b0737a854 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 25 Nov 2009 16:09:04 +0000 Subject: sfc: Comment corrections Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index f97ef3e0572f..140087f83092 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -27,10 +27,7 @@ #include "phy.h" #include "workarounds.h" -/* Falcon hardware control. - * Falcon is the internal codename for the SFC4000 controller that is - * present in SFE400X evaluation boards - */ +/* Hardware control for SFC4000 (aka Falcon). */ /************************************************************************** * -- cgit v1.2.2 From 734a350a6ccee59647f064fd49cd6cebc5dda48b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 25 Nov 2009 16:09:13 +0000 Subject: sfc: Remove unused constant Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 140087f83092..2c0be6ccc624 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -109,9 +109,6 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); /* Size and alignment of special buffers (4KB) */ #define FALCON_BUF_SIZE 4096 -/* Dummy SRAM size code */ -#define SRM_NB_BSZ_ONCHIP_ONLY (-1) - #define FALCON_IS_DUAL_FUNC(efx) \ (falcon_rev(efx) < FALCON_REV_B0) -- cgit v1.2.2 From 44838a447de3b1541cbf845853c4f8999310b0dd Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 25 Nov 2009 16:09:41 +0000 Subject: sfc: Clean up struct falcon_board and struct falcon_board_data Put all static information in struct falcon_board_type and replace it with a pointer in struct falcon_board. Simplify probing aocordingly. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 2c0be6ccc624..2f1f1fca0802 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2864,7 +2864,7 @@ int falcon_probe_nic(struct efx_nic *efx) if (rc) goto fail5; - rc = falcon_board(efx)->init(efx); + rc = falcon_board(efx)->type->init(efx); if (rc) { EFX_ERR(efx, "failed to initialise board\n"); goto fail6; @@ -3067,7 +3067,7 @@ void falcon_remove_nic(struct efx_nic *efx) struct falcon_board *board = falcon_board(efx); int rc; - falcon_board(efx)->fini(efx); + board->type->fini(efx); /* Remove I2C adapter and clear it in preparation for a retry */ rc = i2c_del_adapter(&board->i2c_adap); -- cgit v1.2.2 From 127e6e10ad17585c48cba8e1dcf30d98b90ee583 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 25 Nov 2009 16:09:55 +0000 Subject: sfc: Fix bugs in RX queue flushing Avoid overrunning the hardware limit of 4 concurrent RX queue flushes. Expand the queue flush state to support this. Make similar changes to TX flushing to keep the code symmetric. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 103 +++++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 39 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 2f1f1fca0802..e1b9ce30429a 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -109,6 +109,9 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); /* Size and alignment of special buffers (4KB) */ #define FALCON_BUF_SIZE 4096 +/* Depth of RX flush request fifo */ +#define FALCON_RX_FLUSH_COUNT 4 + #define FALCON_IS_DUAL_FUNC(efx) \ (falcon_rev(efx) < FALCON_REV_B0) @@ -426,7 +429,7 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) efx_oword_t tx_desc_ptr; struct efx_nic *efx = tx_queue->efx; - tx_queue->flushed = false; + tx_queue->flushed = FLUSH_NONE; /* Pin TX descriptor ring */ falcon_init_special_buffer(efx, &tx_queue->txd); @@ -476,6 +479,8 @@ static void falcon_flush_tx_queue(struct efx_tx_queue *tx_queue) struct efx_nic *efx = tx_queue->efx; efx_oword_t tx_flush_descq; + tx_queue->flushed = FLUSH_PENDING; + /* Post a flush command */ EFX_POPULATE_OWORD_2(tx_flush_descq, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1, @@ -489,7 +494,7 @@ void falcon_fini_tx(struct efx_tx_queue *tx_queue) efx_oword_t tx_desc_ptr; /* The queue should have been flushed */ - WARN_ON(!tx_queue->flushed); + WARN_ON(tx_queue->flushed != FLUSH_DONE); /* Remove TX descriptor ring from card */ EFX_ZERO_OWORD(tx_desc_ptr); @@ -578,7 +583,7 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue) rx_queue->queue, rx_queue->rxd.index, rx_queue->rxd.index + rx_queue->rxd.entries - 1); - rx_queue->flushed = false; + rx_queue->flushed = FLUSH_NONE; /* Pin RX descriptor ring */ falcon_init_special_buffer(efx, &rx_queue->rxd); @@ -607,6 +612,8 @@ static void falcon_flush_rx_queue(struct efx_rx_queue *rx_queue) struct efx_nic *efx = rx_queue->efx; efx_oword_t rx_flush_descq; + rx_queue->flushed = FLUSH_PENDING; + /* Post a flush command */ EFX_POPULATE_OWORD_2(rx_flush_descq, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1, @@ -620,7 +627,7 @@ void falcon_fini_rx(struct efx_rx_queue *rx_queue) struct efx_nic *efx = rx_queue->efx; /* The queue should already have been flushed */ - WARN_ON(!rx_queue->flushed); + WARN_ON(rx_queue->flushed != FLUSH_DONE); /* Remove RX descriptor ring from card */ EFX_ZERO_OWORD(rx_desc_ptr); @@ -1181,7 +1188,7 @@ static void falcon_poll_flush_events(struct efx_nic *efx) FSF_AZ_DRIVER_EV_SUBDATA); if (ev_queue < EFX_TX_QUEUE_COUNT) { tx_queue = efx->tx_queue + ev_queue; - tx_queue->flushed = true; + tx_queue->flushed = FLUSH_DONE; } } else if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV && ev_sub_code == FSE_AZ_RX_DESCQ_FLS_DONE_EV) { @@ -1191,17 +1198,29 @@ static void falcon_poll_flush_events(struct efx_nic *efx) *event, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL); if (ev_queue < efx->n_rx_queues) { rx_queue = efx->rx_queue + ev_queue; - - /* retry the rx flush */ - if (ev_failed) - falcon_flush_rx_queue(rx_queue); - else - rx_queue->flushed = true; + rx_queue->flushed = + ev_failed ? FLUSH_FAILED : FLUSH_DONE; } } + /* We're about to destroy the queue anyway, so + * it's ok to throw away every non-flush event */ + EFX_SET_QWORD(*event); + read_ptr = (read_ptr + 1) & EFX_EVQ_MASK; } while (read_ptr != end_ptr); + + channel->eventq_read_ptr = read_ptr; +} + +static void falcon_prepare_flush(struct efx_nic *efx) +{ + falcon_deconfigure_mac_wrapper(efx); + + /* Wait for the tx and rx fifo's to get to the next packet boundary + * (~1ms without back-pressure), then to drain the remainder of the + * fifo's at data path speeds (negligible), with a healthy margin. */ + msleep(10); } /* Handle tx and rx flushes at the same time, since they run in @@ -1211,50 +1230,56 @@ int falcon_flush_queues(struct efx_nic *efx) { struct efx_rx_queue *rx_queue; struct efx_tx_queue *tx_queue; - int i; - bool outstanding; + int i, tx_pending, rx_pending; - /* Issue flush requests */ - efx_for_each_tx_queue(tx_queue, efx) { - tx_queue->flushed = false; + falcon_prepare_flush(efx); + + /* Flush all tx queues in parallel */ + efx_for_each_tx_queue(tx_queue, efx) falcon_flush_tx_queue(tx_queue); - } - efx_for_each_rx_queue(rx_queue, efx) { - rx_queue->flushed = false; - falcon_flush_rx_queue(rx_queue); - } - /* Poll the evq looking for flush completions. Since we're not pushing - * any more rx or tx descriptors at this point, we're in no danger of - * overflowing the evq whilst we wait */ + /* The hardware supports four concurrent rx flushes, each of which may + * need to be retried if there is an outstanding descriptor fetch */ for (i = 0; i < FALCON_FLUSH_POLL_COUNT; ++i) { - msleep(FALCON_FLUSH_INTERVAL); - falcon_poll_flush_events(efx); + rx_pending = tx_pending = 0; + efx_for_each_rx_queue(rx_queue, efx) { + if (rx_queue->flushed == FLUSH_PENDING) + ++rx_pending; + } + efx_for_each_rx_queue(rx_queue, efx) { + if (rx_pending == FALCON_RX_FLUSH_COUNT) + break; + if (rx_queue->flushed == FLUSH_FAILED || + rx_queue->flushed == FLUSH_NONE) { + falcon_flush_rx_queue(rx_queue); + ++rx_pending; + } + } + efx_for_each_tx_queue(tx_queue, efx) { + if (tx_queue->flushed != FLUSH_DONE) + ++tx_pending; + } - /* Check if every queue has been succesfully flushed */ - outstanding = false; - efx_for_each_tx_queue(tx_queue, efx) - outstanding |= !tx_queue->flushed; - efx_for_each_rx_queue(rx_queue, efx) - outstanding |= !rx_queue->flushed; - if (!outstanding) + if (rx_pending == 0 && tx_pending == 0) return 0; + + msleep(FALCON_FLUSH_INTERVAL); + falcon_poll_flush_events(efx); } /* Mark the queues as all flushed. We're going to return failure - * leading to a reset, or fake up success anyway. "flushed" now - * indicates that we tried to flush. */ + * leading to a reset, or fake up success anyway */ efx_for_each_tx_queue(tx_queue, efx) { - if (!tx_queue->flushed) + if (tx_queue->flushed != FLUSH_DONE) EFX_ERR(efx, "tx queue %d flush command timed out\n", tx_queue->queue); - tx_queue->flushed = true; + tx_queue->flushed = FLUSH_DONE; } efx_for_each_rx_queue(rx_queue, efx) { - if (!rx_queue->flushed) + if (rx_queue->flushed != FLUSH_DONE) EFX_ERR(efx, "rx queue %d flush command timed out\n", rx_queue->queue); - rx_queue->flushed = true; + rx_queue->flushed = FLUSH_DONE; } if (EFX_WORKAROUND_7803(efx)) -- cgit v1.2.2 From 26deba501371c215f95624ede81ab5b611fd7d95 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Wed, 25 Nov 2009 16:11:03 +0000 Subject: sfc: Only switch Falcon MAC clocks as necessary Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index e1b9ce30429a..9eec88502101 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2183,11 +2183,29 @@ static int falcon_mdio_read(struct net_device *net_dev, return rc; } +static void falcon_clock_mac(struct efx_nic *efx) +{ + unsigned strap_val; + efx_oword_t nic_stat; + + /* Configure the NIC generated MAC clock correctly */ + efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); + strap_val = EFX_IS10G(efx) ? 5 : 3; + if (falcon_rev(efx) >= FALCON_REV_B0) { + EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP_EN, 1); + EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP, strap_val); + efx_writeo(efx, &nic_stat, FR_AB_NIC_STAT); + } else { + /* Falcon A1 does not support 1G/10G speed switching + * and must not be used with a PHY that does. */ + BUG_ON(EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_PINS) != + strap_val); + } +} + int falcon_switch_mac(struct efx_nic *efx) { struct efx_mac_operations *old_mac_op = efx->mac_op; - efx_oword_t nic_stat; - unsigned strap_val; int rc = 0; /* Don't try to fetch MAC stats while we're switching MACs */ @@ -2206,24 +2224,11 @@ int falcon_switch_mac(struct efx_nic *efx) efx->mac_op = (EFX_IS10G(efx) ? &falcon_xmac_operations : &falcon_gmac_operations); - /* Always push the NIC_STAT_REG setting even if the mac hasn't - * changed, because this function is run post online reset */ - efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); - strap_val = EFX_IS10G(efx) ? 5 : 3; - if (falcon_rev(efx) >= FALCON_REV_B0) { - EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP_EN, 1); - EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP, strap_val); - efx_writeo(efx, &nic_stat, FR_AB_NIC_STAT); - } else { - /* Falcon A1 does not support 1G/10G speed switching - * and must not be used with a PHY that does. */ - BUG_ON(EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_PINS) != - strap_val); - } - if (old_mac_op == efx->mac_op) goto out; + falcon_clock_mac(efx); + EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); /* Not all macs support a mac-level link state */ efx->mac_up = true; @@ -2982,6 +2987,9 @@ int falcon_init_nic(struct efx_nic *efx) efx_writeo(efx, &temp, FR_AB_GPIO_CTL); } + /* Select the correct MAC */ + falcon_clock_mac(efx); + rc = falcon_reset_sram(efx); if (rc) return rc; -- cgit v1.2.2 From 55edc6e6ff728681ebc10d418222740705376664 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 25 Nov 2009 16:11:35 +0000 Subject: sfc: Split MAC stats DMA initiation and completion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Steve Hodgson Currently we initiate MAC stats DMA and busy-wait for completion when stats are requested. We can improve on this with a periodic timer to initiate and poll for stats, and opportunistically poll when stats are requested. Since efx_nic::stats_disable_count and efx_stats_{disable,enable}() are Falcon-specific, rename them and move them accordingly. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 131 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 30 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 9eec88502101..3ab2daff6b48 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -36,8 +36,6 @@ ************************************************************************** */ -static int disable_dma_stats; - /* This is set to 16 for a good reason. In summary, if larger than * 16, the descriptor cache holds more than a default socket * buffer's worth of packets (for UDP we can only have at most one @@ -1890,7 +1888,7 @@ static int falcon_reset_macs(struct efx_nic *efx) /* MAC stats will fail whilst the TX fifo is draining. Serialise * the drain sequence with the statistics fetch */ - efx_stats_disable(efx); + falcon_stop_nic_stats(efx); efx_reado(efx, ®, FR_AB_MAC_CTRL); EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, 1); @@ -1920,13 +1918,13 @@ static int falcon_reset_macs(struct efx_nic *efx) udelay(10); } - efx_stats_enable(efx); - /* If we've reset the EM block and the link is up, then * we'll have to kick the XAUI link so the PHY can recover */ if (efx->link_state.up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx)) falcon_reset_xaui(efx); + falcon_start_nic_stats(efx); + return 0; } @@ -2010,25 +2008,19 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) efx_writeo(efx, ®, FR_AZ_RX_CFG); } -int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) +static void falcon_stats_request(struct efx_nic *efx) { + struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t reg; - u32 *dma_done; - int i; - if (disable_dma_stats) - return 0; + WARN_ON(nic_data->stats_pending); + WARN_ON(nic_data->stats_disable_count); - /* Statistics fetch will fail if the MAC is in TX drain */ - if (falcon_rev(efx) >= FALCON_REV_B0) { - efx_oword_t temp; - efx_reado(efx, &temp, FR_AB_MAC_CTRL); - if (EFX_OWORD_FIELD(temp, FRF_BB_TXFIFO_DRAIN_EN)) - return 0; - } + if (nic_data->stats_dma_done == NULL) + return; /* no mac selected */ - dma_done = (efx->stats_buffer.addr + done_offset); - *dma_done = FALCON_STATS_NOT_DONE; + *nic_data->stats_dma_done = FALCON_STATS_NOT_DONE; + nic_data->stats_pending = true; wmb(); /* ensure done flag is clear */ /* Initiate DMA transfer of stats */ @@ -2038,17 +2030,37 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) efx->stats_buffer.dma_addr); efx_writeo(efx, ®, FR_AB_MAC_STAT_DMA); - /* Wait for transfer to complete */ - for (i = 0; i < 400; i++) { - if (*(volatile u32 *)dma_done == FALCON_STATS_DONE) { - rmb(); /* Ensure the stats are valid. */ - return 0; - } - udelay(10); + mod_timer(&nic_data->stats_timer, round_jiffies_up(jiffies + HZ / 2)); +} + +static void falcon_stats_complete(struct efx_nic *efx) +{ + struct falcon_nic_data *nic_data = efx->nic_data; + + if (!nic_data->stats_pending) + return; + + nic_data->stats_pending = 0; + if (*nic_data->stats_dma_done == FALCON_STATS_DONE) { + rmb(); /* read the done flag before the stats */ + efx->mac_op->update_stats(efx); + } else { + EFX_ERR(efx, "timed out waiting for statistics\n"); } +} - EFX_ERR(efx, "timed out waiting for statistics\n"); - return -ETIMEDOUT; +static void falcon_stats_timer_func(unsigned long context) +{ + struct efx_nic *efx = (struct efx_nic *)context; + struct falcon_nic_data *nic_data = efx->nic_data; + + spin_lock(&efx->stats_lock); + + falcon_stats_complete(efx); + if (nic_data->stats_disable_count == 0) + falcon_stats_request(efx); + + spin_unlock(&efx->stats_lock); } /************************************************************************** @@ -2206,10 +2218,12 @@ static void falcon_clock_mac(struct efx_nic *efx) int falcon_switch_mac(struct efx_nic *efx) { struct efx_mac_operations *old_mac_op = efx->mac_op; + struct falcon_nic_data *nic_data = efx->nic_data; + unsigned int stats_done_offset; int rc = 0; /* Don't try to fetch MAC stats while we're switching MACs */ - efx_stats_disable(efx); + falcon_stop_nic_stats(efx); /* Internal loopbacks override the phy speed setting */ if (efx->loopback_mode == LOOPBACK_GMAC) { @@ -2224,6 +2238,12 @@ int falcon_switch_mac(struct efx_nic *efx) efx->mac_op = (EFX_IS10G(efx) ? &falcon_xmac_operations : &falcon_gmac_operations); + if (EFX_IS10G(efx)) + stats_done_offset = XgDmaDone_offset; + else + stats_done_offset = GDmaDone_offset; + nic_data->stats_dma_done = efx->stats_buffer.addr + stats_done_offset; + if (old_mac_op == efx->mac_op) goto out; @@ -2235,7 +2255,7 @@ int falcon_switch_mac(struct efx_nic *efx) rc = falcon_reset_macs(efx); out: - efx_stats_enable(efx); + falcon_start_nic_stats(efx); return rc; } @@ -2900,6 +2920,10 @@ int falcon_probe_nic(struct efx_nic *efx) goto fail6; } + nic_data->stats_disable_count = 1; + setup_timer(&nic_data->stats_timer, &falcon_stats_timer_func, + (unsigned long)efx); + return 0; fail6: @@ -3125,11 +3149,58 @@ void falcon_remove_nic(struct efx_nic *efx) void falcon_update_nic_stats(struct efx_nic *efx) { + struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t cnt; + if (nic_data->stats_disable_count) + return; + efx_reado(efx, &cnt, FR_AZ_RX_NODESC_DROP); efx->n_rx_nodesc_drop_cnt += EFX_OWORD_FIELD(cnt, FRF_AB_RX_NODESC_DROP_CNT); + + if (nic_data->stats_pending && + *nic_data->stats_dma_done == FALCON_STATS_DONE) { + nic_data->stats_pending = false; + rmb(); /* read the done flag before the stats */ + efx->mac_op->update_stats(efx); + } +} + +void falcon_start_nic_stats(struct efx_nic *efx) +{ + struct falcon_nic_data *nic_data = efx->nic_data; + + spin_lock_bh(&efx->stats_lock); + if (--nic_data->stats_disable_count == 0) + falcon_stats_request(efx); + spin_unlock_bh(&efx->stats_lock); +} + +void falcon_stop_nic_stats(struct efx_nic *efx) +{ + struct falcon_nic_data *nic_data = efx->nic_data; + int i; + + might_sleep(); + + spin_lock_bh(&efx->stats_lock); + ++nic_data->stats_disable_count; + spin_unlock_bh(&efx->stats_lock); + + del_timer_sync(&nic_data->stats_timer); + + /* Wait enough time for the most recent transfer to + * complete. */ + for (i = 0; i < 4 && nic_data->stats_pending; i++) { + if (*nic_data->stats_dma_done == FALCON_STATS_DONE) + break; + msleep(1); + } + + spin_lock_bh(&efx->stats_lock); + falcon_stats_complete(efx); + spin_unlock_bh(&efx->stats_lock); } /************************************************************************** -- cgit v1.2.2 From fe75820b99ff2de713de23252432f0f9d0ca1d35 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 25 Nov 2009 16:11:45 +0000 Subject: sfc: Move Falcon board/PHY/MAC monitoring code to falcon.c Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 3ab2daff6b48..c43c5e6f077b 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2612,6 +2612,21 @@ fail5: return rc; } +void falcon_monitor(struct efx_nic *efx) +{ + int rc; + + rc = falcon_board(efx)->type->monitor(efx); + if (rc) { + EFX_ERR(efx, "Board sensor %s; shutting down PHY\n", + (rc == -ERANGE) ? "reported fault" : "failed"); + efx->phy_mode |= PHY_MODE_LOW_POWER; + falcon_sim_phy_event(efx); + } + efx->phy_op->poll(efx); + efx->mac_op->poll(efx); +} + /* Zeroes out the SRAM contents. This routine must be called in * process context and is allowed to sleep. */ -- cgit v1.2.2 From 9007b9fa368b172e6b9a985899080fbebb7d3204 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 25 Nov 2009 16:12:01 +0000 Subject: sfc: Simplify XMAC link polling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Steve Hodgson Only the XMAC on Falcon needs help from the driver to poll and reset the MAC-PHY link (XAUI); GMII is a simple parallel bus and on later NICs firmware takes care of the XAUI link. Also, an XMAC interrupt currently schedules a work item which simply clears a flag (efx_nic::mac_up) to be checked by the regular monitor (or the next link reconfiguration, if that is sooner). Rename the flag to xmac_poll_required, changing its sense. Remove the needless indirection and just set the flag immediately. Call falcon_xmac_poll() directly where required. Add a new generic operation mac_op::check_fault to check the link outside of regular monitoring, as required during self-tests. (Note that this leaves us with an unused work item, but we will immediately have another use for it.) Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index c43c5e6f077b..fac534a274c8 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -900,7 +900,7 @@ static void falcon_handle_global_event(struct efx_channel *channel, if ((falcon_rev(efx) >= FALCON_REV_B0) && EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) { - queue_work(efx->workqueue, &efx->mac_work); + efx->xmac_poll_required = true; handled = true; } @@ -2251,7 +2251,7 @@ int falcon_switch_mac(struct efx_nic *efx) EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); /* Not all macs support a mac-level link state */ - efx->mac_up = true; + efx->xmac_poll_required = false; rc = falcon_reset_macs(efx); out: @@ -2624,7 +2624,8 @@ void falcon_monitor(struct efx_nic *efx) falcon_sim_phy_event(efx); } efx->phy_op->poll(efx); - efx->mac_op->poll(efx); + if (EFX_IS10G(efx)) + falcon_poll_xmac(efx); } /* Zeroes out the SRAM contents. This routine must be called in -- cgit v1.2.2 From 8be4f3e6f7b670529bd67aa1f0319bec1e29ebcf Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 25 Nov 2009 16:12:16 +0000 Subject: sfc: Change MAC promiscuity and multicast hash at the same time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Steve Hodgson Currently we can set multicast hash immediately (in atomic context) but must delay setting MAC promiscuity. There is not that much point in deferring one but not the other, and setting the multicast hash on Siena will involve a firmware request. So process them both in efx_mac_work(). Also, set the broadcast bit in the multicast hash in efx_set_multicast_list(), since this is required for both Falcon and Siena. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index fac534a274c8..e26043eb01b5 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1993,7 +1993,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) efx_writeo(efx, ®, FR_AB_MAC_CTRL); /* Restore the multicast hash registers. */ - falcon_set_multicast_hash(efx); + falcon_push_multicast_hash(efx); /* Transmission of pause frames when RX crosses the threshold is * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL. @@ -2327,15 +2327,11 @@ void falcon_remove_port(struct efx_nic *efx) ************************************************************************** */ -void falcon_set_multicast_hash(struct efx_nic *efx) +void falcon_push_multicast_hash(struct efx_nic *efx) { union efx_multicast_hash *mc_hash = &efx->multicast_hash; - /* Broadcast packets go through the multicast hash filter. - * ether_crc_le() of the broadcast address is 0xbe2612ff - * so we always add bit 0xff to the mask. - */ - set_bit_le(0xff, mc_hash->byte); + WARN_ON(!mutex_is_locked(&efx->mac_lock)); efx_writeo(efx, &mc_hash->oword[0], FR_AB_MAC_MC_HASH_REG0); efx_writeo(efx, &mc_hash->oword[1], FR_AB_MAC_MC_HASH_REG1); -- cgit v1.2.2 From fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Sat, 28 Nov 2009 05:34:05 +0000 Subject: sfc: Simplify PHY polling Falcon can generate events for LASI interrupts from the PHY, but in practice we have never implemented this in reference designs. Instead we have polled, inserted the appropriate events, and then handled the events later. This is a waste of time and code. Instead, make PHY poll functions update the link state synchronously and report whether it changed. We can still make use of the LASI registers as a shortcut on the SFT9001. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 69 +++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 27 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index e26043eb01b5..e16faad70283 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -893,8 +893,7 @@ static void falcon_handle_global_event(struct efx_channel *channel, if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) || EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) || EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR)) { - efx->phy_op->clear_interrupt(efx); - queue_work(efx->workqueue, &efx->phy_work); + /* Ignored */ handled = true; } @@ -1140,20 +1139,6 @@ void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic) falcon_generate_event(channel, &test_event); } -void falcon_sim_phy_event(struct efx_nic *efx) -{ - efx_qword_t phy_event; - - EFX_POPULATE_QWORD_1(phy_event, FSF_AZ_EV_CODE, - FSE_AZ_EV_CODE_GLOBAL_EV); - if (EFX_IS10G(efx)) - EFX_SET_QWORD_FIELD(phy_event, FSF_AB_GLB_EV_XG_PHY0_INTR, 1); - else - EFX_SET_QWORD_FIELD(phy_event, FSF_AB_GLB_EV_G_PHY0_INTR, 1); - - falcon_generate_event(&efx->channel[0], &phy_event); -} - /************************************************************************** * * Flush handling @@ -2063,6 +2048,25 @@ static void falcon_stats_timer_func(unsigned long context) spin_unlock(&efx->stats_lock); } +static bool falcon_loopback_link_poll(struct efx_nic *efx) +{ + struct efx_link_state old_state = efx->link_state; + + WARN_ON(!mutex_is_locked(&efx->mac_lock)); + WARN_ON(!LOOPBACK_INTERNAL(efx)); + + efx->link_state.fd = true; + efx->link_state.fc = efx->wanted_fc; + efx->link_state.up = true; + + if (efx->loopback_mode == LOOPBACK_GMAC) + efx->link_state.speed = 1000; + else + efx->link_state.speed = 10000; + + return !efx_link_state_equal(&efx->link_state, &old_state); +} + /************************************************************************** * * PHY access via GMII @@ -2225,15 +2229,6 @@ int falcon_switch_mac(struct efx_nic *efx) /* Don't try to fetch MAC stats while we're switching MACs */ falcon_stop_nic_stats(efx); - /* Internal loopbacks override the phy speed setting */ - if (efx->loopback_mode == LOOPBACK_GMAC) { - efx->link_state.speed = 1000; - efx->link_state.fd = true; - } else if (LOOPBACK_INTERNAL(efx)) { - efx->link_state.speed = 10000; - efx->link_state.fd = true; - } - WARN_ON(!mutex_is_locked(&efx->mac_lock)); efx->mac_op = (EFX_IS10G(efx) ? &falcon_xmac_operations : &falcon_gmac_operations); @@ -2610,16 +2605,36 @@ fail5: void falcon_monitor(struct efx_nic *efx) { + bool link_changed; int rc; + BUG_ON(!mutex_is_locked(&efx->mac_lock)); + rc = falcon_board(efx)->type->monitor(efx); if (rc) { EFX_ERR(efx, "Board sensor %s; shutting down PHY\n", (rc == -ERANGE) ? "reported fault" : "failed"); efx->phy_mode |= PHY_MODE_LOW_POWER; - falcon_sim_phy_event(efx); + __efx_reconfigure_port(efx); } - efx->phy_op->poll(efx); + + if (LOOPBACK_INTERNAL(efx)) + link_changed = falcon_loopback_link_poll(efx); + else + link_changed = efx->phy_op->poll(efx); + + if (link_changed) { + falcon_stop_nic_stats(efx); + falcon_deconfigure_mac_wrapper(efx); + + falcon_switch_mac(efx); + efx->mac_op->reconfigure(efx); + + falcon_start_nic_stats(efx); + + efx_link_status_changed(efx); + } + if (EFX_IS10G(efx)) falcon_poll_xmac(efx); } -- cgit v1.2.2 From ab86746175a5e1379abb9c7c38522af4d3176f57 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Sat, 28 Nov 2009 05:34:44 +0000 Subject: sfc: Replace MDIO spinlock with mutex We never use MDIO in atomic context, so we don't need to spin. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index e16faad70283..372dbbc72404 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2110,7 +2110,7 @@ static int falcon_mdio_write(struct net_device *net_dev, EFX_REGDUMP(efx, "writing MDIO %d register %d.%d with 0x%04x\n", prtad, devad, addr, value); - spin_lock_bh(&efx->phy_lock); + mutex_lock(&efx->mdio_lock); /* Check MDIO not currently being accessed */ rc = falcon_gmii_wait(efx); @@ -2145,8 +2145,8 @@ static int falcon_mdio_write(struct net_device *net_dev, udelay(10); } - out: - spin_unlock_bh(&efx->phy_lock); +out: + mutex_unlock(&efx->mdio_lock); return rc; } @@ -2158,7 +2158,7 @@ static int falcon_mdio_read(struct net_device *net_dev, efx_oword_t reg; int rc; - spin_lock_bh(&efx->phy_lock); + mutex_lock(&efx->mdio_lock); /* Check MDIO not currently being accessed */ rc = falcon_gmii_wait(efx); @@ -2194,8 +2194,8 @@ static int falcon_mdio_read(struct net_device *net_dev, prtad, devad, addr, rc); } - out: - spin_unlock_bh(&efx->phy_lock); +out: + mutex_unlock(&efx->mdio_lock); return rc; } -- cgit v1.2.2 From b895d73e9836fccc402e48a8f63e6805d2edc87b Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Sat, 28 Nov 2009 05:35:00 +0000 Subject: sfc: Always start Falcon using the XMAC The strap bits are only important on Falcon A and all production boards using it have fixed-speed 10G PHYs. Replace dummy MAC operations with default MAC operations. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 372dbbc72404..9c4f8985aa71 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2291,6 +2291,10 @@ int falcon_probe_port(struct efx_nic *efx) efx->mdio.mdio_read = falcon_mdio_read; efx->mdio.mdio_write = falcon_mdio_write; + /* Initial assumption */ + efx->link_state.speed = 10000; + efx->link_state.fd = true; + /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ if (falcon_rev(efx) >= FALCON_REV_B0) efx->wanted_fc = EFX_FC_RX | EFX_FC_TX; @@ -2809,6 +2813,10 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) return -ENODEV; case FALCON_REV_A1: + if (EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) == 0) { + EFX_ERR(efx, "Falcon rev A1 1G not supported\n"); + return -ENODEV; + } if (EFX_OWORD_FIELD(nic_stat, FRF_AA_STRAP_PCIE) == 0) { EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); return -ENODEV; @@ -2823,9 +2831,6 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) return -ENODEV; } - /* Initial assumed speed */ - efx->link_state.speed = EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) ? 10000 : 1000; - return 0; } @@ -3238,6 +3243,8 @@ void falcon_stop_nic_stats(struct efx_nic *efx) */ struct efx_nic_type falcon_a_nic_type = { + .default_mac_ops = &falcon_xmac_operations, + .mem_map_size = 0x20000, .txd_ptr_tbl_base = FR_AA_TX_DESC_PTR_TBL_KER, .rxd_ptr_tbl_base = FR_AA_RX_DESC_PTR_TBL_KER, @@ -3251,6 +3258,8 @@ struct efx_nic_type falcon_a_nic_type = { }; struct efx_nic_type falcon_b_nic_type = { + .default_mac_ops = &falcon_xmac_operations, + /* Map everything up to and including the RSS indirection * table. Don't map MSI-X table, MSI-X PBA since Linux * requires that they not be mapped. */ -- cgit v1.2.2 From 0589ece031e31a238e60057ef2abfa1ff18d46d0 Mon Sep 17 00:00:00 2001 From: Matthew Slattery Date: Sat, 28 Nov 2009 05:35:24 +0000 Subject: sfc: Remove EFX_WORKAROUND_9141 macro The "bug9141 workaround" of setting TX_FLUSH_MIN_LEN_EN should really be considered as a normal bit of configuration rather than a workaround. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 9c4f8985aa71..b186fd2c9b6f 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -3128,7 +3128,7 @@ int falcon_init_nic(struct efx_nic *efx) /* Prefetch threshold 2 => fetch when descriptor cache half empty */ EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2); /* Squash TX of packets of 16 bytes or less */ - if (falcon_rev(efx) >= FALCON_REV_B0 && EFX_WORKAROUND_9141(efx)) + if (falcon_rev(efx) >= FALCON_REV_B0) EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); efx_writeo(efx, &temp, FR_AZ_TX_RESERVED); -- cgit v1.2.2 From daeda6309e1382819a8f8bab548560742ac26cc2 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 28 Nov 2009 05:36:04 +0000 Subject: sfc: Decouple NIC revision number from Falcon PCI revision number Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 68 ++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 37 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index b186fd2c9b6f..7c9c9c935957 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -111,7 +111,7 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); #define FALCON_RX_FLUSH_COUNT 4 #define FALCON_IS_DUAL_FUNC(efx) \ - (falcon_rev(efx) < FALCON_REV_B0) + (efx_nic_rev(efx) < EFX_REV_FALCON_B0) /************************************************************************** * @@ -447,7 +447,7 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) FRF_AZ_TX_DESCQ_TYPE, 0, FRF_BZ_TX_NON_IP_DROP_DIS, 1); - if (falcon_rev(efx) >= FALCON_REV_B0) { + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { int csum = tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM; EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_IP_CHKSM_DIS, !csum); EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_TCP_CHKSM_DIS, @@ -457,7 +457,7 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) efx_writeo_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, tx_queue->queue); - if (falcon_rev(efx) < FALCON_REV_B0) { + if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) { efx_oword_t reg; /* Only 128 bits in this register */ @@ -574,7 +574,7 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue) { efx_oword_t rx_desc_ptr; struct efx_nic *efx = rx_queue->efx; - bool is_b0 = falcon_rev(efx) >= FALCON_REV_B0; + bool is_b0 = efx_nic_rev(efx) >= EFX_REV_FALCON_B0; bool iscsi_digest_en = is_b0; EFX_LOG(efx, "RX queue %d ring in special buffers %d-%d\n", @@ -752,7 +752,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR); rx_ev_eth_crc_err = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_ETH_CRC_ERR); rx_ev_frm_trunc = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_FRM_TRUNC); - rx_ev_drib_nib = ((falcon_rev(efx) >= FALCON_REV_B0) ? + rx_ev_drib_nib = ((efx_nic_rev(efx) >= EFX_REV_FALCON_B0) ? 0 : EFX_QWORD_FIELD(*event, FSF_AA_RX_EV_DRIB_NIB)); rx_ev_pause_frm = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PAUSE_FRM_ERR); @@ -897,13 +897,13 @@ static void falcon_handle_global_event(struct efx_channel *channel, handled = true; } - if ((falcon_rev(efx) >= FALCON_REV_B0) && + if ((efx_nic_rev(efx) >= EFX_REV_FALCON_B0) && EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) { efx->xmac_poll_required = true; handled = true; } - if (falcon_rev(efx) <= FALCON_REV_A1 ? + if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1 ? EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) : EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) { EFX_ERR(efx, "channel %d seen global RX_RESET " @@ -1531,7 +1531,7 @@ static void falcon_setup_rss_indir_table(struct efx_nic *efx) unsigned long offset; efx_dword_t dword; - if (falcon_rev(efx) < FALCON_REV_B0) + if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) return; for (offset = FR_BZ_RX_INDIRECTION_TBL; @@ -1554,7 +1554,7 @@ int falcon_init_interrupt(struct efx_nic *efx) if (!EFX_INT_MODE_USE_MSI(efx)) { irq_handler_t handler; - if (falcon_rev(efx) >= FALCON_REV_B0) + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) handler = falcon_legacy_interrupt_b0; else handler = falcon_legacy_interrupt_a1; @@ -1601,7 +1601,7 @@ void falcon_fini_interrupt(struct efx_nic *efx) } /* ACK legacy interrupt */ - if (falcon_rev(efx) >= FALCON_REV_B0) + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) efx_reado(efx, ®, FR_BZ_INT_ISR0); else falcon_irq_ack_a1(efx); @@ -1841,7 +1841,7 @@ static int falcon_reset_macs(struct efx_nic *efx) efx_oword_t reg; int count; - if (falcon_rev(efx) < FALCON_REV_B0) { + if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) { /* It's not safe to use GLB_CTL_REG to reset the * macs, so instead use the internal MAC resets */ @@ -1917,7 +1917,7 @@ void falcon_drain_tx_fifo(struct efx_nic *efx) { efx_oword_t reg; - if ((falcon_rev(efx) < FALCON_REV_B0) || + if ((efx_nic_rev(efx) < EFX_REV_FALCON_B0) || (efx->loopback_mode != LOOPBACK_NONE)) return; @@ -1933,7 +1933,7 @@ void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) { efx_oword_t reg; - if (falcon_rev(efx) < FALCON_REV_B0) + if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) return; /* Isolate the MAC -> RX */ @@ -1970,7 +1970,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) FRF_AB_MAC_SPEED, link_speed); /* On B0, MAC backpressure can be disabled and packets get * discarded. */ - if (falcon_rev(efx) >= FALCON_REV_B0) { + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, !link_state->up); } @@ -1988,7 +1988,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, tx_fc); /* Unisolate the MAC -> RX */ - if (falcon_rev(efx) >= FALCON_REV_B0) + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1); efx_writeo(efx, ®, FR_AZ_RX_CFG); } @@ -2207,7 +2207,7 @@ static void falcon_clock_mac(struct efx_nic *efx) /* Configure the NIC generated MAC clock correctly */ efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); strap_val = EFX_IS10G(efx) ? 5 : 3; - if (falcon_rev(efx) >= FALCON_REV_B0) { + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP_EN, 1); EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP, strap_val); efx_writeo(efx, &nic_stat, FR_AB_NIC_STAT); @@ -2296,7 +2296,7 @@ int falcon_probe_port(struct efx_nic *efx) efx->link_state.fd = true; /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ - if (falcon_rev(efx) >= FALCON_REV_B0) + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) efx->wanted_fc = EFX_FC_RX | EFX_FC_TX; else efx->wanted_fc = EFX_FC_RX; @@ -2806,13 +2806,13 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); - switch (falcon_rev(efx)) { - case FALCON_REV_A0: - case 0xff: - EFX_ERR(efx, "Falcon rev A0 not supported\n"); - return -ENODEV; + if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) { + u8 pci_rev = efx->pci_dev->revision; - case FALCON_REV_A1: + if ((pci_rev == 0xff) || (pci_rev == 0)) { + EFX_ERR(efx, "Falcon rev A0 not supported\n"); + return -ENODEV; + } if (EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) == 0) { EFX_ERR(efx, "Falcon rev A1 1G not supported\n"); return -ENODEV; @@ -2821,14 +2821,6 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); return -ENODEV; } - break; - - case FALCON_REV_B0: - break; - - default: - EFX_ERR(efx, "Unknown Falcon rev %d\n", falcon_rev(efx)); - return -ENODEV; } return 0; @@ -2991,7 +2983,7 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) efx_oword_t reg; efx_reado(efx, ®, FR_AZ_RX_CFG); - if (falcon_rev(efx) <= FALCON_REV_A1) { + if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) { /* Data FIFO size is 5.5K */ if (data_xon_thr < 0) data_xon_thr = 512 >> 8; @@ -3037,7 +3029,7 @@ int falcon_init_nic(struct efx_nic *efx) efx_writeo(efx, &temp, FR_AB_NIC_STAT); /* Set the source of the GMAC clock */ - if (falcon_rev(efx) == FALCON_REV_B0) { + if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) { efx_reado(efx, &temp, FR_AB_GPIO_CTL); EFX_SET_OWORD_FIELD(temp, FRF_AB_USE_NIC_CLK, true); efx_writeo(efx, &temp, FR_AB_GPIO_CTL); @@ -3128,7 +3120,7 @@ int falcon_init_nic(struct efx_nic *efx) /* Prefetch threshold 2 => fetch when descriptor cache half empty */ EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2); /* Squash TX of packets of 16 bytes or less */ - if (falcon_rev(efx) >= FALCON_REV_B0) + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); efx_writeo(efx, &temp, FR_AZ_TX_RESERVED); @@ -3142,7 +3134,7 @@ int falcon_init_nic(struct efx_nic *efx) falcon_init_rx_cfg(efx); /* Set destination of both TX and RX Flush events */ - if (falcon_rev(efx) >= FALCON_REV_B0) { + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { EFX_POPULATE_OWORD_1(temp, FRF_BZ_FLS_EVQ_ID, 0); efx_writeo(efx, &temp, FR_BZ_DP_CTRL); } @@ -3242,9 +3234,10 @@ void falcon_stop_nic_stats(struct efx_nic *efx) ************************************************************************** */ -struct efx_nic_type falcon_a_nic_type = { +struct efx_nic_type falcon_a1_nic_type = { .default_mac_ops = &falcon_xmac_operations, + .revision = EFX_REV_FALCON_A1, .mem_map_size = 0x20000, .txd_ptr_tbl_base = FR_AA_TX_DESC_PTR_TBL_KER, .rxd_ptr_tbl_base = FR_AA_RX_DESC_PTR_TBL_KER, @@ -3257,9 +3250,10 @@ struct efx_nic_type falcon_a_nic_type = { .phys_addr_channels = 4, }; -struct efx_nic_type falcon_b_nic_type = { +struct efx_nic_type falcon_b0_nic_type = { .default_mac_ops = &falcon_xmac_operations, + .revision = EFX_REV_FALCON_B0, /* Map everything up to and including the RSS indirection * table. Don't map MSI-X table, MSI-X PBA since Linux * requires that they not be mapped. */ -- cgit v1.2.2 From 0228f5cdb03f6656247cf2876f9f4f8fc213ffd6 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 28 Nov 2009 05:36:12 +0000 Subject: sfc: Move descriptor cache base addresses to struct efx_nic_type Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 7c9c9c935957..539d0223b434 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -45,11 +45,9 @@ */ #define TX_DC_ENTRIES 16 #define TX_DC_ENTRIES_ORDER 1 -#define TX_DC_BASE 0x130000 #define RX_DC_ENTRIES 64 #define RX_DC_ENTRIES_ORDER 3 -#define RX_DC_BASE 0x100000 static const unsigned int /* "Large" EEPROM device: Atmel AT25640 or similar @@ -3043,9 +3041,11 @@ int falcon_init_nic(struct efx_nic *efx) return rc; /* Set positions of descriptor caches in SRAM. */ - EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_TX_DC_BASE_ADR, TX_DC_BASE / 8); + EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_TX_DC_BASE_ADR, + efx->type->tx_dc_base / 8); efx_writeo(efx, &temp, FR_AZ_SRM_TX_DC_CFG); - EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_RX_DC_BASE_ADR, RX_DC_BASE / 8); + EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_RX_DC_BASE_ADR, + efx->type->rx_dc_base / 8); efx_writeo(efx, &temp, FR_AZ_SRM_RX_DC_CFG); /* Set TX descriptor cache size. */ @@ -3248,6 +3248,8 @@ struct efx_nic_type falcon_a1_nic_type = { .rx_buffer_padding = 0x24, .max_interrupt_mode = EFX_INT_MODE_MSI, .phys_addr_channels = 4, + .tx_dc_base = 0x130000, + .rx_dc_base = 0x100000, }; struct efx_nic_type falcon_b0_nic_type = { @@ -3271,5 +3273,7 @@ struct efx_nic_type falcon_b0_nic_type = { .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy * interrupt handler only supports 32 * channels */ + .tx_dc_base = 0x130000, + .rx_dc_base = 0x100000, }; -- cgit v1.2.2 From c1ac403bfa240617da2bce861ea5c3a907a65612 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 28 Nov 2009 05:36:29 +0000 Subject: sfc: Clean up RX event handling Add 'likely' hint to test of rx_checksum_enabled. Don't count IP fragments; the IP stack can do that. Do count non-matching multicast packets. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 539d0223b434..2f219ce61392 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -734,7 +734,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err; bool rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc; bool rx_ev_other_err, rx_ev_pause_frm; - bool rx_ev_ip_frag_err, rx_ev_hdr_type, rx_ev_mcast_pkt; + bool rx_ev_hdr_type, rx_ev_mcast_pkt; unsigned rx_ev_pkt_type; rx_ev_hdr_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE); @@ -743,7 +743,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, rx_ev_pkt_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_TYPE); rx_ev_buf_owner_id_err = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_BUF_OWNER_ID_ERR); - rx_ev_ip_frag_err = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_IP_FRAG_ERR); rx_ev_ip_hdr_chksum_err = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR); rx_ev_tcp_udp_chksum_err = EFX_QWORD_FIELD(*event, @@ -771,8 +770,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, else if (rx_ev_tcp_udp_chksum_err) ++rx_queue->channel->n_rx_tcp_udp_chksum_err; } - if (rx_ev_ip_frag_err) - ++rx_queue->channel->n_rx_ip_frag_err; /* The frame must be discarded if any of these are true. */ *discard = (rx_ev_eth_crc_err | rx_ev_frm_trunc | rx_ev_drib_nib | @@ -855,7 +852,7 @@ static void falcon_handle_rx_event(struct efx_channel *channel, * UDP/IPv4, then we can rely on the hardware checksum. */ checksummed = - efx->rx_checksum_enabled && + likely(efx->rx_checksum_enabled) && (rx_ev_hdr_type == FSE_AB_RX_EV_HDR_TYPE_IPV4_TCP || rx_ev_hdr_type == FSE_AB_RX_EV_HDR_TYPE_IPV4_UDP); } else { @@ -870,8 +867,10 @@ static void falcon_handle_rx_event(struct efx_channel *channel, unsigned int rx_ev_mcast_hash_match = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_HASH_MATCH); - if (unlikely(!rx_ev_mcast_hash_match)) + if (unlikely(!rx_ev_mcast_hash_match)) { + ++channel->n_rx_mcast_mismatch; discard = true; + } } channel->irq_mod_score += 2; -- cgit v1.2.2 From 39e60212087a36a53daca3904563012ccaf6e92d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 03:42:03 +0000 Subject: sfc: Remove redundant writes to INT_ADR_KER This register only needs to be written after reset, not each time we enable interrupts. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 2f219ce61392..b7e9238aaec4 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1290,19 +1290,11 @@ static inline void falcon_interrupts(struct efx_nic *efx, int enabled, void falcon_enable_interrupts(struct efx_nic *efx) { - efx_oword_t int_adr_reg_ker; struct efx_channel *channel; EFX_ZERO_OWORD(*((efx_oword_t *) efx->irq_status.addr)); wmb(); /* Ensure interrupt vector is clear before interrupts enabled */ - /* Program address */ - EFX_POPULATE_OWORD_2(int_adr_reg_ker, - FRF_AZ_NORM_INT_VEC_DIS_KER, - EFX_INT_MODE_USE_MSI(efx), - FRF_AZ_INT_ADR_KER, efx->irq_status.dma_addr); - efx_writeo(efx, &int_adr_reg_ker, FR_AZ_INT_ADR_KER); - /* Enable interrupts */ falcon_interrupts(efx, 1, 0); @@ -3061,6 +3053,13 @@ int falcon_init_nic(struct efx_nic *efx) EFX_POPULATE_OWORD_1(temp, FRF_AZ_RX_DC_PF_LWM, RX_DC_ENTRIES - 8); efx_writeo(efx, &temp, FR_AZ_RX_DC_PF_WM); + /* Program INT_KER address */ + EFX_POPULATE_OWORD_2(temp, + FRF_AZ_NORM_INT_VEC_DIS_KER, + EFX_INT_MODE_USE_MSI(efx), + FRF_AZ_INT_ADR_KER, efx->irq_status.dma_addr); + efx_writeo(efx, &temp, FR_AZ_INT_ADR_KER); + /* Clear the parity enables on the TX data fifos as * they produce false parity errors because of timing issues */ -- cgit v1.2.2 From 674979d33566ab7e524e25fdc227923e27a3fb78 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 03:42:10 +0000 Subject: sfc: Remove duplicate hardware structure definitions Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index b7e9238aaec4..08f540f072b8 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1463,8 +1463,8 @@ static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) /* Determine interrupting queues, clear interrupt status * register and acknowledge the device interrupt. */ - BUILD_BUG_ON(INT_EVQS_WIDTH > EFX_MAX_CHANNELS); - queues = EFX_OWORD_FIELD(*int_ker, INT_EVQS); + BUILD_BUG_ON(FSF_AZ_NET_IVEC_INT_Q_WIDTH > EFX_MAX_CHANNELS); + queues = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_INT_Q); EFX_ZERO_OWORD(*int_ker); wmb(); /* Ensure the vector is cleared before interrupt ack */ falcon_irq_ack_a1(efx); @@ -1500,7 +1500,7 @@ static irqreturn_t falcon_msi_interrupt(int irq, void *dev_id) irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker)); /* Check to see if we have a serious error condition */ - syserr = EFX_OWORD_FIELD(*int_ker, FATAL_INT); + syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); if (unlikely(syserr)) return falcon_fatal_interrupt(efx); -- cgit v1.2.2 From 4b0d29dcfca9eafbf6e940862ab022df3ef2dd6f Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 03:42:18 +0000 Subject: sfc: Turn pause frame generation on and off at the MAC, not the RX FIFO Pause frame generation is gated by both RX_XOFF_MAC_EN and an enable bit in each MAC. RX_XOFF_MAC_EN bit always reads back as 0 so we need to set it correctly every time we modify RX_CFG_REG. Simplify this by always setting it to 1 and only changing the enable bits in the MACs. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 08f540f072b8..040f553de665 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1939,7 +1939,6 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) struct efx_link_state *link_state = &efx->link_state; efx_oword_t reg; int link_speed; - bool tx_fc; switch (link_state->speed) { case 10000: link_speed = 3; break; @@ -1969,13 +1968,10 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) /* Restore the multicast hash registers. */ falcon_push_multicast_hash(efx); - /* Transmission of pause frames when RX crosses the threshold is - * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL. - * Action on receipt of pause frames is controller by XM_DIS_FCNTL */ - tx_fc = !!(efx->link_state.fc & EFX_FC_TX); efx_reado(efx, ®, FR_AZ_RX_CFG); - EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, tx_fc); - + /* Enable XOFF signal from RX FIFO (we enabled it during NIC + * initialisation but it may read back as 0) */ + EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, 1); /* Unisolate the MAC -> RX */ if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1); @@ -3000,6 +2996,9 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_TX_TH, ctrl_xoff_thr); EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1); } + /* Always enable XOFF signal from RX FIFO. We enable + * or disable transmission of pause frames at the MAC. */ + EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, 1); efx_writeo(efx, ®, FR_AZ_RX_CFG); } -- cgit v1.2.2 From ef2b90ee4dba7a3d9001f1f0003b860b39a4aaae Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 03:42:31 +0000 Subject: sfc: Move Falcon NIC operations to efx_nic_type This is preparation for adding differing implementations for new NICs. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 79 ++++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 29 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 040f553de665..f6d10213d0b7 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1041,7 +1041,7 @@ int falcon_process_eventq(struct efx_channel *channel, int rx_quota) return rx_packets; } -void falcon_set_int_moderation(struct efx_channel *channel) +static void falcon_push_irq_moderation(struct efx_channel *channel) { efx_dword_t timer_cmd; struct efx_nic *efx = channel->efx; @@ -1098,7 +1098,7 @@ void falcon_init_eventq(struct efx_channel *channel) efx_writeo_table(efx, &evq_ptr, efx->type->evq_ptr_tbl_base, channel->channel); - falcon_set_int_moderation(channel); + falcon_push_irq_moderation(channel); } void falcon_fini_eventq(struct efx_channel *channel) @@ -1212,7 +1212,8 @@ int falcon_flush_queues(struct efx_nic *efx) struct efx_tx_queue *tx_queue; int i, tx_pending, rx_pending; - falcon_prepare_flush(efx); + /* If necessary prepare the hardware for flushing */ + efx->type->prepare_flush(efx); /* Flush all tx queues in parallel */ efx_for_each_tx_queue(tx_queue, efx) @@ -1825,6 +1826,16 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, ************************************************************************** */ +static void falcon_push_multicast_hash(struct efx_nic *efx) +{ + union efx_multicast_hash *mc_hash = &efx->multicast_hash; + + WARN_ON(!mutex_is_locked(&efx->mac_lock)); + + efx_writeo(efx, &mc_hash->oword[0], FR_AB_MAC_MC_HASH_REG0); + efx_writeo(efx, &mc_hash->oword[1], FR_AB_MAC_MC_HASH_REG1); +} + static int falcon_reset_macs(struct efx_nic *efx) { efx_oword_t reg; @@ -2240,7 +2251,7 @@ out: } /* This call is responsible for hooking in the MAC and PHY operations */ -int falcon_probe_port(struct efx_nic *efx) +static int falcon_probe_port(struct efx_nic *efx) { int rc; @@ -2299,29 +2310,11 @@ int falcon_probe_port(struct efx_nic *efx) return 0; } -void falcon_remove_port(struct efx_nic *efx) +static void falcon_remove_port(struct efx_nic *efx) { falcon_free_buffer(efx, &efx->stats_buffer); } -/************************************************************************** - * - * Multicast filtering - * - ************************************************************************** - */ - -void falcon_push_multicast_hash(struct efx_nic *efx) -{ - union efx_multicast_hash *mc_hash = &efx->multicast_hash; - - WARN_ON(!mutex_is_locked(&efx->mac_lock)); - - efx_writeo(efx, &mc_hash->oword[0], FR_AB_MAC_MC_HASH_REG0); - efx_writeo(efx, &mc_hash->oword[1], FR_AB_MAC_MC_HASH_REG1); -} - - /************************************************************************** * * Falcon test code @@ -2503,7 +2496,7 @@ fail: /* Resets NIC to known state. This routine must be called in process * context and is allowed to sleep. */ -int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) +static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) { struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t glb_ctl_reg_ker; @@ -2592,7 +2585,7 @@ fail5: return rc; } -void falcon_monitor(struct efx_nic *efx) +static void falcon_monitor(struct efx_nic *efx) { bool link_changed; int rc; @@ -2850,7 +2843,7 @@ static void falcon_probe_spi_devices(struct efx_nic *efx) large_eeprom_type); } -int falcon_probe_nic(struct efx_nic *efx) +static int falcon_probe_nic(struct efx_nic *efx) { struct falcon_nic_data *nic_data; struct falcon_board *board; @@ -3006,7 +2999,7 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) * defining the descriptor cache sizes and number of RSS channels. * It does not set up any buffers, descriptor rings or event queues. */ -int falcon_init_nic(struct efx_nic *efx) +static int falcon_init_nic(struct efx_nic *efx) { efx_oword_t temp; int rc; @@ -3139,7 +3132,7 @@ int falcon_init_nic(struct efx_nic *efx) return 0; } -void falcon_remove_nic(struct efx_nic *efx) +static void falcon_remove_nic(struct efx_nic *efx) { struct falcon_nic_data *nic_data = efx->nic_data; struct falcon_board *board = falcon_board(efx); @@ -3168,7 +3161,7 @@ void falcon_remove_nic(struct efx_nic *efx) efx->nic_data = NULL; } -void falcon_update_nic_stats(struct efx_nic *efx) +static void falcon_update_nic_stats(struct efx_nic *efx) { struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t cnt; @@ -3232,6 +3225,20 @@ void falcon_stop_nic_stats(struct efx_nic *efx) */ struct efx_nic_type falcon_a1_nic_type = { + .probe = falcon_probe_nic, + .remove = falcon_remove_nic, + .init = falcon_init_nic, + .fini = efx_port_dummy_op_void, + .monitor = falcon_monitor, + .reset = falcon_reset_hw, + .probe_port = falcon_probe_port, + .remove_port = falcon_remove_port, + .prepare_flush = falcon_prepare_flush, + .update_stats = falcon_update_nic_stats, + .start_stats = falcon_start_nic_stats, + .stop_stats = falcon_stop_nic_stats, + .push_irq_moderation = falcon_push_irq_moderation, + .push_multicast_hash = falcon_push_multicast_hash, .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_A1, @@ -3250,6 +3257,20 @@ struct efx_nic_type falcon_a1_nic_type = { }; struct efx_nic_type falcon_b0_nic_type = { + .probe = falcon_probe_nic, + .remove = falcon_remove_nic, + .init = falcon_init_nic, + .fini = efx_port_dummy_op_void, + .monitor = falcon_monitor, + .reset = falcon_reset_hw, + .probe_port = falcon_probe_port, + .remove_port = falcon_remove_port, + .prepare_flush = falcon_prepare_flush, + .update_stats = falcon_update_nic_stats, + .start_stats = falcon_start_nic_stats, + .stop_stats = falcon_stop_nic_stats, + .push_irq_moderation = falcon_push_irq_moderation, + .push_multicast_hash = falcon_push_multicast_hash, .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_B0, -- cgit v1.2.2 From d3245b28ef2a45ec4e115062a38100bd06229289 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 03:42:41 +0000 Subject: sfc: Refactor link configuration Refactor PHY, MAC and NIC configuration operations so that the existing link configuration can be re-pushed with: efx->phy_op->reconfigure(efx); efx->mac_op->reconfigure(efx); and a new configuration with: efx->nic_op->reconfigure_port(efx); (plus locking and error-checking). We have not held the link settings in software (aside from flow control), and have relied on asking the hardware what they are. This is a problem because in some cases the hardware may no longer be in a state to tell us. In particular, if an entire multi-port board is reset through one port, the driver bindings to other ports have no chance to save settings before recovering. We only actually need to keep track of the autonegotiation settings, so add an ethtool advertising mask to struct efx_nic, initialise it in PHY init and update it as necessary. Remove now-unneeded uses of efx_phy_op::{get,set}_settings() and struct ethtool_cmd. Much of this was done by Steve Hodgson . Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 98 +++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 35 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index f6d10213d0b7..3466616c01c0 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1193,6 +1193,8 @@ static void falcon_poll_flush_events(struct efx_nic *efx) channel->eventq_read_ptr = read_ptr; } +static void falcon_deconfigure_mac_wrapper(struct efx_nic *efx); + static void falcon_prepare_flush(struct efx_nic *efx) { falcon_deconfigure_mac_wrapper(efx); @@ -1836,9 +1838,10 @@ static void falcon_push_multicast_hash(struct efx_nic *efx) efx_writeo(efx, &mc_hash->oword[1], FR_AB_MAC_MC_HASH_REG1); } -static int falcon_reset_macs(struct efx_nic *efx) +static void falcon_reset_macs(struct efx_nic *efx) { - efx_oword_t reg; + struct falcon_nic_data *nic_data = efx->nic_data; + efx_oword_t reg, mac_ctrl; int count; if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) { @@ -1853,7 +1856,7 @@ static int falcon_reset_macs(struct efx_nic *efx) EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 0); efx_writeo(efx, ®, FR_AB_GM_CFG1); udelay(1000); - return 0; + return; } else { EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1); efx_writeo(efx, ®, FR_AB_XM_GLB_CFG); @@ -1862,22 +1865,20 @@ static int falcon_reset_macs(struct efx_nic *efx) efx_reado(efx, ®, FR_AB_XM_GLB_CFG); if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) == 0) - return 0; + return; udelay(10); } EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); - return -ETIMEDOUT; } } - /* MAC stats will fail whilst the TX fifo is draining. Serialise - * the drain sequence with the statistics fetch */ - falcon_stop_nic_stats(efx); + /* Mac stats will fail whist the TX fifo is draining */ + WARN_ON(nic_data->stats_disable_count == 0); - efx_reado(efx, ®, FR_AB_MAC_CTRL); - EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN, 1); - efx_writeo(efx, ®, FR_AB_MAC_CTRL); + efx_reado(efx, &mac_ctrl, FR_AB_MAC_CTRL); + EFX_SET_OWORD_FIELD(mac_ctrl, FRF_BB_TXFIFO_DRAIN_EN, 1); + efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL); efx_reado(efx, ®, FR_AB_GLB_CTL); EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGTX, 1); @@ -1903,14 +1904,9 @@ static int falcon_reset_macs(struct efx_nic *efx) udelay(10); } - /* If we've reset the EM block and the link is up, then - * we'll have to kick the XAUI link so the PHY can recover */ - if (efx->link_state.up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx)) - falcon_reset_xaui(efx); - - falcon_start_nic_stats(efx); - - return 0; + /* Ensure the correct MAC is selected before statistics + * are re-enabled by the caller */ + efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL); } void falcon_drain_tx_fifo(struct efx_nic *efx) @@ -1929,7 +1925,7 @@ void falcon_drain_tx_fifo(struct efx_nic *efx) falcon_reset_macs(efx); } -void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) +static void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) { efx_oword_t reg; @@ -1941,8 +1937,8 @@ void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 0); efx_writeo(efx, ®, FR_AZ_RX_CFG); - if (!efx->link_state.up) - falcon_drain_tx_fifo(efx); + /* Isolate TX -> MAC */ + falcon_drain_tx_fifo(efx); } void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) @@ -2044,6 +2040,8 @@ static void falcon_stats_timer_func(unsigned long context) spin_unlock(&efx->stats_lock); } +static void falcon_switch_mac(struct efx_nic *efx); + static bool falcon_loopback_link_poll(struct efx_nic *efx) { struct efx_link_state old_state = efx->link_state; @@ -2063,6 +2061,38 @@ static bool falcon_loopback_link_poll(struct efx_nic *efx) return !efx_link_state_equal(&efx->link_state, &old_state); } +static int falcon_reconfigure_port(struct efx_nic *efx) +{ + int rc; + + WARN_ON(efx_nic_rev(efx) > EFX_REV_FALCON_B0); + + /* Poll the PHY link state *before* reconfiguring it. This means we + * will pick up the correct speed (in loopback) to select the correct + * MAC. + */ + if (LOOPBACK_INTERNAL(efx)) + falcon_loopback_link_poll(efx); + else + efx->phy_op->poll(efx); + + falcon_stop_nic_stats(efx); + falcon_deconfigure_mac_wrapper(efx); + + falcon_switch_mac(efx); + + efx->phy_op->reconfigure(efx); + rc = efx->mac_op->reconfigure(efx); + BUG_ON(rc); + + falcon_start_nic_stats(efx); + + /* Synchronise efx->link_state with the kernel */ + efx_link_status_changed(efx); + + return 0; +} + /************************************************************************** * * PHY access via GMII @@ -2215,17 +2245,15 @@ static void falcon_clock_mac(struct efx_nic *efx) } } -int falcon_switch_mac(struct efx_nic *efx) +static void falcon_switch_mac(struct efx_nic *efx) { struct efx_mac_operations *old_mac_op = efx->mac_op; struct falcon_nic_data *nic_data = efx->nic_data; unsigned int stats_done_offset; - int rc = 0; - - /* Don't try to fetch MAC stats while we're switching MACs */ - falcon_stop_nic_stats(efx); WARN_ON(!mutex_is_locked(&efx->mac_lock)); + WARN_ON(nic_data->stats_disable_count == 0); + efx->mac_op = (EFX_IS10G(efx) ? &falcon_xmac_operations : &falcon_gmac_operations); @@ -2236,18 +2264,14 @@ int falcon_switch_mac(struct efx_nic *efx) nic_data->stats_dma_done = efx->stats_buffer.addr + stats_done_offset; if (old_mac_op == efx->mac_op) - goto out; + return; falcon_clock_mac(efx); EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); /* Not all macs support a mac-level link state */ efx->xmac_poll_required = false; - - rc = falcon_reset_macs(efx); -out: - falcon_start_nic_stats(efx); - return rc; + falcon_reset_macs(efx); } /* This call is responsible for hooking in the MAC and PHY operations */ @@ -2597,7 +2621,8 @@ static void falcon_monitor(struct efx_nic *efx) EFX_ERR(efx, "Board sensor %s; shutting down PHY\n", (rc == -ERANGE) ? "reported fault" : "failed"); efx->phy_mode |= PHY_MODE_LOW_POWER; - __efx_reconfigure_port(efx); + rc = __efx_reconfigure_port(efx); + WARN_ON(rc); } if (LOOPBACK_INTERNAL(efx)) @@ -2610,7 +2635,8 @@ static void falcon_monitor(struct efx_nic *efx) falcon_deconfigure_mac_wrapper(efx); falcon_switch_mac(efx); - efx->mac_op->reconfigure(efx); + rc = efx->mac_op->reconfigure(efx); + BUG_ON(rc); falcon_start_nic_stats(efx); @@ -3239,6 +3265,7 @@ struct efx_nic_type falcon_a1_nic_type = { .stop_stats = falcon_stop_nic_stats, .push_irq_moderation = falcon_push_irq_moderation, .push_multicast_hash = falcon_push_multicast_hash, + .reconfigure_port = falcon_reconfigure_port, .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_A1, @@ -3271,6 +3298,7 @@ struct efx_nic_type falcon_b0_nic_type = { .stop_stats = falcon_stop_nic_stats, .push_irq_moderation = falcon_push_irq_moderation, .push_multicast_hash = falcon_push_multicast_hash, + .reconfigure_port = falcon_reconfigure_port, .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_B0, -- cgit v1.2.2 From 89c758fa47b54d8ce10d2b39ed09de6da0ba4324 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 03:43:07 +0000 Subject: sfc: Add power-management and wake-on-LAN support Wake-on-LAN is a stub for Falcon, but will be implemented fully for new NICs. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 3466616c01c0..8f2c58305538 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -3243,6 +3243,27 @@ void falcon_stop_nic_stats(struct efx_nic *efx) spin_unlock_bh(&efx->stats_lock); } +/************************************************************************** + * + * Wake on LAN + * + ************************************************************************** + */ + +static void falcon_get_wol(struct efx_nic *efx, struct ethtool_wolinfo *wol) +{ + wol->supported = 0; + wol->wolopts = 0; + memset(&wol->sopass, 0, sizeof(wol->sopass)); +} + +static int falcon_set_wol(struct efx_nic *efx, u32 type) +{ + if (type != 0) + return -EINVAL; + return 0; +} + /************************************************************************** * * Revision-dependent attributes used by efx.c @@ -3266,6 +3287,9 @@ struct efx_nic_type falcon_a1_nic_type = { .push_irq_moderation = falcon_push_irq_moderation, .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, + .get_wol = falcon_get_wol, + .set_wol = falcon_set_wol, + .resume_wol = efx_port_dummy_op_void, .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_A1, @@ -3299,6 +3323,9 @@ struct efx_nic_type falcon_b0_nic_type = { .push_irq_moderation = falcon_push_irq_moderation, .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, + .get_wol = falcon_get_wol, + .set_wol = falcon_set_wol, + .resume_wol = efx_port_dummy_op_void, .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_B0, -- cgit v1.2.2 From eb9f6744cbfa97674c13263802259b5aa0034594 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 03:43:15 +0000 Subject: sfc: Implement ethtool reset operation Refactor efx_reset_down() and efx_reset_up() accordingly. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 8f2c58305538..6a96c699e15b 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -3305,6 +3305,7 @@ struct efx_nic_type falcon_a1_nic_type = { .phys_addr_channels = 4, .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, + .reset_world_flags = ETH_RESET_IRQ, }; struct efx_nic_type falcon_b0_nic_type = { @@ -3348,5 +3349,6 @@ struct efx_nic_type falcon_b0_nic_type = { * channels */ .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, + .reset_world_flags = ETH_RESET_IRQ, }; -- cgit v1.2.2 From 9bfc4bb1f9b5863b177752b88e8bfa364e83a4fa Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 03:43:23 +0000 Subject: sfc: Add efx_nic_type operation for register self-test Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 6a96c699e15b..bcdc5452bfd0 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2458,7 +2458,7 @@ static bool efx_masked_compare_oword(const efx_oword_t *a, const efx_oword_t *b, ((a->u64[1] ^ b->u64[1]) & mask->u64[1]); } -int falcon_test_registers(struct efx_nic *efx) +static int falcon_b0_test_registers(struct efx_nic *efx) { unsigned address = 0, i, j; efx_oword_t mask, imask, original, reg, buf; @@ -3327,6 +3327,7 @@ struct efx_nic_type falcon_b0_nic_type = { .get_wol = falcon_get_wol, .set_wol = falcon_set_wol, .resume_wol = efx_port_dummy_op_void, + .test_registers = falcon_b0_test_registers, .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_B0, -- cgit v1.2.2 From 0aa3fbaa3f2d29a14231ebb0c8e521c23701d41f Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 03:43:33 +0000 Subject: sfc: Add efx_nic_type operation for NVRAM self-test Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index bcdc5452bfd0..d4d13c13f8ae 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2345,7 +2345,8 @@ static void falcon_remove_port(struct efx_nic *efx) * **************************************************************************/ -int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) +static int +falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) { struct falcon_nvconfig *nvconfig; struct efx_spi_device *spi; @@ -2408,6 +2409,11 @@ int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) return rc; } +static int falcon_test_nvram(struct efx_nic *efx) +{ + return falcon_read_nvram(efx, NULL); +} + /* Registers tested in the falcon register test */ static struct { unsigned address; @@ -3290,6 +3296,7 @@ struct efx_nic_type falcon_a1_nic_type = { .get_wol = falcon_get_wol, .set_wol = falcon_set_wol, .resume_wol = efx_port_dummy_op_void, + .test_nvram = falcon_test_nvram, .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_A1, @@ -3328,6 +3335,7 @@ struct efx_nic_type falcon_b0_nic_type = { .set_wol = falcon_set_wol, .resume_wol = efx_port_dummy_op_void, .test_registers = falcon_b0_test_registers, + .test_nvram = falcon_test_nvram, .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_B0, -- cgit v1.2.2 From 06629f07248b259e08a6e4089fbe6aa3f98dfbe6 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 03:43:43 +0000 Subject: sfc: Add efx_nic_type operation for identity LED control Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index d4d13c13f8ae..61cc9948b233 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -3249,6 +3249,11 @@ void falcon_stop_nic_stats(struct efx_nic *efx) spin_unlock_bh(&efx->stats_lock); } +static void falcon_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) +{ + falcon_board(efx)->type->set_id_led(efx, mode); +} + /************************************************************************** * * Wake on LAN @@ -3290,6 +3295,7 @@ struct efx_nic_type falcon_a1_nic_type = { .update_stats = falcon_update_nic_stats, .start_stats = falcon_start_nic_stats, .stop_stats = falcon_stop_nic_stats, + .set_id_led = falcon_set_id_led, .push_irq_moderation = falcon_push_irq_moderation, .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, @@ -3328,6 +3334,7 @@ struct efx_nic_type falcon_b0_nic_type = { .update_stats = falcon_update_nic_stats, .start_stats = falcon_start_nic_stats, .stop_stats = falcon_stop_nic_stats, + .set_id_led = falcon_set_id_led, .push_irq_moderation = falcon_push_irq_moderation, .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, -- cgit v1.2.2 From 152b6a62aea2d43359dd37004e9c218bf7bdeb3b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 03:43:56 +0000 Subject: sfc: Separate shared NIC code from Falcon-specific and rename accordingly Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 507 ++++++++++++++++++++++++----------------------- 1 file changed, 259 insertions(+), 248 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 61cc9948b233..2e4c71114630 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -69,8 +69,8 @@ default_flash_type = ((17 << SPI_DEV_TYPE_SIZE_LBN) * watermark send XOFF. Only used if RX flow control is enabled (ethtool -A) * This also has an effect on RX/TX arbitration */ -static int rx_xoff_thresh_bytes = -1; -module_param(rx_xoff_thresh_bytes, int, 0644); +int efx_nic_rx_xoff_thresh = -1; +module_param_named(rx_xoff_thresh_bytes, efx_nic_rx_xoff_thresh, int, 0644); MODULE_PARM_DESC(rx_xoff_thresh_bytes, "RX fifo XOFF threshold"); /* RX FIFO XON watermark @@ -79,21 +79,21 @@ MODULE_PARM_DESC(rx_xoff_thresh_bytes, "RX fifo XOFF threshold"); * watermark send XON. Only used if TX flow control is enabled (ethtool -A) * This also has an effect on RX/TX arbitration */ -static int rx_xon_thresh_bytes = -1; -module_param(rx_xon_thresh_bytes, int, 0644); +int efx_nic_rx_xon_thresh = -1; +module_param_named(rx_xon_thresh_bytes, efx_nic_rx_xon_thresh, int, 0644); MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); -/* If FALCON_MAX_INT_ERRORS internal errors occur within - * FALCON_INT_ERROR_EXPIRE seconds, we consider the NIC broken and +/* If EFX_MAX_INT_ERRORS internal errors occur within + * EFX_INT_ERROR_EXPIRE seconds, we consider the NIC broken and * disable it. */ -#define FALCON_INT_ERROR_EXPIRE 3600 -#define FALCON_MAX_INT_ERRORS 5 +#define EFX_INT_ERROR_EXPIRE 3600 +#define EFX_MAX_INT_ERRORS 5 /* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times */ -#define FALCON_FLUSH_INTERVAL 10 -#define FALCON_FLUSH_POLL_COUNT 100 +#define EFX_FLUSH_INTERVAL 10 +#define EFX_FLUSH_POLL_COUNT 100 /************************************************************************** * @@ -103,30 +103,27 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); */ /* Size and alignment of special buffers (4KB) */ -#define FALCON_BUF_SIZE 4096 +#define EFX_BUF_SIZE 4096 /* Depth of RX flush request fifo */ -#define FALCON_RX_FLUSH_COUNT 4 - -#define FALCON_IS_DUAL_FUNC(efx) \ - (efx_nic_rev(efx) < EFX_REV_FALCON_B0) +#define EFX_RX_FLUSH_COUNT 4 /************************************************************************** * - * Falcon hardware access + * Solarstorm hardware access * **************************************************************************/ -static inline void falcon_write_buf_tbl(struct efx_nic *efx, efx_qword_t *value, - unsigned int index) +static inline void efx_write_buf_tbl(struct efx_nic *efx, efx_qword_t *value, + unsigned int index) { efx_sram_writeq(efx, efx->membase + efx->type->buf_tbl_base, value, index); } /* Read the current event from the event queue */ -static inline efx_qword_t *falcon_event(struct efx_channel *channel, - unsigned int index) +static inline efx_qword_t *efx_event(struct efx_channel *channel, + unsigned int index) { return (((efx_qword_t *) (channel->eventq.addr)) + index); } @@ -141,7 +138,7 @@ static inline efx_qword_t *falcon_event(struct efx_channel *channel, * Note that using a single 64-bit comparison is incorrect; even * though the CPU read will be atomic, the DMA write may not be. */ -static inline int falcon_event_present(efx_qword_t *event) +static inline int efx_event_present(efx_qword_t *event) { return (!(EFX_DWORD_IS_ALL_ONES(event->dword[0]) | EFX_DWORD_IS_ALL_ONES(event->dword[1]))); @@ -205,22 +202,21 @@ static struct i2c_algo_bit_data falcon_i2c_bit_operations = { /************************************************************************** * - * Falcon special buffer handling + * Special buffer handling * Special buffers are used for event queues and the TX and RX * descriptor rings. * *************************************************************************/ /* - * Initialise a Falcon special buffer + * Initialise a special buffer * * This will define a buffer (previously allocated via - * falcon_alloc_special_buffer()) in Falcon's buffer table, allowing + * efx_alloc_special_buffer()) in the buffer table, allowing * it to be used for event queues, descriptor rings etc. */ static void -falcon_init_special_buffer(struct efx_nic *efx, - struct efx_special_buffer *buffer) +efx_init_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer) { efx_qword_t buf_desc; int index; @@ -239,14 +235,13 @@ falcon_init_special_buffer(struct efx_nic *efx, FRF_AZ_BUF_ADR_REGION, 0, FRF_AZ_BUF_ADR_FBUF, dma_addr >> 12, FRF_AZ_BUF_OWNER_ID_FBUF, 0); - falcon_write_buf_tbl(efx, &buf_desc, index); + efx_write_buf_tbl(efx, &buf_desc, index); } } -/* Unmaps a buffer from Falcon and clears the buffer table entries */ +/* Unmaps a buffer and clears the buffer table entries */ static void -falcon_fini_special_buffer(struct efx_nic *efx, - struct efx_special_buffer *buffer) +efx_fini_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer) { efx_oword_t buf_tbl_upd; unsigned int start = buffer->index; @@ -267,27 +262,27 @@ falcon_fini_special_buffer(struct efx_nic *efx, } /* - * Allocate a new Falcon special buffer + * Allocate a new special buffer * * This allocates memory for a new buffer, clears it and allocates a - * new buffer ID range. It does not write into Falcon's buffer table. + * new buffer ID range. It does not write into the buffer table. * - * This call will allocate 4KB buffers, since Falcon can't use 8KB - * buffers for event queues and descriptor rings. + * This call will allocate 4KB buffers, since 8KB buffers can't be + * used for event queues and descriptor rings. */ -static int falcon_alloc_special_buffer(struct efx_nic *efx, - struct efx_special_buffer *buffer, - unsigned int len) +static int efx_alloc_special_buffer(struct efx_nic *efx, + struct efx_special_buffer *buffer, + unsigned int len) { - len = ALIGN(len, FALCON_BUF_SIZE); + len = ALIGN(len, EFX_BUF_SIZE); buffer->addr = pci_alloc_consistent(efx->pci_dev, len, &buffer->dma_addr); if (!buffer->addr) return -ENOMEM; buffer->len = len; - buffer->entries = len / FALCON_BUF_SIZE; - BUG_ON(buffer->dma_addr & (FALCON_BUF_SIZE - 1)); + buffer->entries = len / EFX_BUF_SIZE; + BUG_ON(buffer->dma_addr & (EFX_BUF_SIZE - 1)); /* All zeros is a potentially valid event so memset to 0xff */ memset(buffer->addr, 0xff, len); @@ -305,8 +300,8 @@ static int falcon_alloc_special_buffer(struct efx_nic *efx, return 0; } -static void falcon_free_special_buffer(struct efx_nic *efx, - struct efx_special_buffer *buffer) +static void +efx_free_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer) { if (!buffer->addr) return; @@ -325,13 +320,13 @@ static void falcon_free_special_buffer(struct efx_nic *efx, /************************************************************************** * - * Falcon generic buffer handling + * Generic buffer handling * These buffers are used for interrupt status and MAC stats * **************************************************************************/ -static int falcon_alloc_buffer(struct efx_nic *efx, - struct efx_buffer *buffer, unsigned int len) +int efx_nic_alloc_buffer(struct efx_nic *efx, struct efx_buffer *buffer, + unsigned int len) { buffer->addr = pci_alloc_consistent(efx->pci_dev, len, &buffer->dma_addr); @@ -342,7 +337,7 @@ static int falcon_alloc_buffer(struct efx_nic *efx, return 0; } -static void falcon_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer) +void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer) { if (buffer->addr) { pci_free_consistent(efx->pci_dev, buffer->len, @@ -353,21 +348,21 @@ static void falcon_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer) /************************************************************************** * - * Falcon TX path + * TX path * **************************************************************************/ /* Returns a pointer to the specified transmit descriptor in the TX * descriptor queue belonging to the specified channel. */ -static inline efx_qword_t *falcon_tx_desc(struct efx_tx_queue *tx_queue, - unsigned int index) +static inline efx_qword_t * +efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index) { return (((efx_qword_t *) (tx_queue->txd.addr)) + index); } /* This writes to the TX_DESC_WPTR; write pointer for TX descriptor ring */ -static inline void falcon_notify_tx_desc(struct efx_tx_queue *tx_queue) +static inline void efx_notify_tx_desc(struct efx_tx_queue *tx_queue) { unsigned write_ptr; efx_dword_t reg; @@ -383,7 +378,7 @@ static inline void falcon_notify_tx_desc(struct efx_tx_queue *tx_queue) * descriptor in the hardware TX descriptor ring (in host memory), and * write a doorbell. */ -void falcon_push_buffers(struct efx_tx_queue *tx_queue) +void efx_nic_push_buffers(struct efx_tx_queue *tx_queue) { struct efx_tx_buffer *buffer; @@ -395,7 +390,7 @@ void falcon_push_buffers(struct efx_tx_queue *tx_queue) do { write_ptr = tx_queue->write_count & EFX_TXQ_MASK; buffer = &tx_queue->buffer[write_ptr]; - txd = falcon_tx_desc(tx_queue, write_ptr); + txd = efx_tx_desc(tx_queue, write_ptr); ++tx_queue->write_count; /* Create TX descriptor ring entry */ @@ -407,20 +402,20 @@ void falcon_push_buffers(struct efx_tx_queue *tx_queue) } while (tx_queue->write_count != tx_queue->insert_count); wmb(); /* Ensure descriptors are written before they are fetched */ - falcon_notify_tx_desc(tx_queue); + efx_notify_tx_desc(tx_queue); } /* Allocate hardware resources for a TX queue */ -int falcon_probe_tx(struct efx_tx_queue *tx_queue) +int efx_nic_probe_tx(struct efx_tx_queue *tx_queue) { struct efx_nic *efx = tx_queue->efx; BUILD_BUG_ON(EFX_TXQ_SIZE < 512 || EFX_TXQ_SIZE > 4096 || EFX_TXQ_SIZE & EFX_TXQ_MASK); - return falcon_alloc_special_buffer(efx, &tx_queue->txd, - EFX_TXQ_SIZE * sizeof(efx_qword_t)); + return efx_alloc_special_buffer(efx, &tx_queue->txd, + EFX_TXQ_SIZE * sizeof(efx_qword_t)); } -void falcon_init_tx(struct efx_tx_queue *tx_queue) +void efx_nic_init_tx(struct efx_tx_queue *tx_queue) { efx_oword_t tx_desc_ptr; struct efx_nic *efx = tx_queue->efx; @@ -428,7 +423,7 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) tx_queue->flushed = FLUSH_NONE; /* Pin TX descriptor ring */ - falcon_init_special_buffer(efx, &tx_queue->txd); + efx_init_special_buffer(efx, &tx_queue->txd); /* Push TX descriptor ring to card */ EFX_POPULATE_OWORD_10(tx_desc_ptr, @@ -470,7 +465,7 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) } } -static void falcon_flush_tx_queue(struct efx_tx_queue *tx_queue) +static void efx_flush_tx_queue(struct efx_tx_queue *tx_queue) { struct efx_nic *efx = tx_queue->efx; efx_oword_t tx_flush_descq; @@ -484,7 +479,7 @@ static void falcon_flush_tx_queue(struct efx_tx_queue *tx_queue) efx_writeo(efx, &tx_flush_descq, FR_AZ_TX_FLUSH_DESCQ); } -void falcon_fini_tx(struct efx_tx_queue *tx_queue) +void efx_nic_fini_tx(struct efx_tx_queue *tx_queue) { struct efx_nic *efx = tx_queue->efx; efx_oword_t tx_desc_ptr; @@ -498,36 +493,36 @@ void falcon_fini_tx(struct efx_tx_queue *tx_queue) tx_queue->queue); /* Unpin TX descriptor ring */ - falcon_fini_special_buffer(efx, &tx_queue->txd); + efx_fini_special_buffer(efx, &tx_queue->txd); } /* Free buffers backing TX queue */ -void falcon_remove_tx(struct efx_tx_queue *tx_queue) +void efx_nic_remove_tx(struct efx_tx_queue *tx_queue) { - falcon_free_special_buffer(tx_queue->efx, &tx_queue->txd); + efx_free_special_buffer(tx_queue->efx, &tx_queue->txd); } /************************************************************************** * - * Falcon RX path + * RX path * **************************************************************************/ /* Returns a pointer to the specified descriptor in the RX descriptor queue */ -static inline efx_qword_t *falcon_rx_desc(struct efx_rx_queue *rx_queue, - unsigned int index) +static inline efx_qword_t * +efx_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index) { return (((efx_qword_t *) (rx_queue->rxd.addr)) + index); } /* This creates an entry in the RX descriptor queue */ -static inline void falcon_build_rx_desc(struct efx_rx_queue *rx_queue, - unsigned index) +static inline void +efx_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned index) { struct efx_rx_buffer *rx_buf; efx_qword_t *rxd; - rxd = falcon_rx_desc(rx_queue, index); + rxd = efx_rx_desc(rx_queue, index); rx_buf = efx_rx_buffer(rx_queue, index); EFX_POPULATE_QWORD_3(*rxd, FSF_AZ_RX_KER_BUF_SIZE, @@ -540,15 +535,15 @@ static inline void falcon_build_rx_desc(struct efx_rx_queue *rx_queue, /* This writes to the RX_DESC_WPTR register for the specified receive * descriptor ring. */ -void falcon_notify_rx_desc(struct efx_rx_queue *rx_queue) +void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue) { efx_dword_t reg; unsigned write_ptr; while (rx_queue->notified_count != rx_queue->added_count) { - falcon_build_rx_desc(rx_queue, - rx_queue->notified_count & - EFX_RXQ_MASK); + efx_build_rx_desc(rx_queue, + rx_queue->notified_count & + EFX_RXQ_MASK); ++rx_queue->notified_count; } @@ -559,16 +554,16 @@ void falcon_notify_rx_desc(struct efx_rx_queue *rx_queue) FR_AZ_RX_DESC_UPD_DWORD_P0, rx_queue->queue); } -int falcon_probe_rx(struct efx_rx_queue *rx_queue) +int efx_nic_probe_rx(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; BUILD_BUG_ON(EFX_RXQ_SIZE < 512 || EFX_RXQ_SIZE > 4096 || EFX_RXQ_SIZE & EFX_RXQ_MASK); - return falcon_alloc_special_buffer(efx, &rx_queue->rxd, - EFX_RXQ_SIZE * sizeof(efx_qword_t)); + return efx_alloc_special_buffer(efx, &rx_queue->rxd, + EFX_RXQ_SIZE * sizeof(efx_qword_t)); } -void falcon_init_rx(struct efx_rx_queue *rx_queue) +void efx_nic_init_rx(struct efx_rx_queue *rx_queue) { efx_oword_t rx_desc_ptr; struct efx_nic *efx = rx_queue->efx; @@ -582,7 +577,7 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue) rx_queue->flushed = FLUSH_NONE; /* Pin RX descriptor ring */ - falcon_init_special_buffer(efx, &rx_queue->rxd); + efx_init_special_buffer(efx, &rx_queue->rxd); /* Push RX descriptor ring to card */ EFX_POPULATE_OWORD_10(rx_desc_ptr, @@ -603,7 +598,7 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue) rx_queue->queue); } -static void falcon_flush_rx_queue(struct efx_rx_queue *rx_queue) +static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; efx_oword_t rx_flush_descq; @@ -617,7 +612,7 @@ static void falcon_flush_rx_queue(struct efx_rx_queue *rx_queue) efx_writeo(efx, &rx_flush_descq, FR_AZ_RX_FLUSH_DESCQ); } -void falcon_fini_rx(struct efx_rx_queue *rx_queue) +void efx_nic_fini_rx(struct efx_rx_queue *rx_queue) { efx_oword_t rx_desc_ptr; struct efx_nic *efx = rx_queue->efx; @@ -631,18 +626,18 @@ void falcon_fini_rx(struct efx_rx_queue *rx_queue) rx_queue->queue); /* Unpin RX descriptor ring */ - falcon_fini_special_buffer(efx, &rx_queue->rxd); + efx_fini_special_buffer(efx, &rx_queue->rxd); } /* Free buffers backing RX queue */ -void falcon_remove_rx(struct efx_rx_queue *rx_queue) +void efx_nic_remove_rx(struct efx_rx_queue *rx_queue) { - falcon_free_special_buffer(rx_queue->efx, &rx_queue->rxd); + efx_free_special_buffer(rx_queue->efx, &rx_queue->rxd); } /************************************************************************** * - * Falcon event queue processing + * Event queue processing * Event queues are processed by per-channel tasklets. * **************************************************************************/ @@ -656,7 +651,7 @@ void falcon_remove_rx(struct efx_rx_queue *rx_queue) * whereas channel->eventq_read_ptr contains the index of the "next to * read" event. */ -void falcon_eventq_read_ack(struct efx_channel *channel) +void efx_nic_eventq_read_ack(struct efx_channel *channel) { efx_dword_t reg; struct efx_nic *efx = channel->efx; @@ -667,7 +662,7 @@ void falcon_eventq_read_ack(struct efx_channel *channel) } /* Use HW to insert a SW defined event */ -void falcon_generate_event(struct efx_channel *channel, efx_qword_t *event) +void efx_generate_event(struct efx_channel *channel, efx_qword_t *event) { efx_oword_t drv_ev_reg; @@ -683,11 +678,11 @@ void falcon_generate_event(struct efx_channel *channel, efx_qword_t *event) /* Handle a transmit completion event * - * Falcon batches TX completion events; the message we receive is of + * The NIC batches TX completion events; the message we receive is of * the form "complete all TX events up to this index". */ -static void falcon_handle_tx_event(struct efx_channel *channel, - efx_qword_t *event) +static void +efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) { unsigned int tx_ev_desc_ptr; unsigned int tx_ev_q_label; @@ -710,7 +705,7 @@ static void falcon_handle_tx_event(struct efx_channel *channel, if (efx_dev_registered(efx)) netif_tx_lock(efx->net_dev); - falcon_notify_tx_desc(tx_queue); + efx_notify_tx_desc(tx_queue); if (efx_dev_registered(efx)) netif_tx_unlock(efx->net_dev); } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_PKT_ERR) && @@ -724,10 +719,10 @@ static void falcon_handle_tx_event(struct efx_channel *channel, } /* Detect errors included in the rx_evt_pkt_ok bit. */ -static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, - const efx_qword_t *event, - bool *rx_ev_pkt_ok, - bool *discard) +static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, + const efx_qword_t *event, + bool *rx_ev_pkt_ok, + bool *discard) { struct efx_nic *efx = rx_queue->efx; bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err; @@ -799,8 +794,8 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, } /* Handle receive events that are not in-order. */ -static void falcon_handle_rx_bad_index(struct efx_rx_queue *rx_queue, - unsigned index) +static void +efx_handle_rx_bad_index(struct efx_rx_queue *rx_queue, unsigned index) { struct efx_nic *efx = rx_queue->efx; unsigned expected, dropped; @@ -816,13 +811,13 @@ static void falcon_handle_rx_bad_index(struct efx_rx_queue *rx_queue, /* Handle a packet received event * - * Falcon silicon gives a "discard" flag if it's a unicast packet with the + * The NIC gives a "discard" flag if it's a unicast packet with the * wrong destination address * Also "is multicast" and "matches multicast filter" flags can be used to * discard non-matching multicast packets. */ -static void falcon_handle_rx_event(struct efx_channel *channel, - const efx_qword_t *event) +static void +efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) { unsigned int rx_ev_desc_ptr, rx_ev_byte_cnt; unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt; @@ -845,19 +840,18 @@ static void falcon_handle_rx_event(struct efx_channel *channel, rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR); expected_ptr = rx_queue->removed_count & EFX_RXQ_MASK; if (unlikely(rx_ev_desc_ptr != expected_ptr)) - falcon_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr); + efx_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr); if (likely(rx_ev_pkt_ok)) { - /* If packet is marked as OK and packet type is TCP/IPv4 or - * UDP/IPv4, then we can rely on the hardware checksum. + /* If packet is marked as OK and packet type is TCP/IP or + * UDP/IP, then we can rely on the hardware checksum. */ checksummed = likely(efx->rx_checksum_enabled) && - (rx_ev_hdr_type == FSE_AB_RX_EV_HDR_TYPE_IPV4_TCP || - rx_ev_hdr_type == FSE_AB_RX_EV_HDR_TYPE_IPV4_UDP); + (rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP || + rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP); } else { - falcon_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, - &discard); + efx_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard); checksummed = false; } @@ -881,8 +875,8 @@ static void falcon_handle_rx_event(struct efx_channel *channel, } /* Global events are basically PHY events */ -static void falcon_handle_global_event(struct efx_channel *channel, - efx_qword_t *event) +static void +efx_handle_global_event(struct efx_channel *channel, efx_qword_t *event) { struct efx_nic *efx = channel->efx; bool handled = false; @@ -918,8 +912,8 @@ static void falcon_handle_global_event(struct efx_channel *channel, EFX_QWORD_VAL(*event)); } -static void falcon_handle_driver_event(struct efx_channel *channel, - efx_qword_t *event) +static void +efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event) { struct efx_nic *efx = channel->efx; unsigned int ev_sub_code; @@ -980,7 +974,7 @@ static void falcon_handle_driver_event(struct efx_channel *channel, } } -int falcon_process_eventq(struct efx_channel *channel, int rx_quota) +int efx_nic_process_eventq(struct efx_channel *channel, int rx_quota) { unsigned int read_ptr; efx_qword_t event, *p_event; @@ -990,10 +984,10 @@ int falcon_process_eventq(struct efx_channel *channel, int rx_quota) read_ptr = channel->eventq_read_ptr; do { - p_event = falcon_event(channel, read_ptr); + p_event = efx_event(channel, read_ptr); event = *p_event; - if (!falcon_event_present(&event)) + if (!efx_event_present(&event)) /* End of events */ break; @@ -1007,11 +1001,11 @@ int falcon_process_eventq(struct efx_channel *channel, int rx_quota) switch (ev_code) { case FSE_AZ_EV_CODE_RX_EV: - falcon_handle_rx_event(channel, &event); + efx_handle_rx_event(channel, &event); ++rx_packets; break; case FSE_AZ_EV_CODE_TX_EV: - falcon_handle_tx_event(channel, &event); + efx_handle_tx_event(channel, &event); break; case FSE_AZ_EV_CODE_DRV_GEN_EV: channel->eventq_magic = EFX_QWORD_FIELD( @@ -1021,10 +1015,10 @@ int falcon_process_eventq(struct efx_channel *channel, int rx_quota) EFX_QWORD_VAL(event)); break; case FSE_AZ_EV_CODE_GLOBAL_EV: - falcon_handle_global_event(channel, &event); + efx_handle_global_event(channel, &event); break; case FSE_AZ_EV_CODE_DRIVER_EV: - falcon_handle_driver_event(channel, &event); + efx_handle_driver_event(channel, &event); break; default: EFX_ERR(channel->efx, "channel %d unknown event type %d" @@ -1066,16 +1060,16 @@ static void falcon_push_irq_moderation(struct efx_channel *channel) } /* Allocate buffer table entries for event queue */ -int falcon_probe_eventq(struct efx_channel *channel) +int efx_nic_probe_eventq(struct efx_channel *channel) { struct efx_nic *efx = channel->efx; BUILD_BUG_ON(EFX_EVQ_SIZE < 512 || EFX_EVQ_SIZE > 32768 || EFX_EVQ_SIZE & EFX_EVQ_MASK); - return falcon_alloc_special_buffer(efx, &channel->eventq, - EFX_EVQ_SIZE * sizeof(efx_qword_t)); + return efx_alloc_special_buffer(efx, &channel->eventq, + EFX_EVQ_SIZE * sizeof(efx_qword_t)); } -void falcon_init_eventq(struct efx_channel *channel) +void efx_nic_init_eventq(struct efx_channel *channel) { efx_oword_t evq_ptr; struct efx_nic *efx = channel->efx; @@ -1085,7 +1079,7 @@ void falcon_init_eventq(struct efx_channel *channel) channel->eventq.index + channel->eventq.entries - 1); /* Pin event queue buffer */ - falcon_init_special_buffer(efx, &channel->eventq); + efx_init_special_buffer(efx, &channel->eventq); /* Fill event queue with all ones (i.e. empty events) */ memset(channel->eventq.addr, 0xff, channel->eventq.len); @@ -1098,10 +1092,10 @@ void falcon_init_eventq(struct efx_channel *channel) efx_writeo_table(efx, &evq_ptr, efx->type->evq_ptr_tbl_base, channel->channel); - falcon_push_irq_moderation(channel); + efx->type->push_irq_moderation(channel); } -void falcon_fini_eventq(struct efx_channel *channel) +void efx_nic_fini_eventq(struct efx_channel *channel) { efx_oword_t eventq_ptr; struct efx_nic *efx = channel->efx; @@ -1112,13 +1106,13 @@ void falcon_fini_eventq(struct efx_channel *channel) channel->channel); /* Unpin event queue */ - falcon_fini_special_buffer(efx, &channel->eventq); + efx_fini_special_buffer(efx, &channel->eventq); } /* Free buffers backing event queue */ -void falcon_remove_eventq(struct efx_channel *channel) +void efx_nic_remove_eventq(struct efx_channel *channel) { - falcon_free_special_buffer(channel->efx, &channel->eventq); + efx_free_special_buffer(channel->efx, &channel->eventq); } @@ -1126,14 +1120,14 @@ void falcon_remove_eventq(struct efx_channel *channel) * process_eventq() should pick up the event and place the value of * "magic" into channel->eventq_magic; */ -void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic) +void efx_nic_generate_test_event(struct efx_channel *channel, unsigned int magic) { efx_qword_t test_event; EFX_POPULATE_QWORD_2(test_event, FSF_AZ_EV_CODE, FSE_AZ_EV_CODE_DRV_GEN_EV, FSF_AZ_DRV_GEN_EV_MAGIC, magic); - falcon_generate_event(channel, &test_event); + efx_generate_event(channel, &test_event); } /************************************************************************** @@ -1143,7 +1137,7 @@ void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic) **************************************************************************/ -static void falcon_poll_flush_events(struct efx_nic *efx) +static void efx_poll_flush_events(struct efx_nic *efx) { struct efx_channel *channel = &efx->channel[0]; struct efx_tx_queue *tx_queue; @@ -1152,11 +1146,11 @@ static void falcon_poll_flush_events(struct efx_nic *efx) unsigned int end_ptr = (read_ptr - 1) & EFX_EVQ_MASK; do { - efx_qword_t *event = falcon_event(channel, read_ptr); + efx_qword_t *event = efx_event(channel, read_ptr); int ev_code, ev_sub_code, ev_queue; bool ev_failed; - if (!falcon_event_present(event)) + if (!efx_event_present(event)) break; ev_code = EFX_QWORD_FIELD(*event, FSF_AZ_EV_CODE); @@ -1208,7 +1202,7 @@ static void falcon_prepare_flush(struct efx_nic *efx) /* Handle tx and rx flushes at the same time, since they run in * parallel in the hardware and there's no reason for us to * serialise them */ -int falcon_flush_queues(struct efx_nic *efx) +int efx_nic_flush_queues(struct efx_nic *efx) { struct efx_rx_queue *rx_queue; struct efx_tx_queue *tx_queue; @@ -1219,22 +1213,22 @@ int falcon_flush_queues(struct efx_nic *efx) /* Flush all tx queues in parallel */ efx_for_each_tx_queue(tx_queue, efx) - falcon_flush_tx_queue(tx_queue); + efx_flush_tx_queue(tx_queue); /* The hardware supports four concurrent rx flushes, each of which may * need to be retried if there is an outstanding descriptor fetch */ - for (i = 0; i < FALCON_FLUSH_POLL_COUNT; ++i) { + for (i = 0; i < EFX_FLUSH_POLL_COUNT; ++i) { rx_pending = tx_pending = 0; efx_for_each_rx_queue(rx_queue, efx) { if (rx_queue->flushed == FLUSH_PENDING) ++rx_pending; } efx_for_each_rx_queue(rx_queue, efx) { - if (rx_pending == FALCON_RX_FLUSH_COUNT) + if (rx_pending == EFX_RX_FLUSH_COUNT) break; if (rx_queue->flushed == FLUSH_FAILED || rx_queue->flushed == FLUSH_NONE) { - falcon_flush_rx_queue(rx_queue); + efx_flush_rx_queue(rx_queue); ++rx_pending; } } @@ -1246,8 +1240,8 @@ int falcon_flush_queues(struct efx_nic *efx) if (rx_pending == 0 && tx_pending == 0) return 0; - msleep(FALCON_FLUSH_INTERVAL); - falcon_poll_flush_events(efx); + msleep(EFX_FLUSH_INTERVAL); + efx_poll_flush_events(efx); } /* Mark the queues as all flushed. We're going to return failure @@ -1273,15 +1267,15 @@ int falcon_flush_queues(struct efx_nic *efx) /************************************************************************** * - * Falcon hardware interrupts + * Hardware interrupts * The hardware interrupt handler does very little work; all the event * queue processing is carried out by per-channel tasklets. * **************************************************************************/ -/* Enable/disable/generate Falcon interrupts */ -static inline void falcon_interrupts(struct efx_nic *efx, int enabled, - int force) +/* Enable/disable/generate interrupts */ +static inline void efx_nic_interrupts(struct efx_nic *efx, + bool enabled, bool force) { efx_oword_t int_en_reg_ker; @@ -1291,7 +1285,7 @@ static inline void falcon_interrupts(struct efx_nic *efx, int enabled, efx_writeo(efx, &int_en_reg_ker, FR_AZ_INT_EN_KER); } -void falcon_enable_interrupts(struct efx_nic *efx) +void efx_nic_enable_interrupts(struct efx_nic *efx) { struct efx_channel *channel; @@ -1299,7 +1293,7 @@ void falcon_enable_interrupts(struct efx_nic *efx) wmb(); /* Ensure interrupt vector is clear before interrupts enabled */ /* Enable interrupts */ - falcon_interrupts(efx, 1, 0); + efx_nic_interrupts(efx, true, false); /* Force processing of all the channels to get the EVQ RPTRs up to date */ @@ -1307,19 +1301,19 @@ void falcon_enable_interrupts(struct efx_nic *efx) efx_schedule_channel(channel); } -void falcon_disable_interrupts(struct efx_nic *efx) +void efx_nic_disable_interrupts(struct efx_nic *efx) { /* Disable interrupts */ - falcon_interrupts(efx, 0, 0); + efx_nic_interrupts(efx, false, false); } -/* Generate a Falcon test interrupt +/* Generate a test interrupt * Interrupt must already have been enabled, otherwise nasty things * may happen. */ -void falcon_generate_interrupt(struct efx_nic *efx) +void efx_nic_generate_interrupt(struct efx_nic *efx) { - falcon_interrupts(efx, 1, 1); + efx_nic_interrupts(efx, true, true); } /* Acknowledge a legacy interrupt from Falcon @@ -1332,7 +1326,7 @@ void falcon_generate_interrupt(struct efx_nic *efx) * * NB most hardware supports MSI interrupts */ -static inline void falcon_irq_ack_a1(struct efx_nic *efx) +inline void falcon_irq_ack_a1(struct efx_nic *efx) { efx_dword_t reg; @@ -1344,7 +1338,7 @@ static inline void falcon_irq_ack_a1(struct efx_nic *efx) /* Process a fatal interrupt * Disable bus mastering ASAP and schedule a reset */ -static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) +irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx) { struct falcon_nic_data *nic_data = efx->nic_data; efx_oword_t *int_ker = efx->irq_status.addr; @@ -1372,18 +1366,18 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) /* Disable both devices */ pci_clear_master(efx->pci_dev); - if (FALCON_IS_DUAL_FUNC(efx)) + if (efx_nic_is_dual_func(efx)) pci_clear_master(nic_data->pci_dev2); - falcon_disable_interrupts(efx); + efx_nic_disable_interrupts(efx); /* Count errors and reset or disable the NIC accordingly */ if (efx->int_error_count == 0 || time_after(jiffies, efx->int_error_expire)) { efx->int_error_count = 0; efx->int_error_expire = - jiffies + FALCON_INT_ERROR_EXPIRE * HZ; + jiffies + EFX_INT_ERROR_EXPIRE * HZ; } - if (++efx->int_error_count < FALCON_MAX_INT_ERRORS) { + if (++efx->int_error_count < EFX_MAX_INT_ERRORS) { EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n"); efx_schedule_reset(efx, RESET_TYPE_INT_ERROR); } else { @@ -1395,10 +1389,10 @@ out: return IRQ_HANDLED; } -/* Handle a legacy interrupt from Falcon +/* Handle a legacy interrupt * Acknowledges the interrupt and schedule event queue processing. */ -static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) +static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) { struct efx_nic *efx = dev_id; efx_oword_t *int_ker = efx->irq_status.addr; @@ -1415,13 +1409,13 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) /* Check to see if we have a serious error condition */ syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); if (unlikely(syserr)) - return falcon_fatal_interrupt(efx); + return efx_nic_fatal_interrupt(efx); /* Schedule processing of any interrupting queues */ efx_for_each_channel(channel, efx) { if ((queues & 1) || - falcon_event_present( - falcon_event(channel, channel->eventq_read_ptr))) { + efx_event_present( + efx_event(channel, channel->eventq_read_ptr))) { efx_schedule_channel(channel); result = IRQ_HANDLED; } @@ -1438,7 +1432,7 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) } -static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) +irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) { struct efx_nic *efx = dev_id; efx_oword_t *int_ker = efx->irq_status.addr; @@ -1461,7 +1455,7 @@ static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) /* Check to see if we have a serious error condition */ syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); if (unlikely(syserr)) - return falcon_fatal_interrupt(efx); + return efx_nic_fatal_interrupt(efx); /* Determine interrupting queues, clear interrupt status * register and acknowledge the device interrupt. @@ -1484,14 +1478,14 @@ static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) return IRQ_HANDLED; } -/* Handle an MSI interrupt from Falcon +/* Handle an MSI interrupt * * Handle an MSI hardware interrupt. This routine schedules event * queue processing. No interrupt acknowledgement cycle is necessary. * Also, we never need to check that the interrupt is for us, since * MSI interrupts cannot be shared. */ -static irqreturn_t falcon_msi_interrupt(int irq, void *dev_id) +static irqreturn_t efx_msi_interrupt(int irq, void *dev_id) { struct efx_channel *channel = dev_id; struct efx_nic *efx = channel->efx; @@ -1505,7 +1499,7 @@ static irqreturn_t falcon_msi_interrupt(int irq, void *dev_id) /* Check to see if we have a serious error condition */ syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); if (unlikely(syserr)) - return falcon_fatal_interrupt(efx); + return efx_nic_fatal_interrupt(efx); /* Schedule processing of the channel */ efx_schedule_channel(channel); @@ -1517,7 +1511,7 @@ static irqreturn_t falcon_msi_interrupt(int irq, void *dev_id) /* Setup RSS indirection table. * This maps from the hash value of the packet to RXQ */ -static void falcon_setup_rss_indir_table(struct efx_nic *efx) +static void efx_setup_rss_indir_table(struct efx_nic *efx) { int i = 0; unsigned long offset; @@ -1539,7 +1533,7 @@ static void falcon_setup_rss_indir_table(struct efx_nic *efx) /* Hook interrupt handler(s) * Try MSI and then legacy interrupts. */ -int falcon_init_interrupt(struct efx_nic *efx) +int efx_nic_init_interrupt(struct efx_nic *efx) { struct efx_channel *channel; int rc; @@ -1547,7 +1541,7 @@ int falcon_init_interrupt(struct efx_nic *efx) if (!EFX_INT_MODE_USE_MSI(efx)) { irq_handler_t handler; if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) - handler = falcon_legacy_interrupt_b0; + handler = efx_legacy_interrupt; else handler = falcon_legacy_interrupt_a1; @@ -1563,7 +1557,7 @@ int falcon_init_interrupt(struct efx_nic *efx) /* Hook MSI or MSI-X interrupt */ efx_for_each_channel(channel, efx) { - rc = request_irq(channel->irq, falcon_msi_interrupt, + rc = request_irq(channel->irq, efx_msi_interrupt, IRQF_PROBE_SHARED, /* Not shared */ channel->name, channel); if (rc) { @@ -1581,7 +1575,7 @@ int falcon_init_interrupt(struct efx_nic *efx) return rc; } -void falcon_fini_interrupt(struct efx_nic *efx) +void efx_nic_fini_interrupt(struct efx_nic *efx) { struct efx_channel *channel; efx_oword_t reg; @@ -2322,8 +2316,8 @@ static int falcon_probe_port(struct efx_nic *efx) efx->wanted_fc = EFX_FC_RX; /* Allocate buffer for stats */ - rc = falcon_alloc_buffer(efx, &efx->stats_buffer, - FALCON_MAC_STATS_SIZE); + rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer, + FALCON_MAC_STATS_SIZE); if (rc) return rc; EFX_LOG(efx, "stats buffer at %llx (virt %p phys %llx)\n", @@ -2336,7 +2330,7 @@ static int falcon_probe_port(struct efx_nic *efx) static void falcon_remove_port(struct efx_nic *efx) { - falcon_free_buffer(efx, &efx->stats_buffer); + efx_nic_free_buffer(efx, &efx->stats_buffer); } /************************************************************************** @@ -2414,11 +2408,7 @@ static int falcon_test_nvram(struct efx_nic *efx) return falcon_read_nvram(efx, NULL); } -/* Registers tested in the falcon register test */ -static struct { - unsigned address; - efx_oword_t mask; -} efx_test_registers[] = { +static const struct efx_nic_register_test falcon_b0_register_tests[] = { { FR_AZ_ADR_REGION, EFX_OWORD32(0x0001FFFF, 0x0001FFFF, 0x0001FFFF, 0x0001FFFF) }, { FR_AZ_RX_CFG, @@ -2464,7 +2454,9 @@ static bool efx_masked_compare_oword(const efx_oword_t *a, const efx_oword_t *b, ((a->u64[1] ^ b->u64[1]) & mask->u64[1]); } -static int falcon_b0_test_registers(struct efx_nic *efx) +int efx_nic_test_registers(struct efx_nic *efx, + const struct efx_nic_register_test *regs, + size_t n_regs) { unsigned address = 0, i, j; efx_oword_t mask, imask, original, reg, buf; @@ -2472,9 +2464,9 @@ static int falcon_b0_test_registers(struct efx_nic *efx) /* Falcon should be in loopback to isolate the XMAC from the PHY */ WARN_ON(!LOOPBACK_INTERNAL(efx)); - for (i = 0; i < ARRAY_SIZE(efx_test_registers); ++i) { - address = efx_test_registers[i].address; - mask = imask = efx_test_registers[i].mask; + for (i = 0; i < n_regs; ++i) { + address = regs[i].address; + mask = imask = regs[i].mask; EFX_INVERT_OWORD(imask); efx_reado(efx, &original, address); @@ -2517,6 +2509,12 @@ fail: return -EIO; } +static int falcon_b0_test_registers(struct efx_nic *efx) +{ + return efx_nic_test_registers(efx, falcon_b0_register_tests, + ARRAY_SIZE(falcon_b0_register_tests)); +} + /************************************************************************** * * Device reset @@ -2542,7 +2540,7 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) "function prior to hardware reset\n"); goto fail1; } - if (FALCON_IS_DUAL_FUNC(efx)) { + if (efx_nic_is_dual_func(efx)) { rc = pci_save_state(nic_data->pci_dev2); if (rc) { EFX_ERR(efx, "failed to backup PCI state of " @@ -2577,7 +2575,7 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) /* Restore PCI configuration if needed */ if (method == RESET_TYPE_WORLD) { - if (FALCON_IS_DUAL_FUNC(efx)) { + if (efx_nic_is_dual_func(efx)) { rc = pci_restore_state(nic_data->pci_dev2); if (rc) { EFX_ERR(efx, "failed to restore PCI config for " @@ -2800,16 +2798,22 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) return rc; } +u32 efx_nic_fpga_ver(struct efx_nic *efx) +{ + efx_oword_t altera_build; + + efx_reado(efx, &altera_build, FR_AZ_ALTERA_BUILD); + return EFX_OWORD_FIELD(altera_build, FRF_AZ_ALTERA_BUILD_VER); +} + /* Probe the NIC variant (revision, ASIC vs FPGA, function count, port * count, port speed). Set workaround and feature flags accordingly. */ static int falcon_probe_nic_variant(struct efx_nic *efx) { - efx_oword_t altera_build; efx_oword_t nic_stat; - efx_reado(efx, &altera_build, FR_AZ_ALTERA_BUILD); - if (EFX_OWORD_FIELD(altera_build, FRF_AZ_ALTERA_BUILD_VER)) { + if (efx_nic_fpga_ver(efx) != 0) { EFX_ERR(efx, "Falcon FPGA not supported\n"); return -ENODEV; } @@ -2893,7 +2897,7 @@ static int falcon_probe_nic(struct efx_nic *efx) goto fail1; /* Probe secondary function if expected */ - if (FALCON_IS_DUAL_FUNC(efx)) { + if (efx_nic_is_dual_func(efx)) { struct pci_dev *dev = pci_dev_get(efx->pci_dev); while ((dev = pci_get_device(EFX_VENDID_SFC, FALCON_A_S_DEVID, @@ -2919,7 +2923,7 @@ static int falcon_probe_nic(struct efx_nic *efx) } /* Allocate memory for INT_KER */ - rc = falcon_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t)); + rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t)); if (rc) goto fail4; BUG_ON(efx->irq_status.dma_addr & 0x0f); @@ -2965,7 +2969,7 @@ static int falcon_probe_nic(struct efx_nic *efx) memset(&board->i2c_adap, 0, sizeof(board->i2c_adap)); fail5: falcon_remove_spi_devices(efx); - falcon_free_buffer(efx, &efx->irq_status); + efx_nic_free_buffer(efx, &efx->irq_status); fail4: fail3: if (nic_data->pci_dev2) { @@ -2988,8 +2992,8 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) const unsigned ctrl_xon_thr = 20; const unsigned ctrl_xoff_thr = 25; /* RX data FIFO thresholds (256-byte units; size varies) */ - int data_xon_thr = rx_xon_thresh_bytes >> 8; - int data_xoff_thr = rx_xoff_thresh_bytes >> 8; + int data_xon_thr = efx_nic_rx_xon_thresh >> 8; + int data_xoff_thr = efx_nic_rx_xoff_thresh >> 8; efx_oword_t reg; efx_reado(efx, ®, FR_AZ_RX_CFG); @@ -3027,33 +3031,9 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) efx_writeo(efx, ®, FR_AZ_RX_CFG); } -/* This call performs hardware-specific global initialisation, such as - * defining the descriptor cache sizes and number of RSS channels. - * It does not set up any buffers, descriptor rings or event queues. - */ -static int falcon_init_nic(struct efx_nic *efx) +void efx_nic_init_common(struct efx_nic *efx) { efx_oword_t temp; - int rc; - - /* Use on-chip SRAM */ - efx_reado(efx, &temp, FR_AB_NIC_STAT); - EFX_SET_OWORD_FIELD(temp, FRF_AB_ONCHIP_SRAM, 1); - efx_writeo(efx, &temp, FR_AB_NIC_STAT); - - /* Set the source of the GMAC clock */ - if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) { - efx_reado(efx, &temp, FR_AB_GPIO_CTL); - EFX_SET_OWORD_FIELD(temp, FRF_AB_USE_NIC_CLK, true); - efx_writeo(efx, &temp, FR_AB_GPIO_CTL); - } - - /* Select the correct MAC */ - falcon_clock_mac(efx); - - rc = falcon_reset_sram(efx); - if (rc) - return rc; /* Set positions of descriptor caches in SRAM. */ EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_TX_DC_BASE_ADR, @@ -3084,15 +3064,6 @@ static int falcon_init_nic(struct efx_nic *efx) FRF_AZ_INT_ADR_KER, efx->irq_status.dma_addr); efx_writeo(efx, &temp, FR_AZ_INT_ADR_KER); - /* Clear the parity enables on the TX data fifos as - * they produce false parity errors because of timing issues - */ - if (EFX_WORKAROUND_5129(efx)) { - efx_reado(efx, &temp, FR_AZ_CSR_SPARE); - EFX_SET_OWORD_FIELD(temp, FRF_AB_MEM_PERR_EN_TX_DATA, 0); - efx_writeo(efx, &temp, FR_AZ_CSR_SPARE); - } - /* Enable all the genuinely fatal interrupts. (They are still * masked by the overall interrupt mask, controlled by * falcon_interrupts()). @@ -3106,6 +3077,64 @@ static int falcon_init_nic(struct efx_nic *efx) EFX_INVERT_OWORD(temp); efx_writeo(efx, &temp, FR_AZ_FATAL_INTR_KER); + efx_setup_rss_indir_table(efx); + + /* Disable the ugly timer-based TX DMA backoff and allow TX DMA to be + * controlled by the RX FIFO fill level. Set arbitration to one pkt/Q. + */ + efx_reado(efx, &temp, FR_AZ_TX_RESERVED); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER, 0xfe); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER_EN, 1); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_ONE_PKT_PER_Q, 1); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PUSH_EN, 0); + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_DIS_NON_IP_EV, 1); + /* Enable SW_EV to inherit in char driver - assume harmless here */ + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1); + /* Prefetch threshold 2 => fetch when descriptor cache half empty */ + EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2); + /* Squash TX of packets of 16 bytes or less */ + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) + EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); + efx_writeo(efx, &temp, FR_AZ_TX_RESERVED); +} + +/* This call performs hardware-specific global initialisation, such as + * defining the descriptor cache sizes and number of RSS channels. + * It does not set up any buffers, descriptor rings or event queues. + */ +static int falcon_init_nic(struct efx_nic *efx) +{ + efx_oword_t temp; + int rc; + + /* Use on-chip SRAM */ + efx_reado(efx, &temp, FR_AB_NIC_STAT); + EFX_SET_OWORD_FIELD(temp, FRF_AB_ONCHIP_SRAM, 1); + efx_writeo(efx, &temp, FR_AB_NIC_STAT); + + /* Set the source of the GMAC clock */ + if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) { + efx_reado(efx, &temp, FR_AB_GPIO_CTL); + EFX_SET_OWORD_FIELD(temp, FRF_AB_USE_NIC_CLK, true); + efx_writeo(efx, &temp, FR_AB_GPIO_CTL); + } + + /* Select the correct MAC */ + falcon_clock_mac(efx); + + rc = falcon_reset_sram(efx); + if (rc) + return rc; + + /* Clear the parity enables on the TX data fifos as + * they produce false parity errors because of timing issues + */ + if (EFX_WORKAROUND_5129(efx)) { + efx_reado(efx, &temp, FR_AZ_CSR_SPARE); + EFX_SET_OWORD_FIELD(temp, FRF_AB_MEM_PERR_EN_TX_DATA, 0); + efx_writeo(efx, &temp, FR_AZ_CSR_SPARE); + } + if (EFX_WORKAROUND_7244(efx)) { efx_reado(efx, &temp, FR_BZ_RX_FILTER_CTL); EFX_SET_OWORD_FIELD(temp, FRF_BZ_UDP_FULL_SRCH_LIMIT, 8); @@ -3115,8 +3144,6 @@ static int falcon_init_nic(struct efx_nic *efx) efx_writeo(efx, &temp, FR_BZ_RX_FILTER_CTL); } - falcon_setup_rss_indir_table(efx); - /* XXX This is documented only for Falcon A0/A1 */ /* Setup RX. Wait for descriptor is broken and must * be disabled. RXDP recovery shouldn't be needed, but is. @@ -3128,24 +3155,6 @@ static int falcon_init_nic(struct efx_nic *efx) EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_ISCSI_DIS, 1); efx_writeo(efx, &temp, FR_AA_RX_SELF_RST); - /* Disable the ugly timer-based TX DMA backoff and allow TX DMA to be - * controlled by the RX FIFO fill level. Set arbitration to one pkt/Q. - */ - efx_reado(efx, &temp, FR_AZ_TX_RESERVED); - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER, 0xfe); - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER_EN, 1); - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_ONE_PKT_PER_Q, 1); - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PUSH_EN, 0); - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_DIS_NON_IP_EV, 1); - /* Enable SW_EV to inherit in char driver - assume harmless here */ - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1); - /* Prefetch threshold 2 => fetch when descriptor cache half empty */ - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2); - /* Squash TX of packets of 16 bytes or less */ - if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) - EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); - efx_writeo(efx, &temp, FR_AZ_TX_RESERVED); - /* Do not enable TX_NO_EOP_DISC_EN, since it limits packets to 16 * descriptors (which is bad). */ @@ -3161,6 +3170,8 @@ static int falcon_init_nic(struct efx_nic *efx) efx_writeo(efx, &temp, FR_BZ_DP_CTRL); } + efx_nic_init_common(efx); + return 0; } @@ -3178,7 +3189,7 @@ static void falcon_remove_nic(struct efx_nic *efx) memset(&board->i2c_adap, 0, sizeof(board->i2c_adap)); falcon_remove_spi_devices(efx); - falcon_free_buffer(efx, &efx->irq_status); + efx_nic_free_buffer(efx, &efx->irq_status); falcon_reset_hw(efx, RESET_TYPE_ALL); -- cgit v1.2.2 From 5784946068f81c5f1cce2906a7655652e34f44f3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 15:08:21 +0000 Subject: sfc: Fold falcon_probe_nic_variant() into falcon_probe_nic() falcon_probe_nic_variant() does a lot less than it used to, and a lot less than it claims to. Fold the remainder into its caller. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 64 ++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 40 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 2e4c71114630..63e6734d8341 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2806,40 +2806,6 @@ u32 efx_nic_fpga_ver(struct efx_nic *efx) return EFX_OWORD_FIELD(altera_build, FRF_AZ_ALTERA_BUILD_VER); } -/* Probe the NIC variant (revision, ASIC vs FPGA, function count, port - * count, port speed). Set workaround and feature flags accordingly. - */ -static int falcon_probe_nic_variant(struct efx_nic *efx) -{ - efx_oword_t nic_stat; - - if (efx_nic_fpga_ver(efx) != 0) { - EFX_ERR(efx, "Falcon FPGA not supported\n"); - return -ENODEV; - } - - efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); - - if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) { - u8 pci_rev = efx->pci_dev->revision; - - if ((pci_rev == 0xff) || (pci_rev == 0)) { - EFX_ERR(efx, "Falcon rev A0 not supported\n"); - return -ENODEV; - } - if (EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) == 0) { - EFX_ERR(efx, "Falcon rev A1 1G not supported\n"); - return -ENODEV; - } - if (EFX_OWORD_FIELD(nic_stat, FRF_AA_STRAP_PCIE) == 0) { - EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); - return -ENODEV; - } - } - - return 0; -} - /* Probe all SPI devices on the NIC */ static void falcon_probe_spi_devices(struct efx_nic *efx) { @@ -2891,15 +2857,33 @@ static int falcon_probe_nic(struct efx_nic *efx) return -ENOMEM; efx->nic_data = nic_data; - /* Determine number of ports etc. */ - rc = falcon_probe_nic_variant(efx); - if (rc) + rc = -ENODEV; + + if (efx_nic_fpga_ver(efx) != 0) { + EFX_ERR(efx, "Falcon FPGA not supported\n"); goto fail1; + } + + if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) { + efx_oword_t nic_stat; + struct pci_dev *dev; + u8 pci_rev = efx->pci_dev->revision; - /* Probe secondary function if expected */ - if (efx_nic_is_dual_func(efx)) { - struct pci_dev *dev = pci_dev_get(efx->pci_dev); + if ((pci_rev == 0xff) || (pci_rev == 0)) { + EFX_ERR(efx, "Falcon rev A0 not supported\n"); + goto fail1; + } + efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); + if (EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) == 0) { + EFX_ERR(efx, "Falcon rev A1 1G not supported\n"); + goto fail1; + } + if (EFX_OWORD_FIELD(nic_stat, FRF_AA_STRAP_PCIE) == 0) { + EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); + goto fail1; + } + dev = pci_dev_get(efx->pci_dev); while ((dev = pci_get_device(EFX_VENDID_SFC, FALCON_A_S_DEVID, dev))) { if (dev->bus == efx->pci_dev->bus && -- cgit v1.2.2 From c1c4f453b61463df4df16f7aa5782fc0cfe05b9e Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 15:08:55 +0000 Subject: sfc: Remove static PHY data and enumerations New NICs have firmware managing the PHY, and we will discover the PHY capabilities at run-time. Replace the static data with probe() and test_name() operations. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 63e6734d8341..29d45376e4c9 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2291,19 +2291,12 @@ static int falcon_probe_port(struct efx_nic *efx) return -ENODEV; } - if (efx->phy_op->macs & EFX_XMAC) - efx->loopback_modes |= ((1 << LOOPBACK_XGMII) | - (1 << LOOPBACK_XGXS) | - (1 << LOOPBACK_XAUI)); - if (efx->phy_op->macs & EFX_GMAC) - efx->loopback_modes |= (1 << LOOPBACK_GMAC); - efx->loopback_modes |= efx->phy_op->loopbacks; - - /* Set up MDIO structure for PHY */ - efx->mdio.mmds = efx->phy_op->mmds; - efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + /* Fill out MDIO structure and loopback modes */ efx->mdio.mdio_read = falcon_mdio_read; efx->mdio.mdio_write = falcon_mdio_write; + rc = efx->phy_op->probe(efx); + if (rc != 0) + return rc; /* Initial assumption */ efx->link_state.speed = 10000; -- cgit v1.2.2 From 76884835684411264cda2f15585261eb02183541 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 15:10:44 +0000 Subject: sfc: Extend MTD driver for use with new NICs In new NICs flash is managed by firmware and we will use high-level operations on partitions rather than direct SPI commands. Add support for multiple MTD partitions per flash device and remove the direct link between MTD and SPI devices. Maintain a list of MTD partitions in struct efx_nic. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 29d45376e4c9..950de847d22b 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1640,11 +1640,10 @@ static int falcon_spi_wait(struct efx_nic *efx) } } -int falcon_spi_cmd(const struct efx_spi_device *spi, +int falcon_spi_cmd(struct efx_nic *efx, const struct efx_spi_device *spi, unsigned int command, int address, const void *in, void *out, size_t len) { - struct efx_nic *efx = spi->efx; bool addressed = (address >= 0); bool reading = (out != NULL); efx_oword_t reg; @@ -1713,15 +1712,15 @@ efx_spi_munge_command(const struct efx_spi_device *spi, } /* Wait up to 10 ms for buffered write completion */ -int falcon_spi_wait_write(const struct efx_spi_device *spi) +int +falcon_spi_wait_write(struct efx_nic *efx, const struct efx_spi_device *spi) { - struct efx_nic *efx = spi->efx; unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100); u8 status; int rc; for (;;) { - rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL, + rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL, &status, sizeof(status)); if (rc) return rc; @@ -1737,8 +1736,8 @@ int falcon_spi_wait_write(const struct efx_spi_device *spi) } } -int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, - size_t len, size_t *retlen, u8 *buffer) +int falcon_spi_read(struct efx_nic *efx, const struct efx_spi_device *spi, + loff_t start, size_t len, size_t *retlen, u8 *buffer) { size_t block_len, pos = 0; unsigned int command; @@ -1748,7 +1747,7 @@ int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, block_len = min(len - pos, FALCON_SPI_MAX_LEN); command = efx_spi_munge_command(spi, SPI_READ, start + pos); - rc = falcon_spi_cmd(spi, command, start + pos, NULL, + rc = falcon_spi_cmd(efx, spi, command, start + pos, NULL, buffer + pos, block_len); if (rc) break; @@ -1767,8 +1766,9 @@ int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, return rc; } -int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, - size_t len, size_t *retlen, const u8 *buffer) +int +falcon_spi_write(struct efx_nic *efx, const struct efx_spi_device *spi, + loff_t start, size_t len, size_t *retlen, const u8 *buffer) { u8 verify_buffer[FALCON_SPI_MAX_LEN]; size_t block_len, pos = 0; @@ -1776,24 +1776,24 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, int rc = 0; while (pos < len) { - rc = falcon_spi_cmd(spi, SPI_WREN, -1, NULL, NULL, 0); + rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0); if (rc) break; block_len = min(len - pos, falcon_spi_write_limit(spi, start + pos)); command = efx_spi_munge_command(spi, SPI_WRITE, start + pos); - rc = falcon_spi_cmd(spi, command, start + pos, + rc = falcon_spi_cmd(efx, spi, command, start + pos, buffer + pos, NULL, block_len); if (rc) break; - rc = falcon_spi_wait_write(spi); + rc = falcon_spi_wait_write(efx, spi); if (rc) break; command = efx_spi_munge_command(spi, SPI_READ, start + pos); - rc = falcon_spi_cmd(spi, command, start + pos, + rc = falcon_spi_cmd(efx, spi, command, start + pos, NULL, verify_buffer, block_len); if (memcmp(verify_buffer, buffer + pos, block_len)) { rc = -EIO; @@ -2352,7 +2352,7 @@ falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) nvconfig = region + FALCON_NVCONFIG_OFFSET; mutex_lock(&efx->spi_lock); - rc = falcon_spi_read(spi, 0, FALCON_NVCONFIG_END, NULL, region); + rc = falcon_spi_read(efx, spi, 0, FALCON_NVCONFIG_END, NULL, region); mutex_unlock(&efx->spi_lock); if (rc) { EFX_ERR(efx, "Failed to read %s\n", @@ -2710,8 +2710,6 @@ static int falcon_spi_device_init(struct efx_nic *efx, spi_device->block_size = 1 << SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_BLOCK_SIZE); - - spi_device->efx = efx; } else { spi_device = NULL; } -- cgit v1.2.2 From c383b53729a9bbbceee132a85955d084ba00ca3a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 15:11:02 +0000 Subject: sfc: Allow for additional checksum offload features Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 950de847d22b..f77bbbeacb60 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -3304,6 +3304,7 @@ struct efx_nic_type falcon_a1_nic_type = { .phys_addr_channels = 4, .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, + .offload_features = NETIF_F_IP_CSUM, .reset_world_flags = ETH_RESET_IRQ, }; @@ -3351,6 +3352,7 @@ struct efx_nic_type falcon_b0_nic_type = { * channels */ .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, + .offload_features = NETIF_F_IP_CSUM, .reset_world_flags = ETH_RESET_IRQ, }; -- cgit v1.2.2 From 744093c98363f8a65853aed39708c9effc80f8ff Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 15:12:08 +0000 Subject: sfc: Rename falcon.h to nic.h nic.h is no longer specific to Falcon. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index f77bbbeacb60..64b47da12326 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -20,7 +20,7 @@ #include "efx.h" #include "mac.h" #include "spi.h" -#include "falcon.h" +#include "nic.h" #include "regs.h" #include "io.h" #include "mdio_10g.h" -- cgit v1.2.2 From 8e730c15e1560415f33d7301b617be26050ffb86 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 15:14:45 +0000 Subject: sfc: Move shared NIC code from falcon.c to new source file nic.c Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 1578 +--------------------------------------------- 1 file changed, 21 insertions(+), 1557 deletions(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 64b47da12326..48d28d828d46 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -29,26 +29,6 @@ /* Hardware control for SFC4000 (aka Falcon). */ -/************************************************************************** - * - * Configurable values - * - ************************************************************************** - */ - -/* This is set to 16 for a good reason. In summary, if larger than - * 16, the descriptor cache holds more than a default socket - * buffer's worth of packets (for UDP we can only have at most one - * socket buffer's worth outstanding). This combined with the fact - * that we only get 1 TX event per descriptor cache means the NIC - * goes idle. - */ -#define TX_DC_ENTRIES 16 -#define TX_DC_ENTRIES_ORDER 1 - -#define RX_DC_ENTRIES 64 -#define RX_DC_ENTRIES_ORDER 3 - static const unsigned int /* "Large" EEPROM device: Atmel AT25640 or similar * 8 KB, 16-bit address, 32 B write block */ @@ -63,87 +43,6 @@ default_flash_type = ((17 << SPI_DEV_TYPE_SIZE_LBN) | (15 << SPI_DEV_TYPE_ERASE_SIZE_LBN) | (8 << SPI_DEV_TYPE_BLOCK_SIZE_LBN)); -/* RX FIFO XOFF watermark - * - * When the amount of the RX FIFO increases used increases past this - * watermark send XOFF. Only used if RX flow control is enabled (ethtool -A) - * This also has an effect on RX/TX arbitration - */ -int efx_nic_rx_xoff_thresh = -1; -module_param_named(rx_xoff_thresh_bytes, efx_nic_rx_xoff_thresh, int, 0644); -MODULE_PARM_DESC(rx_xoff_thresh_bytes, "RX fifo XOFF threshold"); - -/* RX FIFO XON watermark - * - * When the amount of the RX FIFO used decreases below this - * watermark send XON. Only used if TX flow control is enabled (ethtool -A) - * This also has an effect on RX/TX arbitration - */ -int efx_nic_rx_xon_thresh = -1; -module_param_named(rx_xon_thresh_bytes, efx_nic_rx_xon_thresh, int, 0644); -MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); - -/* If EFX_MAX_INT_ERRORS internal errors occur within - * EFX_INT_ERROR_EXPIRE seconds, we consider the NIC broken and - * disable it. - */ -#define EFX_INT_ERROR_EXPIRE 3600 -#define EFX_MAX_INT_ERRORS 5 - -/* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times - */ -#define EFX_FLUSH_INTERVAL 10 -#define EFX_FLUSH_POLL_COUNT 100 - -/************************************************************************** - * - * Falcon constants - * - ************************************************************************** - */ - -/* Size and alignment of special buffers (4KB) */ -#define EFX_BUF_SIZE 4096 - -/* Depth of RX flush request fifo */ -#define EFX_RX_FLUSH_COUNT 4 - -/************************************************************************** - * - * Solarstorm hardware access - * - **************************************************************************/ - -static inline void efx_write_buf_tbl(struct efx_nic *efx, efx_qword_t *value, - unsigned int index) -{ - efx_sram_writeq(efx, efx->membase + efx->type->buf_tbl_base, - value, index); -} - -/* Read the current event from the event queue */ -static inline efx_qword_t *efx_event(struct efx_channel *channel, - unsigned int index) -{ - return (((efx_qword_t *) (channel->eventq.addr)) + index); -} - -/* See if an event is present - * - * We check both the high and low dword of the event for all ones. We - * wrote all ones when we cleared the event, and no valid event can - * have all ones in either its high or low dwords. This approach is - * robust against reordering. - * - * Note that using a single 64-bit comparison is incorrect; even - * though the CPU read will be atomic, the DMA write may not be. - */ -static inline int efx_event_present(efx_qword_t *event) -{ - return (!(EFX_DWORD_IS_ALL_ONES(event->dword[0]) | - EFX_DWORD_IS_ALL_ONES(event->dword[1]))); -} - /************************************************************************** * * I2C bus - this is a bit-bashing interface using GPIO pins @@ -174,867 +73,32 @@ static void falcon_setscl(void *data, int state) static int falcon_getsda(void *data) { - struct efx_nic *efx = (struct efx_nic *)data; - efx_oword_t reg; - - efx_reado(efx, ®, FR_AB_GPIO_CTL); - return EFX_OWORD_FIELD(reg, FRF_AB_GPIO3_IN); -} - -static int falcon_getscl(void *data) -{ - struct efx_nic *efx = (struct efx_nic *)data; - efx_oword_t reg; - - efx_reado(efx, ®, FR_AB_GPIO_CTL); - return EFX_OWORD_FIELD(reg, FRF_AB_GPIO0_IN); -} - -static struct i2c_algo_bit_data falcon_i2c_bit_operations = { - .setsda = falcon_setsda, - .setscl = falcon_setscl, - .getsda = falcon_getsda, - .getscl = falcon_getscl, - .udelay = 5, - /* Wait up to 50 ms for slave to let us pull SCL high */ - .timeout = DIV_ROUND_UP(HZ, 20), -}; - -/************************************************************************** - * - * Special buffer handling - * Special buffers are used for event queues and the TX and RX - * descriptor rings. - * - *************************************************************************/ - -/* - * Initialise a special buffer - * - * This will define a buffer (previously allocated via - * efx_alloc_special_buffer()) in the buffer table, allowing - * it to be used for event queues, descriptor rings etc. - */ -static void -efx_init_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer) -{ - efx_qword_t buf_desc; - int index; - dma_addr_t dma_addr; - int i; - - EFX_BUG_ON_PARANOID(!buffer->addr); - - /* Write buffer descriptors to NIC */ - for (i = 0; i < buffer->entries; i++) { - index = buffer->index + i; - dma_addr = buffer->dma_addr + (i * 4096); - EFX_LOG(efx, "mapping special buffer %d at %llx\n", - index, (unsigned long long)dma_addr); - EFX_POPULATE_QWORD_3(buf_desc, - FRF_AZ_BUF_ADR_REGION, 0, - FRF_AZ_BUF_ADR_FBUF, dma_addr >> 12, - FRF_AZ_BUF_OWNER_ID_FBUF, 0); - efx_write_buf_tbl(efx, &buf_desc, index); - } -} - -/* Unmaps a buffer and clears the buffer table entries */ -static void -efx_fini_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer) -{ - efx_oword_t buf_tbl_upd; - unsigned int start = buffer->index; - unsigned int end = (buffer->index + buffer->entries - 1); - - if (!buffer->entries) - return; - - EFX_LOG(efx, "unmapping special buffers %d-%d\n", - buffer->index, buffer->index + buffer->entries - 1); - - EFX_POPULATE_OWORD_4(buf_tbl_upd, - FRF_AZ_BUF_UPD_CMD, 0, - FRF_AZ_BUF_CLR_CMD, 1, - FRF_AZ_BUF_CLR_END_ID, end, - FRF_AZ_BUF_CLR_START_ID, start); - efx_writeo(efx, &buf_tbl_upd, FR_AZ_BUF_TBL_UPD); -} - -/* - * Allocate a new special buffer - * - * This allocates memory for a new buffer, clears it and allocates a - * new buffer ID range. It does not write into the buffer table. - * - * This call will allocate 4KB buffers, since 8KB buffers can't be - * used for event queues and descriptor rings. - */ -static int efx_alloc_special_buffer(struct efx_nic *efx, - struct efx_special_buffer *buffer, - unsigned int len) -{ - len = ALIGN(len, EFX_BUF_SIZE); - - buffer->addr = pci_alloc_consistent(efx->pci_dev, len, - &buffer->dma_addr); - if (!buffer->addr) - return -ENOMEM; - buffer->len = len; - buffer->entries = len / EFX_BUF_SIZE; - BUG_ON(buffer->dma_addr & (EFX_BUF_SIZE - 1)); - - /* All zeros is a potentially valid event so memset to 0xff */ - memset(buffer->addr, 0xff, len); - - /* Select new buffer ID */ - buffer->index = efx->next_buffer_table; - efx->next_buffer_table += buffer->entries; - - EFX_LOG(efx, "allocating special buffers %d-%d at %llx+%x " - "(virt %p phys %llx)\n", buffer->index, - buffer->index + buffer->entries - 1, - (u64)buffer->dma_addr, len, - buffer->addr, (u64)virt_to_phys(buffer->addr)); - - return 0; -} - -static void -efx_free_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer) -{ - if (!buffer->addr) - return; - - EFX_LOG(efx, "deallocating special buffers %d-%d at %llx+%x " - "(virt %p phys %llx)\n", buffer->index, - buffer->index + buffer->entries - 1, - (u64)buffer->dma_addr, buffer->len, - buffer->addr, (u64)virt_to_phys(buffer->addr)); - - pci_free_consistent(efx->pci_dev, buffer->len, buffer->addr, - buffer->dma_addr); - buffer->addr = NULL; - buffer->entries = 0; -} - -/************************************************************************** - * - * Generic buffer handling - * These buffers are used for interrupt status and MAC stats - * - **************************************************************************/ - -int efx_nic_alloc_buffer(struct efx_nic *efx, struct efx_buffer *buffer, - unsigned int len) -{ - buffer->addr = pci_alloc_consistent(efx->pci_dev, len, - &buffer->dma_addr); - if (!buffer->addr) - return -ENOMEM; - buffer->len = len; - memset(buffer->addr, 0, len); - return 0; -} - -void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer) -{ - if (buffer->addr) { - pci_free_consistent(efx->pci_dev, buffer->len, - buffer->addr, buffer->dma_addr); - buffer->addr = NULL; - } -} - -/************************************************************************** - * - * TX path - * - **************************************************************************/ - -/* Returns a pointer to the specified transmit descriptor in the TX - * descriptor queue belonging to the specified channel. - */ -static inline efx_qword_t * -efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index) -{ - return (((efx_qword_t *) (tx_queue->txd.addr)) + index); -} - -/* This writes to the TX_DESC_WPTR; write pointer for TX descriptor ring */ -static inline void efx_notify_tx_desc(struct efx_tx_queue *tx_queue) -{ - unsigned write_ptr; - efx_dword_t reg; - - write_ptr = tx_queue->write_count & EFX_TXQ_MASK; - EFX_POPULATE_DWORD_1(reg, FRF_AZ_TX_DESC_WPTR_DWORD, write_ptr); - efx_writed_page(tx_queue->efx, ®, - FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue); -} - - -/* For each entry inserted into the software descriptor ring, create a - * descriptor in the hardware TX descriptor ring (in host memory), and - * write a doorbell. - */ -void efx_nic_push_buffers(struct efx_tx_queue *tx_queue) -{ - - struct efx_tx_buffer *buffer; - efx_qword_t *txd; - unsigned write_ptr; - - BUG_ON(tx_queue->write_count == tx_queue->insert_count); - - do { - write_ptr = tx_queue->write_count & EFX_TXQ_MASK; - buffer = &tx_queue->buffer[write_ptr]; - txd = efx_tx_desc(tx_queue, write_ptr); - ++tx_queue->write_count; - - /* Create TX descriptor ring entry */ - EFX_POPULATE_QWORD_4(*txd, - FSF_AZ_TX_KER_CONT, buffer->continuation, - FSF_AZ_TX_KER_BYTE_COUNT, buffer->len, - FSF_AZ_TX_KER_BUF_REGION, 0, - FSF_AZ_TX_KER_BUF_ADDR, buffer->dma_addr); - } while (tx_queue->write_count != tx_queue->insert_count); - - wmb(); /* Ensure descriptors are written before they are fetched */ - efx_notify_tx_desc(tx_queue); -} - -/* Allocate hardware resources for a TX queue */ -int efx_nic_probe_tx(struct efx_tx_queue *tx_queue) -{ - struct efx_nic *efx = tx_queue->efx; - BUILD_BUG_ON(EFX_TXQ_SIZE < 512 || EFX_TXQ_SIZE > 4096 || - EFX_TXQ_SIZE & EFX_TXQ_MASK); - return efx_alloc_special_buffer(efx, &tx_queue->txd, - EFX_TXQ_SIZE * sizeof(efx_qword_t)); -} - -void efx_nic_init_tx(struct efx_tx_queue *tx_queue) -{ - efx_oword_t tx_desc_ptr; - struct efx_nic *efx = tx_queue->efx; - - tx_queue->flushed = FLUSH_NONE; - - /* Pin TX descriptor ring */ - efx_init_special_buffer(efx, &tx_queue->txd); - - /* Push TX descriptor ring to card */ - EFX_POPULATE_OWORD_10(tx_desc_ptr, - FRF_AZ_TX_DESCQ_EN, 1, - FRF_AZ_TX_ISCSI_DDIG_EN, 0, - FRF_AZ_TX_ISCSI_HDIG_EN, 0, - FRF_AZ_TX_DESCQ_BUF_BASE_ID, tx_queue->txd.index, - FRF_AZ_TX_DESCQ_EVQ_ID, - tx_queue->channel->channel, - FRF_AZ_TX_DESCQ_OWNER_ID, 0, - FRF_AZ_TX_DESCQ_LABEL, tx_queue->queue, - FRF_AZ_TX_DESCQ_SIZE, - __ffs(tx_queue->txd.entries), - FRF_AZ_TX_DESCQ_TYPE, 0, - FRF_BZ_TX_NON_IP_DROP_DIS, 1); - - if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { - int csum = tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM; - EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_IP_CHKSM_DIS, !csum); - EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_TCP_CHKSM_DIS, - !csum); - } - - efx_writeo_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, - tx_queue->queue); - - if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) { - efx_oword_t reg; - - /* Only 128 bits in this register */ - BUILD_BUG_ON(EFX_TX_QUEUE_COUNT >= 128); - - efx_reado(efx, ®, FR_AA_TX_CHKSM_CFG); - if (tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM) - clear_bit_le(tx_queue->queue, (void *)®); - else - set_bit_le(tx_queue->queue, (void *)®); - efx_writeo(efx, ®, FR_AA_TX_CHKSM_CFG); - } -} - -static void efx_flush_tx_queue(struct efx_tx_queue *tx_queue) -{ - struct efx_nic *efx = tx_queue->efx; - efx_oword_t tx_flush_descq; - - tx_queue->flushed = FLUSH_PENDING; - - /* Post a flush command */ - EFX_POPULATE_OWORD_2(tx_flush_descq, - FRF_AZ_TX_FLUSH_DESCQ_CMD, 1, - FRF_AZ_TX_FLUSH_DESCQ, tx_queue->queue); - efx_writeo(efx, &tx_flush_descq, FR_AZ_TX_FLUSH_DESCQ); -} - -void efx_nic_fini_tx(struct efx_tx_queue *tx_queue) -{ - struct efx_nic *efx = tx_queue->efx; - efx_oword_t tx_desc_ptr; - - /* The queue should have been flushed */ - WARN_ON(tx_queue->flushed != FLUSH_DONE); - - /* Remove TX descriptor ring from card */ - EFX_ZERO_OWORD(tx_desc_ptr); - efx_writeo_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, - tx_queue->queue); - - /* Unpin TX descriptor ring */ - efx_fini_special_buffer(efx, &tx_queue->txd); -} - -/* Free buffers backing TX queue */ -void efx_nic_remove_tx(struct efx_tx_queue *tx_queue) -{ - efx_free_special_buffer(tx_queue->efx, &tx_queue->txd); -} - -/************************************************************************** - * - * RX path - * - **************************************************************************/ - -/* Returns a pointer to the specified descriptor in the RX descriptor queue */ -static inline efx_qword_t * -efx_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index) -{ - return (((efx_qword_t *) (rx_queue->rxd.addr)) + index); -} - -/* This creates an entry in the RX descriptor queue */ -static inline void -efx_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned index) -{ - struct efx_rx_buffer *rx_buf; - efx_qword_t *rxd; - - rxd = efx_rx_desc(rx_queue, index); - rx_buf = efx_rx_buffer(rx_queue, index); - EFX_POPULATE_QWORD_3(*rxd, - FSF_AZ_RX_KER_BUF_SIZE, - rx_buf->len - - rx_queue->efx->type->rx_buffer_padding, - FSF_AZ_RX_KER_BUF_REGION, 0, - FSF_AZ_RX_KER_BUF_ADDR, rx_buf->dma_addr); -} - -/* This writes to the RX_DESC_WPTR register for the specified receive - * descriptor ring. - */ -void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue) -{ - efx_dword_t reg; - unsigned write_ptr; - - while (rx_queue->notified_count != rx_queue->added_count) { - efx_build_rx_desc(rx_queue, - rx_queue->notified_count & - EFX_RXQ_MASK); - ++rx_queue->notified_count; - } - - wmb(); - write_ptr = rx_queue->added_count & EFX_RXQ_MASK; - EFX_POPULATE_DWORD_1(reg, FRF_AZ_RX_DESC_WPTR_DWORD, write_ptr); - efx_writed_page(rx_queue->efx, ®, - FR_AZ_RX_DESC_UPD_DWORD_P0, rx_queue->queue); -} - -int efx_nic_probe_rx(struct efx_rx_queue *rx_queue) -{ - struct efx_nic *efx = rx_queue->efx; - BUILD_BUG_ON(EFX_RXQ_SIZE < 512 || EFX_RXQ_SIZE > 4096 || - EFX_RXQ_SIZE & EFX_RXQ_MASK); - return efx_alloc_special_buffer(efx, &rx_queue->rxd, - EFX_RXQ_SIZE * sizeof(efx_qword_t)); -} - -void efx_nic_init_rx(struct efx_rx_queue *rx_queue) -{ - efx_oword_t rx_desc_ptr; - struct efx_nic *efx = rx_queue->efx; - bool is_b0 = efx_nic_rev(efx) >= EFX_REV_FALCON_B0; - bool iscsi_digest_en = is_b0; - - EFX_LOG(efx, "RX queue %d ring in special buffers %d-%d\n", - rx_queue->queue, rx_queue->rxd.index, - rx_queue->rxd.index + rx_queue->rxd.entries - 1); - - rx_queue->flushed = FLUSH_NONE; - - /* Pin RX descriptor ring */ - efx_init_special_buffer(efx, &rx_queue->rxd); - - /* Push RX descriptor ring to card */ - EFX_POPULATE_OWORD_10(rx_desc_ptr, - FRF_AZ_RX_ISCSI_DDIG_EN, iscsi_digest_en, - FRF_AZ_RX_ISCSI_HDIG_EN, iscsi_digest_en, - FRF_AZ_RX_DESCQ_BUF_BASE_ID, rx_queue->rxd.index, - FRF_AZ_RX_DESCQ_EVQ_ID, - rx_queue->channel->channel, - FRF_AZ_RX_DESCQ_OWNER_ID, 0, - FRF_AZ_RX_DESCQ_LABEL, rx_queue->queue, - FRF_AZ_RX_DESCQ_SIZE, - __ffs(rx_queue->rxd.entries), - FRF_AZ_RX_DESCQ_TYPE, 0 /* kernel queue */ , - /* For >=B0 this is scatter so disable */ - FRF_AZ_RX_DESCQ_JUMBO, !is_b0, - FRF_AZ_RX_DESCQ_EN, 1); - efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, - rx_queue->queue); -} - -static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue) -{ - struct efx_nic *efx = rx_queue->efx; - efx_oword_t rx_flush_descq; - - rx_queue->flushed = FLUSH_PENDING; - - /* Post a flush command */ - EFX_POPULATE_OWORD_2(rx_flush_descq, - FRF_AZ_RX_FLUSH_DESCQ_CMD, 1, - FRF_AZ_RX_FLUSH_DESCQ, rx_queue->queue); - efx_writeo(efx, &rx_flush_descq, FR_AZ_RX_FLUSH_DESCQ); -} - -void efx_nic_fini_rx(struct efx_rx_queue *rx_queue) -{ - efx_oword_t rx_desc_ptr; - struct efx_nic *efx = rx_queue->efx; - - /* The queue should already have been flushed */ - WARN_ON(rx_queue->flushed != FLUSH_DONE); - - /* Remove RX descriptor ring from card */ - EFX_ZERO_OWORD(rx_desc_ptr); - efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, - rx_queue->queue); - - /* Unpin RX descriptor ring */ - efx_fini_special_buffer(efx, &rx_queue->rxd); -} - -/* Free buffers backing RX queue */ -void efx_nic_remove_rx(struct efx_rx_queue *rx_queue) -{ - efx_free_special_buffer(rx_queue->efx, &rx_queue->rxd); -} - -/************************************************************************** - * - * Event queue processing - * Event queues are processed by per-channel tasklets. - * - **************************************************************************/ - -/* Update a channel's event queue's read pointer (RPTR) register - * - * This writes the EVQ_RPTR_REG register for the specified channel's - * event queue. - * - * Note that EVQ_RPTR_REG contains the index of the "last read" event, - * whereas channel->eventq_read_ptr contains the index of the "next to - * read" event. - */ -void efx_nic_eventq_read_ack(struct efx_channel *channel) -{ - efx_dword_t reg; - struct efx_nic *efx = channel->efx; - - EFX_POPULATE_DWORD_1(reg, FRF_AZ_EVQ_RPTR, channel->eventq_read_ptr); - efx_writed_table(efx, ®, efx->type->evq_rptr_tbl_base, - channel->channel); -} - -/* Use HW to insert a SW defined event */ -void efx_generate_event(struct efx_channel *channel, efx_qword_t *event) -{ - efx_oword_t drv_ev_reg; - - BUILD_BUG_ON(FRF_AZ_DRV_EV_DATA_LBN != 0 || - FRF_AZ_DRV_EV_DATA_WIDTH != 64); - drv_ev_reg.u32[0] = event->u32[0]; - drv_ev_reg.u32[1] = event->u32[1]; - drv_ev_reg.u32[2] = 0; - drv_ev_reg.u32[3] = 0; - EFX_SET_OWORD_FIELD(drv_ev_reg, FRF_AZ_DRV_EV_QID, channel->channel); - efx_writeo(channel->efx, &drv_ev_reg, FR_AZ_DRV_EV); -} - -/* Handle a transmit completion event - * - * The NIC batches TX completion events; the message we receive is of - * the form "complete all TX events up to this index". - */ -static void -efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) -{ - unsigned int tx_ev_desc_ptr; - unsigned int tx_ev_q_label; - struct efx_tx_queue *tx_queue; - struct efx_nic *efx = channel->efx; - - if (likely(EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_COMP))) { - /* Transmit completion */ - tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR); - tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); - tx_queue = &efx->tx_queue[tx_ev_q_label]; - channel->irq_mod_score += - (tx_ev_desc_ptr - tx_queue->read_count) & - EFX_TXQ_MASK; - efx_xmit_done(tx_queue, tx_ev_desc_ptr); - } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) { - /* Rewrite the FIFO write pointer */ - tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); - tx_queue = &efx->tx_queue[tx_ev_q_label]; - - if (efx_dev_registered(efx)) - netif_tx_lock(efx->net_dev); - efx_notify_tx_desc(tx_queue); - if (efx_dev_registered(efx)) - netif_tx_unlock(efx->net_dev); - } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_PKT_ERR) && - EFX_WORKAROUND_10727(efx)) { - efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH); - } else { - EFX_ERR(efx, "channel %d unexpected TX event " - EFX_QWORD_FMT"\n", channel->channel, - EFX_QWORD_VAL(*event)); - } -} - -/* Detect errors included in the rx_evt_pkt_ok bit. */ -static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, - const efx_qword_t *event, - bool *rx_ev_pkt_ok, - bool *discard) -{ - struct efx_nic *efx = rx_queue->efx; - bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err; - bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err; - bool rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc; - bool rx_ev_other_err, rx_ev_pause_frm; - bool rx_ev_hdr_type, rx_ev_mcast_pkt; - unsigned rx_ev_pkt_type; - - rx_ev_hdr_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE); - rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_PKT); - rx_ev_tobe_disc = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_TOBE_DISC); - rx_ev_pkt_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_TYPE); - rx_ev_buf_owner_id_err = EFX_QWORD_FIELD(*event, - FSF_AZ_RX_EV_BUF_OWNER_ID_ERR); - rx_ev_ip_hdr_chksum_err = EFX_QWORD_FIELD(*event, - FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR); - rx_ev_tcp_udp_chksum_err = EFX_QWORD_FIELD(*event, - FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR); - rx_ev_eth_crc_err = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_ETH_CRC_ERR); - rx_ev_frm_trunc = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_FRM_TRUNC); - rx_ev_drib_nib = ((efx_nic_rev(efx) >= EFX_REV_FALCON_B0) ? - 0 : EFX_QWORD_FIELD(*event, FSF_AA_RX_EV_DRIB_NIB)); - rx_ev_pause_frm = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PAUSE_FRM_ERR); - - /* Every error apart from tobe_disc and pause_frm */ - rx_ev_other_err = (rx_ev_drib_nib | rx_ev_tcp_udp_chksum_err | - rx_ev_buf_owner_id_err | rx_ev_eth_crc_err | - rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err); - - /* Count errors that are not in MAC stats. Ignore expected - * checksum errors during self-test. */ - if (rx_ev_frm_trunc) - ++rx_queue->channel->n_rx_frm_trunc; - else if (rx_ev_tobe_disc) - ++rx_queue->channel->n_rx_tobe_disc; - else if (!efx->loopback_selftest) { - if (rx_ev_ip_hdr_chksum_err) - ++rx_queue->channel->n_rx_ip_hdr_chksum_err; - else if (rx_ev_tcp_udp_chksum_err) - ++rx_queue->channel->n_rx_tcp_udp_chksum_err; - } - - /* The frame must be discarded if any of these are true. */ - *discard = (rx_ev_eth_crc_err | rx_ev_frm_trunc | rx_ev_drib_nib | - rx_ev_tobe_disc | rx_ev_pause_frm); - - /* TOBE_DISC is expected on unicast mismatches; don't print out an - * error message. FRM_TRUNC indicates RXDP dropped the packet due - * to a FIFO overflow. - */ -#ifdef EFX_ENABLE_DEBUG - if (rx_ev_other_err) { - EFX_INFO_RL(efx, " RX queue %d unexpected RX event " - EFX_QWORD_FMT "%s%s%s%s%s%s%s%s\n", - rx_queue->queue, EFX_QWORD_VAL(*event), - rx_ev_buf_owner_id_err ? " [OWNER_ID_ERR]" : "", - rx_ev_ip_hdr_chksum_err ? - " [IP_HDR_CHKSUM_ERR]" : "", - rx_ev_tcp_udp_chksum_err ? - " [TCP_UDP_CHKSUM_ERR]" : "", - rx_ev_eth_crc_err ? " [ETH_CRC_ERR]" : "", - rx_ev_frm_trunc ? " [FRM_TRUNC]" : "", - rx_ev_drib_nib ? " [DRIB_NIB]" : "", - rx_ev_tobe_disc ? " [TOBE_DISC]" : "", - rx_ev_pause_frm ? " [PAUSE]" : ""); - } -#endif -} - -/* Handle receive events that are not in-order. */ -static void -efx_handle_rx_bad_index(struct efx_rx_queue *rx_queue, unsigned index) -{ - struct efx_nic *efx = rx_queue->efx; - unsigned expected, dropped; - - expected = rx_queue->removed_count & EFX_RXQ_MASK; - dropped = (index - expected) & EFX_RXQ_MASK; - EFX_INFO(efx, "dropped %d events (index=%d expected=%d)\n", - dropped, index, expected); - - efx_schedule_reset(efx, EFX_WORKAROUND_5676(efx) ? - RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE); -} - -/* Handle a packet received event - * - * The NIC gives a "discard" flag if it's a unicast packet with the - * wrong destination address - * Also "is multicast" and "matches multicast filter" flags can be used to - * discard non-matching multicast packets. - */ -static void -efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) -{ - unsigned int rx_ev_desc_ptr, rx_ev_byte_cnt; - unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt; - unsigned expected_ptr; - bool rx_ev_pkt_ok, discard = false, checksummed; - struct efx_rx_queue *rx_queue; - struct efx_nic *efx = channel->efx; - - /* Basic packet information */ - rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_BYTE_CNT); - rx_ev_pkt_ok = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_OK); - rx_ev_hdr_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE); - WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_JUMBO_CONT)); - WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_SOP) != 1); - WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_Q_LABEL) != - channel->channel); - - rx_queue = &efx->rx_queue[channel->channel]; - - rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR); - expected_ptr = rx_queue->removed_count & EFX_RXQ_MASK; - if (unlikely(rx_ev_desc_ptr != expected_ptr)) - efx_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr); - - if (likely(rx_ev_pkt_ok)) { - /* If packet is marked as OK and packet type is TCP/IP or - * UDP/IP, then we can rely on the hardware checksum. - */ - checksummed = - likely(efx->rx_checksum_enabled) && - (rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP || - rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP); - } else { - efx_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard); - checksummed = false; - } - - /* Detect multicast packets that didn't match the filter */ - rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_PKT); - if (rx_ev_mcast_pkt) { - unsigned int rx_ev_mcast_hash_match = - EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_HASH_MATCH); - - if (unlikely(!rx_ev_mcast_hash_match)) { - ++channel->n_rx_mcast_mismatch; - discard = true; - } - } - - channel->irq_mod_score += 2; - - /* Handle received packet */ - efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt, - checksummed, discard); -} - -/* Global events are basically PHY events */ -static void -efx_handle_global_event(struct efx_channel *channel, efx_qword_t *event) -{ - struct efx_nic *efx = channel->efx; - bool handled = false; - - if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) || - EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) || - EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR)) { - /* Ignored */ - handled = true; - } - - if ((efx_nic_rev(efx) >= EFX_REV_FALCON_B0) && - EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) { - efx->xmac_poll_required = true; - handled = true; - } - - if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1 ? - EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) : - EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) { - EFX_ERR(efx, "channel %d seen global RX_RESET " - "event. Resetting.\n", channel->channel); - - atomic_inc(&efx->rx_reset); - efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ? - RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE); - handled = true; - } - - if (!handled) - EFX_ERR(efx, "channel %d unknown global event " - EFX_QWORD_FMT "\n", channel->channel, - EFX_QWORD_VAL(*event)); -} - -static void -efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event) -{ - struct efx_nic *efx = channel->efx; - unsigned int ev_sub_code; - unsigned int ev_sub_data; - - ev_sub_code = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBCODE); - ev_sub_data = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBDATA); - - switch (ev_sub_code) { - case FSE_AZ_TX_DESCQ_FLS_DONE_EV: - EFX_TRACE(efx, "channel %d TXQ %d flushed\n", - channel->channel, ev_sub_data); - break; - case FSE_AZ_RX_DESCQ_FLS_DONE_EV: - EFX_TRACE(efx, "channel %d RXQ %d flushed\n", - channel->channel, ev_sub_data); - break; - case FSE_AZ_EVQ_INIT_DONE_EV: - EFX_LOG(efx, "channel %d EVQ %d initialised\n", - channel->channel, ev_sub_data); - break; - case FSE_AZ_SRM_UPD_DONE_EV: - EFX_TRACE(efx, "channel %d SRAM update done\n", - channel->channel); - break; - case FSE_AZ_WAKE_UP_EV: - EFX_TRACE(efx, "channel %d RXQ %d wakeup event\n", - channel->channel, ev_sub_data); - break; - case FSE_AZ_TIMER_EV: - EFX_TRACE(efx, "channel %d RX queue %d timer expired\n", - channel->channel, ev_sub_data); - break; - case FSE_AA_RX_RECOVER_EV: - EFX_ERR(efx, "channel %d seen DRIVER RX_RESET event. " - "Resetting.\n", channel->channel); - atomic_inc(&efx->rx_reset); - efx_schedule_reset(efx, - EFX_WORKAROUND_6555(efx) ? - RESET_TYPE_RX_RECOVERY : - RESET_TYPE_DISABLE); - break; - case FSE_BZ_RX_DSC_ERROR_EV: - EFX_ERR(efx, "RX DMA Q %d reports descriptor fetch error." - " RX Q %d is disabled.\n", ev_sub_data, ev_sub_data); - efx_schedule_reset(efx, RESET_TYPE_RX_DESC_FETCH); - break; - case FSE_BZ_TX_DSC_ERROR_EV: - EFX_ERR(efx, "TX DMA Q %d reports descriptor fetch error." - " TX Q %d is disabled.\n", ev_sub_data, ev_sub_data); - efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH); - break; - default: - EFX_TRACE(efx, "channel %d unknown driver event code %d " - "data %04x\n", channel->channel, ev_sub_code, - ev_sub_data); - break; - } -} - -int efx_nic_process_eventq(struct efx_channel *channel, int rx_quota) -{ - unsigned int read_ptr; - efx_qword_t event, *p_event; - int ev_code; - int rx_packets = 0; - - read_ptr = channel->eventq_read_ptr; - - do { - p_event = efx_event(channel, read_ptr); - event = *p_event; - - if (!efx_event_present(&event)) - /* End of events */ - break; - - EFX_TRACE(channel->efx, "channel %d event is "EFX_QWORD_FMT"\n", - channel->channel, EFX_QWORD_VAL(event)); - - /* Clear this event by marking it all ones */ - EFX_SET_QWORD(*p_event); - - ev_code = EFX_QWORD_FIELD(event, FSF_AZ_EV_CODE); - - switch (ev_code) { - case FSE_AZ_EV_CODE_RX_EV: - efx_handle_rx_event(channel, &event); - ++rx_packets; - break; - case FSE_AZ_EV_CODE_TX_EV: - efx_handle_tx_event(channel, &event); - break; - case FSE_AZ_EV_CODE_DRV_GEN_EV: - channel->eventq_magic = EFX_QWORD_FIELD( - event, FSF_AZ_DRV_GEN_EV_MAGIC); - EFX_LOG(channel->efx, "channel %d received generated " - "event "EFX_QWORD_FMT"\n", channel->channel, - EFX_QWORD_VAL(event)); - break; - case FSE_AZ_EV_CODE_GLOBAL_EV: - efx_handle_global_event(channel, &event); - break; - case FSE_AZ_EV_CODE_DRIVER_EV: - efx_handle_driver_event(channel, &event); - break; - default: - EFX_ERR(channel->efx, "channel %d unknown event type %d" - " (data " EFX_QWORD_FMT ")\n", channel->channel, - ev_code, EFX_QWORD_VAL(event)); - } + struct efx_nic *efx = (struct efx_nic *)data; + efx_oword_t reg; - /* Increment read pointer */ - read_ptr = (read_ptr + 1) & EFX_EVQ_MASK; + efx_reado(efx, ®, FR_AB_GPIO_CTL); + return EFX_OWORD_FIELD(reg, FRF_AB_GPIO3_IN); +} - } while (rx_packets < rx_quota); +static int falcon_getscl(void *data) +{ + struct efx_nic *efx = (struct efx_nic *)data; + efx_oword_t reg; - channel->eventq_read_ptr = read_ptr; - return rx_packets; + efx_reado(efx, ®, FR_AB_GPIO_CTL); + return EFX_OWORD_FIELD(reg, FRF_AB_GPIO0_IN); } +static struct i2c_algo_bit_data falcon_i2c_bit_operations = { + .setsda = falcon_setsda, + .setscl = falcon_setscl, + .getsda = falcon_getsda, + .getscl = falcon_getscl, + .udelay = 5, + /* Wait up to 50 ms for slave to let us pull SCL high */ + .timeout = DIV_ROUND_UP(HZ, 20), +}; + static void falcon_push_irq_moderation(struct efx_channel *channel) { efx_dword_t timer_cmd; @@ -1056,135 +120,6 @@ static void falcon_push_irq_moderation(struct efx_channel *channel) BUILD_BUG_ON(FR_AA_TIMER_COMMAND_KER != FR_BZ_TIMER_COMMAND_P0); efx_writed_page_locked(efx, &timer_cmd, FR_BZ_TIMER_COMMAND_P0, channel->channel); - -} - -/* Allocate buffer table entries for event queue */ -int efx_nic_probe_eventq(struct efx_channel *channel) -{ - struct efx_nic *efx = channel->efx; - BUILD_BUG_ON(EFX_EVQ_SIZE < 512 || EFX_EVQ_SIZE > 32768 || - EFX_EVQ_SIZE & EFX_EVQ_MASK); - return efx_alloc_special_buffer(efx, &channel->eventq, - EFX_EVQ_SIZE * sizeof(efx_qword_t)); -} - -void efx_nic_init_eventq(struct efx_channel *channel) -{ - efx_oword_t evq_ptr; - struct efx_nic *efx = channel->efx; - - EFX_LOG(efx, "channel %d event queue in special buffers %d-%d\n", - channel->channel, channel->eventq.index, - channel->eventq.index + channel->eventq.entries - 1); - - /* Pin event queue buffer */ - efx_init_special_buffer(efx, &channel->eventq); - - /* Fill event queue with all ones (i.e. empty events) */ - memset(channel->eventq.addr, 0xff, channel->eventq.len); - - /* Push event queue to card */ - EFX_POPULATE_OWORD_3(evq_ptr, - FRF_AZ_EVQ_EN, 1, - FRF_AZ_EVQ_SIZE, __ffs(channel->eventq.entries), - FRF_AZ_EVQ_BUF_BASE_ID, channel->eventq.index); - efx_writeo_table(efx, &evq_ptr, efx->type->evq_ptr_tbl_base, - channel->channel); - - efx->type->push_irq_moderation(channel); -} - -void efx_nic_fini_eventq(struct efx_channel *channel) -{ - efx_oword_t eventq_ptr; - struct efx_nic *efx = channel->efx; - - /* Remove event queue from card */ - EFX_ZERO_OWORD(eventq_ptr); - efx_writeo_table(efx, &eventq_ptr, efx->type->evq_ptr_tbl_base, - channel->channel); - - /* Unpin event queue */ - efx_fini_special_buffer(efx, &channel->eventq); -} - -/* Free buffers backing event queue */ -void efx_nic_remove_eventq(struct efx_channel *channel) -{ - efx_free_special_buffer(channel->efx, &channel->eventq); -} - - -/* Generates a test event on the event queue. A subsequent call to - * process_eventq() should pick up the event and place the value of - * "magic" into channel->eventq_magic; - */ -void efx_nic_generate_test_event(struct efx_channel *channel, unsigned int magic) -{ - efx_qword_t test_event; - - EFX_POPULATE_QWORD_2(test_event, FSF_AZ_EV_CODE, - FSE_AZ_EV_CODE_DRV_GEN_EV, - FSF_AZ_DRV_GEN_EV_MAGIC, magic); - efx_generate_event(channel, &test_event); -} - -/************************************************************************** - * - * Flush handling - * - **************************************************************************/ - - -static void efx_poll_flush_events(struct efx_nic *efx) -{ - struct efx_channel *channel = &efx->channel[0]; - struct efx_tx_queue *tx_queue; - struct efx_rx_queue *rx_queue; - unsigned int read_ptr = channel->eventq_read_ptr; - unsigned int end_ptr = (read_ptr - 1) & EFX_EVQ_MASK; - - do { - efx_qword_t *event = efx_event(channel, read_ptr); - int ev_code, ev_sub_code, ev_queue; - bool ev_failed; - - if (!efx_event_present(event)) - break; - - ev_code = EFX_QWORD_FIELD(*event, FSF_AZ_EV_CODE); - ev_sub_code = EFX_QWORD_FIELD(*event, - FSF_AZ_DRIVER_EV_SUBCODE); - if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV && - ev_sub_code == FSE_AZ_TX_DESCQ_FLS_DONE_EV) { - ev_queue = EFX_QWORD_FIELD(*event, - FSF_AZ_DRIVER_EV_SUBDATA); - if (ev_queue < EFX_TX_QUEUE_COUNT) { - tx_queue = efx->tx_queue + ev_queue; - tx_queue->flushed = FLUSH_DONE; - } - } else if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV && - ev_sub_code == FSE_AZ_RX_DESCQ_FLS_DONE_EV) { - ev_queue = EFX_QWORD_FIELD( - *event, FSF_AZ_DRIVER_EV_RX_DESCQ_ID); - ev_failed = EFX_QWORD_FIELD( - *event, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL); - if (ev_queue < efx->n_rx_queues) { - rx_queue = efx->rx_queue + ev_queue; - rx_queue->flushed = - ev_failed ? FLUSH_FAILED : FLUSH_DONE; - } - } - - /* We're about to destroy the queue anyway, so - * it's ok to throw away every non-flush event */ - EFX_SET_QWORD(*event); - - read_ptr = (read_ptr + 1) & EFX_EVQ_MASK; - } while (read_ptr != end_ptr); - - channel->eventq_read_ptr = read_ptr; } static void falcon_deconfigure_mac_wrapper(struct efx_nic *efx); @@ -1199,123 +134,6 @@ static void falcon_prepare_flush(struct efx_nic *efx) msleep(10); } -/* Handle tx and rx flushes at the same time, since they run in - * parallel in the hardware and there's no reason for us to - * serialise them */ -int efx_nic_flush_queues(struct efx_nic *efx) -{ - struct efx_rx_queue *rx_queue; - struct efx_tx_queue *tx_queue; - int i, tx_pending, rx_pending; - - /* If necessary prepare the hardware for flushing */ - efx->type->prepare_flush(efx); - - /* Flush all tx queues in parallel */ - efx_for_each_tx_queue(tx_queue, efx) - efx_flush_tx_queue(tx_queue); - - /* The hardware supports four concurrent rx flushes, each of which may - * need to be retried if there is an outstanding descriptor fetch */ - for (i = 0; i < EFX_FLUSH_POLL_COUNT; ++i) { - rx_pending = tx_pending = 0; - efx_for_each_rx_queue(rx_queue, efx) { - if (rx_queue->flushed == FLUSH_PENDING) - ++rx_pending; - } - efx_for_each_rx_queue(rx_queue, efx) { - if (rx_pending == EFX_RX_FLUSH_COUNT) - break; - if (rx_queue->flushed == FLUSH_FAILED || - rx_queue->flushed == FLUSH_NONE) { - efx_flush_rx_queue(rx_queue); - ++rx_pending; - } - } - efx_for_each_tx_queue(tx_queue, efx) { - if (tx_queue->flushed != FLUSH_DONE) - ++tx_pending; - } - - if (rx_pending == 0 && tx_pending == 0) - return 0; - - msleep(EFX_FLUSH_INTERVAL); - efx_poll_flush_events(efx); - } - - /* Mark the queues as all flushed. We're going to return failure - * leading to a reset, or fake up success anyway */ - efx_for_each_tx_queue(tx_queue, efx) { - if (tx_queue->flushed != FLUSH_DONE) - EFX_ERR(efx, "tx queue %d flush command timed out\n", - tx_queue->queue); - tx_queue->flushed = FLUSH_DONE; - } - efx_for_each_rx_queue(rx_queue, efx) { - if (rx_queue->flushed != FLUSH_DONE) - EFX_ERR(efx, "rx queue %d flush command timed out\n", - rx_queue->queue); - rx_queue->flushed = FLUSH_DONE; - } - - if (EFX_WORKAROUND_7803(efx)) - return 0; - - return -ETIMEDOUT; -} - -/************************************************************************** - * - * Hardware interrupts - * The hardware interrupt handler does very little work; all the event - * queue processing is carried out by per-channel tasklets. - * - **************************************************************************/ - -/* Enable/disable/generate interrupts */ -static inline void efx_nic_interrupts(struct efx_nic *efx, - bool enabled, bool force) -{ - efx_oword_t int_en_reg_ker; - - EFX_POPULATE_OWORD_2(int_en_reg_ker, - FRF_AZ_KER_INT_KER, force, - FRF_AZ_DRV_INT_EN_KER, enabled); - efx_writeo(efx, &int_en_reg_ker, FR_AZ_INT_EN_KER); -} - -void efx_nic_enable_interrupts(struct efx_nic *efx) -{ - struct efx_channel *channel; - - EFX_ZERO_OWORD(*((efx_oword_t *) efx->irq_status.addr)); - wmb(); /* Ensure interrupt vector is clear before interrupts enabled */ - - /* Enable interrupts */ - efx_nic_interrupts(efx, true, false); - - /* Force processing of all the channels to get the EVQ RPTRs up to - date */ - efx_for_each_channel(channel, efx) - efx_schedule_channel(channel); -} - -void efx_nic_disable_interrupts(struct efx_nic *efx) -{ - /* Disable interrupts */ - efx_nic_interrupts(efx, false, false); -} - -/* Generate a test interrupt - * Interrupt must already have been enabled, otherwise nasty things - * may happen. - */ -void efx_nic_generate_interrupt(struct efx_nic *efx) -{ - efx_nic_interrupts(efx, true, true); -} - /* Acknowledge a legacy interrupt from Falcon * * This acknowledges a legacy (not MSI) interrupt via INT_ACK_KER_REG. @@ -1335,102 +153,6 @@ inline void falcon_irq_ack_a1(struct efx_nic *efx) efx_readd(efx, ®, FR_AA_WORK_AROUND_BROKEN_PCI_READS); } -/* Process a fatal interrupt - * Disable bus mastering ASAP and schedule a reset - */ -irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx) -{ - struct falcon_nic_data *nic_data = efx->nic_data; - efx_oword_t *int_ker = efx->irq_status.addr; - efx_oword_t fatal_intr; - int error, mem_perr; - - efx_reado(efx, &fatal_intr, FR_AZ_FATAL_INTR_KER); - error = EFX_OWORD_FIELD(fatal_intr, FRF_AZ_FATAL_INTR); - - EFX_ERR(efx, "SYSTEM ERROR " EFX_OWORD_FMT " status " - EFX_OWORD_FMT ": %s\n", EFX_OWORD_VAL(*int_ker), - EFX_OWORD_VAL(fatal_intr), - error ? "disabling bus mastering" : "no recognised error"); - if (error == 0) - goto out; - - /* If this is a memory parity error dump which blocks are offending */ - mem_perr = EFX_OWORD_FIELD(fatal_intr, FRF_AZ_MEM_PERR_INT_KER); - if (mem_perr) { - efx_oword_t reg; - efx_reado(efx, ®, FR_AZ_MEM_STAT); - EFX_ERR(efx, "SYSTEM ERROR: memory parity error " - EFX_OWORD_FMT "\n", EFX_OWORD_VAL(reg)); - } - - /* Disable both devices */ - pci_clear_master(efx->pci_dev); - if (efx_nic_is_dual_func(efx)) - pci_clear_master(nic_data->pci_dev2); - efx_nic_disable_interrupts(efx); - - /* Count errors and reset or disable the NIC accordingly */ - if (efx->int_error_count == 0 || - time_after(jiffies, efx->int_error_expire)) { - efx->int_error_count = 0; - efx->int_error_expire = - jiffies + EFX_INT_ERROR_EXPIRE * HZ; - } - if (++efx->int_error_count < EFX_MAX_INT_ERRORS) { - EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n"); - efx_schedule_reset(efx, RESET_TYPE_INT_ERROR); - } else { - EFX_ERR(efx, "SYSTEM ERROR - max number of errors seen." - "NIC will be disabled\n"); - efx_schedule_reset(efx, RESET_TYPE_DISABLE); - } -out: - return IRQ_HANDLED; -} - -/* Handle a legacy interrupt - * Acknowledges the interrupt and schedule event queue processing. - */ -static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) -{ - struct efx_nic *efx = dev_id; - efx_oword_t *int_ker = efx->irq_status.addr; - irqreturn_t result = IRQ_NONE; - struct efx_channel *channel; - efx_dword_t reg; - u32 queues; - int syserr; - - /* Read the ISR which also ACKs the interrupts */ - efx_readd(efx, ®, FR_BZ_INT_ISR0); - queues = EFX_EXTRACT_DWORD(reg, 0, 31); - - /* Check to see if we have a serious error condition */ - syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); - if (unlikely(syserr)) - return efx_nic_fatal_interrupt(efx); - - /* Schedule processing of any interrupting queues */ - efx_for_each_channel(channel, efx) { - if ((queues & 1) || - efx_event_present( - efx_event(channel, channel->eventq_read_ptr))) { - efx_schedule_channel(channel); - result = IRQ_HANDLED; - } - queues >>= 1; - } - - if (result == IRQ_HANDLED) { - efx->last_irq_cpu = raw_smp_processor_id(); - EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n", - irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg)); - } - - return result; -} - irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) { @@ -1477,126 +199,6 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) return IRQ_HANDLED; } - -/* Handle an MSI interrupt - * - * Handle an MSI hardware interrupt. This routine schedules event - * queue processing. No interrupt acknowledgement cycle is necessary. - * Also, we never need to check that the interrupt is for us, since - * MSI interrupts cannot be shared. - */ -static irqreturn_t efx_msi_interrupt(int irq, void *dev_id) -{ - struct efx_channel *channel = dev_id; - struct efx_nic *efx = channel->efx; - efx_oword_t *int_ker = efx->irq_status.addr; - int syserr; - - efx->last_irq_cpu = raw_smp_processor_id(); - EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_OWORD_FMT "\n", - irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker)); - - /* Check to see if we have a serious error condition */ - syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); - if (unlikely(syserr)) - return efx_nic_fatal_interrupt(efx); - - /* Schedule processing of the channel */ - efx_schedule_channel(channel); - - return IRQ_HANDLED; -} - - -/* Setup RSS indirection table. - * This maps from the hash value of the packet to RXQ - */ -static void efx_setup_rss_indir_table(struct efx_nic *efx) -{ - int i = 0; - unsigned long offset; - efx_dword_t dword; - - if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) - return; - - for (offset = FR_BZ_RX_INDIRECTION_TBL; - offset < FR_BZ_RX_INDIRECTION_TBL + 0x800; - offset += 0x10) { - EFX_POPULATE_DWORD_1(dword, FRF_BZ_IT_QUEUE, - i % efx->n_rx_queues); - efx_writed(efx, &dword, offset); - i++; - } -} - -/* Hook interrupt handler(s) - * Try MSI and then legacy interrupts. - */ -int efx_nic_init_interrupt(struct efx_nic *efx) -{ - struct efx_channel *channel; - int rc; - - if (!EFX_INT_MODE_USE_MSI(efx)) { - irq_handler_t handler; - if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) - handler = efx_legacy_interrupt; - else - handler = falcon_legacy_interrupt_a1; - - rc = request_irq(efx->legacy_irq, handler, IRQF_SHARED, - efx->name, efx); - if (rc) { - EFX_ERR(efx, "failed to hook legacy IRQ %d\n", - efx->pci_dev->irq); - goto fail1; - } - return 0; - } - - /* Hook MSI or MSI-X interrupt */ - efx_for_each_channel(channel, efx) { - rc = request_irq(channel->irq, efx_msi_interrupt, - IRQF_PROBE_SHARED, /* Not shared */ - channel->name, channel); - if (rc) { - EFX_ERR(efx, "failed to hook IRQ %d\n", channel->irq); - goto fail2; - } - } - - return 0; - - fail2: - efx_for_each_channel(channel, efx) - free_irq(channel->irq, channel); - fail1: - return rc; -} - -void efx_nic_fini_interrupt(struct efx_nic *efx) -{ - struct efx_channel *channel; - efx_oword_t reg; - - /* Disable MSI/MSI-X interrupts */ - efx_for_each_channel(channel, efx) { - if (channel->irq) - free_irq(channel->irq, channel); - } - - /* ACK legacy interrupt */ - if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) - efx_reado(efx, ®, FR_BZ_INT_ISR0); - else - falcon_irq_ack_a1(efx); - - /* Disable legacy interrupt */ - if (efx->legacy_irq) - free_irq(efx->legacy_irq, efx); -} - /************************************************************************** * * EEPROM/flash @@ -2440,68 +1042,6 @@ static const struct efx_nic_register_test falcon_b0_register_tests[] = { EFX_OWORD32(0x0003FF0F, 0x00000000, 0x00000000, 0x00000000) }, }; -static bool efx_masked_compare_oword(const efx_oword_t *a, const efx_oword_t *b, - const efx_oword_t *mask) -{ - return ((a->u64[0] ^ b->u64[0]) & mask->u64[0]) || - ((a->u64[1] ^ b->u64[1]) & mask->u64[1]); -} - -int efx_nic_test_registers(struct efx_nic *efx, - const struct efx_nic_register_test *regs, - size_t n_regs) -{ - unsigned address = 0, i, j; - efx_oword_t mask, imask, original, reg, buf; - - /* Falcon should be in loopback to isolate the XMAC from the PHY */ - WARN_ON(!LOOPBACK_INTERNAL(efx)); - - for (i = 0; i < n_regs; ++i) { - address = regs[i].address; - mask = imask = regs[i].mask; - EFX_INVERT_OWORD(imask); - - efx_reado(efx, &original, address); - - /* bit sweep on and off */ - for (j = 0; j < 128; j++) { - if (!EFX_EXTRACT_OWORD32(mask, j, j)) - continue; - - /* Test this testable bit can be set in isolation */ - EFX_AND_OWORD(reg, original, mask); - EFX_SET_OWORD32(reg, j, j, 1); - - efx_writeo(efx, ®, address); - efx_reado(efx, &buf, address); - - if (efx_masked_compare_oword(®, &buf, &mask)) - goto fail; - - /* Test this testable bit can be cleared in isolation */ - EFX_OR_OWORD(reg, original, mask); - EFX_SET_OWORD32(reg, j, j, 0); - - efx_writeo(efx, ®, address); - efx_reado(efx, &buf, address); - - if (efx_masked_compare_oword(®, &buf, &mask)) - goto fail; - } - - efx_writeo(efx, &original, address); - } - - return 0; - -fail: - EFX_ERR(efx, "wrote "EFX_OWORD_FMT" read "EFX_OWORD_FMT - " at address 0x%x mask "EFX_OWORD_FMT"\n", EFX_OWORD_VAL(reg), - EFX_OWORD_VAL(buf), address, EFX_OWORD_VAL(mask)); - return -EIO; -} - static int falcon_b0_test_registers(struct efx_nic *efx) { return efx_nic_test_registers(efx, falcon_b0_register_tests, @@ -2719,7 +1259,6 @@ static int falcon_spi_device_init(struct efx_nic *efx, return 0; } - static void falcon_remove_spi_devices(struct efx_nic *efx) { kfree(efx->spi_eeprom); @@ -2789,14 +1328,6 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) return rc; } -u32 efx_nic_fpga_ver(struct efx_nic *efx) -{ - efx_oword_t altera_build; - - efx_reado(efx, &altera_build, FR_AZ_ALTERA_BUILD); - return EFX_OWORD_FIELD(altera_build, FRF_AZ_ALTERA_BUILD_VER); -} - /* Probe all SPI devices on the NIC */ static void falcon_probe_spi_devices(struct efx_nic *efx) { @@ -3006,73 +1537,6 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) efx_writeo(efx, ®, FR_AZ_RX_CFG); } -void efx_nic_init_common(struct efx_nic *efx) -{ - efx_oword_t temp; - - /* Set positions of descriptor caches in SRAM. */ - EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_TX_DC_BASE_ADR, - efx->type->tx_dc_base / 8); - efx_writeo(efx, &temp, FR_AZ_SRM_TX_DC_CFG); - EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_RX_DC_BASE_ADR, - efx->type->rx_dc_base / 8); - efx_writeo(efx, &temp, FR_AZ_SRM_RX_DC_CFG); - - /* Set TX descriptor cache size. */ - BUILD_BUG_ON(TX_DC_ENTRIES != (8 << TX_DC_ENTRIES_ORDER)); - EFX_POPULATE_OWORD_1(temp, FRF_AZ_TX_DC_SIZE, TX_DC_ENTRIES_ORDER); - efx_writeo(efx, &temp, FR_AZ_TX_DC_CFG); - - /* Set RX descriptor cache size. Set low watermark to size-8, as - * this allows most efficient prefetching. - */ - BUILD_BUG_ON(RX_DC_ENTRIES != (8 << RX_DC_ENTRIES_ORDER)); - EFX_POPULATE_OWORD_1(temp, FRF_AZ_RX_DC_SIZE, RX_DC_ENTRIES_ORDER); - efx_writeo(efx, &temp, FR_AZ_RX_DC_CFG); - EFX_POPULATE_OWORD_1(temp, FRF_AZ_RX_DC_PF_LWM, RX_DC_ENTRIES - 8); - efx_writeo(efx, &temp, FR_AZ_RX_DC_PF_WM); - - /* Program INT_KER address */ - EFX_POPULATE_OWORD_2(temp, - FRF_AZ_NORM_INT_VEC_DIS_KER, - EFX_INT_MODE_USE_MSI(efx), - FRF_AZ_INT_ADR_KER, efx->irq_status.dma_addr); - efx_writeo(efx, &temp, FR_AZ_INT_ADR_KER); - - /* Enable all the genuinely fatal interrupts. (They are still - * masked by the overall interrupt mask, controlled by - * falcon_interrupts()). - * - * Note: All other fatal interrupts are enabled - */ - EFX_POPULATE_OWORD_3(temp, - FRF_AZ_ILL_ADR_INT_KER_EN, 1, - FRF_AZ_RBUF_OWN_INT_KER_EN, 1, - FRF_AZ_TBUF_OWN_INT_KER_EN, 1); - EFX_INVERT_OWORD(temp); - efx_writeo(efx, &temp, FR_AZ_FATAL_INTR_KER); - - efx_setup_rss_indir_table(efx); - - /* Disable the ugly timer-based TX DMA backoff and allow TX DMA to be - * controlled by the RX FIFO fill level. Set arbitration to one pkt/Q. - */ - efx_reado(efx, &temp, FR_AZ_TX_RESERVED); - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER, 0xfe); - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER_EN, 1); - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_ONE_PKT_PER_Q, 1); - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PUSH_EN, 0); - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_DIS_NON_IP_EV, 1); - /* Enable SW_EV to inherit in char driver - assume harmless here */ - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1); - /* Prefetch threshold 2 => fetch when descriptor cache half empty */ - EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2); - /* Squash TX of packets of 16 bytes or less */ - if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) - EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); - efx_writeo(efx, &temp, FR_AZ_TX_RESERVED); -} - /* This call performs hardware-specific global initialisation, such as * defining the descriptor cache sizes and number of RSS channels. * It does not set up any buffers, descriptor rings or event queues. -- cgit v1.2.2 From 906bb26c0624d87df74e6642f2d74cde176fcc12 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 29 Nov 2009 15:16:19 +0000 Subject: sfc: Update version, copyright dates, authors This driver has been mostly rewritten since Michael Brown's initial work, so swap the order of the authors. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/sfc/falcon.c') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 48d28d828d46..17afcd26e870 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2008 Solarflare Communications Inc. + * Copyright 2006-2009 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published -- cgit v1.2.2