aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 82c1e0d45cf..3272608ced8 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4123,9 +4123,8 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
4123 * Also restock the Rx queue via iwl3945_rx_queue_restock. 4123 * Also restock the Rx queue via iwl3945_rx_queue_restock.
4124 * This is called as a scheduled work item (except for during initialization) 4124 * This is called as a scheduled work item (except for during initialization)
4125 */ 4125 */
4126void iwl3945_rx_replenish(void *data) 4126static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
4127{ 4127{
4128 struct iwl3945_priv *priv = data;
4129 struct iwl3945_rx_queue *rxq = &priv->rxq; 4128 struct iwl3945_rx_queue *rxq = &priv->rxq;
4130 struct list_head *element; 4129 struct list_head *element;
4131 struct iwl3945_rx_mem_buffer *rxb; 4130 struct iwl3945_rx_mem_buffer *rxb;
@@ -4158,6 +4157,26 @@ void iwl3945_rx_replenish(void *data)
4158 rxq->free_count++; 4157 rxq->free_count++;
4159 } 4158 }
4160 spin_unlock_irqrestore(&rxq->lock, flags); 4159 spin_unlock_irqrestore(&rxq->lock, flags);
4160}
4161
4162/*
4163 * this should be called while priv->lock is locked
4164 */
4165void __iwl3945_rx_replenish(void *data)
4166{
4167 struct iwl3945_priv *priv = data;
4168
4169 iwl3945_rx_allocate(priv);
4170 iwl3945_rx_queue_restock(priv);
4171}
4172
4173
4174void iwl3945_rx_replenish(void *data)
4175{
4176 struct iwl3945_priv *priv = data;
4177 unsigned long flags;
4178
4179 iwl3945_rx_allocate(priv);
4161 4180
4162 spin_lock_irqsave(&priv->lock, flags); 4181 spin_lock_irqsave(&priv->lock, flags);
4163 iwl3945_rx_queue_restock(priv); 4182 iwl3945_rx_queue_restock(priv);
@@ -4335,12 +4354,16 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
4335 u32 r, i; 4354 u32 r, i;
4336 int reclaim; 4355 int reclaim;
4337 unsigned long flags; 4356 unsigned long flags;
4357 u8 fill_rx = 0;
4358 u32 count = 0;
4338 4359
4339 /* uCode's read index (stored in shared DRAM) indicates the last Rx 4360 /* uCode's read index (stored in shared DRAM) indicates the last Rx
4340 * buffer that the driver may process (last buffer filled by ucode). */ 4361 * buffer that the driver may process (last buffer filled by ucode). */
4341 r = iwl3945_hw_get_rx_read(priv); 4362 r = iwl3945_hw_get_rx_read(priv);
4342 i = rxq->read; 4363 i = rxq->read;
4343 4364
4365 if (iwl3945_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
4366 fill_rx = 1;
4344 /* Rx interrupt, but nothing sent from uCode */ 4367 /* Rx interrupt, but nothing sent from uCode */
4345 if (i == r) 4368 if (i == r)
4346 IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i); 4369 IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
@@ -4411,6 +4434,16 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
4411 list_add_tail(&rxb->list, &priv->rxq.rx_used); 4434 list_add_tail(&rxb->list, &priv->rxq.rx_used);
4412 spin_unlock_irqrestore(&rxq->lock, flags); 4435 spin_unlock_irqrestore(&rxq->lock, flags);
4413 i = (i + 1) & RX_QUEUE_MASK; 4436 i = (i + 1) & RX_QUEUE_MASK;
4437 /* If there are a lot of unused frames,
4438 * restock the Rx queue so ucode won't assert. */
4439 if (fill_rx) {
4440 count++;
4441 if (count >= 8) {
4442 priv->rxq.read = i;
4443 __iwl3945_rx_replenish(priv);
4444 count = 0;
4445 }
4446 }
4414 } 4447 }
4415 4448
4416 /* Backtrack one entry */ 4449 /* Backtrack one entry */