aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c31
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tx.c5
2 files changed, 24 insertions, 12 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 52de3c6d760c..e64aeb4a2204 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1466,6 +1466,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
1466{ 1466{
1467 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1467 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1468 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta); 1468 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
1469 u8 sta_id = mvm_sta->sta_id;
1469 int ret; 1470 int ret;
1470 1471
1471 lockdep_assert_held(&mvm->mutex); 1472 lockdep_assert_held(&mvm->mutex);
@@ -1474,7 +1475,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
1474 kfree(mvm_sta->dup_data); 1475 kfree(mvm_sta->dup_data);
1475 1476
1476 if ((vif->type == NL80211_IFTYPE_STATION && 1477 if ((vif->type == NL80211_IFTYPE_STATION &&
1477 mvmvif->ap_sta_id == mvm_sta->sta_id) || 1478 mvmvif->ap_sta_id == sta_id) ||
1478 iwl_mvm_is_dqa_supported(mvm)){ 1479 iwl_mvm_is_dqa_supported(mvm)){
1479 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); 1480 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
1480 if (ret) 1481 if (ret)
@@ -1497,6 +1498,15 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
1497 iwl_mvm_disable_sta_queues(mvm, vif, mvm_sta); 1498 iwl_mvm_disable_sta_queues(mvm, vif, mvm_sta);
1498 1499
1499 /* 1500 /*
1501 * If pending_frames is set at this point - it must be
1502 * driver internal logic error, since queues are empty
1503 * and removed successuly.
1504 * warn on it but set it to 0 anyway to avoid station
1505 * not being removed later in the function
1506 */
1507 WARN_ON(atomic_xchg(&mvm->pending_frames[sta_id], 0));
1508
1509 /*
1500 * If no traffic has gone through the reserved TXQ - it 1510 * If no traffic has gone through the reserved TXQ - it
1501 * is still marked as IWL_MVM_QUEUE_RESERVED, and 1511 * is still marked as IWL_MVM_QUEUE_RESERVED, and
1502 * should be manually marked as free again 1512 * should be manually marked as free again
@@ -1506,7 +1516,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
1506 if (WARN((*status != IWL_MVM_QUEUE_RESERVED) && 1516 if (WARN((*status != IWL_MVM_QUEUE_RESERVED) &&
1507 (*status != IWL_MVM_QUEUE_FREE), 1517 (*status != IWL_MVM_QUEUE_FREE),
1508 "sta_id %d reserved txq %d status %d", 1518 "sta_id %d reserved txq %d status %d",
1509 mvm_sta->sta_id, reserved_txq, *status)) { 1519 sta_id, reserved_txq, *status)) {
1510 spin_unlock_bh(&mvm->queue_info_lock); 1520 spin_unlock_bh(&mvm->queue_info_lock);
1511 return -EINVAL; 1521 return -EINVAL;
1512 } 1522 }
@@ -1516,7 +1526,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
1516 } 1526 }
1517 1527
1518 if (vif->type == NL80211_IFTYPE_STATION && 1528 if (vif->type == NL80211_IFTYPE_STATION &&
1519 mvmvif->ap_sta_id == mvm_sta->sta_id) { 1529 mvmvif->ap_sta_id == sta_id) {
1520 /* if associated - we can't remove the AP STA now */ 1530 /* if associated - we can't remove the AP STA now */
1521 if (vif->bss_conf.assoc) 1531 if (vif->bss_conf.assoc)
1522 return ret; 1532 return ret;
@@ -1525,7 +1535,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
1525 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT; 1535 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
1526 1536
1527 /* clear d0i3_ap_sta_id if no longer relevant */ 1537 /* clear d0i3_ap_sta_id if no longer relevant */
1528 if (mvm->d0i3_ap_sta_id == mvm_sta->sta_id) 1538 if (mvm->d0i3_ap_sta_id == sta_id)
1529 mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT; 1539 mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT;
1530 } 1540 }
1531 } 1541 }
@@ -1534,7 +1544,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
1534 * This shouldn't happen - the TDLS channel switch should be canceled 1544 * This shouldn't happen - the TDLS channel switch should be canceled
1535 * before the STA is removed. 1545 * before the STA is removed.
1536 */ 1546 */
1537 if (WARN_ON_ONCE(mvm->tdls_cs.peer.sta_id == mvm_sta->sta_id)) { 1547 if (WARN_ON_ONCE(mvm->tdls_cs.peer.sta_id == sta_id)) {
1538 mvm->tdls_cs.peer.sta_id = IWL_MVM_STATION_COUNT; 1548 mvm->tdls_cs.peer.sta_id = IWL_MVM_STATION_COUNT;
1539 cancel_delayed_work(&mvm->tdls_cs.dwork); 1549 cancel_delayed_work(&mvm->tdls_cs.dwork);
1540 } 1550 }
@@ -1544,21 +1554,20 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
1544 * calls the drain worker. 1554 * calls the drain worker.
1545 */ 1555 */
1546 spin_lock_bh(&mvm_sta->lock); 1556 spin_lock_bh(&mvm_sta->lock);
1557
1547 /* 1558 /*
1548 * There are frames pending on the AC queues for this station. 1559 * There are frames pending on the AC queues for this station.
1549 * We need to wait until all the frames are drained... 1560 * We need to wait until all the frames are drained...
1550 */ 1561 */
1551 if (atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) { 1562 if (atomic_read(&mvm->pending_frames[sta_id])) {
1552 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], 1563 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id],
1553 ERR_PTR(-EBUSY)); 1564 ERR_PTR(-EBUSY));
1554 spin_unlock_bh(&mvm_sta->lock); 1565 spin_unlock_bh(&mvm_sta->lock);
1555 1566
1556 /* disable TDLS sta queues on drain complete */ 1567 /* disable TDLS sta queues on drain complete */
1557 if (sta->tdls) { 1568 if (sta->tdls) {
1558 mvm->tfd_drained[mvm_sta->sta_id] = 1569 mvm->tfd_drained[sta_id] = mvm_sta->tfd_queue_msk;
1559 mvm_sta->tfd_queue_msk; 1570 IWL_DEBUG_TDLS(mvm, "Draining TDLS sta %d\n", sta_id);
1560 IWL_DEBUG_TDLS(mvm, "Draining TDLS sta %d\n",
1561 mvm_sta->sta_id);
1562 } 1571 }
1563 1572
1564 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); 1573 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 1d116c06cd1c..4cb839ae3e22 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -1008,7 +1008,10 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
1008 spin_unlock(&mvmsta->lock); 1008 spin_unlock(&mvmsta->lock);
1009 1009
1010 /* Increase pending frames count if this isn't AMPDU */ 1010 /* Increase pending frames count if this isn't AMPDU */
1011 if (!is_ampdu) 1011 if ((iwl_mvm_is_dqa_supported(mvm) &&
1012 mvmsta->tid_data[tx_cmd->tid_tspec].state != IWL_AGG_ON &&
1013 mvmsta->tid_data[tx_cmd->tid_tspec].state != IWL_AGG_STARTING) ||
1014 (!iwl_mvm_is_dqa_supported(mvm) && !is_ampdu))
1012 atomic_inc(&mvm->pending_frames[mvmsta->sta_id]); 1015 atomic_inc(&mvm->pending_frames[mvmsta->sta_id]);
1013 1016
1014 return 0; 1017 return 0;