1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* 3 * Copyright (C) 2017 Intel Deutschland GmbH 4 * Copyright (C) 2018-2021 Intel Corporation 5 */ 6 #include "rs.h" 7 #include "fw-api.h" 8 #include "sta.h" 9 #include "iwl-op-mode.h" 10 #include "mvm.h" 11 12 static u8 rs_fw_bw_from_sta_bw(struct ieee80211_sta *sta) 13 { 14 switch (sta->bandwidth) { 15 case IEEE80211_STA_RX_BW_160: 16 return IWL_TLC_MNG_CH_WIDTH_160MHZ; 17 case IEEE80211_STA_RX_BW_80: 18 return IWL_TLC_MNG_CH_WIDTH_80MHZ; 19 case IEEE80211_STA_RX_BW_40: 20 return IWL_TLC_MNG_CH_WIDTH_40MHZ; 21 case IEEE80211_STA_RX_BW_20: 22 default: 23 return IWL_TLC_MNG_CH_WIDTH_20MHZ; 24 } 25 } 26 27 static u8 rs_fw_set_active_chains(u8 chains) 28 { 29 u8 fw_chains = 0; 30 31 if (chains & ANT_A) 32 fw_chains |= IWL_TLC_MNG_CHAIN_A_MSK; 33 if (chains & ANT_B) 34 fw_chains |= IWL_TLC_MNG_CHAIN_B_MSK; 35 36 return fw_chains; 37 } 38 39 static u8 rs_fw_sgi_cw_support(struct ieee80211_sta *sta) 40 { 41 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 42 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; 43 struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; 44 u8 supp = 0; 45 46 if (he_cap->has_he) 47 return 0; 48 49 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) 50 supp |= BIT(IWL_TLC_MNG_CH_WIDTH_20MHZ); 51 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40) 52 supp |= BIT(IWL_TLC_MNG_CH_WIDTH_40MHZ); 53 if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80) 54 supp |= BIT(IWL_TLC_MNG_CH_WIDTH_80MHZ); 55 if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_160) 56 supp |= BIT(IWL_TLC_MNG_CH_WIDTH_160MHZ); 57 58 return supp; 59 } 60 61 static u16 rs_fw_get_config_flags(struct iwl_mvm *mvm, 62 struct ieee80211_sta *sta, 63 struct ieee80211_supported_band *sband) 64 { 65 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 66 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; 67 struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; 68 bool vht_ena = vht_cap->vht_supported; 69 u16 flags = 0; 70 71 /* get STBC flags */ 72 if (mvm->cfg->ht_params->stbc && 73 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1)) { 74 if (he_cap->has_he && he_cap->he_cap_elem.phy_cap_info[2] & 75 IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) 76 flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; 77 else if (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) 78 flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; 79 else if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) 80 flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; 81 } 82 83 if (mvm->cfg->ht_params->ldpc && 84 ((ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING) || 85 (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) 86 flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; 87 88 /* consider LDPC support in case of HE */ 89 if (he_cap->has_he && (he_cap->he_cap_elem.phy_cap_info[1] & 90 IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) 91 flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; 92 93 if (sband->iftype_data && sband->iftype_data->he_cap.has_he && 94 !(sband->iftype_data->he_cap.he_cap_elem.phy_cap_info[1] & 95 IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) 96 flags &= ~IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; 97 98 if (he_cap->has_he && 99 (he_cap->he_cap_elem.phy_cap_info[3] & 100 IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK)) 101 flags |= IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_1_MSK; 102 103 return flags; 104 } 105 106 static 107 int rs_fw_vht_highest_rx_mcs_index(const struct ieee80211_sta_vht_cap *vht_cap, 108 int nss) 109 { 110 u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) & 111 (0x3 << (2 * (nss - 1))); 112 rx_mcs >>= (2 * (nss - 1)); 113 114 switch (rx_mcs) { 115 case IEEE80211_VHT_MCS_SUPPORT_0_7: 116 return IWL_TLC_MNG_HT_RATE_MCS7; 117 case IEEE80211_VHT_MCS_SUPPORT_0_8: 118 return IWL_TLC_MNG_HT_RATE_MCS8; 119 case IEEE80211_VHT_MCS_SUPPORT_0_9: 120 return IWL_TLC_MNG_HT_RATE_MCS9; 121 default: 122 WARN_ON_ONCE(1); 123 break; 124 } 125 126 return 0; 127 } 128 129 static void 130 rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta, 131 const struct ieee80211_sta_vht_cap *vht_cap, 132 struct iwl_tlc_config_cmd *cmd) 133 { 134 u16 supp; 135 int i, highest_mcs; 136 u8 max_nss = sta->rx_nss; 137 struct ieee80211_vht_cap ieee_vht_cap = { 138 .vht_cap_info = cpu_to_le32(vht_cap->cap), 139 .supp_mcs = vht_cap->vht_mcs, 140 }; 141 142 /* the station support only a single receive chain */ 143 if (sta->smps_mode == IEEE80211_SMPS_STATIC) 144 max_nss = 1; 145 146 for (i = 0; i < max_nss && i < IWL_TLC_NSS_MAX; i++) { 147 int nss = i + 1; 148 149 highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, nss); 150 if (!highest_mcs) 151 continue; 152 153 supp = BIT(highest_mcs + 1) - 1; 154 if (sta->bandwidth == IEEE80211_STA_RX_BW_20) 155 supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9); 156 157 cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160] = cpu_to_le16(supp); 158 /* 159 * Check if VHT extended NSS indicates that the bandwidth/NSS 160 * configuration is supported - only for MCS 0 since we already 161 * decoded the MCS bits anyway ourselves. 162 */ 163 if (sta->bandwidth == IEEE80211_STA_RX_BW_160 && 164 ieee80211_get_vht_max_nss(&ieee_vht_cap, 165 IEEE80211_VHT_CHANWIDTH_160MHZ, 166 0, true, nss) >= nss) 167 cmd->ht_rates[i][IWL_TLC_HT_BW_160] = 168 cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160]; 169 } 170 } 171 172 static u16 rs_fw_he_ieee80211_mcs_to_rs_mcs(u16 mcs) 173 { 174 switch (mcs) { 175 case IEEE80211_HE_MCS_SUPPORT_0_7: 176 return BIT(IWL_TLC_MNG_HT_RATE_MCS7 + 1) - 1; 177 case IEEE80211_HE_MCS_SUPPORT_0_9: 178 return BIT(IWL_TLC_MNG_HT_RATE_MCS9 + 1) - 1; 179 case IEEE80211_HE_MCS_SUPPORT_0_11: 180 return BIT(IWL_TLC_MNG_HT_RATE_MCS11 + 1) - 1; 181 case IEEE80211_HE_MCS_NOT_SUPPORTED: 182 return 0; 183 } 184 185 WARN(1, "invalid HE MCS %d\n", mcs); 186 return 0; 187 } 188 189 static void 190 rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta, 191 struct ieee80211_supported_band *sband, 192 struct iwl_tlc_config_cmd *cmd) 193 { 194 const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; 195 u16 mcs_160 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); 196 u16 mcs_80 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); 197 u16 tx_mcs_80 = 198 le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80); 199 u16 tx_mcs_160 = 200 le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160); 201 int i; 202 u8 nss = sta->rx_nss; 203 204 /* the station support only a single receive chain */ 205 if (sta->smps_mode == IEEE80211_SMPS_STATIC) 206 nss = 1; 207 208 for (i = 0; i < nss && i < IWL_TLC_NSS_MAX; i++) { 209 u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3; 210 u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3; 211 u16 _tx_mcs_160 = (tx_mcs_160 >> (2 * i)) & 0x3; 212 u16 _tx_mcs_80 = (tx_mcs_80 >> (2 * i)) & 0x3; 213 214 /* If one side doesn't support - mark both as not supporting */ 215 if (_mcs_80 == IEEE80211_HE_MCS_NOT_SUPPORTED || 216 _tx_mcs_80 == IEEE80211_HE_MCS_NOT_SUPPORTED) { 217 _mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED; 218 _tx_mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED; 219 } 220 if (_mcs_80 > _tx_mcs_80) 221 _mcs_80 = _tx_mcs_80; 222 cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160] = 223 cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_80)); 224 225 /* If one side doesn't support - mark both as not supporting */ 226 if (_mcs_160 == IEEE80211_HE_MCS_NOT_SUPPORTED || 227 _tx_mcs_160 == IEEE80211_HE_MCS_NOT_SUPPORTED) { 228 _mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED; 229 _tx_mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED; 230 } 231 if (_mcs_160 > _tx_mcs_160) 232 _mcs_160 = _tx_mcs_160; 233 cmd->ht_rates[i][IWL_TLC_HT_BW_160] = 234 cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_160)); 235 } 236 } 237 238 static void rs_fw_set_supp_rates(struct ieee80211_sta *sta, 239 struct ieee80211_supported_band *sband, 240 struct iwl_tlc_config_cmd *cmd) 241 { 242 int i; 243 u16 supp = 0; 244 unsigned long tmp; /* must be unsigned long for for_each_set_bit */ 245 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 246 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; 247 const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; 248 249 /* non HT rates */ 250 tmp = sta->supp_rates[sband->band]; 251 for_each_set_bit(i, &tmp, BITS_PER_LONG) 252 supp |= BIT(sband->bitrates[i].hw_value); 253 254 cmd->non_ht_rates = cpu_to_le16(supp); 255 cmd->mode = IWL_TLC_MNG_MODE_NON_HT; 256 257 /* HT/VHT rates */ 258 if (he_cap->has_he) { 259 cmd->mode = IWL_TLC_MNG_MODE_HE; 260 rs_fw_he_set_enabled_rates(sta, sband, cmd); 261 } else if (vht_cap->vht_supported) { 262 cmd->mode = IWL_TLC_MNG_MODE_VHT; 263 rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd); 264 } else if (ht_cap->ht_supported) { 265 cmd->mode = IWL_TLC_MNG_MODE_HT; 266 cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_HT_BW_NONE_160] = 267 cpu_to_le16(ht_cap->mcs.rx_mask[0]); 268 269 /* the station support only a single receive chain */ 270 if (sta->smps_mode == IEEE80211_SMPS_STATIC) 271 cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = 272 0; 273 else 274 cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = 275 cpu_to_le16(ht_cap->mcs.rx_mask[1]); 276 } 277 } 278 279 void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, 280 struct iwl_rx_cmd_buffer *rxb) 281 { 282 struct iwl_rx_packet *pkt = rxb_addr(rxb); 283 struct iwl_tlc_update_notif *notif; 284 struct ieee80211_sta *sta; 285 struct iwl_mvm_sta *mvmsta; 286 struct iwl_lq_sta_rs_fw *lq_sta; 287 u32 flags; 288 289 rcu_read_lock(); 290 291 notif = (void *)pkt->data; 292 sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]); 293 if (IS_ERR_OR_NULL(sta)) { 294 IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n", 295 notif->sta_id); 296 goto out; 297 } 298 299 mvmsta = iwl_mvm_sta_from_mac80211(sta); 300 301 if (!mvmsta) { 302 IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n", 303 notif->sta_id); 304 goto out; 305 } 306 307 flags = le32_to_cpu(notif->flags); 308 309 lq_sta = &mvmsta->lq_sta.rs_fw; 310 311 if (flags & IWL_TLC_NOTIF_FLAG_RATE) { 312 char pretty_rate[100]; 313 314 if (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP, 315 TLC_MNG_UPDATE_NOTIF, 0) < 3) { 316 rs_pretty_print_rate_v1(pretty_rate, sizeof(pretty_rate), 317 le32_to_cpu(notif->rate)); 318 IWL_DEBUG_RATE(mvm, 319 "Got rate in old format. Rate: %s. Converting.\n", 320 pretty_rate); 321 lq_sta->last_rate_n_flags = 322 iwl_new_rate_from_v1(le32_to_cpu(notif->rate)); 323 } else { 324 lq_sta->last_rate_n_flags = le32_to_cpu(notif->rate); 325 } 326 rs_pretty_print_rate(pretty_rate, sizeof(pretty_rate), 327 lq_sta->last_rate_n_flags); 328 IWL_DEBUG_RATE(mvm, "new rate: %s\n", pretty_rate); 329 } 330 331 if (flags & IWL_TLC_NOTIF_FLAG_AMSDU && !mvmsta->orig_amsdu_len) { 332 u16 size = le32_to_cpu(notif->amsdu_size); 333 int i; 334 335 if (sta->max_amsdu_len < size) { 336 /* 337 * In debug sta->max_amsdu_len < size 338 * so also check with orig_amsdu_len which holds the 339 * original data before debugfs changed the value 340 */ 341 WARN_ON(mvmsta->orig_amsdu_len < size); 342 goto out; 343 } 344 345 mvmsta->amsdu_enabled = le32_to_cpu(notif->amsdu_enabled); 346 mvmsta->max_amsdu_len = size; 347 sta->max_rc_amsdu_len = mvmsta->max_amsdu_len; 348 349 for (i = 0; i < IWL_MAX_TID_COUNT; i++) { 350 if (mvmsta->amsdu_enabled & BIT(i)) 351 sta->max_tid_amsdu_len[i] = 352 iwl_mvm_max_amsdu_size(mvm, sta, i); 353 else 354 /* 355 * Not so elegant, but this will effectively 356 * prevent AMSDU on this TID 357 */ 358 sta->max_tid_amsdu_len[i] = 1; 359 } 360 361 IWL_DEBUG_RATE(mvm, 362 "AMSDU update. AMSDU size: %d, AMSDU selected size: %d, AMSDU TID bitmap 0x%X\n", 363 le32_to_cpu(notif->amsdu_size), size, 364 mvmsta->amsdu_enabled); 365 } 366 out: 367 rcu_read_unlock(); 368 } 369 370 u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta) 371 { 372 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 373 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; 374 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 375 376 if (mvmsta->vif->bss_conf.chandef.chan->band == NL80211_BAND_6GHZ) { 377 switch (le16_get_bits(sta->he_6ghz_capa.capa, 378 IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN)) { 379 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: 380 return IEEE80211_MAX_MPDU_LEN_VHT_11454; 381 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991: 382 return IEEE80211_MAX_MPDU_LEN_VHT_7991; 383 default: 384 return IEEE80211_MAX_MPDU_LEN_VHT_3895; 385 } 386 } else 387 if (vht_cap->vht_supported) { 388 switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) { 389 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: 390 return IEEE80211_MAX_MPDU_LEN_VHT_11454; 391 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991: 392 return IEEE80211_MAX_MPDU_LEN_VHT_7991; 393 default: 394 return IEEE80211_MAX_MPDU_LEN_VHT_3895; 395 } 396 } else if (ht_cap->ht_supported) { 397 if (ht_cap->cap & IEEE80211_HT_CAP_MAX_AMSDU) 398 /* 399 * agg is offloaded so we need to assume that agg 400 * are enabled and max mpdu in ampdu is 4095 401 * (spec 802.11-2016 9.3.2.1) 402 */ 403 return IEEE80211_MAX_MPDU_LEN_HT_BA; 404 else 405 return IEEE80211_MAX_MPDU_LEN_HT_3839; 406 } 407 408 /* in legacy mode no amsdu is enabled so return zero */ 409 return 0; 410 } 411 412 void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 413 enum nl80211_band band, bool update) 414 { 415 struct ieee80211_hw *hw = mvm->hw; 416 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 417 struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw; 418 u32 cmd_id = iwl_cmd_id(TLC_MNG_CONFIG_CMD, DATA_PATH_GROUP, 0); 419 struct ieee80211_supported_band *sband = hw->wiphy->bands[band]; 420 u16 max_amsdu_len = rs_fw_get_max_amsdu_len(sta); 421 struct iwl_tlc_config_cmd cfg_cmd = { 422 .sta_id = mvmsta->sta_id, 423 .max_ch_width = update ? 424 rs_fw_bw_from_sta_bw(sta) : RATE_MCS_CHAN_WIDTH_20, 425 .flags = cpu_to_le16(rs_fw_get_config_flags(mvm, sta, sband)), 426 .chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)), 427 .sgi_ch_width_supp = rs_fw_sgi_cw_support(sta), 428 .max_mpdu_len = cpu_to_le16(max_amsdu_len), 429 .amsdu = iwl_mvm_is_csum_supported(mvm), 430 }; 431 int ret; 432 u16 cmd_size = sizeof(cfg_cmd); 433 434 /* In old versions of the API the struct is 4 bytes smaller */ 435 if (iwl_fw_lookup_cmd_ver(mvm->fw, DATA_PATH_GROUP, 436 TLC_MNG_CONFIG_CMD, 0) < 3) 437 cmd_size -= 4; 438 439 memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers)); 440 441 #ifdef CONFIG_IWLWIFI_DEBUGFS 442 iwl_mvm_reset_frame_stats(mvm); 443 #endif 444 rs_fw_set_supp_rates(sta, sband, &cfg_cmd); 445 446 /* 447 * since TLC offload works with one mode we can assume 448 * that only vht/ht is used and also set it as station max amsdu 449 */ 450 sta->max_amsdu_len = max_amsdu_len; 451 452 ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, CMD_ASYNC, cmd_size, 453 &cfg_cmd); 454 if (ret) 455 IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret); 456 } 457 458 int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, 459 bool enable) 460 { 461 /* TODO: need to introduce a new FW cmd since LQ cmd is not relevant */ 462 IWL_DEBUG_RATE(mvm, "tx protection - not implemented yet.\n"); 463 return 0; 464 } 465 466 void iwl_mvm_rs_add_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta) 467 { 468 struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw; 469 470 IWL_DEBUG_RATE(mvm, "create station rate scale window\n"); 471 472 lq_sta->pers.drv = mvm; 473 lq_sta->pers.sta_id = mvmsta->sta_id; 474 lq_sta->pers.chains = 0; 475 memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal)); 476 lq_sta->pers.last_rssi = S8_MIN; 477 lq_sta->last_rate_n_flags = 0; 478 479 #ifdef CONFIG_MAC80211_DEBUGFS 480 lq_sta->pers.dbg_fixed_rate = 0; 481 #endif 482 } 483