iwlwifi: silently ignore fw flaws in Tx path
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Sun, 2 Dec 2012 07:56:44 +0000 (09:56 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 10 Dec 2012 21:39:28 +0000 (22:39 +0100)
We know that we have issues with the fw in the reclaim path.
This is why iwl_reclaim doesn't complain too loud when it
happens since it is recoverable. Somehow, the caller of
iwl_reclaim however WARNed when it happens. This doesn't
make any sense.

When I digged into the history of that code, I discovered
that this bug occurs only when we receive a BA notification.
So move the W/A in the BA notification handling code where
it was before.

This patch addresses:
http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2387

Cc: stable@vger.kernel.org
Reported-by: Florian Reitmeir <florian@reitmeir.org>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/iwlwifi/dvm/tx.c

index 517562b90fdad946f84f12005df7c7ecb2cfbed8..da21328ca8ed84e9e06e3aebde44fade0973e870 100644 (file)
@@ -1097,29 +1097,6 @@ static void iwl_check_abort_status(struct iwl_priv *priv,
        }
 }
 
-static int iwl_reclaim(struct iwl_priv *priv, int sta_id, int tid,
-                      int txq_id, int ssn, struct sk_buff_head *skbs)
-{
-       if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE &&
-                    tid != IWL_TID_NON_QOS &&
-                    txq_id != priv->tid_data[sta_id][tid].agg.txq_id)) {
-               /*
-                * FIXME: this is a uCode bug which need to be addressed,
-                * log the information and return for now.
-                * Since it is can possibly happen very often and in order
-                * not to fill the syslog, don't use IWL_ERR or IWL_WARN
-                */
-               IWL_DEBUG_TX_QUEUES(priv,
-                       "Bad queue mapping txq_id=%d, agg_txq[sta:%d,tid:%d]=%d\n",
-                       txq_id, sta_id, tid,
-                       priv->tid_data[sta_id][tid].agg.txq_id);
-               return 1;
-       }
-
-       iwl_trans_reclaim(priv->trans, txq_id, ssn, skbs);
-       return 0;
-}
-
 int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd)
 {
@@ -1181,9 +1158,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                                                  next_reclaimed);
                }
 
-               /*we can free until ssn % q.n_bd not inclusive */
-               WARN_ON_ONCE(iwl_reclaim(priv, sta_id, tid,
-                                        txq_id, ssn, &skbs));
+               iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);
+
                iwlagn_check_ratid_empty(priv, sta_id, tid);
                freed = 0;
 
@@ -1308,16 +1284,27 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
                return 0;
        }
 
+       if (unlikely(scd_flow != agg->txq_id)) {
+               /*
+                * FIXME: this is a uCode bug which need to be addressed,
+                * log the information and return for now.
+                * Since it is can possibly happen very often and in order
+                * not to fill the syslog, don't use IWL_ERR or IWL_WARN
+                */
+               IWL_DEBUG_TX_QUEUES(priv,
+                                   "Bad queue mapping txq_id=%d, agg_txq[sta:%d,tid:%d]=%d\n",
+                                   scd_flow, sta_id, tid, agg->txq_id);
+               spin_unlock(&priv->sta_lock);
+               return 0;
+       }
+
        __skb_queue_head_init(&reclaimed_skbs);
 
        /* Release all TFDs before the SSN, i.e. all TFDs in front of
         * block-ack window (we assume that they've been successfully
         * transmitted ... if not, it's too late anyway). */
-       if (iwl_reclaim(priv, sta_id, tid, scd_flow,
-                       ba_resp_scd_ssn, &reclaimed_skbs)) {
-               spin_unlock(&priv->sta_lock);
-               return 0;
-       }
+       iwl_trans_reclaim(priv->trans, scd_flow, ba_resp_scd_ssn,
+                         &reclaimed_skbs);
 
        IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
                           "sta_id = %d\n",