diff options
author | Garen Tamrazian <garenx.tamrazian@intel.com> | 2011-03-30 02:29:32 -0700 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-04-08 07:59:37 -0700 |
commit | 68b993118f715cc631b62b6a50574e4701fe9ace (patch) | |
tree | 4f4a138506a2903f6ecd406b4afc0990d34aa7b8 /drivers/net/wireless/iwlwifi/iwl-rx.c | |
parent | 3ecccbcd3c67374aeee447c08fcb9e39a99f7ee5 (diff) | |
download | op-kernel-dev-68b993118f715cc631b62b6a50574e4701fe9ace.zip op-kernel-dev-68b993118f715cc631b62b6a50574e4701fe9ace.tar.gz |
iwlagn: fix radar frame rejection
The microcode may sometimes reject TX frames when
on a radar channel even after we associated as it
clears information during association and needs to
receive a new beacon before allowing that channel
again. This manifests itself as a TX status value
of TX_STATUS_FAIL_PASSIVE_NO_RX. So in this case,
stop the corresponding queue and give the frame
back to mac80211 for retransmission. We start the
queue again when a beacon from the AP is received
which will make the regulatory enforcement in the
device allow transmitting again.
Signed-off-by: Garen Tamrazian <garenx.tamrazian@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-rx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index c421f56..4472761 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -873,6 +873,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, { struct sk_buff *skb; __le16 fc = hdr->frame_control; + struct iwl_rxon_context *ctx; /* We only process data packets if the interface is open */ if (unlikely(!priv->is_open)) { @@ -895,6 +896,26 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); iwl_update_stats(priv, false, fc, len); + + /* + * Wake any queues that were stopped due to a passive channel tx + * failure. This can happen because the regulatory enforcement in + * the device waits for a beacon before allowing transmission, + * sometimes even after already having transmitted frames for the + * association because the new RXON may reset the information. + */ + if (unlikely(ieee80211_is_beacon(fc))) { + for_each_context(priv, ctx) { + if (!ctx->last_tx_rejected) + continue; + if (compare_ether_addr(hdr->addr3, + ctx->active.bssid_addr)) + continue; + ctx->last_tx_rejected = false; + iwl_wake_any_queue(priv, ctx); + } + } + memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); ieee80211_rx(priv->hw, skb); |