Lines Matching +full:rates +full:- +full:ru

1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2024-2025 Intel Corporation
25 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_send_link_cmd()
27 cmd->action = cpu_to_le32(action); in iwl_mld_send_link_cmd()
40 struct ieee80211_vif *vif = link_conf->vif; in iwl_mld_add_link_to_fw()
45 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_add_link_to_fw()
48 return -EINVAL; in iwl_mld_add_link_to_fw()
50 cmd.link_id = cpu_to_le32(link->fw_id); in iwl_mld_add_link_to_fw()
51 cmd.mac_id = cpu_to_le32(mld_vif->fw_id); in iwl_mld_add_link_to_fw()
52 cmd.spec_link_id = link_conf->link_id; in iwl_mld_add_link_to_fw()
55 ether_addr_copy(cmd.local_link_addr, link_conf->addr); in iwl_mld_add_link_to_fw()
57 if (vif->type == NL80211_IFTYPE_ADHOC && link_conf->bssid) in iwl_mld_add_link_to_fw()
58 ether_addr_copy(cmd.ibss_bssid_addr, link_conf->bssid); in iwl_mld_add_link_to_fw()
63 /* Get the basic rates of the used band and add the mandatory ones */
72 mld->hw->wiphy->bands[chandef->chan->band]; in iwl_mld_fill_rates()
73 unsigned long basic = link->basic_rates; in iwl_mld_fill_rates()
81 int hw = sband->bitrates[i].hw_value; in iwl_mld_fill_rates()
84 ofdm |= BIT(hw - IWL_FIRST_OFDM_RATE); in iwl_mld_fill_rates()
96 /* Now we've got the basic rates as bitmaps in the ofdm and cck in iwl_mld_fill_rates()
98 * be all the right rates in the bitmap. E.g. if the only basic in iwl_mld_fill_rates()
99 * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps in iwl_mld_fill_rates()
100 * and 6 Mbps because the 802.11-2007 standard says in 9.6: in iwl_mld_fill_rates()
114 * As a consequence, we need to add all mandatory rates that are in iwl_mld_fill_rates()
115 * lower than all of the basic rates to these bitmaps. in iwl_mld_fill_rates()
127 * - if no CCK rates are basic, it must be ERP since there must in iwl_mld_fill_rates()
128 * be some basic rates at all, so they're OFDM => ERP PHY in iwl_mld_fill_rates()
130 * - if 11M is a basic rate, it must be ERP as well, so add 5.5M in iwl_mld_fill_rates()
131 * - if 5.5M is basic, 1M and 2M are mandatory in iwl_mld_fill_rates()
132 * - if 2M is basic, 1M is mandatory in iwl_mld_fill_rates()
133 * - if 1M is basic, that's the only valid ACK rate. in iwl_mld_fill_rates()
135 * any lower rates to the ACK rate bitmap. in iwl_mld_fill_rates()
154 u8 protection_mode = link->ht_operation_mode & in iwl_mld_fill_protection_flags()
160 if (link->use_cts_prot) in iwl_mld_fill_protection_flags()
163 /* See section 9.23.3.1 of IEEE 80211-2012. in iwl_mld_fill_protection_flags()
175 if (link->chanreq.oper.width > NL80211_CHAN_WIDTH_20) in iwl_mld_fill_protection_flags()
205 cpu_to_le16(mld_link->queue_params[mac_ac].cw_min); in iwl_mld_fill_qos_params()
207 cpu_to_le16(mld_link->queue_params[mac_ac].cw_max); in iwl_mld_fill_qos_params()
209 cpu_to_le16(mld_link->queue_params[mac_ac].txop * 32); in iwl_mld_fill_qos_params()
210 ac[fw_ac].aifsn = mld_link->queue_params[mac_ac].aifs; in iwl_mld_fill_qos_params()
214 if (link->qos) in iwl_mld_fill_qos_params()
217 if (link->chanreq.oper.width != NL80211_CHAN_WIDTH_20_NOHT) in iwl_mld_fill_qos_params()
227 &mld_link->queue_params[mac_ac].mu_edca_param_rec; in iwl_mld_fill_mu_edca()
230 if (!mld_link->queue_params[mac_ac].mu_edca) in iwl_mld_fill_mu_edca()
234 cpu_to_le16(mu_edca->ecw_min_max & 0xf); in iwl_mld_fill_mu_edca()
236 cpu_to_le16((mu_edca->ecw_min_max & 0xf0) >> 4); in iwl_mld_fill_mu_edca()
238 cpu_to_le16(mu_edca->aifsn & 0xf); in iwl_mld_fill_mu_edca()
240 cpu_to_le16(mu_edca->mu_edca_timer); in iwl_mld_fill_mu_edca()
250 struct ieee80211_vif *vif = link->vif; in iwl_mld_change_link_in_fw()
256 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_change_link_in_fw()
259 return -EINVAL; in iwl_mld_change_link_in_fw()
261 cmd.link_id = cpu_to_le32(mld_link->fw_id); in iwl_mld_change_link_in_fw()
262 cmd.spec_link_id = link->link_id; in iwl_mld_change_link_in_fw()
263 cmd.mac_id = cpu_to_le32(mld_vif->fw_id); in iwl_mld_change_link_in_fw()
265 chan_ctx = wiphy_dereference(mld->wiphy, mld_link->chan_ctx); in iwl_mld_change_link_in_fw()
268 iwl_mld_phy_from_mac80211(chan_ctx)->fw_id : in iwl_mld_change_link_in_fw()
271 ether_addr_copy(cmd.local_link_addr, link->addr); in iwl_mld_change_link_in_fw()
273 cmd.active = cpu_to_le32(mld_link->active); in iwl_mld_change_link_in_fw()
275 if ((changes & LINK_CONTEXT_MODIFY_ACTIVE) && !mld_link->active && in iwl_mld_change_link_in_fw()
276 mld_link->silent_deactivation) { in iwl_mld_change_link_in_fw()
277 /* We are de-activating a link that is having CSA with in iwl_mld_change_link_in_fw()
282 mld_link->silent_deactivation = false; in iwl_mld_change_link_in_fw()
285 if (vif->type == NL80211_IFTYPE_ADHOC && link->bssid) in iwl_mld_change_link_in_fw()
286 ether_addr_copy(cmd.ibss_bssid_addr, link->bssid); in iwl_mld_change_link_in_fw()
288 /* Channel context is needed to get the rates */ in iwl_mld_change_link_in_fw()
293 cmd.cck_short_preamble = cpu_to_le32(link->use_short_preamble); in iwl_mld_change_link_in_fw()
294 cmd.short_slot = cpu_to_le32(link->use_short_slot); in iwl_mld_change_link_in_fw()
300 cmd.bi = cpu_to_le32(link->beacon_int); in iwl_mld_change_link_in_fw()
301 cmd.dtim_interval = cpu_to_le32(link->beacon_int * link->dtim_period); in iwl_mld_change_link_in_fw()
306 if (!link->he_support || iwlwifi_mod_params.disable_11ax || in iwl_mld_change_link_in_fw()
307 (vif->type == NL80211_IFTYPE_STATION && !vif->cfg.assoc)) { in iwl_mld_change_link_in_fw()
313 if (mld_vif->ap_sta) { in iwl_mld_change_link_in_fw()
315 link_sta_dereference_check(mld_vif->ap_sta, in iwl_mld_change_link_in_fw()
316 link->link_id); in iwl_mld_change_link_in_fw()
318 if (!WARN_ON(!link_sta) && link_sta->he_cap.has_he && in iwl_mld_change_link_in_fw()
319 link_sta->he_cap.he_cap_elem.mac_cap_info[5] & in iwl_mld_change_link_in_fw()
324 cmd.htc_trig_based_pkt_ext = link->htc_trig_based_pkt_ext; in iwl_mld_change_link_in_fw()
326 if (link->uora_exists) { in iwl_mld_change_link_in_fw()
327 cmd.rand_alloc_ecwmin = link->uora_ocw_range & 0x7; in iwl_mld_change_link_in_fw()
328 cmd.rand_alloc_ecwmax = (link->uora_ocw_range >> 3) & 0x7; in iwl_mld_change_link_in_fw()
334 cmd.bss_color = link->he_bss_color.color; in iwl_mld_change_link_in_fw()
336 if (!link->he_bss_color.enabled) in iwl_mld_change_link_in_fw()
339 cmd.frame_time_rts_th = cpu_to_le16(link->frame_time_rts_th); in iwl_mld_change_link_in_fw()
341 /* Block 26-tone RU OFDMA transmissions */ in iwl_mld_change_link_in_fw()
342 if (mld_link->he_ru_2mhz_block) in iwl_mld_change_link_in_fw()
345 if (link->nontransmitted) { in iwl_mld_change_link_in_fw()
346 ether_addr_copy(cmd.ref_bssid_addr, link->transmitter_bssid); in iwl_mld_change_link_in_fw()
347 cmd.bssid_index = link->bssid_index; in iwl_mld_change_link_in_fw()
351 * version 6 - it is sent there. For older versions of the PHY cmd, in iwl_mld_change_link_in_fw()
368 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(link->vif); in iwl_mld_activate_link()
371 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_activate_link()
373 if (WARN_ON(!mld_link || mld_link->active)) in iwl_mld_activate_link()
374 return -EINVAL; in iwl_mld_activate_link()
376 mld_link->active = true; in iwl_mld_activate_link()
381 mld_link->active = false; in iwl_mld_activate_link()
383 mld_vif->last_link_activation_time = in iwl_mld_activate_link()
395 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_deactivate_link()
397 if (WARN_ON(!mld_link || !mld_link->active)) in iwl_mld_deactivate_link()
400 iwl_mld_cancel_session_protection(mld, link->vif, link->link_id); in iwl_mld_deactivate_link()
406 probe_data = wiphy_dereference(mld->wiphy, mld_link->probe_resp_data); in iwl_mld_deactivate_link()
407 RCU_INIT_POINTER(mld_link->probe_resp_data, NULL); in iwl_mld_deactivate_link()
411 mld_link->active = false; in iwl_mld_deactivate_link()
419 mld_link->fw_id); in iwl_mld_deactivate_link()
428 lockdep_assert_wiphy(mld->wiphy); in iwl_mld_rm_link_from_fw()
433 cmd.link_id = cpu_to_le32(mld_link->fw_id); in iwl_mld_rm_link_from_fw()
434 cmd.spec_link_id = link->link_id; in iwl_mld_rm_link_from_fw()
447 mld_link->average_beacon_energy = 0; in IWL_MLD_ALLOC_FN()
449 iwl_mld_init_internal_sta(&mld_link->bcast_sta); in IWL_MLD_ALLOC_FN()
450 iwl_mld_init_internal_sta(&mld_link->mcast_sta); in IWL_MLD_ALLOC_FN()
451 iwl_mld_init_internal_sta(&mld_link->mon_sta); in IWL_MLD_ALLOC_FN()
453 return iwl_mld_allocate_link_fw_id(mld, &mld_link->fw_id, link); in IWL_MLD_ALLOC_FN()
462 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(bss_conf->vif); in iwl_mld_add_link()
464 bool is_deflink = bss_conf == &bss_conf->vif->bss_conf; in iwl_mld_add_link()
469 link = &mld_vif->deflink; in iwl_mld_add_link()
473 WARN_ON(!mld->fw_status.in_hw_restart); in iwl_mld_add_link()
480 rcu_assign_pointer(mld_vif->link[bss_conf->link_id], link); in iwl_mld_add_link()
484 RCU_INIT_POINTER(mld->fw_id_to_bss_conf[link->fw_id], NULL); in iwl_mld_add_link()
485 RCU_INIT_POINTER(mld_vif->link[bss_conf->link_id], NULL); in iwl_mld_add_link()
501 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(bss_conf->vif); in iwl_mld_remove_link()
503 bool is_deflink = link == &mld_vif->deflink; in iwl_mld_remove_link()
504 u8 fw_id = link->fw_id; in iwl_mld_remove_link()
506 if (WARN_ON(!link || link->active)) in iwl_mld_remove_link()
515 RCU_INIT_POINTER(mld_vif->link[bss_conf->link_id], NULL); in iwl_mld_remove_link()
517 if (WARN_ON(fw_id >= mld->fw->ucode_capa.num_links)) in iwl_mld_remove_link()
520 RCU_INIT_POINTER(mld->fw_id_to_bss_conf[fw_id], NULL); in iwl_mld_remove_link()
526 const struct iwl_missed_beacons_notif *notif = (const void *)pkt->data; in iwl_mld_handle_missed_beacon_notif()
528 u32 fw_link_id = le32_to_cpu(notif->link_id); in iwl_mld_handle_missed_beacon_notif()
529 u32 missed_bcon = le32_to_cpu(notif->consec_missed_beacons); in iwl_mld_handle_missed_beacon_notif()
531 le32_to_cpu(notif->consec_missed_beacons_since_last_rx); in iwl_mld_handle_missed_beacon_notif()
533 le32_to_cpu(notif->consec_missed_beacons_other_link); in iwl_mld_handle_missed_beacon_notif()
544 vif = link_conf->vif; in iwl_mld_handle_missed_beacon_notif()
545 link_id = link_conf->link_id; in iwl_mld_handle_missed_beacon_notif()
546 bss_param_ch_cnt_link_id = link_conf->bss_param_ch_cnt_link_id; in iwl_mld_handle_missed_beacon_notif()
555 iwl_dbg_tlv_time_point(&mld->fwrt, in iwl_mld_handle_missed_beacon_notif()
580 if (hweight16(vif->active_links) <= 1) in iwl_mld_handle_missed_beacon_notif()
584 if (le32_to_cpu(notif->other_link_id) == FW_CTXT_ID_INVALID) in iwl_mld_handle_missed_beacon_notif()
587 other_link_fw_id = le32_to_cpu(notif->other_link_id); in iwl_mld_handle_missed_beacon_notif()
596 other_link->link_id, scnd_lnk_bcn_lost); in iwl_mld_handle_missed_beacon_notif()
621 struct iwl_missed_beacons_notif *notif = (void *)pkt->data; in iwl_mld_cancel_missed_beacon_notif()
623 if (le32_to_cpu(notif->other_link_id) == removed_link_id) { in iwl_mld_cancel_missed_beacon_notif()
627 notif->other_link_id = cpu_to_le32(FW_CTXT_ID_INVALID); in iwl_mld_cancel_missed_beacon_notif()
631 return le32_to_cpu(notif->link_id) == removed_link_id; in iwl_mld_cancel_missed_beacon_notif()
655 * The grades are actually estimated throughput, represented as fixed-point
659 RSSI_TO_GRADE_LINE(-85, -89, 172),
660 RSSI_TO_GRADE_LINE(-83, -86, 344),
661 RSSI_TO_GRADE_LINE(-82, -85, 516),
662 RSSI_TO_GRADE_LINE(-80, -83, 688),
663 RSSI_TO_GRADE_LINE(-77, -79, 1032),
664 RSSI_TO_GRADE_LINE(-73, -76, 1376),
665 RSSI_TO_GRADE_LINE(-70, -74, 1548),
666 RSSI_TO_GRADE_LINE(-69, -72, 1720),
667 RSSI_TO_GRADE_LINE(-65, -68, 2064),
668 RSSI_TO_GRADE_LINE(-61, -66, 2294),
669 RSSI_TO_GRADE_LINE(-58, -61, 2580),
670 RSSI_TO_GRADE_LINE(-55, -58, 2868),
671 RSSI_TO_GRADE_LINE(-46, -55, 3098),
672 RSSI_TO_GRADE_LINE(-43, -54, 3442)
675 #define MAX_GRADE (rssi_to_grade_map[ARRAY_SIZE(rssi_to_grade_map) - 1].grade)
681 /* Factors calculation is done with fixed-point with a scaling factor of 1/256 */
689 link_conf->chanreq.oper.width; in iwl_mld_get_n_subchannels()
702 n_subchannels -= hweight16(link_conf->chanreq.oper.punctured); in iwl_mld_get_n_subchannels()
711 struct ieee80211_vif *vif = link_conf->vif; in iwl_mld_get_chan_load_from_element()
718 if (ieee80211_vif_link_active(vif, link_conf->link_id)) in iwl_mld_get_chan_load_from_element()
719 ies = rcu_dereference(link_conf->bss->beacon_ies); in iwl_mld_get_chan_load_from_element()
721 ies = rcu_dereference(link_conf->bss->ies); in iwl_mld_get_chan_load_from_element()
725 ies->data, ies->len); in iwl_mld_get_chan_load_from_element()
728 bss_load_elem->datalen != sizeof(*bss_load)) in iwl_mld_get_chan_load_from_element()
729 return -EINVAL; in iwl_mld_get_chan_load_from_element()
731 bss_load = (const void *)bss_load_elem->data; in iwl_mld_get_chan_load_from_element()
733 return bss_load->channel_util; in iwl_mld_get_chan_load_from_element()
745 if (!mld_link || !mld_link->active) { in iwl_mld_get_chan_load_by_us()
750 if (WARN_ONCE(!rcu_access_pointer(mld_link->chan_ctx), in iwl_mld_get_chan_load_by_us()
752 link_conf->link_id)) in iwl_mld_get_chan_load_by_us()
755 chan_ctx = wiphy_dereference(mld->wiphy, mld_link->chan_ctx); in iwl_mld_get_chan_load_by_us()
758 return phy->channel_load_by_us; in iwl_mld_get_chan_load_by_us()
783 chan_load -= chan_load_by_us; in iwl_mld_get_chan_load_by_others()
791 enum nl80211_band band = link_conf->chanreq.oper.chan->band; in iwl_mld_get_default_chan_load()
826 return MAX_CHAN_LOAD - iwl_mld_get_chan_load(mld, link_conf); in iwl_mld_get_avail_chan_load()
841 band = link_conf->chanreq.oper.chan->band; in iwl_mld_get_link_grade()
848 link_rssi = MBM_TO_DBM(link_conf->bss->signal); in iwl_mld_get_link_grade()
858 /* No valid RSSI - take the lowest grade */ in iwl_mld_get_link_grade()
864 link_conf->link_id, band, in iwl_mld_get_link_grade()
865 link_conf->chanreq.oper.width, in iwl_mld_get_link_grade()
866 link_conf->chanreq.oper.punctured, link_rssi); in iwl_mld_get_link_grade()
873 if (link_rssi > line->rssi[rssi_idx]) in iwl_mld_get_link_grade()
875 grade = line->grade; in iwl_mld_get_link_grade()
883 IWL_DEBUG_EHT(mld, "Link %d's grade: %d\n", link_conf->link_id, grade); in iwl_mld_get_link_grade()
892 const struct iwl_beacon_filter_notif *notif = (const void *)pkt->data; in iwl_mld_handle_beacon_filter_notif()
893 u32 link_id = le32_to_cpu(notif->link_id); in iwl_mld_handle_beacon_filter_notif()
905 mld_link->average_beacon_energy = le32_to_cpu(notif->average_energy); in iwl_mld_handle_beacon_filter_notif()