Lines Matching +full:rates +full:- +full:mcs
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
4 * Copyright (C) 2018-2024 Intel Corporation
7 #include "fw-api.h"
9 #include "iwl-op-mode.h"
14 switch (link_sta->bandwidth) {
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;
48 if (he_cap->has_he)
51 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
53 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
55 if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80)
57 if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_160)
68 struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap;
69 struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap;
70 struct ieee80211_sta_he_cap *he_cap = &link_sta->he_cap;
71 bool vht_ena = vht_cap->vht_supported;
75 if (mvm->cfg->ht_params->stbc &&
77 if (he_cap->has_he && he_cap->he_cap_elem.phy_cap_info[2] &
80 else if (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
82 else if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)
86 if (mvm->cfg->ht_params->ldpc &&
87 ((ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING) ||
88 (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC))))
92 if (he_cap->has_he && (he_cap->he_cap_elem.phy_cap_info[1] &
97 !(sband_he_cap->he_cap_elem.phy_cap_info[1] &
101 if (he_cap->has_he &&
102 (he_cap->he_cap_elem.phy_cap_info[3] &
105 sband_he_cap->he_cap_elem.phy_cap_info[3] &
116 u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) &
117 (0x3 << (2 * (nss - 1)));
118 rx_mcs >>= (2 * (nss - 1));
142 u8 max_nss = link_sta->rx_nss;
144 .vht_cap_info = cpu_to_le32(vht_cap->cap),
145 .supp_mcs = vht_cap->vht_mcs,
149 if (link_sta->smps_mode == IEEE80211_SMPS_STATIC)
159 supp = BIT(highest_mcs + 1) - 1;
160 if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
163 cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_80] = cpu_to_le16(supp);
166 * configuration is supported - only for MCS 0 since we already
167 * decoded the MCS bits anyway ourselves.
169 if (link_sta->bandwidth == IEEE80211_STA_RX_BW_160 &&
173 cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_160] =
174 cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_80];
178 static u16 rs_fw_he_ieee80211_mcs_to_rs_mcs(u16 mcs)
180 switch (mcs) {
182 return BIT(IWL_TLC_MNG_HT_RATE_MCS7 + 1) - 1;
184 return BIT(IWL_TLC_MNG_HT_RATE_MCS9 + 1) - 1;
186 return BIT(IWL_TLC_MNG_HT_RATE_MCS11 + 1) - 1;
191 WARN(1, "invalid HE MCS %d\n", mcs);
200 const struct ieee80211_sta_he_cap *he_cap = &link_sta->he_cap;
201 u16 mcs_160 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
202 u16 mcs_80 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80);
203 u16 tx_mcs_80 = le16_to_cpu(sband_he_cap->he_mcs_nss_supp.tx_mcs_80);
204 u16 tx_mcs_160 = le16_to_cpu(sband_he_cap->he_mcs_nss_supp.tx_mcs_160);
206 u8 nss = link_sta->rx_nss;
209 if (link_sta->smps_mode == IEEE80211_SMPS_STATIC)
218 /* If one side doesn't support - mark both as not supporting */
226 cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_80] =
229 /* If one side doesn't support - mark both as not supporting */
237 cmd->ht_rates[i][IWL_TLC_MCS_PER_BW_160] =
253 rs_fw_eht_max_nss((rx)->rx_tx_mcs ##mcs_num## _max_nss, \
254 (tx)->rx_tx_mcs ##mcs_num## _max_nss)
274 return &eht_mcs->bw._80;
276 return &eht_mcs->bw._160;
278 return &eht_mcs->bw._320;
291 /* peer RX mcs capa */
293 &link_sta->eht_cap.eht_mcs_nss_supp;
294 /* our TX mcs capa */
296 &sband_eht_cap->eht_mcs_nss_supp;
303 if (vif->type == NL80211_IFTYPE_AP &&
304 !(link_sta->he_cap.he_cap_elem.phy_cap_info[0] &
306 mcs_rx_20 = eht_rx_mcs->only_20mhz;
308 mcs_rx_20.rx_tx_mcs7_max_nss = eht_rx_mcs->bw._80.rx_tx_mcs9_max_nss;
309 mcs_rx_20.rx_tx_mcs9_max_nss = eht_rx_mcs->bw._80.rx_tx_mcs9_max_nss;
310 mcs_rx_20.rx_tx_mcs11_max_nss = eht_rx_mcs->bw._80.rx_tx_mcs11_max_nss;
311 mcs_rx_20.rx_tx_mcs13_max_nss = eht_rx_mcs->bw._80.rx_tx_mcs13_max_nss;
315 if (!(sband_he_cap->he_cap_elem.phy_cap_info[0] &
317 mcs_tx_20 = eht_tx_mcs->only_20mhz;
319 mcs_tx_20.rx_tx_mcs7_max_nss = eht_tx_mcs->bw._80.rx_tx_mcs9_max_nss;
320 mcs_tx_20.rx_tx_mcs9_max_nss = eht_tx_mcs->bw._80.rx_tx_mcs9_max_nss;
321 mcs_tx_20.rx_tx_mcs11_max_nss = eht_tx_mcs->bw._80.rx_tx_mcs11_max_nss;
322 mcs_tx_20.rx_tx_mcs13_max_nss = eht_tx_mcs->bw._80.rx_tx_mcs13_max_nss;
325 /* rates for 20/40/80 bw */
327 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw,
329 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw,
331 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw,
333 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw,
348 if (cmd->max_ch_width < (bw + IWL_TLC_MNG_CH_WIDTH_80MHZ))
351 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw,
353 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw,
355 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw,
360 if (link_sta->smps_mode == IEEE80211_SMPS_STATIC ||
361 link_sta->rx_nss < 2)
362 memset(cmd->ht_rates[IWL_TLC_NSS_2], 0,
363 sizeof(cmd->ht_rates[IWL_TLC_NSS_2]));
376 const struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap;
377 const struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap;
378 const struct ieee80211_sta_he_cap *he_cap = &link_sta->he_cap;
380 /* non HT rates */
381 tmp = link_sta->supp_rates[sband->band];
383 supp |= BIT(sband->bitrates[i].hw_value);
385 cmd->non_ht_rates = cpu_to_le16(supp);
386 cmd->mode = IWL_TLC_MNG_MODE_NON_HT;
388 /* HT/VHT rates */
389 if (link_sta->eht_cap.has_eht && sband_he_cap && sband_eht_cap) {
390 cmd->mode = IWL_TLC_MNG_MODE_EHT;
393 } else if (he_cap->has_he && sband_he_cap) {
394 cmd->mode = IWL_TLC_MNG_MODE_HE;
396 } else if (vht_cap->vht_supported) {
397 cmd->mode = IWL_TLC_MNG_MODE_VHT;
399 } else if (ht_cap->ht_supported) {
400 cmd->mode = IWL_TLC_MNG_MODE_HT;
401 cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_MCS_PER_BW_80] =
402 cpu_to_le16(ht_cap->mcs.rx_mask[0]);
405 if (link_sta->smps_mode == IEEE80211_SMPS_STATIC)
406 cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_MCS_PER_BW_80] =
409 cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_MCS_PER_BW_80] =
410 cpu_to_le16(ht_cap->mcs.rx_mask[1]);
428 notif = (void *)pkt->data;
429 link_sta = rcu_dereference(mvm->fw_id_to_link_sta[notif->sta_id]);
430 sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]);
437 notif->sta_id);
445 notif->sta_id);
449 flags = le32_to_cpu(notif->flags);
451 mvm_link_sta = rcu_dereference(mvmsta->link[link_sta->link_id]);
455 link_sta->link_id, notif->sta_id);
458 lq_sta = &mvm_link_sta->lq_sta.rs_fw;
463 if (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP,
467 le32_to_cpu(notif->rate));
471 lq_sta->last_rate_n_flags =
472 iwl_new_rate_from_v1(le32_to_cpu(notif->rate));
474 lq_sta->last_rate_n_flags = le32_to_cpu(notif->rate);
477 lq_sta->last_rate_n_flags);
481 if (flags & IWL_TLC_NOTIF_FLAG_AMSDU && !mvm_link_sta->orig_amsdu_len) {
482 u32 enabled = le32_to_cpu(notif->amsdu_enabled);
483 u16 size = le32_to_cpu(notif->amsdu_size);
491 if (link_sta->agg.max_amsdu_len < size) {
493 * In debug link_sta->agg.max_amsdu_len < size
497 WARN_ON(mvm_link_sta->orig_amsdu_len < size);
501 mvmsta->amsdu_enabled = enabled;
502 mvmsta->max_amsdu_len = size;
503 link_sta->agg.max_rc_amsdu_len = mvmsta->max_amsdu_len;
506 if (mvmsta->amsdu_enabled & BIT(i))
507 link_sta->agg.max_tid_amsdu_len[i] =
514 link_sta->agg.max_tid_amsdu_len[i] = 1;
521 le32_to_cpu(notif->amsdu_size), size,
522 mvmsta->amsdu_enabled);
535 const struct ieee80211_sta_vht_cap *vht_cap = &link_sta->vht_cap;
536 const struct ieee80211_sta_ht_cap *ht_cap = &link_sta->ht_cap;
537 const struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap;
539 if (WARN_ON_ONCE(!link_conf->chanreq.oper.chan))
542 if (link_conf->chanreq.oper.chan->band == NL80211_BAND_6GHZ) {
543 switch (le16_get_bits(link_sta->he_6ghz_capa.capa,
552 } else if (link_conf->chanreq.oper.chan->band == NL80211_BAND_2GHZ &&
553 eht_cap->has_eht) {
554 switch (u8_get_bits(eht_cap->eht_cap_elem.mac_cap_info[0],
563 } else if (vht_cap->vht_supported) {
564 switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) {
572 } else if (ht_cap->ht_supported) {
573 if (ht_cap->cap & IEEE80211_HT_CAP_MAX_AMSDU)
577 * (spec 802.11-2016 9.3.2.1)
595 struct ieee80211_hw *hw = mvm->hw;
598 struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
607 .max_ch_width = mvmsta->authorized ?
616 unsigned int link_id = link_conf->link_id;
617 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
624 if (CSR_HW_REV_TYPE(mvm->trans->hw_rev) == IWL_CFG_MAC_TYPE_GL &&
626 sband_eht_cap->eht_cap_elem.phy_cap_info[5] &
628 link_sta->eht_cap.has_eht &&
629 link_sta->eht_cap.eht_cap_elem.phy_cap_info[5] &
637 mvm_link_sta = rcu_dereference(mvmsta->link[link_id]);
643 cfg_cmd.sta_id = mvm_link_sta->sta_id;
645 lq_sta = &mvm_link_sta->lq_sta.rs_fw;
661 link_sta->agg.max_amsdu_len = max_amsdu_len;
664 cfg_cmd.max_tx_op = cpu_to_le16(mvmvif->max_tx_op);
666 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 0);
702 if (iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 0) < 3)
703 cmd_size -= 4;
708 ret = -EINVAL;
719 IWL_DEBUG_RATE(mvm, "tx protection - not implemented yet.\n");
728 lq_sta = &link_sta->lq_sta.rs_fw;
730 lq_sta->pers.drv = mvm;
731 lq_sta->pers.sta_id = link_sta->sta_id;
732 lq_sta->pers.chains = 0;
733 memset(lq_sta->pers.chain_signal, 0,
734 sizeof(lq_sta->pers.chain_signal));
735 lq_sta->pers.last_rssi = S8_MIN;
736 lq_sta->last_rate_n_flags = 0;
739 lq_sta->pers.dbg_fixed_rate = 0;
749 for (link_id = 0; link_id < ARRAY_SIZE(mvmsta->link); link_id++) {
751 rcu_dereference_protected(mvmsta->link[link_id],
752 lockdep_is_held(&mvm->mutex));