diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2012-12-02 02:56:44 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-12-10 16:39:28 -0500 |
commit | 27edb1accf5695ff00a32c85c4a00ac7e1e7f298 (patch) | |
tree | 30c19e68800a11387af9068e40f09c8ce835becd | |
parent | 8907a6fb6281a9aa25df2c7e2996cedcd6e5559f (diff) |
iwlwifi: silently ignore fw flaws in Tx path
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>
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/tx.c | 49 |
1 files changed, 18 insertions, 31 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 517562b90fda..da21328ca8ed 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -1097,29 +1097,6 @@ static void iwl_check_abort_status(struct iwl_priv *priv, | |||
1097 | } | 1097 | } |
1098 | } | 1098 | } |
1099 | 1099 | ||
1100 | static int iwl_reclaim(struct iwl_priv *priv, int sta_id, int tid, | ||
1101 | int txq_id, int ssn, struct sk_buff_head *skbs) | ||
1102 | { | ||
1103 | if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE && | ||
1104 | tid != IWL_TID_NON_QOS && | ||
1105 | txq_id != priv->tid_data[sta_id][tid].agg.txq_id)) { | ||
1106 | /* | ||
1107 | * FIXME: this is a uCode bug which need to be addressed, | ||
1108 | * log the information and return for now. | ||
1109 | * Since it is can possibly happen very often and in order | ||
1110 | * not to fill the syslog, don't use IWL_ERR or IWL_WARN | ||
1111 | */ | ||
1112 | IWL_DEBUG_TX_QUEUES(priv, | ||
1113 | "Bad queue mapping txq_id=%d, agg_txq[sta:%d,tid:%d]=%d\n", | ||
1114 | txq_id, sta_id, tid, | ||
1115 | priv->tid_data[sta_id][tid].agg.txq_id); | ||
1116 | return 1; | ||
1117 | } | ||
1118 | |||
1119 | iwl_trans_reclaim(priv->trans, txq_id, ssn, skbs); | ||
1120 | return 0; | ||
1121 | } | ||
1122 | |||
1123 | int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | 1100 | int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
1124 | struct iwl_device_cmd *cmd) | 1101 | struct iwl_device_cmd *cmd) |
1125 | { | 1102 | { |
@@ -1181,9 +1158,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1181 | next_reclaimed); | 1158 | next_reclaimed); |
1182 | } | 1159 | } |
1183 | 1160 | ||
1184 | /*we can free until ssn % q.n_bd not inclusive */ | 1161 | iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs); |
1185 | WARN_ON_ONCE(iwl_reclaim(priv, sta_id, tid, | 1162 | |
1186 | txq_id, ssn, &skbs)); | ||
1187 | iwlagn_check_ratid_empty(priv, sta_id, tid); | 1163 | iwlagn_check_ratid_empty(priv, sta_id, tid); |
1188 | freed = 0; | 1164 | freed = 0; |
1189 | 1165 | ||
@@ -1308,16 +1284,27 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1308 | return 0; | 1284 | return 0; |
1309 | } | 1285 | } |
1310 | 1286 | ||
1287 | if (unlikely(scd_flow != agg->txq_id)) { | ||
1288 | /* | ||
1289 | * FIXME: this is a uCode bug which need to be addressed, | ||
1290 | * log the information and return for now. | ||
1291 | * Since it is can possibly happen very often and in order | ||
1292 | * not to fill the syslog, don't use IWL_ERR or IWL_WARN | ||
1293 | */ | ||
1294 | IWL_DEBUG_TX_QUEUES(priv, | ||
1295 | "Bad queue mapping txq_id=%d, agg_txq[sta:%d,tid:%d]=%d\n", | ||
1296 | scd_flow, sta_id, tid, agg->txq_id); | ||
1297 | spin_unlock(&priv->sta_lock); | ||
1298 | return 0; | ||
1299 | } | ||
1300 | |||
1311 | __skb_queue_head_init(&reclaimed_skbs); | 1301 | __skb_queue_head_init(&reclaimed_skbs); |
1312 | 1302 | ||
1313 | /* Release all TFDs before the SSN, i.e. all TFDs in front of | 1303 | /* Release all TFDs before the SSN, i.e. all TFDs in front of |
1314 | * block-ack window (we assume that they've been successfully | 1304 | * block-ack window (we assume that they've been successfully |
1315 | * transmitted ... if not, it's too late anyway). */ | 1305 | * transmitted ... if not, it's too late anyway). */ |
1316 | if (iwl_reclaim(priv, sta_id, tid, scd_flow, | 1306 | iwl_trans_reclaim(priv->trans, scd_flow, ba_resp_scd_ssn, |
1317 | ba_resp_scd_ssn, &reclaimed_skbs)) { | 1307 | &reclaimed_skbs); |
1318 | spin_unlock(&priv->sta_lock); | ||
1319 | return 0; | ||
1320 | } | ||
1321 | 1308 | ||
1322 | IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " | 1309 | IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " |
1323 | "sta_id = %d\n", | 1310 | "sta_id = %d\n", |