aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl4965-base.c
diff options
context:
space:
mode:
authorMohamed Abbas <mabbas@linux.intel.com>2007-11-28 22:10:14 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:05:36 -0500
commit5c0eef960bdb87a53ba390aab7b069b2bc8d7f6d (patch)
tree7c219792536fc1bfcbdf35ae2741a0621f3ccdea /drivers/net/wireless/iwlwifi/iwl4965-base.c
parent7878a5a4fcc5002e805c054730c4c5639c9d071d (diff)
iwlwifi: fix ucode assertion for RX queue overrun
This patch allows the driver to restock the RX queue early if the RX queue is almost empty. This will help on avoiding any ucode assert for the RX overrun problem. Signed-off-by: Mohamed Abbas <mabbas@linux.intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 670f611adf9f..6be38ce701f5 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -4477,9 +4477,8 @@ static int iwl4965_rx_queue_restock(struct iwl4965_priv *priv)
4477 * Also restock the Rx queue via iwl4965_rx_queue_restock. 4477 * Also restock the Rx queue via iwl4965_rx_queue_restock.
4478 * This is called as a scheduled work item (except for during initialization) 4478 * This is called as a scheduled work item (except for during initialization)
4479 */ 4479 */
4480void iwl4965_rx_replenish(void *data) 4480static void iwl4965_rx_allocate(struct iwl4965_priv *priv)
4481{ 4481{
4482 struct iwl4965_priv *priv = data;
4483 struct iwl4965_rx_queue *rxq = &priv->rxq; 4482 struct iwl4965_rx_queue *rxq = &priv->rxq;
4484 struct list_head *element; 4483 struct list_head *element;
4485 struct iwl4965_rx_mem_buffer *rxb; 4484 struct iwl4965_rx_mem_buffer *rxb;
@@ -4512,6 +4511,26 @@ void iwl4965_rx_replenish(void *data)
4512 rxq->free_count++; 4511 rxq->free_count++;
4513 } 4512 }
4514 spin_unlock_irqrestore(&rxq->lock, flags); 4513 spin_unlock_irqrestore(&rxq->lock, flags);
4514}
4515
4516/*
4517 * this should be called while priv->lock is locked
4518*/
4519void __iwl4965_rx_replenish(void *data)
4520{
4521 struct iwl4965_priv *priv = data;
4522
4523 iwl4965_rx_allocate(priv);
4524 iwl4965_rx_queue_restock(priv);
4525}
4526
4527
4528void iwl4965_rx_replenish(void *data)
4529{
4530 struct iwl4965_priv *priv = data;
4531 unsigned long flags;
4532
4533 iwl4965_rx_allocate(priv);
4515 4534
4516 spin_lock_irqsave(&priv->lock, flags); 4535 spin_lock_irqsave(&priv->lock, flags);
4517 iwl4965_rx_queue_restock(priv); 4536 iwl4965_rx_queue_restock(priv);
@@ -4689,6 +4708,8 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv)
4689 u32 r, i; 4708 u32 r, i;
4690 int reclaim; 4709 int reclaim;
4691 unsigned long flags; 4710 unsigned long flags;
4711 u8 fill_rx = 0;
4712 u32 count = 0;
4692 4713
4693 /* uCode's read index (stored in shared DRAM) indicates the last Rx 4714 /* uCode's read index (stored in shared DRAM) indicates the last Rx
4694 * buffer that the driver may process (last buffer filled by ucode). */ 4715 * buffer that the driver may process (last buffer filled by ucode). */
@@ -4699,6 +4720,9 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv)
4699 if (i == r) 4720 if (i == r)
4700 IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i); 4721 IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
4701 4722
4723 if (iwl4965_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
4724 fill_rx = 1;
4725
4702 while (i != r) { 4726 while (i != r) {
4703 rxb = rxq->queue[i]; 4727 rxb = rxq->queue[i];
4704 4728
@@ -4768,6 +4792,16 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv)
4768 list_add_tail(&rxb->list, &priv->rxq.rx_used); 4792 list_add_tail(&rxb->list, &priv->rxq.rx_used);
4769 spin_unlock_irqrestore(&rxq->lock, flags); 4793 spin_unlock_irqrestore(&rxq->lock, flags);
4770 i = (i + 1) & RX_QUEUE_MASK; 4794 i = (i + 1) & RX_QUEUE_MASK;
4795 /* If there are a lot of unused frames,
4796 * restock the Rx queue so ucode wont assert. */
4797 if (fill_rx) {
4798 count++;
4799 if (count >= 8) {
4800 priv->rxq.read = i;
4801 __iwl4965_rx_replenish(priv);
4802 count = 0;
4803 }
4804 }
4771 } 4805 }
4772 4806
4773 /* Backtrack one entry */ 4807 /* Backtrack one entry */