Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / mac80211 / rx.c
index 54858a68abd730abf731583c3bca7633f9418c34..7fa8c6be7bf02564cd5714033fbdb8761b30b03d 100644 (file)
@@ -143,7 +143,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
        if (status->flag & RX_FLAG_HT) {
                /*
                 * MCS information is a separate field in radiotap,
-                * added below.
+                * added below. The byte here is needed as padding
+                * for the channel though, so initialise it to 0.
                 */
                *pos = 0;
        } else {
@@ -381,7 +382,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
  * specs were sane enough this time around to require padding each A-MSDU
  * subframe to a length that is a multiple of four.
  *
- * Padding like Atheros hardware adds which is inbetween the 802.11 header and
+ * Padding like Atheros hardware adds which is between the 802.11 header and
  * the payload is not supported, the driver is required to move the 802.11
  * header to be directly in front of the payload in that case.
  */
@@ -403,11 +404,13 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
        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)))
+       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))
+           test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+           local->sched_scanning)
                return ieee80211_scan_rx(rx->sdata, skb);
 
        /* scanning finished during invoking of handlers */
@@ -487,15 +490,18 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
         * establisment frame, beacon or probe, drop the frame.
         */
 
-       if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) {
+       if (!rx->sta || sta_plink_state(rx->sta) != NL80211_PLINK_ESTAB) {
                struct ieee80211_mgmt *mgmt;
 
                if (!ieee80211_is_mgmt(hdr->frame_control))
                        return RX_DROP_MONITOR;
 
                if (ieee80211_is_action(hdr->frame_control)) {
+                       u8 category;
                        mgmt = (struct ieee80211_mgmt *)hdr;
-                       if (mgmt->u.action.category != WLAN_CATEGORY_MESH_PLINK)
+                       category = mgmt->u.action.category;
+                       if (category != WLAN_CATEGORY_MESH_ACTION &&
+                               category != WLAN_CATEGORY_SELF_PROTECTED)
                                return RX_DROP_MONITOR;
                        return RX_CONTINUE;
                }
@@ -651,7 +657,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
  set_release_timer:
 
                mod_timer(&tid_agg_rx->reorder_timer,
-                         tid_agg_rx->reorder_time[j] +
+                         tid_agg_rx->reorder_time[j] + 1 +
                          HT_RX_REORDER_BUF_TIMEOUT);
        } else {
                del_timer(&tid_agg_rx->reorder_timer);
@@ -1777,7 +1783,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
 
        ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
                                 rx->sdata->vif.type,
-                                rx->local->hw.extra_tx_headroom);
+                                rx->local->hw.extra_tx_headroom, true);
 
        while (!skb_queue_empty(&frame_list)) {
                rx->skb = __skb_dequeue(&frame_list);
@@ -2204,7 +2210,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                        goto handled;
                }
                break;
-       case WLAN_CATEGORY_MESH_PLINK:
+       case WLAN_CATEGORY_MESH_ACTION:
                if (!ieee80211_vif_is_mesh(&sdata->vif))
                        break;
                goto queue;
@@ -2367,47 +2373,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
        return RX_QUEUED;
 }
 
-static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr,
-                                           struct ieee80211_rx_data *rx)
-{
-       int keyidx;
-       unsigned int hdrlen;
-
-       hdrlen = ieee80211_hdrlen(hdr->frame_control);
-       if (rx->skb->len >= hdrlen + 4)
-               keyidx = rx->skb->data[hdrlen + 3] >> 6;
-       else
-               keyidx = -1;
-
-       if (!rx->sta) {
-               /*
-                * Some hardware seem to generate incorrect Michael MIC
-                * reports; ignore them to avoid triggering countermeasures.
-                */
-               return;
-       }
-
-       if (!ieee80211_has_protected(hdr->frame_control))
-               return;
-
-       if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) {
-               /*
-                * APs with pairwise keys should never receive Michael MIC
-                * errors for non-zero keyidx because these are reserved for
-                * group keys and only the AP is sending real multicast
-                * frames in the BSS.
-                */
-               return;
-       }
-
-       if (!ieee80211_is_data(hdr->frame_control) &&
-           !ieee80211_is_auth(hdr->frame_control))
-               return;
-
-       mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL,
-                                       GFP_ATOMIC);
-}
-
 /* TODO: use IEEE80211_RX_FRAGMENTED */
 static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
                                        struct ieee80211_rate *rate)
@@ -2751,12 +2716,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
        if (!prepares)
                return false;
 
-       if (status->flag & RX_FLAG_MMIC_ERROR) {
-               if (status->rx_flags & IEEE80211_RX_RA_MATCH)
-                       ieee80211_rx_michael_mic_report(hdr, rx);
-               return false;
-       }
-
        if (!consume) {
                skb = skb_copy(skb, GFP_ATOMIC);
                if (!skb) {