diff options
Diffstat (limited to 'net/mac80211/rx.c')
| -rw-r--r-- | net/mac80211/rx.c | 205 |
1 files changed, 78 insertions, 127 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index bcfe8c77c839..0cb4edee6af5 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -94,7 +94,7 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local, return len; } -/* +/** * ieee80211_add_rx_radiotap_header - add radiotap header * * add a radiotap header containing all the fields which the hardware provided. @@ -103,7 +103,7 @@ static void ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, struct sk_buff *skb, struct ieee80211_rate *rate, - int rtap_len) + int rtap_len, bool has_fcs) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_radiotap_header *rthdr; @@ -134,7 +134,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, } /* IEEE80211_RADIOTAP_FLAGS */ - if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) + if (has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)) *pos |= IEEE80211_RADIOTAP_F_FCS; if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) *pos |= IEEE80211_RADIOTAP_F_BADFCS; @@ -204,14 +204,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, if (status->flag & RX_FLAG_HT) { rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS); - *pos++ = IEEE80211_RADIOTAP_MCS_HAVE_MCS | - IEEE80211_RADIOTAP_MCS_HAVE_GI | - IEEE80211_RADIOTAP_MCS_HAVE_BW; + *pos++ = local->hw.radiotap_mcs_details; *pos = 0; if (status->flag & RX_FLAG_SHORT_GI) *pos |= IEEE80211_RADIOTAP_MCS_SGI; if (status->flag & RX_FLAG_40MHZ) *pos |= IEEE80211_RADIOTAP_MCS_BW_40; + if (status->flag & RX_FLAG_HT_GF) + *pos |= IEEE80211_RADIOTAP_MCS_FMT_GF; pos++; *pos++ = status->rate_idx; } @@ -294,7 +294,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, } /* prepend radiotap information */ - ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); + ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom, + true); skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -412,28 +413,6 @@ static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx) /* rx handlers */ -static ieee80211_rx_result debug_noinline -ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) -{ - struct ieee80211_local *local = rx->local; - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); - struct sk_buff *skb = rx->skb; - - if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN) && - !local->sched_scanning)) - return RX_CONTINUE; - - if (test_bit(SCAN_HW_SCANNING, &local->scanning) || - test_bit(SCAN_SW_SCANNING, &local->scanning) || - local->sched_scanning) - return ieee80211_scan_rx(rx->sdata, skb); - - /* scanning finished during invoking of handlers */ - I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); - return RX_DROP_UNUSABLE; -} - - static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; @@ -490,12 +469,12 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) if (ieee80211_has_tods(hdr->frame_control) || !ieee80211_has_fromds(hdr->frame_control)) return RX_DROP_MONITOR; - if (compare_ether_addr(hdr->addr3, dev_addr) == 0) + if (ether_addr_equal(hdr->addr3, dev_addr)) return RX_DROP_MONITOR; } else { if (!ieee80211_has_a4(hdr->frame_control)) return RX_DROP_MONITOR; - if (compare_ether_addr(hdr->addr4, dev_addr) == 0) + if (ether_addr_equal(hdr->addr4, dev_addr)) return RX_DROP_MONITOR; } } @@ -552,11 +531,11 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) } -static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, +static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx, int index) { - struct ieee80211_local *local = hw_to_local(hw); + struct ieee80211_local *local = sdata->local; struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; struct ieee80211_rx_status *status; @@ -576,7 +555,7 @@ no_frame: tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); } -static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, +static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx, u16 head_seq_num) { @@ -587,7 +566,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; - ieee80211_release_reorder_frame(hw, tid_agg_rx, index); + ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); } } @@ -602,7 +581,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, */ #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) -static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, +static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx) { int index, j; @@ -630,12 +609,9 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, HT_RX_REORDER_BUF_TIMEOUT)) goto set_release_timer; -#ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - wiphy_debug(hw->wiphy, - "release an RX reorder frame due to timeout on earlier frames\n"); -#endif - ieee80211_release_reorder_frame(hw, tid_agg_rx, j); + ht_dbg_ratelimited(sdata, + "release an RX reorder frame due to timeout on earlier frames\n"); + ieee80211_release_reorder_frame(sdata, tid_agg_rx, j); /* * Increment the head seq# also for the skipped slots. @@ -645,7 +621,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, skipped = 0; } } else while (tid_agg_rx->reorder_buf[index]) { - ieee80211_release_reorder_frame(hw, tid_agg_rx, index); + ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; } @@ -675,7 +651,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, * rcu_read_lock protection. It returns false if the frame * can be processed immediately, true if it was consumed. */ -static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, +static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx, struct sk_buff *skb) { @@ -704,7 +680,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); /* release stored frames up to new head to stack */ - ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num); + ieee80211_release_reorder_frames(sdata, tid_agg_rx, + head_seq_num); } /* Now the new frame is always in the range of the reordering buffer */ @@ -734,7 +711,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, tid_agg_rx->reorder_buf[index] = skb; tid_agg_rx->reorder_time[index] = jiffies; tid_agg_rx->stored_mpdu_num++; - ieee80211_sta_reorder_release(hw, tid_agg_rx); + ieee80211_sta_reorder_release(sdata, tid_agg_rx); out: spin_unlock(&tid_agg_rx->reorder_lock); @@ -749,7 +726,6 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) { struct sk_buff *skb = rx->skb; struct ieee80211_local *local = rx->local; - struct ieee80211_hw *hw = &local->hw; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct sta_info *sta = rx->sta; @@ -793,8 +769,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) /* reset session timer */ if (tid_agg_rx->timeout) - mod_timer(&tid_agg_rx->session_timer, - TU_TO_EXP_TIME(tid_agg_rx->timeout)); + tid_agg_rx->last_rx = jiffies; /* if this mpdu is fragmented - terminate rx aggregation session */ sc = le16_to_cpu(hdr->seq_ctrl); @@ -812,7 +787,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) * sure that we cannot get to it any more before doing * anything with it. */ - if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb)) + if (ieee80211_sta_manage_reorder_buf(rx->sdata, tid_agg_rx, skb)) return; dont_reorder: @@ -1135,24 +1110,18 @@ static void ap_sta_ps_start(struct sta_info *sta) set_sta_flag(sta, WLAN_STA_PS_STA); if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", - sdata->name, sta->sta.addr, sta->sta.aid); -#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ + ps_dbg(sdata, "STA %pM aid %d enters power save mode\n", + sta->sta.addr, sta->sta.aid); } static void ap_sta_ps_end(struct sta_info *sta) { -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", - sta->sdata->name, sta->sta.addr, sta->sta.aid); -#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ + ps_dbg(sta->sdata, "STA %pM aid %d exits power save mode\n", + sta->sta.addr, sta->sta.aid); if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { -#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", - sta->sdata->name, sta->sta.addr, sta->sta.aid); -#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ + ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", + sta->sta.addr, sta->sta.aid); return; } @@ -1274,7 +1243,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) { u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, NL80211_IFTYPE_ADHOC); - if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0) { + if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid)) { sta->last_rx = jiffies; if (ieee80211_is_data(hdr->frame_control)) { sta->last_rx_rate_idx = status->rate_idx; @@ -1382,19 +1351,8 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) sdata->fragment_next = 0; - if (!skb_queue_empty(&entry->skb_list)) { -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *) entry->skb_list.next->data; - printk(KERN_DEBUG "%s: RX reassembly removed oldest " - "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " - "addr1=%pM addr2=%pM\n", - sdata->name, idx, - jiffies - entry->first_frag_time, entry->seq, - entry->last_frag, hdr->addr1, hdr->addr2); -#endif + if (!skb_queue_empty(&entry->skb_list)) __skb_queue_purge(&entry->skb_list); - } __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ *skb = NULL; @@ -1437,8 +1395,8 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, */ if (((hdr->frame_control ^ f_hdr->frame_control) & cpu_to_le16(IEEE80211_FCTL_FTYPE)) || - compare_ether_addr(hdr->addr1, f_hdr->addr1) != 0 || - compare_ether_addr(hdr->addr2, f_hdr->addr2) != 0) + !ether_addr_equal(hdr->addr1, f_hdr->addr1) || + !ether_addr_equal(hdr->addr2, f_hdr->addr2)) continue; if (time_after(jiffies, entry->first_frag_time + 2 * HZ)) { @@ -1713,8 +1671,8 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) * of whether the frame was encrypted or not. */ if (ehdr->h_proto == rx->sdata->control_port_protocol && - (compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 || - compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) + (ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) || + ether_addr_equal(ehdr->h_dest, pae_group_addr))) return true; if (ieee80211_802_1x_port_control(rx) || @@ -1751,9 +1709,9 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) * local net stack and back to the wireless medium */ xmit_skb = skb_copy(skb, GFP_ATOMIC); - if (!xmit_skb && net_ratelimit()) - printk(KERN_DEBUG "%s: failed to clone " - "multicast frame\n", dev->name); + if (!xmit_skb) + net_info_ratelimited("%s: failed to clone multicast frame\n", + dev->name); } else { dsta = sta_info_get(sdata, skb->data); if (dsta) { @@ -1924,7 +1882,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) mpp_path_add(proxied_addr, mpp_addr, sdata); } else { spin_lock_bh(&mppath->state_lock); - if (compare_ether_addr(mppath->mpp, mpp_addr) != 0) + if (!ether_addr_equal(mppath->mpp, mpp_addr)) memcpy(mppath->mpp, mpp_addr, ETH_ALEN); spin_unlock_bh(&mppath->state_lock); } @@ -1933,10 +1891,10 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) /* Frame has reached destination. Don't forward */ if (!is_multicast_ether_addr(hdr->addr1) && - compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0) + ether_addr_equal(sdata->vif.addr, hdr->addr3)) return RX_CONTINUE; - q = ieee80211_select_queue_80211(local, skb, hdr); + q = ieee80211_select_queue_80211(sdata, skb, hdr); if (ieee80211_queue_stopped(&local->hw, q)) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); return RX_DROP_MONITOR; @@ -1956,9 +1914,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) fwd_skb = skb_copy(skb, GFP_ATOMIC); if (!fwd_skb) { - if (net_ratelimit()) - printk(KERN_DEBUG "%s: failed to clone mesh frame\n", - sdata->name); + net_info_ratelimited("%s: failed to clone mesh frame\n", + sdata->name); goto out; } @@ -2060,8 +2017,6 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) static ieee80211_rx_result debug_noinline ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) { - struct ieee80211_local *local = rx->local; - struct ieee80211_hw *hw = &local->hw; struct sk_buff *skb = rx->skb; struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; struct tid_ampdu_rx *tid_agg_rx; @@ -2098,7 +2053,8 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) spin_lock(&tid_agg_rx->reorder_lock); /* release stored frames up to start of BAR */ - ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num); + ieee80211_release_reorder_frames(rx->sdata, tid_agg_rx, + start_seq_num); spin_unlock(&tid_agg_rx->reorder_lock); kfree_skb(skb); @@ -2121,13 +2077,13 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb; struct ieee80211_mgmt *resp; - if (compare_ether_addr(mgmt->da, sdata->vif.addr) != 0) { + if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) { /* Not to own unicast address */ return; } - if (compare_ether_addr(mgmt->sa, sdata->u.mgd.bssid) != 0 || - compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid) != 0) { + if (!ether_addr_equal(mgmt->sa, sdata->u.mgd.bssid) || + !ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid)) { /* Not from the current AP or not associated yet. */ return; } @@ -2269,11 +2225,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) sband = rx->local->hw.wiphy->bands[status->band]; - rate_control_rate_update( - local, sband, rx->sta, - IEEE80211_RC_SMPS_CHANGED, - ieee80211_get_tx_channel_type( - local, local->_oper_channel_type)); + rate_control_rate_update(local, sband, rx->sta, + IEEE80211_RC_SMPS_CHANGED); goto handled; } default: @@ -2340,7 +2293,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) if (sdata->vif.type != NL80211_IFTYPE_STATION) break; - if (compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid)) + if (!ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid)) break; goto queue; @@ -2428,7 +2381,7 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) sig = status->signal; - if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, sig, + if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig, rx->skb->data, rx->skb->len, GFP_ATOMIC)) { if (rx->sta) @@ -2458,7 +2411,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) * frames that we didn't handle, including returning unknown * ones. For all other modes we will return them to the sender, * setting the 0x80 bit in the action category, as required by - * 802.11-2007 7.3.1.11. + * 802.11-2012 9.24.4. * Newer versions of hostapd shall also use the management frame * registration mechanisms, but older ones still use cooked * monitor interfaces so push all frames there. @@ -2468,6 +2421,9 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) return RX_DROP_MONITOR; + if (is_multicast_ether_addr(mgmt->da)) + return RX_DROP_MONITOR; + /* do not return rejected action frames */ if (mgmt->u.action.category & 0x80) return RX_DROP_UNUSABLE; @@ -2571,7 +2527,8 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, goto out_free_skb; /* prepend radiotap information */ - ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); + ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom, + false); skb_set_mac_header(skb, 0); skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -2715,7 +2672,6 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) goto rxh_next; \ } while (0); - CALL_RXH(ieee80211_rx_h_passive_scan) CALL_RXH(ieee80211_rx_h_check) ieee80211_rx_reorder_ampdu(rx); @@ -2751,7 +2707,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) return; spin_lock(&tid_agg_rx->reorder_lock); - ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx); + ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx); spin_unlock(&tid_agg_rx->reorder_lock); ieee80211_rx_handlers(&rx); @@ -2773,7 +2729,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, if (!bssid && !sdata->u.mgd.use_4addr) return 0; if (!multicast && - compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { + !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { if (!(sdata->dev->flags & IFF_PROMISC) || sdata->u.mgd.use_4addr) return 0; @@ -2785,14 +2741,10 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, return 0; if (ieee80211_is_beacon(hdr->frame_control)) { return 1; - } - else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { - if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) - return 0; - status->rx_flags &= ~IEEE80211_RX_RA_MATCH; + } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { + return 0; } else if (!multicast && - compare_ether_addr(sdata->vif.addr, - hdr->addr1) != 0) { + !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { if (!(sdata->dev->flags & IFF_PROMISC)) return 0; status->rx_flags &= ~IEEE80211_RX_RA_MATCH; @@ -2808,8 +2760,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, break; case NL80211_IFTYPE_MESH_POINT: if (!multicast && - compare_ether_addr(sdata->vif.addr, - hdr->addr1) != 0) { + !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { if (!(sdata->dev->flags & IFF_PROMISC)) return 0; @@ -2819,8 +2770,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_AP: if (!bssid) { - if (compare_ether_addr(sdata->vif.addr, - hdr->addr1)) + if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) return 0; } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { @@ -2830,11 +2780,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, * and location updates. Note that mac80211 * itself never looks at these frames. */ - if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && - ieee80211_is_public_action(hdr, skb->len)) + if (ieee80211_is_public_action(hdr, skb->len)) return 1; - if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && - !ieee80211_is_beacon(hdr->frame_control)) + if (!ieee80211_is_beacon(hdr->frame_control)) return 0; status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } @@ -2842,7 +2790,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, case NL80211_IFTYPE_WDS: if (bssid || !ieee80211_is_data(hdr->frame_control)) return 0; - if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) + if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) return 0; break; default: @@ -2900,7 +2848,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, struct sk_buff *skb) { - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_sub_if_data *sdata; struct ieee80211_hdr *hdr; @@ -2918,10 +2865,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) local->dot11ReceivedFragmentCount++; - if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || - test_bit(SCAN_SW_SCANNING, &local->scanning))) - status->rx_flags |= IEEE80211_RX_IN_SCAN; - if (ieee80211_is_mgmt(fc)) err = skb_linearize(skb); else @@ -2936,6 +2879,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, ieee80211_parse_qos(&rx); ieee80211_verify_alignment(&rx); + if (unlikely(ieee80211_is_probe_resp(hdr->frame_control) || + ieee80211_is_beacon(hdr->frame_control))) + ieee80211_scan_rx(local, skb); + if (ieee80211_is_data(fc)) { prev_sta = NULL; @@ -3033,6 +2980,10 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) if (unlikely(local->quiescing || local->suspended)) goto drop; + /* We might be during a HW reconfig, prevent Rx for the same reason */ + if (unlikely(local->in_reconfig)) + goto drop; + /* * The same happens when we're not even started, * but that's worth a warning. |
