|
@@ -4,7 +4,7 @@
|
|
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
|
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
|
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
|
|
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
|
|
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
|
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
|
- * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
|
|
|
|
|
|
+ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
@@ -1034,6 +1034,18 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
|
|
buf_size = tid_agg_rx->buf_size;
|
|
buf_size = tid_agg_rx->buf_size;
|
|
head_seq_num = tid_agg_rx->head_seq_num;
|
|
head_seq_num = tid_agg_rx->head_seq_num;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * If the current MPDU's SN is smaller than the SSN, it shouldn't
|
|
|
|
+ * be reordered.
|
|
|
|
+ */
|
|
|
|
+ if (unlikely(!tid_agg_rx->started)) {
|
|
|
|
+ if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) {
|
|
|
|
+ ret = false;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ tid_agg_rx->started = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* frame with out of date sequence number */
|
|
/* frame with out of date sequence number */
|
|
if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) {
|
|
if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) {
|
|
dev_kfree_skb(skb);
|
|
dev_kfree_skb(skb);
|
|
@@ -3880,6 +3892,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
|
|
stats->last_rate = sta_stats_encode_rate(status);
|
|
stats->last_rate = sta_stats_encode_rate(status);
|
|
|
|
|
|
stats->fragments++;
|
|
stats->fragments++;
|
|
|
|
+ stats->packets++;
|
|
|
|
|
|
if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
|
|
if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
|
|
stats->last_signal = status->signal;
|
|
stats->last_signal = status->signal;
|
|
@@ -4073,15 +4086,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
|
ieee80211_is_beacon(hdr->frame_control)))
|
|
ieee80211_is_beacon(hdr->frame_control)))
|
|
ieee80211_scan_rx(local, skb);
|
|
ieee80211_scan_rx(local, skb);
|
|
|
|
|
|
- if (pubsta) {
|
|
|
|
- rx.sta = container_of(pubsta, struct sta_info, sta);
|
|
|
|
- rx.sdata = rx.sta->sdata;
|
|
|
|
- if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
|
|
|
|
- return;
|
|
|
|
- goto out;
|
|
|
|
- } else if (ieee80211_is_data(fc)) {
|
|
|
|
|
|
+ if (ieee80211_is_data(fc)) {
|
|
struct sta_info *sta, *prev_sta;
|
|
struct sta_info *sta, *prev_sta;
|
|
|
|
|
|
|
|
+ if (pubsta) {
|
|
|
|
+ rx.sta = container_of(pubsta, struct sta_info, sta);
|
|
|
|
+ rx.sdata = rx.sta->sdata;
|
|
|
|
+ if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
|
|
|
|
+ return;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
prev_sta = NULL;
|
|
prev_sta = NULL;
|
|
|
|
|
|
for_each_sta_info(local, hdr->addr2, sta, tmp) {
|
|
for_each_sta_info(local, hdr->addr2, sta, tmp) {
|