aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-rx.c
diff options
context:
space:
mode:
authorGaren Tamrazian <garenx.tamrazian@intel.com>2011-03-30 05:29:32 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2011-04-08 10:59:37 -0400
commit68b993118f715cc631b62b6a50574e4701fe9ace (patch)
tree4f4a138506a2903f6ecd406b4afc0990d34aa7b8 /drivers/net/wireless/iwlwifi/iwl-rx.c
parent3ecccbcd3c67374aeee447c08fcb9e39a99f7ee5 (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.c21
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);