diff options
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 5 |
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; |