Skip to content

Commit 9d6b9b8

Browse files
author
Kalle Valo
committed
Merge tag 'iwlwifi-for-kalle-2018-08-09' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes
Some more fixes for 4.13 * Fix a memory leak in the SAR code; * Fix a stuck queue case in AP mode; * Convert a WARN to a simple debug in a legitimate race case (from which we can recover); * Fix a severe throughput aggregation on 9000-family devices due to aggregation issues.
2 parents 368bd88 + 20fc690 commit 9d6b9b8

File tree

6 files changed

+59
-10
lines changed

6 files changed

+59
-10
lines changed

drivers/net/wireless/intel/iwlwifi/mvm/fw.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,8 +1275,10 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm)
12751275

12761276
entry = &wifi_pkg->package.elements[idx++];
12771277
if ((entry->type != ACPI_TYPE_INTEGER) ||
1278-
(entry->integer.value > U8_MAX))
1279-
return -EINVAL;
1278+
(entry->integer.value > U8_MAX)) {
1279+
ret = -EINVAL;
1280+
goto out_free;
1281+
}
12801282

12811283
mvm->geo_profiles[i].values[j] = entry->integer.value;
12821284
}

drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2597,8 +2597,18 @@ static void iwl_mvm_purge_deferred_tx_frames(struct iwl_mvm *mvm,
25972597
spin_lock_bh(&mvm_sta->lock);
25982598
for (i = 0; i <= IWL_MAX_TID_COUNT; i++) {
25992599
tid_data = &mvm_sta->tid_data[i];
2600-
while ((skb = __skb_dequeue(&tid_data->deferred_tx_frames)))
2600+
2601+
while ((skb = __skb_dequeue(&tid_data->deferred_tx_frames))) {
2602+
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2603+
2604+
/*
2605+
* The first deferred frame should've stopped the MAC
2606+
* queues, so we should never get a second deferred
2607+
* frame for the RA/TID.
2608+
*/
2609+
iwl_mvm_start_mac_queues(mvm, info->hw_queue);
26012610
ieee80211_free_txskb(mvm->hw, skb);
2611+
}
26022612
}
26032613
spin_unlock_bh(&mvm_sta->lock);
26042614
}

drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -636,9 +636,9 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
636636

637637
baid_data = rcu_dereference(mvm->baid_map[baid]);
638638
if (!baid_data) {
639-
WARN(!(reorder & IWL_RX_MPDU_REORDER_BA_OLD_SN),
640-
"Received baid %d, but no data exists for this BAID\n",
641-
baid);
639+
IWL_DEBUG_RX(mvm,
640+
"Got valid BAID but no baid allocated, bypass the re-ordering buffer. Baid %d reorder 0x%x\n",
641+
baid, reorder);
642642
return false;
643643
}
644644

@@ -759,7 +759,9 @@ static void iwl_mvm_agg_rx_received(struct iwl_mvm *mvm,
759759

760760
data = rcu_dereference(mvm->baid_map[baid]);
761761
if (!data) {
762-
WARN_ON(!(reorder_data & IWL_RX_MPDU_REORDER_BA_OLD_SN));
762+
IWL_DEBUG_RX(mvm,
763+
"Got valid BAID but no baid allocated, bypass the re-ordering buffer. Baid %d reorder 0x%x\n",
764+
baid, reorder_data);
763765
goto out;
764766
}
765767

drivers/net/wireless/intel/iwlwifi/mvm/sta.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,8 @@ static void iwl_mvm_rx_agg_session_expired(unsigned long data)
291291
goto unlock;
292292

293293
mvm_sta = iwl_mvm_sta_from_mac80211(sta);
294-
ieee80211_stop_rx_ba_session_offl(mvm_sta->vif,
295-
sta->addr, ba_data->tid);
294+
ieee80211_rx_ba_timer_expired(mvm_sta->vif,
295+
sta->addr, ba_data->tid);
296296
unlock:
297297
rcu_read_unlock();
298298
}

include/net/mac80211.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5499,6 +5499,21 @@ static inline void ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif,
54995499
ieee80211_manage_rx_ba_offl(vif, addr, tid + IEEE80211_NUM_TIDS);
55005500
}
55015501

5502+
/**
5503+
* ieee80211_rx_ba_timer_expired - stop a Rx BA session due to timeout
5504+
*
5505+
* Some device drivers do not offload AddBa/DelBa negotiation, but handle rx
5506+
* buffer reording internally, and therefore also handle the session timer.
5507+
*
5508+
* Trigger the timeout flow, which sends a DelBa.
5509+
*
5510+
* @vif: &struct ieee80211_vif pointer from the add_interface callback
5511+
* @addr: station mac address
5512+
* @tid: the rx tid
5513+
*/
5514+
void ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif,
5515+
const u8 *addr, unsigned int tid);
5516+
55025517
/* Rate control API */
55035518

55045519
/**

net/mac80211/agg-rx.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright 2006-2007 Jiri Benc <[email protected]>
88
* Copyright 2007, Michael Wu <[email protected]>
99
* Copyright 2007-2010, Intel Corporation
10-
* Copyright(c) 2015 Intel Deutschland GmbH
10+
* Copyright(c) 2015-2017 Intel Deutschland GmbH
1111
*
1212
* This program is free software; you can redistribute it and/or modify
1313
* it under the terms of the GNU General Public License version 2 as
@@ -466,3 +466,23 @@ void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
466466
rcu_read_unlock();
467467
}
468468
EXPORT_SYMBOL(ieee80211_manage_rx_ba_offl);
469+
470+
void ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif,
471+
const u8 *addr, unsigned int tid)
472+
{
473+
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
474+
struct ieee80211_local *local = sdata->local;
475+
struct sta_info *sta;
476+
477+
rcu_read_lock();
478+
sta = sta_info_get_bss(sdata, addr);
479+
if (!sta)
480+
goto unlock;
481+
482+
set_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired);
483+
ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
484+
485+
unlock:
486+
rcu_read_unlock();
487+
}
488+
EXPORT_SYMBOL(ieee80211_rx_ba_timer_expired);

0 commit comments

Comments
 (0)