aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-trans.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-trans.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
index ca969028710..6b7cb73442b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -64,6 +64,7 @@
64#include "iwl-trans.h" 64#include "iwl-trans.h"
65#include "iwl-core.h" 65#include "iwl-core.h"
66#include "iwl-helpers.h" 66#include "iwl-helpers.h"
67#include "iwl-trans-int-pcie.h"
67/*TODO remove uneeded includes when the transport layer tx_free will be here */ 68/*TODO remove uneeded includes when the transport layer tx_free will be here */
68#include "iwl-agn.h" 69#include "iwl-agn.h"
69#include "iwl-core.h" 70#include "iwl-core.h"
@@ -127,6 +128,55 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_priv *priv)
127 } 128 }
128} 129}
129 130
131static void iwl_trans_rx_hw_init(struct iwl_priv *priv,
132 struct iwl_rx_queue *rxq)
133{
134 u32 rb_size;
135 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
136 u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
137
138 rb_timeout = RX_RB_TIMEOUT;
139
140 if (iwlagn_mod_params.amsdu_size_8K)
141 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
142 else
143 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
144
145 /* Stop Rx DMA */
146 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
147
148 /* Reset driver's Rx queue write index */
149 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
150
151 /* Tell device where to find RBD circular buffer in DRAM */
152 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
153 (u32)(rxq->bd_dma >> 8));
154
155 /* Tell device where in DRAM to update its Rx status */
156 iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
157 rxq->rb_stts_dma >> 4);
158
159 /* Enable Rx DMA
160 * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
161 * the credit mechanism in 5000 HW RX FIFO
162 * Direct rx interrupts to hosts
163 * Rx buffer size 4 or 8k
164 * RB timeout 0x10
165 * 256 RBDs
166 */
167 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
168 FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
169 FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
170 FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
171 FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
172 rb_size|
173 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
174 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
175
176 /* Set interrupt coalescing timer to default (2048 usecs) */
177 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
178}
179
130static int iwl_trans_rx_init(struct iwl_priv *priv) 180static int iwl_trans_rx_init(struct iwl_priv *priv)
131{ 181{
132 struct iwl_rx_queue *rxq = &priv->rxq; 182 struct iwl_rx_queue *rxq = &priv->rxq;
@@ -155,6 +205,15 @@ static int iwl_trans_rx_init(struct iwl_priv *priv)
155 rxq->free_count = 0; 205 rxq->free_count = 0;
156 spin_unlock_irqrestore(&rxq->lock, flags); 206 spin_unlock_irqrestore(&rxq->lock, flags);
157 207
208 iwlagn_rx_replenish(priv);
209
210 iwl_trans_rx_hw_init(priv, rxq);
211
212 spin_lock_irqsave(&priv->lock, flags);
213 rxq->need_update = 1;
214 iwl_rx_queue_update_write_ptr(priv, rxq);
215 spin_unlock_irqrestore(&priv->lock, flags);
216
158 return 0; 217 return 0;
159} 218}
160 219
@@ -756,5 +815,7 @@ int iwl_trans_register(struct iwl_priv *priv)
756 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 815 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
757 iwl_irq_tasklet, (unsigned long)priv); 816 iwl_irq_tasklet, (unsigned long)priv);
758 817
818 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
819
759 return 0; 820 return 0;
760} 821}