Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
[linux-2.6-microblaze.git] / drivers / net / wireless / intel / iwlwifi / mvm / rs-fw.c
index 8169d14..dabbc04 100644 (file)
@@ -98,8 +98,12 @@ static u8 rs_fw_sgi_cw_support(struct ieee80211_sta *sta)
 {
        struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
        struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
+       struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
        u8 supp = 0;
 
+       if (he_cap && he_cap->has_he)
+               return 0;
+
        if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
                supp |= BIT(IWL_TLC_MNG_CH_WIDTH_20MHZ);
        if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
@@ -117,20 +121,42 @@ static u16 rs_fw_set_config_flags(struct iwl_mvm *mvm,
 {
        struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
        struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
+       struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
        bool vht_ena = vht_cap && vht_cap->vht_supported;
        u16 flags = 0;
 
        if (mvm->cfg->ht_params->stbc &&
-           (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
-           ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) ||
-            (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))))
-               flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK;
+           (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1)) {
+               if (he_cap && he_cap->has_he) {
+                       if (he_cap->he_cap_elem.phy_cap_info[2] &
+                           IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
+                               flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK;
+
+                       if (he_cap->he_cap_elem.phy_cap_info[7] &
+                           IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ)
+                               flags |= IWL_TLC_MNG_CFG_FLAGS_HE_STBC_160MHZ_MSK;
+               } else if ((ht_cap &&
+                           (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) ||
+                          (vht_ena &&
+                           (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)))
+                       flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK;
+       }
 
        if (mvm->cfg->ht_params->ldpc &&
            ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) ||
             (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC))))
                flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK;
 
+       if (he_cap && he_cap->has_he &&
+           (he_cap->he_cap_elem.phy_cap_info[3] &
+            IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK)) {
+               flags |= IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_1_MSK;
+
+               if (he_cap->he_cap_elem.phy_cap_info[3] &
+                   IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2)
+                       flags |= IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_2_MSK;
+       }
+
        return flags;
 }
 
@@ -311,7 +337,7 @@ out:
 }
 
 void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
-                    enum nl80211_band band)
+                    enum nl80211_band band, bool update)
 {
        struct ieee80211_hw *hw = mvm->hw;
        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
@@ -320,7 +346,8 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
        struct ieee80211_supported_band *sband;
        struct iwl_tlc_config_cmd cfg_cmd = {
                .sta_id = mvmsta->sta_id,
-               .max_ch_width = rs_fw_bw_from_sta_bw(sta),
+               .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),