1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* 3 * Copyright (C) 2017 Intel Deutschland GmbH 4 * Copyright (C) 2018-2022 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(const struct ieee80211_link_sta *link_sta) 13 { 14 switch (link_sta->bandwidth) { 15 case IEEE80211_STA_RX_BW_320: 16 return IWL_TLC_MNG_CH_WIDTH_320MHZ; 17 case IEEE80211_STA_RX_BW_160: 18 return IWL_TLC_MNG_CH_WIDTH_160MHZ; 19 case IEEE80211_STA_RX_BW_80: 20 return IWL_TLC_MNG_CH_WIDTH_80MHZ; 21 case IEEE80211_STA_RX_BW_40: 22 return IWL_TLC_MNG_CH_WIDTH_40MHZ; 23 case IEEE80211_STA_RX_BW_20: 24 default: 25 return IWL_TLC_MNG_CH_WIDTH_20MHZ; 26 } 27 } 28 29 static u8 rs_fw_set_active_chains(u8 chains) 30 { 31 u8 fw_chains = 0; 32 33 if (chains & ANT_A) 34 fw_chains |= IWL_TLC_MNG_CHAIN_A_MSK; 35 if (chains & ANT_B) 36 fw_chains |= IWL_TLC_MNG_CHAIN_B_MSK; 37 38 return fw_chains; 39 } 40 41 static u8 rs_fw_sgi_cw_support(struct ieee80211_link_sta *link_sta) 42 { 43 struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap; 44 struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap; 45 struct ieee80211_sta_he_cap *he_cap = &link_sta->he_cap; 46 u8 supp = 0; 47 48 if (he_cap->has_he) 49 return 0; 50 51 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) 52 supp |= BIT(IWL_TLC_MNG_CH_WIDTH_20MHZ); 53 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40) 54 supp |= BIT(IWL_TLC_MNG_CH_WIDTH_40MHZ); 55 if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80) 56 supp |= BIT(IWL_TLC_MNG_CH_WIDTH_80MHZ); 57 if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_160) 58 supp |= BIT(IWL_TLC_MNG_CH_WIDTH_160MHZ); 59 60 return supp; 61 } 62 63 static u16 rs_fw_get_config_flags(struct iwl_mvm *mvm, 64 struct ieee80211_link_sta *link_sta, 65 struct ieee80211_supported_band *sband) 66 { 67 struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap; 68 struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap; 69 struct ieee80211_sta_he_cap *he_cap = &link_sta->he_cap; 70 bool vht_ena = vht_cap->vht_supported; 71 u16 flags = 0; 72 73 /* get STBC flags */ 74 if (mvm->cfg->ht_params->stbc && 75 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1)) { 76 if (he_cap->has_he && he_cap->he_cap_elem.phy_cap_info[2] & 77 IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) 78 flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; 79 else if (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) 80 flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; 81 else if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) 82 flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; 83 } 84 85 if (mvm->cfg->ht_params->ldpc && 86 ((ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING) || 87 (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) 88 flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; 89 90 /* consider LDPC support in case of HE */ 91 if (he_cap->has_he && (he_cap->he_cap_elem.phy_cap_info[1] & 92 IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) 93 flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; 94 95 if (sband->iftype_data && sband->iftype_data->he_cap.has_he && 96 !(sband->iftype_data->he_cap.he_cap_elem.phy_cap_info[1] & 97 IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) 98 flags &= ~IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; 99 100 if (he_cap->has_he && 101 (he_cap->he_cap_elem.phy_cap_info[3] & 102 IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK && 103 sband->iftype_data && 104 sband->iftype_data->he_cap.he_cap_elem.phy_cap_info[3] & 105 IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK)) 106 flags |= IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_1_MSK; 107 108 return flags; 109 } 110 111 static 112 int rs_fw_vht_highest_rx_mcs_index(const struct ieee80211_sta_vht_cap *vht_cap, 113 int nss) 114 { 115 u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) & 116 (0x3 << (2 * (nss - 1))); 117 rx_mcs >>= (2 * (nss - 1)); 118 119 switch (rx_mcs) { 120 case IEEE80211_VHT_MCS_SUPPORT_0_7: 121 return IWL_TLC_MNG_HT_RATE_MCS7; 122 case IEEE80211_VHT_MCS_SUPPORT_0_8: 123 return IWL_TLC_MNG_HT_RATE_MCS8; 124 case IEEE80211_VHT_MCS_SUPPORT_0_9: 125 return IWL_TLC_MNG_HT_RATE_MCS9; 126 default: 127 WARN_ON_ONCE(1); 128 break; 129 } 130 131 return 0; 132 } 133 134 static void 135 rs_fw_vht_set_enabled_rates(const struct ieee80211_link_sta *link_sta, 136 const struct ieee80211_sta_vht_cap *vht_cap, 137 struct iwl_tlc_config_cmd_v4 *cmd) 138 { 139 u16 supp; 140 int i, highest_mcs; 141 u8 max_nss = link_sta->rx_nss; 142 struct ieee80211_vht_cap ieee_vht_cap = { 143 .vht_cap_info = cpu_to_le32(vht_cap->cap), 144 .supp_mcs = vht_cap->vht_mcs, 145 }; 146 147 /* the station support only a single receive chain */ 148 if (link_sta->smps_mode == IEEE80211_SMPS_STATIC) 149 max_nss = 1; 150 151 for (i = 0; i < max_nss && i < IWL_TLC_NSS_MAX; i++) { 152 int nss = i + 1; 153 154 highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, nss); 155 if (!highest_mcs) 156 continue; 157 158 supp = BIT(highest_mcs + 1) - 1; 159 if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20) 160 supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9); 161 162 cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_80] = cpu_to_le16(supp); 163 /* 164 * Check if VHT extended NSS indicates that the bandwidth/NSS 165 * configuration is supported - only for MCS 0 since we already 166 * decoded the MCS bits anyway ourselves. 167 */ 168 if (link_sta->bandwidth == IEEE80211_STA_RX_BW_160 && 169 ieee80211_get_vht_max_nss(&ieee_vht_cap, 170 IEEE80211_VHT_CHANWIDTH_160MHZ, 171 0, true, nss) >= nss) 172 cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_160] = 173 cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_80]; 174 } 175 } 176 177 static u16 rs_fw_he_ieee80211_mcs_to_rs_mcs(u16 mcs) 178 { 179 switch (mcs) { 180 case IEEE80211_HE_MCS_SUPPORT_0_7: 181 return BIT(IWL_TLC_MNG_HT_RATE_MCS7 + 1) - 1; 182 case IEEE80211_HE_MCS_SUPPORT_0_9: 183 return BIT(IWL_TLC_MNG_HT_RATE_MCS9 + 1) - 1; 184 case IEEE80211_HE_MCS_SUPPORT_0_11: 185 return BIT(IWL_TLC_MNG_HT_RATE_MCS11 + 1) - 1; 186 case IEEE80211_HE_MCS_NOT_SUPPORTED: 187 return 0; 188 } 189 190 WARN(1, "invalid HE MCS %d\n", mcs); 191 return 0; 192 } 193 194 static void 195 rs_fw_he_set_enabled_rates(const struct ieee80211_link_sta *link_sta, 196 struct ieee80211_supported_band *sband, 197 struct iwl_tlc_config_cmd_v4 *cmd) 198 { 199 const struct ieee80211_sta_he_cap *he_cap = &link_sta->he_cap; 200 u16 mcs_160 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); 201 u16 mcs_80 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); 202 u16 tx_mcs_80 = 203 le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80); 204 u16 tx_mcs_160 = 205 le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160); 206 int i; 207 u8 nss = link_sta->rx_nss; 208 209 /* the station support only a single receive chain */ 210 if (link_sta->smps_mode == IEEE80211_SMPS_STATIC) 211 nss = 1; 212 213 for (i = 0; i < nss && i < IWL_TLC_NSS_MAX; i++) { 214 u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3; 215 u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3; 216 u16 _tx_mcs_160 = (tx_mcs_160 >> (2 * i)) & 0x3; 217 u16 _tx_mcs_80 = (tx_mcs_80 >> (2 * i)) & 0x3; 218 219 /* If one side doesn't support - mark both as not supporting */ 220 if (_mcs_80 == IEEE80211_HE_MCS_NOT_SUPPORTED || 221 _tx_mcs_80 == IEEE80211_HE_MCS_NOT_SUPPORTED) { 222 _mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED; 223 _tx_mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED; 224 } 225 if (_mcs_80 > _tx_mcs_80) 226 _mcs_80 = _tx_mcs_80; 227 cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_80] = 228 cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_80)); 229 230 /* If one side doesn't support - mark both as not supporting */ 231 if (_mcs_160 == IEEE80211_HE_MCS_NOT_SUPPORTED || 232 _tx_mcs_160 == IEEE80211_HE_MCS_NOT_SUPPORTED) { 233 _mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED; 234 _tx_mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED; 235 } 236 if (_mcs_160 > _tx_mcs_160) 237 _mcs_160 = _tx_mcs_160; 238 cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_160] = 239 cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_160)); 240 } 241 } 242 243 static u8 rs_fw_eht_max_nss(u8 rx_nss, u8 tx_nss) 244 { 245 u8 tx = u8_get_bits(tx_nss, IEEE80211_EHT_MCS_NSS_TX); 246 u8 rx = u8_get_bits(rx_nss, IEEE80211_EHT_MCS_NSS_RX); 247 /* the max nss that can be used, 248 * is the min with our tx capa and the peer rx capa. 249 */ 250 return min(tx, rx); 251 } 252 253 #define MAX_NSS_MCS(mcs_num, rx, tx) \ 254 rs_fw_eht_max_nss((rx)->rx_tx_mcs ##mcs_num## _max_nss, \ 255 (tx)->rx_tx_mcs ##mcs_num## _max_nss) 256 257 static void rs_fw_set_eht_mcs_nss(__le16 ht_rates[][3], 258 enum IWL_TLC_MCS_PER_BW bw, 259 u8 max_nss, u16 mcs_msk) 260 { 261 if (max_nss >= 2) 262 ht_rates[IWL_TLC_NSS_2][bw] |= cpu_to_le16(mcs_msk); 263 264 if (max_nss >= 1) 265 ht_rates[IWL_TLC_NSS_1][bw] |= cpu_to_le16(mcs_msk); 266 } 267 268 static const 269 struct ieee80211_eht_mcs_nss_supp_bw * 270 rs_fw_rs_mcs2eht_mcs(enum IWL_TLC_MCS_PER_BW bw, 271 const struct ieee80211_eht_mcs_nss_supp *eht_mcs) 272 { 273 switch (bw) { 274 case IWL_TLC_MCS_PER_BW_80: 275 return &eht_mcs->bw._80; 276 case IWL_TLC_MCS_PER_BW_160: 277 return &eht_mcs->bw._160; 278 case IWL_TLC_MCS_PER_BW_320: 279 return &eht_mcs->bw._320; 280 default: 281 return NULL; 282 } 283 } 284 285 static void 286 rs_fw_eht_set_enabled_rates(const struct ieee80211_link_sta *link_sta, 287 struct ieee80211_supported_band *sband, 288 struct iwl_tlc_config_cmd_v4 *cmd) 289 { 290 /* peer RX mcs capa */ 291 const struct ieee80211_eht_mcs_nss_supp *eht_rx_mcs = 292 &link_sta->eht_cap.eht_mcs_nss_supp; 293 /* our TX mcs capa */ 294 const struct ieee80211_eht_mcs_nss_supp *eht_tx_mcs = 295 &sband->iftype_data->eht_cap.eht_mcs_nss_supp; 296 297 enum IWL_TLC_MCS_PER_BW bw; 298 struct ieee80211_eht_mcs_nss_supp_20mhz_only mcs_rx_20; 299 struct ieee80211_eht_mcs_nss_supp_20mhz_only mcs_tx_20; 300 301 /* peer is 20Mhz only */ 302 if (!(link_sta->he_cap.he_cap_elem.phy_cap_info[0] & 303 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) { 304 mcs_rx_20 = eht_rx_mcs->only_20mhz; 305 } else { 306 mcs_rx_20.rx_tx_mcs7_max_nss = eht_rx_mcs->bw._80.rx_tx_mcs9_max_nss; 307 mcs_rx_20.rx_tx_mcs9_max_nss = eht_rx_mcs->bw._80.rx_tx_mcs9_max_nss; 308 mcs_rx_20.rx_tx_mcs11_max_nss = eht_rx_mcs->bw._80.rx_tx_mcs11_max_nss; 309 mcs_rx_20.rx_tx_mcs13_max_nss = eht_rx_mcs->bw._80.rx_tx_mcs13_max_nss; 310 } 311 312 /* nic is 20Mhz only */ 313 if (!(sband->iftype_data->he_cap.he_cap_elem.phy_cap_info[0] & 314 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) { 315 mcs_tx_20 = eht_tx_mcs->only_20mhz; 316 } else { 317 mcs_tx_20.rx_tx_mcs7_max_nss = eht_tx_mcs->bw._80.rx_tx_mcs9_max_nss; 318 mcs_tx_20.rx_tx_mcs9_max_nss = eht_tx_mcs->bw._80.rx_tx_mcs9_max_nss; 319 mcs_tx_20.rx_tx_mcs11_max_nss = eht_tx_mcs->bw._80.rx_tx_mcs11_max_nss; 320 mcs_tx_20.rx_tx_mcs13_max_nss = eht_tx_mcs->bw._80.rx_tx_mcs13_max_nss; 321 } 322 323 /* rates for 20/40/80 bw */ 324 bw = IWL_TLC_MCS_PER_BW_80; 325 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw, 326 MAX_NSS_MCS(7, &mcs_rx_20, &mcs_tx_20), GENMASK(7, 0)); 327 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw, 328 MAX_NSS_MCS(9, &mcs_rx_20, &mcs_tx_20), GENMASK(9, 8)); 329 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw, 330 MAX_NSS_MCS(11, &mcs_rx_20, &mcs_tx_20), GENMASK(11, 10)); 331 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw, 332 MAX_NSS_MCS(13, &mcs_rx_20, &mcs_tx_20), GENMASK(13, 12)); 333 334 /* rate for 160/320 bw */ 335 for (bw = IWL_TLC_MCS_PER_BW_160; bw <= IWL_TLC_MCS_PER_BW_320; bw++) { 336 const struct ieee80211_eht_mcs_nss_supp_bw *mcs_rx = 337 rs_fw_rs_mcs2eht_mcs(bw, eht_rx_mcs); 338 const struct ieee80211_eht_mcs_nss_supp_bw *mcs_tx = 339 rs_fw_rs_mcs2eht_mcs(bw, eht_tx_mcs); 340 341 /* got unsupported index for bw */ 342 if (!mcs_rx || !mcs_tx) 343 continue; 344 345 /* break out if we don't support the bandwidth */ 346 if (cmd->max_ch_width < (bw + IWL_TLC_MNG_CH_WIDTH_80MHZ)) 347 break; 348 349 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw, 350 MAX_NSS_MCS(9, mcs_rx, mcs_tx), GENMASK(9, 0)); 351 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw, 352 MAX_NSS_MCS(11, mcs_rx, mcs_tx), GENMASK(11, 10)); 353 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw, 354 MAX_NSS_MCS(13, mcs_rx, mcs_tx), GENMASK(13, 12)); 355 } 356 357 /* the station support only a single receive chain */ 358 if (link_sta->smps_mode == IEEE80211_SMPS_STATIC || 359 link_sta->rx_nss < 2) 360 memset(cmd->ht_rates[IWL_TLC_NSS_2], 0, 361 sizeof(cmd->ht_rates[IWL_TLC_NSS_2])); 362 } 363 364 static void rs_fw_set_supp_rates(struct ieee80211_link_sta *link_sta, 365 struct ieee80211_supported_band *sband, 366 struct iwl_tlc_config_cmd_v4 *cmd) 367 { 368 int i; 369 u16 supp = 0; 370 unsigned long tmp; /* must be unsigned long for for_each_set_bit */ 371 const struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap; 372 const struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap; 373 const struct ieee80211_sta_he_cap *he_cap = &link_sta->he_cap; 374 375 /* non HT rates */ 376 tmp = link_sta->supp_rates[sband->band]; 377 for_each_set_bit(i, &tmp, BITS_PER_LONG) 378 supp |= BIT(sband->bitrates[i].hw_value); 379 380 cmd->non_ht_rates = cpu_to_le16(supp); 381 cmd->mode = IWL_TLC_MNG_MODE_NON_HT; 382 383 /* HT/VHT rates */ 384 if (link_sta->eht_cap.has_eht) { 385 cmd->mode = IWL_TLC_MNG_MODE_EHT; 386 rs_fw_eht_set_enabled_rates(link_sta, sband, cmd); 387 } else if (he_cap->has_he) { 388 cmd->mode = IWL_TLC_MNG_MODE_HE; 389 rs_fw_he_set_enabled_rates(link_sta, sband, cmd); 390 } else if (vht_cap->vht_supported) { 391 cmd->mode = IWL_TLC_MNG_MODE_VHT; 392 rs_fw_vht_set_enabled_rates(link_sta, vht_cap, cmd); 393 } else if (ht_cap->ht_supported) { 394 cmd->mode = IWL_TLC_MNG_MODE_HT; 395 cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_MCS_PER_BW_80] = 396 cpu_to_le16(ht_cap->mcs.rx_mask[0]); 397 398 /* the station support only a single receive chain */ 399 if (link_sta->smps_mode == IEEE80211_SMPS_STATIC) 400 cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_MCS_PER_BW_80] = 401 0; 402 else 403 cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_MCS_PER_BW_80] = 404 cpu_to_le16(ht_cap->mcs.rx_mask[1]); 405 } 406 } 407 408 void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, 409 struct iwl_rx_cmd_buffer *rxb) 410 { 411 struct iwl_rx_packet *pkt = rxb_addr(rxb); 412 struct iwl_tlc_update_notif *notif; 413 struct ieee80211_sta *sta; 414 struct ieee80211_link_sta *link_sta; 415 struct iwl_mvm_sta *mvmsta; 416 struct iwl_mvm_link_sta *mvm_link_sta; 417 struct iwl_lq_sta_rs_fw *lq_sta; 418 u32 flags; 419 420 rcu_read_lock(); 421 422 notif = (void *)pkt->data; 423 link_sta = rcu_dereference(mvm->fw_id_to_link_sta[notif->sta_id]); 424 sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]); 425 if (IS_ERR_OR_NULL(sta) || !link_sta) { 426 /* can happen in remove station flow where mvm removed internally 427 * the station before removing from FW 428 */ 429 IWL_DEBUG_RATE(mvm, 430 "Invalid mvm RCU pointer for sta id (%d) in TLC notification\n", 431 notif->sta_id); 432 goto out; 433 } 434 435 mvmsta = iwl_mvm_sta_from_mac80211(sta); 436 437 if (!mvmsta) { 438 IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n", 439 notif->sta_id); 440 goto out; 441 } 442 443 flags = le32_to_cpu(notif->flags); 444 445 mvm_link_sta = rcu_dereference(mvmsta->link[link_sta->link_id]); 446 if (!mvm_link_sta) { 447 IWL_DEBUG_RATE(mvm, 448 "Invalid mvmsta RCU pointer for link (%d) of sta id (%d) in TLC notification\n", 449 link_sta->link_id, notif->sta_id); 450 goto out; 451 } 452 lq_sta = &mvm_link_sta->lq_sta.rs_fw; 453 454 if (flags & IWL_TLC_NOTIF_FLAG_RATE) { 455 char pretty_rate[100]; 456 457 if (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP, 458 TLC_MNG_UPDATE_NOTIF, 0) < 3) { 459 rs_pretty_print_rate_v1(pretty_rate, 460 sizeof(pretty_rate), 461 le32_to_cpu(notif->rate)); 462 IWL_DEBUG_RATE(mvm, 463 "Got rate in old format. Rate: %s. Converting.\n", 464 pretty_rate); 465 lq_sta->last_rate_n_flags = 466 iwl_new_rate_from_v1(le32_to_cpu(notif->rate)); 467 } else { 468 lq_sta->last_rate_n_flags = le32_to_cpu(notif->rate); 469 } 470 rs_pretty_print_rate(pretty_rate, sizeof(pretty_rate), 471 lq_sta->last_rate_n_flags); 472 IWL_DEBUG_RATE(mvm, "new rate: %s\n", pretty_rate); 473 } 474 475 if (flags & IWL_TLC_NOTIF_FLAG_AMSDU && !mvmsta->orig_amsdu_len) { 476 u16 size = le32_to_cpu(notif->amsdu_size); 477 int i; 478 479 if (link_sta->agg.max_amsdu_len < size) { 480 /* 481 * In debug link_sta->agg.max_amsdu_len < size 482 * so also check with orig_amsdu_len which holds the 483 * original data before debugfs changed the value 484 */ 485 WARN_ON(mvmsta->orig_amsdu_len < size); 486 goto out; 487 } 488 489 mvmsta->amsdu_enabled = le32_to_cpu(notif->amsdu_enabled); 490 mvmsta->max_amsdu_len = size; 491 link_sta->agg.max_rc_amsdu_len = mvmsta->max_amsdu_len; 492 493 for (i = 0; i < IWL_MAX_TID_COUNT; i++) { 494 if (mvmsta->amsdu_enabled & BIT(i)) 495 link_sta->agg.max_tid_amsdu_len[i] = 496 iwl_mvm_max_amsdu_size(mvm, sta, i); 497 else 498 /* 499 * Not so elegant, but this will effectively 500 * prevent AMSDU on this TID 501 */ 502 link_sta->agg.max_tid_amsdu_len[i] = 1; 503 } 504 505 IWL_DEBUG_RATE(mvm, 506 "AMSDU update. AMSDU size: %d, AMSDU selected size: %d, AMSDU TID bitmap 0x%X\n", 507 le32_to_cpu(notif->amsdu_size), size, 508 mvmsta->amsdu_enabled); 509 } 510 out: 511 rcu_read_unlock(); 512 } 513 514 u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta, 515 struct ieee80211_bss_conf *link_conf, 516 struct ieee80211_link_sta *link_sta) 517 { 518 const struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap; 519 const struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap; 520 521 if (WARN_ON_ONCE(!link_conf->chandef.chan)) 522 return IEEE80211_MAX_MPDU_LEN_VHT_3895; 523 524 if (link_conf->chandef.chan->band == NL80211_BAND_6GHZ) { 525 switch (le16_get_bits(link_sta->he_6ghz_capa.capa, 526 IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN)) { 527 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: 528 return IEEE80211_MAX_MPDU_LEN_VHT_11454; 529 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991: 530 return IEEE80211_MAX_MPDU_LEN_VHT_7991; 531 default: 532 return IEEE80211_MAX_MPDU_LEN_VHT_3895; 533 } 534 } else 535 if (vht_cap->vht_supported) { 536 switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) { 537 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: 538 return IEEE80211_MAX_MPDU_LEN_VHT_11454; 539 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991: 540 return IEEE80211_MAX_MPDU_LEN_VHT_7991; 541 default: 542 return IEEE80211_MAX_MPDU_LEN_VHT_3895; 543 } 544 } else if (ht_cap->ht_supported) { 545 if (ht_cap->cap & IEEE80211_HT_CAP_MAX_AMSDU) 546 /* 547 * agg is offloaded so we need to assume that agg 548 * are enabled and max mpdu in ampdu is 4095 549 * (spec 802.11-2016 9.3.2.1) 550 */ 551 return IEEE80211_MAX_MPDU_LEN_HT_BA; 552 else 553 return IEEE80211_MAX_MPDU_LEN_HT_3839; 554 } 555 556 /* in legacy mode no amsdu is enabled so return zero */ 557 return 0; 558 } 559 560 void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 561 struct ieee80211_bss_conf *link_conf, 562 struct ieee80211_link_sta *link_sta, 563 enum nl80211_band band, bool update) 564 { 565 struct ieee80211_hw *hw = mvm->hw; 566 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 567 u32 cmd_id = WIDE_ID(DATA_PATH_GROUP, TLC_MNG_CONFIG_CMD); 568 struct ieee80211_supported_band *sband = hw->wiphy->bands[band]; 569 u16 max_amsdu_len = rs_fw_get_max_amsdu_len(sta, link_conf, link_sta); 570 struct iwl_mvm_link_sta *mvm_link_sta; 571 struct iwl_lq_sta_rs_fw *lq_sta; 572 struct iwl_tlc_config_cmd_v4 cfg_cmd = { 573 .max_ch_width = update ? 574 rs_fw_bw_from_sta_bw(link_sta) : 575 IWL_TLC_MNG_CH_WIDTH_20MHZ, 576 .flags = cpu_to_le16(rs_fw_get_config_flags(mvm, link_sta, 577 sband)), 578 .chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)), 579 .sgi_ch_width_supp = rs_fw_sgi_cw_support(link_sta), 580 .max_mpdu_len = iwl_mvm_is_csum_supported(mvm) ? 581 cpu_to_le16(max_amsdu_len) : 0, 582 }; 583 unsigned int link_id = link_conf->link_id; 584 int cmd_ver; 585 int ret; 586 587 rcu_read_lock(); 588 mvm_link_sta = rcu_dereference(mvmsta->link[link_id]); 589 if (WARN_ON_ONCE(!mvm_link_sta)) { 590 rcu_read_unlock(); 591 return; 592 } 593 594 cfg_cmd.sta_id = mvm_link_sta->sta_id; 595 596 lq_sta = &mvm_link_sta->lq_sta.rs_fw; 597 memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers)); 598 599 rcu_read_unlock(); 600 601 #ifdef CONFIG_IWLWIFI_DEBUGFS 602 iwl_mvm_reset_frame_stats(mvm); 603 #endif 604 rs_fw_set_supp_rates(link_sta, sband, &cfg_cmd); 605 606 /* 607 * since TLC offload works with one mode we can assume 608 * that only vht/ht is used and also set it as station max amsdu 609 */ 610 sta->deflink.agg.max_amsdu_len = max_amsdu_len; 611 612 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, 613 WIDE_ID(DATA_PATH_GROUP, 614 TLC_MNG_CONFIG_CMD), 615 0); 616 IWL_DEBUG_RATE(mvm, "TLC CONFIG CMD, sta_id=%d, max_ch_width=%d, mode=%d\n", 617 cfg_cmd.sta_id, cfg_cmd.max_ch_width, cfg_cmd.mode); 618 IWL_DEBUG_RATE(mvm, "TLC CONFIG CMD, chains=0x%X, ch_wid_supp=%d, flags=0x%X\n", 619 cfg_cmd.chains, cfg_cmd.sgi_ch_width_supp, cfg_cmd.flags); 620 IWL_DEBUG_RATE(mvm, "TLC CONFIG CMD, mpdu_len=%d, no_ht_rate=0x%X, tx_op=%d\n", 621 cfg_cmd.max_mpdu_len, cfg_cmd.non_ht_rates, cfg_cmd.max_tx_op); 622 IWL_DEBUG_RATE(mvm, "TLC CONFIG CMD, ht_rate[0][0]=0x%X, ht_rate[1][0]=0x%X\n", 623 cfg_cmd.ht_rates[0][0], cfg_cmd.ht_rates[1][0]); 624 IWL_DEBUG_RATE(mvm, "TLC CONFIG CMD, ht_rate[0][1]=0x%X, ht_rate[1][1]=0x%X\n", 625 cfg_cmd.ht_rates[0][1], cfg_cmd.ht_rates[1][1]); 626 IWL_DEBUG_RATE(mvm, "TLC CONFIG CMD, ht_rate[0][2]=0x%X, ht_rate[1][2]=0x%X\n", 627 cfg_cmd.ht_rates[0][2], cfg_cmd.ht_rates[1][2]); 628 if (cmd_ver == 4) { 629 ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, CMD_ASYNC, 630 sizeof(cfg_cmd), &cfg_cmd); 631 } else if (cmd_ver < 4) { 632 struct iwl_tlc_config_cmd_v3 cfg_cmd_v3 = { 633 .sta_id = cfg_cmd.sta_id, 634 .max_ch_width = cfg_cmd.max_ch_width, 635 .mode = cfg_cmd.mode, 636 .chains = cfg_cmd.chains, 637 .amsdu = !!cfg_cmd.max_mpdu_len, 638 .flags = cfg_cmd.flags, 639 .non_ht_rates = cfg_cmd.non_ht_rates, 640 .ht_rates[0][0] = cfg_cmd.ht_rates[0][0], 641 .ht_rates[0][1] = cfg_cmd.ht_rates[0][1], 642 .ht_rates[1][0] = cfg_cmd.ht_rates[1][0], 643 .ht_rates[1][1] = cfg_cmd.ht_rates[1][1], 644 .sgi_ch_width_supp = cfg_cmd.sgi_ch_width_supp, 645 .max_mpdu_len = cfg_cmd.max_mpdu_len, 646 }; 647 648 u16 cmd_size = sizeof(cfg_cmd_v3); 649 650 /* In old versions of the API the struct is 4 bytes smaller */ 651 if (iwl_fw_lookup_cmd_ver(mvm->fw, 652 WIDE_ID(DATA_PATH_GROUP, 653 TLC_MNG_CONFIG_CMD), 0) < 3) 654 cmd_size -= 4; 655 656 ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, CMD_ASYNC, cmd_size, 657 &cfg_cmd_v3); 658 } else { 659 ret = -EINVAL; 660 } 661 662 if (ret) 663 IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret); 664 } 665 666 int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, 667 bool enable) 668 { 669 /* TODO: need to introduce a new FW cmd since LQ cmd is not relevant */ 670 IWL_DEBUG_RATE(mvm, "tx protection - not implemented yet.\n"); 671 return 0; 672 } 673 674 void iwl_mvm_rs_add_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta) 675 { 676 unsigned int link_id; 677 678 IWL_DEBUG_RATE(mvm, "create station rate scale window\n"); 679 680 for (link_id = 0; link_id < ARRAY_SIZE(mvmsta->link); link_id++) { 681 struct iwl_lq_sta_rs_fw *lq_sta; 682 struct iwl_mvm_link_sta *link = 683 rcu_dereference_protected(mvmsta->link[link_id], 684 lockdep_is_held(&mvm->mutex)); 685 if (!link) 686 continue; 687 688 lq_sta = &link->lq_sta.rs_fw; 689 690 lq_sta->pers.drv = mvm; 691 lq_sta->pers.sta_id = link->sta_id; 692 lq_sta->pers.chains = 0; 693 memset(lq_sta->pers.chain_signal, 0, 694 sizeof(lq_sta->pers.chain_signal)); 695 lq_sta->pers.last_rssi = S8_MIN; 696 lq_sta->last_rate_n_flags = 0; 697 698 #ifdef CONFIG_MAC80211_DEBUGFS 699 lq_sta->pers.dbg_fixed_rate = 0; 700 #endif 701 } 702 } 703