diff options
Diffstat (limited to 'drivers/net/sfc/nic.c')
-rw-r--r-- | drivers/net/sfc/nic.c | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index da38659..e839661 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2011 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 @@ -41,26 +41,6 @@ #define RX_DC_ENTRIES 64 #define RX_DC_ENTRIES_ORDER 3 -/* 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. @@ -445,8 +425,8 @@ int efx_nic_probe_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; + efx_oword_t reg; tx_queue->flushed = FLUSH_NONE; @@ -454,7 +434,7 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue) efx_init_special_buffer(efx, &tx_queue->txd); /* Push TX descriptor ring to card */ - EFX_POPULATE_OWORD_10(tx_desc_ptr, + EFX_POPULATE_OWORD_10(reg, FRF_AZ_TX_DESCQ_EN, 1, FRF_AZ_TX_ISCSI_DDIG_EN, 0, FRF_AZ_TX_ISCSI_HDIG_EN, 0, @@ -470,17 +450,15 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue) if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { int csum = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD; - 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, + EFX_SET_OWORD_FIELD(reg, FRF_BZ_TX_IP_CHKSM_DIS, !csum); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_TX_TCP_CHKSM_DIS, !csum); } - efx_writeo_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, + efx_writeo_table(efx, ®, 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_MAX_TX_QUEUES > 128); @@ -491,6 +469,16 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue) set_bit_le(tx_queue->queue, (void *)®); efx_writeo(efx, ®, FR_AA_TX_CHKSM_CFG); } + + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { + EFX_POPULATE_OWORD_1(reg, + FRF_BZ_TX_PACE, + (tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI) ? + FFE_BZ_TX_PACE_OFF : + FFE_BZ_TX_PACE_RESERVED); + efx_writeo_table(efx, ®, FR_BZ_TX_PACE_TBL, + tx_queue->queue); + } } static void efx_flush_tx_queue(struct efx_tx_queue *tx_queue) @@ -1238,8 +1226,10 @@ int efx_nic_flush_queues(struct efx_nic *efx) /* Flush all tx queues in parallel */ efx_for_each_channel(channel, efx) { - efx_for_each_channel_tx_queue(tx_queue, channel) - efx_flush_tx_queue(tx_queue); + efx_for_each_possible_channel_tx_queue(tx_queue, channel) { + if (tx_queue->initialised) + efx_flush_tx_queue(tx_queue); + } } /* The hardware supports four concurrent rx flushes, each of which may @@ -1262,8 +1252,9 @@ int efx_nic_flush_queues(struct efx_nic *efx) ++rx_pending; } } - efx_for_each_channel_tx_queue(tx_queue, channel) { - if (tx_queue->flushed != FLUSH_DONE) + efx_for_each_possible_channel_tx_queue(tx_queue, channel) { + if (tx_queue->initialised && + tx_queue->flushed != FLUSH_DONE) ++tx_pending; } } @@ -1278,8 +1269,9 @@ int efx_nic_flush_queues(struct efx_nic *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_channel(channel, efx) { - efx_for_each_channel_tx_queue(tx_queue, channel) { - if (tx_queue->flushed != FLUSH_DONE) + efx_for_each_possible_channel_tx_queue(tx_queue, channel) { + if (tx_queue->initialised && + tx_queue->flushed != FLUSH_DONE) netif_err(efx, hw, efx->net_dev, "tx queue %d flush command timed out\n", tx_queue->queue); @@ -1682,6 +1674,19 @@ void efx_nic_init_common(struct efx_nic *efx) 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); + + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { + EFX_POPULATE_OWORD_4(temp, + /* Default values */ + FRF_BZ_TX_PACE_SB_NOT_AF, 0x15, + FRF_BZ_TX_PACE_SB_AF, 0xb, + FRF_BZ_TX_PACE_FB_BASE, 0, + /* Allow large pace values in the + * fast bin. */ + FRF_BZ_TX_PACE_BIN_TH, + FFE_BZ_TX_PACE_RESERVED); + efx_writeo(efx, &temp, FR_BZ_TX_PACE); + } } /* Register dump */ |