Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=5c0eef960bdb87a53ba390aab7b069b2bc8d7f6d
Commit:     5c0eef960bdb87a53ba390aab7b069b2bc8d7f6d
Parent:     7878a5a4fcc5002e805c054730c4c5639c9d071d
Author:     Mohamed Abbas <[EMAIL PROTECTED]>
AuthorDate: Thu Nov 29 11:10:14 2007 +0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Mon Jan 28 15:05:36 2008 -0800

    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 <[EMAIL PROTECTED]>
    Signed-off-by: Zhu Yi <[EMAIL PROTECTED]>
    Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
---
 drivers/net/wireless/iwlwifi/iwl3945-base.c |   37 ++++++++++++++++++++++++-
 drivers/net/wireless/iwlwifi/iwl4965-base.c |   38 +++++++++++++++++++++++++-
 2 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c 
b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 82c1e0d..3272608 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)
  * Also restock the Rx queue via iwl3945_rx_queue_restock.
  * This is called as a scheduled work item (except for during initialization)
  */
-void iwl3945_rx_replenish(void *data)
+static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
 {
-       struct iwl3945_priv *priv = data;
        struct iwl3945_rx_queue *rxq = &priv->rxq;
        struct list_head *element;
        struct iwl3945_rx_mem_buffer *rxb;
@@ -4158,6 +4157,26 @@ void iwl3945_rx_replenish(void *data)
                rxq->free_count++;
        }
        spin_unlock_irqrestore(&rxq->lock, flags);
+}
+
+/*
+ * this should be called while priv->lock is locked
+ */
+void __iwl3945_rx_replenish(void *data)
+{
+       struct iwl3945_priv *priv = data;
+
+       iwl3945_rx_allocate(priv);
+       iwl3945_rx_queue_restock(priv);
+}
+
+
+void iwl3945_rx_replenish(void *data)
+{
+       struct iwl3945_priv *priv = data;
+       unsigned long flags;
+
+       iwl3945_rx_allocate(priv);
 
        spin_lock_irqsave(&priv->lock, flags);
        iwl3945_rx_queue_restock(priv);
@@ -4335,12 +4354,16 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
        u32 r, i;
        int reclaim;
        unsigned long flags;
+       u8 fill_rx = 0;
+       u32 count = 0;
 
        /* uCode's read index (stored in shared DRAM) indicates the last Rx
         * buffer that the driver may process (last buffer filled by ucode). */
        r = iwl3945_hw_get_rx_read(priv);
        i = rxq->read;
 
+       if (iwl3945_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+               fill_rx = 1;
        /* Rx interrupt, but nothing sent from uCode */
        if (i == r)
                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)
                list_add_tail(&rxb->list, &priv->rxq.rx_used);
                spin_unlock_irqrestore(&rxq->lock, flags);
                i = (i + 1) & RX_QUEUE_MASK;
+               /* If there are a lot of unused frames,
+                * restock the Rx queue so ucode won't assert. */
+               if (fill_rx) {
+                       count++;
+                       if (count >= 8) {
+                               priv->rxq.read = i;
+                               __iwl3945_rx_replenish(priv);
+                               count = 0;
+                       }
+               }
        }
 
        /* Backtrack one entry */
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c 
b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 670f611..6be38ce 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)
  * Also restock the Rx queue via iwl4965_rx_queue_restock.
  * This is called as a scheduled work item (except for during initialization)
  */
-void iwl4965_rx_replenish(void *data)
+static void iwl4965_rx_allocate(struct iwl4965_priv *priv)
 {
-       struct iwl4965_priv *priv = data;
        struct iwl4965_rx_queue *rxq = &priv->rxq;
        struct list_head *element;
        struct iwl4965_rx_mem_buffer *rxb;
@@ -4512,6 +4511,26 @@ void iwl4965_rx_replenish(void *data)
                rxq->free_count++;
        }
        spin_unlock_irqrestore(&rxq->lock, flags);
+}
+
+/*
+ * this should be called while priv->lock is locked
+*/
+void __iwl4965_rx_replenish(void *data)
+{
+       struct iwl4965_priv *priv = data;
+
+       iwl4965_rx_allocate(priv);
+       iwl4965_rx_queue_restock(priv);
+}
+
+
+void iwl4965_rx_replenish(void *data)
+{
+       struct iwl4965_priv *priv = data;
+       unsigned long flags;
+
+       iwl4965_rx_allocate(priv);
 
        spin_lock_irqsave(&priv->lock, flags);
        iwl4965_rx_queue_restock(priv);
@@ -4689,6 +4708,8 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv)
        u32 r, i;
        int reclaim;
        unsigned long flags;
+       u8 fill_rx = 0;
+       u32 count = 0;
 
        /* uCode's read index (stored in shared DRAM) indicates the last Rx
         * buffer that the driver may process (last buffer filled by ucode). */
@@ -4699,6 +4720,9 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv)
        if (i == r)
                IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
 
+       if (iwl4965_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+               fill_rx = 1;
+
        while (i != r) {
                rxb = rxq->queue[i];
 
@@ -4768,6 +4792,16 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv)
                list_add_tail(&rxb->list, &priv->rxq.rx_used);
                spin_unlock_irqrestore(&rxq->lock, flags);
                i = (i + 1) & RX_QUEUE_MASK;
+               /* If there are a lot of unused frames,
+                * restock the Rx queue so ucode wont assert. */
+               if (fill_rx) {
+                       count++;
+                       if (count >= 8) {
+                               priv->rxq.read = i;
+                               __iwl4965_rx_replenish(priv);
+                               count = 0;
+                       }
+               }
        }
 
        /* Backtrack one entry */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to