iwlwifi: mvm: set max amsdu for TLC offload
authorMordechay Goodstein <mordechay.goodstein@intel.com>
Thu, 7 Feb 2019 12:06:59 +0000 (14:06 +0200)
committerLuca Coelho <luciano.coelho@intel.com>
Fri, 22 Mar 2019 10:59:41 +0000 (12:59 +0200)
mac80211 sets max amsdu to min supported ht vs vht but TLC only works
with one mode so we can set to the exact mode used (vht/ht)
and enable larger amsdu sizes for vht.

Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c

index a28283ff7295afc24b7a37ded7c8d269cdfab221..79f9eaf8dd1b74e7a6affa44acdaf289c59fb611 100644 (file)
@@ -6,7 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2017        Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -27,7 +27,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2017        Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -345,6 +345,37 @@ out:
        rcu_read_unlock();
 }
 
+static u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta)
+{
+       const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
+       const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
+
+       if (vht_cap && vht_cap->vht_supported) {
+               switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) {
+               case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
+                       return IEEE80211_MAX_MPDU_LEN_VHT_11454;
+               case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991:
+                       return IEEE80211_MAX_MPDU_LEN_VHT_7991;
+               default:
+                       return IEEE80211_MAX_MPDU_LEN_VHT_3895;
+       }
+
+       } else if (ht_cap && ht_cap->ht_supported) {
+               if (ht_cap->cap & IEEE80211_HT_CAP_MAX_AMSDU)
+                       /*
+                        * agg is offloaded so we need to assume that agg
+                        * are enabled and max mpdu in ampdu is 4095
+                        * (spec 802.11-2016 9.3.2.1)
+                        */
+                       return IEEE80211_MAX_MPDU_LEN_HT_BA;
+               else
+                       return IEEE80211_MAX_MPDU_LEN_HT_3839;
+       }
+
+       /* in legacy mode no amsdu is enabled so return zero */
+       return 0;
+}
+
 void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                     enum nl80211_band band, bool update)
 {
@@ -353,14 +384,15 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
        struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw;
        u32 cmd_id = iwl_cmd_id(TLC_MNG_CONFIG_CMD, DATA_PATH_GROUP, 0);
        struct ieee80211_supported_band *sband;
+       u16 max_amsdu_len = rs_fw_get_max_amsdu_len(sta);
        struct iwl_tlc_config_cmd cfg_cmd = {
                .sta_id = mvmsta->sta_id,
                .max_ch_width = update ?
                        rs_fw_bw_from_sta_bw(sta) : RATE_MCS_CHAN_WIDTH_20,
                .flags = cpu_to_le16(rs_fw_set_config_flags(mvm, sta)),
                .chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)),
-               .max_mpdu_len = cpu_to_le16(sta->max_amsdu_len),
                .sgi_ch_width_supp = rs_fw_sgi_cw_support(sta),
+               .max_mpdu_len = cpu_to_le16(max_amsdu_len),
                .amsdu = iwl_mvm_is_csum_supported(mvm),
        };
        int ret;
@@ -373,6 +405,12 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
        sband = hw->wiphy->bands[band];
        rs_fw_set_supp_rates(sta, sband, &cfg_cmd);
 
+       /*
+        * since TLC offload works with one mode we can assume
+        * that only vht/ht is used and also set it as station max amsdu
+        */
+       sta->max_amsdu_len = max_amsdu_len;
+
        ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd);
        if (ret)
                IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret);