diff options
author | Garen Tamrazian <garenx.tamrazian@intel.com> | 2011-03-30 05:29:32 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-04-08 10:59:37 -0400 |
commit | 68b993118f715cc631b62b6a50574e4701fe9ace (patch) | |
tree | 4f4a138506a2903f6ecd406b4afc0990d34aa7b8 /drivers/net/wireless/iwlwifi/iwl-rx.c | |
parent | 3ecccbcd3c67374aeee447c08fcb9e39a99f7ee5 (diff) |
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 c421f566982f..4472761fc591 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, | |||
873 | { | 873 | { |
874 | struct sk_buff *skb; | 874 | struct sk_buff *skb; |
875 | __le16 fc = hdr->frame_control; | 875 | __le16 fc = hdr->frame_control; |
876 | struct iwl_rxon_context *ctx; | ||
876 | 877 | ||
877 | /* We only process data packets if the interface is open */ | 878 | /* We only process data packets if the interface is open */ |
878 | if (unlikely(!priv->is_open)) { | 879 | if (unlikely(!priv->is_open)) { |
@@ -895,6 +896,26 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
895 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); | 896 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); |
896 | 897 | ||
897 | iwl_update_stats(priv, false, fc, len); | 898 | iwl_update_stats(priv, false, fc, len); |
899 | |||
900 | /* | ||
901 | * Wake any queues that were stopped due to a passive channel tx | ||
902 | * failure. This can happen because the regulatory enforcement in | ||
903 | * the device waits for a beacon before allowing transmission, | ||
904 | * sometimes even after already having transmitted frames for the | ||
905 | * association because the new RXON may reset the information. | ||
906 | */ | ||
907 | if (unlikely(ieee80211_is_beacon(fc))) { | ||
908 | for_each_context(priv, ctx) { | ||
909 | if (!ctx->last_tx_rejected) | ||
910 | continue; | ||
911 | if (compare_ether_addr(hdr->addr3, | ||
912 | ctx->active.bssid_addr)) | ||
913 | continue; | ||
914 | ctx->last_tx_rejected = false; | ||
915 | iwl_wake_any_queue(priv, ctx); | ||
916 | } | ||
917 | } | ||
918 | |||
898 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | 919 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
899 | 920 | ||
900 | ieee80211_rx(priv->hw, skb); | 921 | ieee80211_rx(priv->hw, skb); |