.. | .. |
---|
6 | 6 | * GPL LICENSE SUMMARY |
---|
7 | 7 | * |
---|
8 | 8 | * Copyright(c) 2017 Intel Deutschland GmbH |
---|
9 | | - * Copyright(c) 2018 Intel Corporation |
---|
| 9 | + * Copyright(c) 2018 - 2020 Intel Corporation |
---|
10 | 10 | * |
---|
11 | 11 | * This program is free software; you can redistribute it and/or modify |
---|
12 | 12 | * it under the terms of version 2 of the GNU General Public License as |
---|
.. | .. |
---|
27 | 27 | * BSD LICENSE |
---|
28 | 28 | * |
---|
29 | 29 | * Copyright(c) 2017 Intel Deutschland GmbH |
---|
30 | | - * Copyright(c) 2018 Intel Corporation |
---|
| 30 | + * Copyright(c) 2018 - 2020 Intel Corporation |
---|
31 | 31 | * All rights reserved. |
---|
32 | 32 | * |
---|
33 | 33 | * Redistribution and use in source and binary forms, with or without |
---|
.. | .. |
---|
101 | 101 | struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; |
---|
102 | 102 | u8 supp = 0; |
---|
103 | 103 | |
---|
104 | | - if (he_cap && he_cap->has_he) |
---|
| 104 | + if (he_cap->has_he) |
---|
105 | 105 | return 0; |
---|
106 | 106 | |
---|
107 | 107 | if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) |
---|
.. | .. |
---|
116 | 116 | return supp; |
---|
117 | 117 | } |
---|
118 | 118 | |
---|
119 | | -static u16 rs_fw_set_config_flags(struct iwl_mvm *mvm, |
---|
120 | | - struct ieee80211_sta *sta) |
---|
| 119 | +static u16 rs_fw_get_config_flags(struct iwl_mvm *mvm, |
---|
| 120 | + struct ieee80211_sta *sta, |
---|
| 121 | + struct ieee80211_supported_band *sband) |
---|
121 | 122 | { |
---|
122 | 123 | struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; |
---|
123 | 124 | struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; |
---|
124 | | - bool vht_ena = vht_cap && vht_cap->vht_supported; |
---|
| 125 | + struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; |
---|
| 126 | + bool vht_ena = vht_cap->vht_supported; |
---|
125 | 127 | u16 flags = 0; |
---|
126 | 128 | |
---|
127 | 129 | if (mvm->cfg->ht_params->stbc && |
---|
128 | | - (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && |
---|
129 | | - ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) || |
---|
130 | | - (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)))) |
---|
131 | | - flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; |
---|
| 130 | + (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1)) { |
---|
| 131 | + if (he_cap->has_he) { |
---|
| 132 | + if (he_cap->he_cap_elem.phy_cap_info[2] & |
---|
| 133 | + IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) |
---|
| 134 | + flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; |
---|
| 135 | + |
---|
| 136 | + if (he_cap->he_cap_elem.phy_cap_info[7] & |
---|
| 137 | + IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ) |
---|
| 138 | + flags |= IWL_TLC_MNG_CFG_FLAGS_HE_STBC_160MHZ_MSK; |
---|
| 139 | + } else if ((ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) || |
---|
| 140 | + (vht_ena && |
---|
| 141 | + (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))) |
---|
| 142 | + flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; |
---|
| 143 | + } |
---|
132 | 144 | |
---|
133 | 145 | if (mvm->cfg->ht_params->ldpc && |
---|
134 | | - ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) || |
---|
| 146 | + ((ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING) || |
---|
135 | 147 | (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) |
---|
136 | 148 | flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; |
---|
| 149 | + |
---|
| 150 | + /* consider LDPC support in case of HE */ |
---|
| 151 | + if (he_cap->has_he && (he_cap->he_cap_elem.phy_cap_info[1] & |
---|
| 152 | + IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) |
---|
| 153 | + flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; |
---|
| 154 | + |
---|
| 155 | + if (sband->iftype_data && sband->iftype_data->he_cap.has_he && |
---|
| 156 | + !(sband->iftype_data->he_cap.he_cap_elem.phy_cap_info[1] & |
---|
| 157 | + IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) |
---|
| 158 | + flags &= ~IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; |
---|
| 159 | + |
---|
| 160 | + if (he_cap->has_he && |
---|
| 161 | + (he_cap->he_cap_elem.phy_cap_info[3] & |
---|
| 162 | + IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK)) |
---|
| 163 | + flags |= IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_1_MSK; |
---|
137 | 164 | |
---|
138 | 165 | return flags; |
---|
139 | 166 | } |
---|
.. | .. |
---|
168 | 195 | { |
---|
169 | 196 | u16 supp; |
---|
170 | 197 | int i, highest_mcs; |
---|
| 198 | + u8 max_nss = sta->rx_nss; |
---|
| 199 | + struct ieee80211_vht_cap ieee_vht_cap = { |
---|
| 200 | + .vht_cap_info = cpu_to_le32(vht_cap->cap), |
---|
| 201 | + .supp_mcs = vht_cap->vht_mcs, |
---|
| 202 | + }; |
---|
171 | 203 | |
---|
172 | | - for (i = 0; i < sta->rx_nss; i++) { |
---|
173 | | - if (i == MAX_NSS) |
---|
174 | | - break; |
---|
| 204 | + /* the station support only a single receive chain */ |
---|
| 205 | + if (sta->smps_mode == IEEE80211_SMPS_STATIC) |
---|
| 206 | + max_nss = 1; |
---|
175 | 207 | |
---|
176 | | - highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1); |
---|
| 208 | + for (i = 0; i < max_nss && i < IWL_TLC_NSS_MAX; i++) { |
---|
| 209 | + int nss = i + 1; |
---|
| 210 | + |
---|
| 211 | + highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, nss); |
---|
177 | 212 | if (!highest_mcs) |
---|
178 | 213 | continue; |
---|
179 | 214 | |
---|
.. | .. |
---|
181 | 216 | if (sta->bandwidth == IEEE80211_STA_RX_BW_20) |
---|
182 | 217 | supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9); |
---|
183 | 218 | |
---|
184 | | - cmd->ht_rates[i][0] = cpu_to_le16(supp); |
---|
185 | | - if (sta->bandwidth == IEEE80211_STA_RX_BW_160) |
---|
186 | | - cmd->ht_rates[i][1] = cmd->ht_rates[i][0]; |
---|
| 219 | + cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160] = cpu_to_le16(supp); |
---|
| 220 | + /* |
---|
| 221 | + * Check if VHT extended NSS indicates that the bandwidth/NSS |
---|
| 222 | + * configuration is supported - only for MCS 0 since we already |
---|
| 223 | + * decoded the MCS bits anyway ourselves. |
---|
| 224 | + */ |
---|
| 225 | + if (sta->bandwidth == IEEE80211_STA_RX_BW_160 && |
---|
| 226 | + ieee80211_get_vht_max_nss(&ieee_vht_cap, |
---|
| 227 | + IEEE80211_VHT_CHANWIDTH_160MHZ, |
---|
| 228 | + 0, true, nss) >= nss) |
---|
| 229 | + cmd->ht_rates[i][IWL_TLC_HT_BW_160] = |
---|
| 230 | + cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160]; |
---|
187 | 231 | } |
---|
188 | 232 | } |
---|
189 | 233 | |
---|
.. | .. |
---|
206 | 250 | |
---|
207 | 251 | static void |
---|
208 | 252 | rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta, |
---|
209 | | - const struct ieee80211_sta_he_cap *he_cap, |
---|
| 253 | + struct ieee80211_supported_band *sband, |
---|
210 | 254 | struct iwl_tlc_config_cmd *cmd) |
---|
211 | 255 | { |
---|
212 | | - u16 mcs_160 = le16_to_cpu(sta->he_cap.he_mcs_nss_supp.rx_mcs_160); |
---|
213 | | - u16 mcs_80 = le16_to_cpu(sta->he_cap.he_mcs_nss_supp.rx_mcs_80); |
---|
| 256 | + const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; |
---|
| 257 | + u16 mcs_160 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); |
---|
| 258 | + u16 mcs_80 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); |
---|
| 259 | + u16 tx_mcs_80 = |
---|
| 260 | + le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80); |
---|
| 261 | + u16 tx_mcs_160 = |
---|
| 262 | + le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160); |
---|
214 | 263 | int i; |
---|
| 264 | + u8 nss = sta->rx_nss; |
---|
215 | 265 | |
---|
216 | | - for (i = 0; i < sta->rx_nss && i < MAX_NSS; i++) { |
---|
| 266 | + /* the station support only a single receive chain */ |
---|
| 267 | + if (sta->smps_mode == IEEE80211_SMPS_STATIC) |
---|
| 268 | + nss = 1; |
---|
| 269 | + |
---|
| 270 | + for (i = 0; i < nss && i < IWL_TLC_NSS_MAX; i++) { |
---|
217 | 271 | u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3; |
---|
218 | 272 | u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3; |
---|
| 273 | + u16 _tx_mcs_160 = (tx_mcs_160 >> (2 * i)) & 0x3; |
---|
| 274 | + u16 _tx_mcs_80 = (tx_mcs_80 >> (2 * i)) & 0x3; |
---|
219 | 275 | |
---|
220 | | - cmd->ht_rates[i][0] = |
---|
| 276 | + /* If one side doesn't support - mark both as not supporting */ |
---|
| 277 | + if (_mcs_80 == IEEE80211_HE_MCS_NOT_SUPPORTED || |
---|
| 278 | + _tx_mcs_80 == IEEE80211_HE_MCS_NOT_SUPPORTED) { |
---|
| 279 | + _mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED; |
---|
| 280 | + _tx_mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED; |
---|
| 281 | + } |
---|
| 282 | + if (_mcs_80 > _tx_mcs_80) |
---|
| 283 | + _mcs_80 = _tx_mcs_80; |
---|
| 284 | + cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160] = |
---|
221 | 285 | cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_80)); |
---|
222 | | - cmd->ht_rates[i][1] = |
---|
| 286 | + |
---|
| 287 | + /* If one side doesn't support - mark both as not supporting */ |
---|
| 288 | + if (_mcs_160 == IEEE80211_HE_MCS_NOT_SUPPORTED || |
---|
| 289 | + _tx_mcs_160 == IEEE80211_HE_MCS_NOT_SUPPORTED) { |
---|
| 290 | + _mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED; |
---|
| 291 | + _tx_mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED; |
---|
| 292 | + } |
---|
| 293 | + if (_mcs_160 > _tx_mcs_160) |
---|
| 294 | + _mcs_160 = _tx_mcs_160; |
---|
| 295 | + cmd->ht_rates[i][IWL_TLC_HT_BW_160] = |
---|
223 | 296 | cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_160)); |
---|
224 | 297 | } |
---|
225 | 298 | } |
---|
.. | .. |
---|
245 | 318 | cmd->mode = IWL_TLC_MNG_MODE_NON_HT; |
---|
246 | 319 | |
---|
247 | 320 | /* HT/VHT rates */ |
---|
248 | | - if (he_cap && he_cap->has_he) { |
---|
| 321 | + if (he_cap->has_he) { |
---|
249 | 322 | cmd->mode = IWL_TLC_MNG_MODE_HE; |
---|
250 | | - rs_fw_he_set_enabled_rates(sta, he_cap, cmd); |
---|
251 | | - } else if (vht_cap && vht_cap->vht_supported) { |
---|
| 323 | + rs_fw_he_set_enabled_rates(sta, sband, cmd); |
---|
| 324 | + } else if (vht_cap->vht_supported) { |
---|
252 | 325 | cmd->mode = IWL_TLC_MNG_MODE_VHT; |
---|
253 | 326 | rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd); |
---|
254 | | - } else if (ht_cap && ht_cap->ht_supported) { |
---|
| 327 | + } else if (ht_cap->ht_supported) { |
---|
255 | 328 | cmd->mode = IWL_TLC_MNG_MODE_HT; |
---|
256 | | - cmd->ht_rates[0][0] = cpu_to_le16(ht_cap->mcs.rx_mask[0]); |
---|
257 | | - cmd->ht_rates[1][0] = cpu_to_le16(ht_cap->mcs.rx_mask[1]); |
---|
| 329 | + cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_HT_BW_NONE_160] = |
---|
| 330 | + cpu_to_le16(ht_cap->mcs.rx_mask[0]); |
---|
| 331 | + |
---|
| 332 | + /* the station support only a single receive chain */ |
---|
| 333 | + if (sta->smps_mode == IEEE80211_SMPS_STATIC) |
---|
| 334 | + cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = |
---|
| 335 | + 0; |
---|
| 336 | + else |
---|
| 337 | + cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = |
---|
| 338 | + cpu_to_le16(ht_cap->mcs.rx_mask[1]); |
---|
258 | 339 | } |
---|
259 | 340 | } |
---|
260 | 341 | |
---|
.. | .. |
---|
291 | 372 | lq_sta = &mvmsta->lq_sta.rs_fw; |
---|
292 | 373 | |
---|
293 | 374 | if (flags & IWL_TLC_NOTIF_FLAG_RATE) { |
---|
| 375 | + char pretty_rate[100]; |
---|
294 | 376 | lq_sta->last_rate_n_flags = le32_to_cpu(notif->rate); |
---|
295 | | - IWL_DEBUG_RATE(mvm, "new rate_n_flags: 0x%X\n", |
---|
296 | | - lq_sta->last_rate_n_flags); |
---|
| 377 | + rs_pretty_print_rate(pretty_rate, sizeof(pretty_rate), |
---|
| 378 | + lq_sta->last_rate_n_flags); |
---|
| 379 | + IWL_DEBUG_RATE(mvm, "new rate: %s\n", pretty_rate); |
---|
297 | 380 | } |
---|
298 | 381 | |
---|
299 | | - if (flags & IWL_TLC_NOTIF_FLAG_AMSDU) { |
---|
| 382 | + if (flags & IWL_TLC_NOTIF_FLAG_AMSDU && !mvmsta->orig_amsdu_len) { |
---|
300 | 383 | u16 size = le32_to_cpu(notif->amsdu_size); |
---|
| 384 | + int i; |
---|
301 | 385 | |
---|
302 | | - if (WARN_ON(sta->max_amsdu_len < size)) |
---|
| 386 | + if (sta->max_amsdu_len < size) { |
---|
| 387 | + /* |
---|
| 388 | + * In debug sta->max_amsdu_len < size |
---|
| 389 | + * so also check with orig_amsdu_len which holds the |
---|
| 390 | + * original data before debugfs changed the value |
---|
| 391 | + */ |
---|
| 392 | + WARN_ON(mvmsta->orig_amsdu_len < size); |
---|
303 | 393 | goto out; |
---|
| 394 | + } |
---|
304 | 395 | |
---|
305 | 396 | mvmsta->amsdu_enabled = le32_to_cpu(notif->amsdu_enabled); |
---|
306 | 397 | mvmsta->max_amsdu_len = size; |
---|
| 398 | + sta->max_rc_amsdu_len = mvmsta->max_amsdu_len; |
---|
| 399 | + |
---|
| 400 | + for (i = 0; i < IWL_MAX_TID_COUNT; i++) { |
---|
| 401 | + if (mvmsta->amsdu_enabled & BIT(i)) |
---|
| 402 | + sta->max_tid_amsdu_len[i] = |
---|
| 403 | + iwl_mvm_max_amsdu_size(mvm, sta, i); |
---|
| 404 | + else |
---|
| 405 | + /* |
---|
| 406 | + * Not so elegant, but this will effectively |
---|
| 407 | + * prevent AMSDU on this TID |
---|
| 408 | + */ |
---|
| 409 | + sta->max_tid_amsdu_len[i] = 1; |
---|
| 410 | + } |
---|
307 | 411 | |
---|
308 | 412 | IWL_DEBUG_RATE(mvm, |
---|
309 | 413 | "AMSDU update. AMSDU size: %d, AMSDU selected size: %d, AMSDU TID bitmap 0x%X\n", |
---|
.. | .. |
---|
314 | 418 | rcu_read_unlock(); |
---|
315 | 419 | } |
---|
316 | 420 | |
---|
| 421 | +u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta) |
---|
| 422 | +{ |
---|
| 423 | + const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; |
---|
| 424 | + const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; |
---|
| 425 | + |
---|
| 426 | + if (vht_cap->vht_supported) { |
---|
| 427 | + switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) { |
---|
| 428 | + case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: |
---|
| 429 | + return IEEE80211_MAX_MPDU_LEN_VHT_11454; |
---|
| 430 | + case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991: |
---|
| 431 | + return IEEE80211_MAX_MPDU_LEN_VHT_7991; |
---|
| 432 | + default: |
---|
| 433 | + return IEEE80211_MAX_MPDU_LEN_VHT_3895; |
---|
| 434 | + } |
---|
| 435 | + } else if (ht_cap->ht_supported) { |
---|
| 436 | + if (ht_cap->cap & IEEE80211_HT_CAP_MAX_AMSDU) |
---|
| 437 | + /* |
---|
| 438 | + * agg is offloaded so we need to assume that agg |
---|
| 439 | + * are enabled and max mpdu in ampdu is 4095 |
---|
| 440 | + * (spec 802.11-2016 9.3.2.1) |
---|
| 441 | + */ |
---|
| 442 | + return IEEE80211_MAX_MPDU_LEN_HT_BA; |
---|
| 443 | + else |
---|
| 444 | + return IEEE80211_MAX_MPDU_LEN_HT_3839; |
---|
| 445 | + } |
---|
| 446 | + |
---|
| 447 | + /* in legacy mode no amsdu is enabled so return zero */ |
---|
| 448 | + return 0; |
---|
| 449 | +} |
---|
| 450 | + |
---|
317 | 451 | void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, |
---|
318 | 452 | enum nl80211_band band, bool update) |
---|
319 | 453 | { |
---|
.. | .. |
---|
321 | 455 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); |
---|
322 | 456 | struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw; |
---|
323 | 457 | u32 cmd_id = iwl_cmd_id(TLC_MNG_CONFIG_CMD, DATA_PATH_GROUP, 0); |
---|
324 | | - struct ieee80211_supported_band *sband; |
---|
| 458 | + struct ieee80211_supported_band *sband = hw->wiphy->bands[band]; |
---|
| 459 | + u16 max_amsdu_len = rs_fw_get_max_amsdu_len(sta); |
---|
325 | 460 | struct iwl_tlc_config_cmd cfg_cmd = { |
---|
326 | 461 | .sta_id = mvmsta->sta_id, |
---|
327 | 462 | .max_ch_width = update ? |
---|
328 | 463 | rs_fw_bw_from_sta_bw(sta) : RATE_MCS_CHAN_WIDTH_20, |
---|
329 | | - .flags = cpu_to_le16(rs_fw_set_config_flags(mvm, sta)), |
---|
| 464 | + .flags = cpu_to_le16(rs_fw_get_config_flags(mvm, sta, sband)), |
---|
330 | 465 | .chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)), |
---|
331 | | - .max_mpdu_len = cpu_to_le16(sta->max_amsdu_len), |
---|
332 | 466 | .sgi_ch_width_supp = rs_fw_sgi_cw_support(sta), |
---|
| 467 | + .max_mpdu_len = cpu_to_le16(max_amsdu_len), |
---|
333 | 468 | .amsdu = iwl_mvm_is_csum_supported(mvm), |
---|
334 | 469 | }; |
---|
335 | 470 | int ret; |
---|
| 471 | + u16 cmd_size = sizeof(cfg_cmd); |
---|
| 472 | + |
---|
| 473 | + /* In old versions of the API the struct is 4 bytes smaller */ |
---|
| 474 | + if (iwl_fw_lookup_cmd_ver(mvm->fw, DATA_PATH_GROUP, |
---|
| 475 | + TLC_MNG_CONFIG_CMD, 0) < 3) |
---|
| 476 | + cmd_size -= 4; |
---|
336 | 477 | |
---|
337 | 478 | memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers)); |
---|
338 | 479 | |
---|
339 | 480 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
---|
340 | 481 | iwl_mvm_reset_frame_stats(mvm); |
---|
341 | 482 | #endif |
---|
342 | | - sband = hw->wiphy->bands[band]; |
---|
343 | 483 | rs_fw_set_supp_rates(sta, sband, &cfg_cmd); |
---|
344 | 484 | |
---|
345 | | - ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd); |
---|
| 485 | + /* |
---|
| 486 | + * since TLC offload works with one mode we can assume |
---|
| 487 | + * that only vht/ht is used and also set it as station max amsdu |
---|
| 488 | + */ |
---|
| 489 | + sta->max_amsdu_len = max_amsdu_len; |
---|
| 490 | + |
---|
| 491 | + ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, CMD_ASYNC, cmd_size, |
---|
| 492 | + &cfg_cmd); |
---|
346 | 493 | if (ret) |
---|
347 | 494 | IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret); |
---|
348 | 495 | } |
---|