diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/tx.c | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 66e1a3ddc75b..1cb793a498ac 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -873,6 +873,19 @@ int iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
873 | return 0; | 873 | return 0; |
874 | } | 874 | } |
875 | 875 | ||
876 | static void iwl_mvm_tx_info_from_ba_notif(struct ieee80211_tx_info *info, | ||
877 | struct iwl_mvm_ba_notif *ba_notif, | ||
878 | struct iwl_mvm_tid_data *tid_data) | ||
879 | { | ||
880 | info->flags |= IEEE80211_TX_STAT_AMPDU; | ||
881 | info->status.ampdu_ack_len = ba_notif->txed_2_done; | ||
882 | info->status.ampdu_len = ba_notif->txed; | ||
883 | iwl_mvm_hwrate_to_tx_status(tid_data->rate_n_flags, | ||
884 | info); | ||
885 | info->status.status_driver_data[0] = | ||
886 | (void *)(uintptr_t)tid_data->reduced_tpc; | ||
887 | } | ||
888 | |||
876 | int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | 889 | int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, |
877 | struct iwl_device_cmd *cmd) | 890 | struct iwl_device_cmd *cmd) |
878 | { | 891 | { |
@@ -959,21 +972,37 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
959 | */ | 972 | */ |
960 | info->flags |= IEEE80211_TX_STAT_ACK; | 973 | info->flags |= IEEE80211_TX_STAT_ACK; |
961 | 974 | ||
962 | if (freed == 1) { | 975 | /* this is the first skb we deliver in this batch */ |
963 | /* this is the first skb we deliver in this batch */ | 976 | /* put the rate scaling data there */ |
964 | /* put the rate scaling data there */ | 977 | if (freed == 1) |
965 | info->flags |= IEEE80211_TX_STAT_AMPDU; | 978 | iwl_mvm_tx_info_from_ba_notif(info, ba_notif, tid_data); |
966 | info->status.ampdu_ack_len = ba_notif->txed_2_done; | ||
967 | info->status.ampdu_len = ba_notif->txed; | ||
968 | iwl_mvm_hwrate_to_tx_status(tid_data->rate_n_flags, | ||
969 | info); | ||
970 | info->status.status_driver_data[0] = | ||
971 | (void *)(uintptr_t)tid_data->reduced_tpc; | ||
972 | } | ||
973 | } | 979 | } |
974 | 980 | ||
975 | spin_unlock_bh(&mvmsta->lock); | 981 | spin_unlock_bh(&mvmsta->lock); |
976 | 982 | ||
983 | /* We got a BA notif with 0 acked or scd_ssn didn't progress which is | ||
984 | * possible (i.e. first MPDU in the aggregation wasn't acked) | ||
985 | * Still it's important to update RS about sent vs. acked. | ||
986 | */ | ||
987 | if (skb_queue_empty(&reclaimed_skbs)) { | ||
988 | struct ieee80211_tx_info ba_info = {}; | ||
989 | struct ieee80211_chanctx_conf *chanctx_conf = NULL; | ||
990 | |||
991 | if (mvmsta->vif) | ||
992 | chanctx_conf = | ||
993 | rcu_dereference(mvmsta->vif->chanctx_conf); | ||
994 | |||
995 | if (WARN_ON_ONCE(!chanctx_conf)) | ||
996 | goto out; | ||
997 | |||
998 | ba_info.band = chanctx_conf->def.chan->band; | ||
999 | iwl_mvm_tx_info_from_ba_notif(&ba_info, ba_notif, tid_data); | ||
1000 | |||
1001 | IWL_DEBUG_TX_REPLY(mvm, "No reclaim. Update rs directly\n"); | ||
1002 | iwl_mvm_rs_tx_status(mvm, sta, tid, &ba_info); | ||
1003 | } | ||
1004 | |||
1005 | out: | ||
977 | rcu_read_unlock(); | 1006 | rcu_read_unlock(); |
978 | 1007 | ||
979 | while (!skb_queue_empty(&reclaimed_skbs)) { | 1008 | while (!skb_queue_empty(&reclaimed_skbs)) { |