1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 /* 3 * Copyright (C) 2024-2025 Intel Corporation 4 */ 5 #ifndef __iwl_mld_link_h__ 6 #define __iwl_mld_link_h__ 7 8 #include <net/mac80211.h> 9 10 #include "mld.h" 11 #include "sta.h" 12 13 /** 14 * struct iwl_probe_resp_data - data for NoA/CSA updates 15 * @rcu_head: used for freeing the data on update 16 * @notif: notification data 17 * @noa_len: length of NoA attribute, calculated from the notification 18 */ 19 struct iwl_probe_resp_data { 20 struct rcu_head rcu_head; 21 struct iwl_probe_resp_data_notif notif; 22 int noa_len; 23 }; 24 25 /** 26 * struct iwl_mld_link - link configuration parameters 27 * 28 * @rcu_head: RCU head for freeing this data. 29 * @fw_id: the fw id of the link. 30 * @active: if the link is active or not. 31 * @queue_params: QoS data from mac80211. This is updated with a call to 32 * drv_conf_tx per each AC, and then notified once with BSS_CHANGED_QOS. 33 * So we store it here and then send one link cmd for all the ACs. 34 * @chan_ctx: pointer to the channel context assigned to the link. If a link 35 * has an assigned channel context it means that it is active. 36 * @he_ru_2mhz_block: 26-tone RU OFDMA transmissions should be blocked. 37 * @igtk: fw can only have one IGTK at a time, whereas mac80211 can have two. 38 * This tracks the one IGTK that currently exists in FW. 39 * @vif: the vif this link belongs to 40 * @bcast_sta: station used for broadcast packets. Used in AP, GO and IBSS. 41 * @mcast_sta: station used for multicast packets. Used in AP, GO and IBSS. 42 * @aux_sta: station used for remain on channel. Used in P2P device. 43 * @mon_sta: station used for TX injection in monitor interface. 44 * @link_id: over the air link ID 45 * @ap_early_keys: The firmware cannot install keys before bcast/mcast STAs, 46 * but higher layers work differently, so we store the keys here for 47 * later installation. 48 * @silent_deactivation: next deactivation needs to be silent. 49 * @probe_resp_data: data from FW notification to store NOA related data to be 50 * inserted into probe response. 51 * @rx_omi: data for BW reduction with OMI 52 * @rx_omi.bw_in_progress: update is in progress (indicates target BW) 53 * @rx_omi.exit_ts: timestamp of last exit 54 * @rx_omi.finished_work: work for the delayed reaction to the firmware saying 55 * the change was applied, and for then applying a new mode if it was 56 * updated while waiting for firmware/AP settle delay. 57 * @rx_omi.desired_bw: desired bandwidth 58 * @rx_omi.last_max_bw: last maximum BW used by firmware, for AP BW changes 59 */ 60 struct iwl_mld_link { 61 struct rcu_head rcu_head; 62 63 /* Add here fields that need clean up on restart */ 64 struct_group(zeroed_on_hw_restart, 65 u8 fw_id; 66 bool active; 67 struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; 68 struct ieee80211_chanctx_conf __rcu *chan_ctx; 69 bool he_ru_2mhz_block; 70 struct ieee80211_key_conf *igtk; 71 ); 72 /* And here fields that survive a fw restart */ 73 struct ieee80211_vif *vif; 74 struct iwl_mld_int_sta bcast_sta; 75 struct iwl_mld_int_sta mcast_sta; 76 struct iwl_mld_int_sta aux_sta; 77 struct iwl_mld_int_sta mon_sta; 78 u8 link_id; 79 80 struct { 81 struct wiphy_delayed_work finished_work; 82 unsigned long exit_ts; 83 enum ieee80211_sta_rx_bandwidth bw_in_progress, 84 desired_bw, 85 last_max_bw; 86 } rx_omi; 87 88 /* we can only have 2 GTK + 2 IGTK + 2 BIGTK active at a time */ 89 struct ieee80211_key_conf *ap_early_keys[6]; 90 bool silent_deactivation; 91 struct iwl_probe_resp_data __rcu *probe_resp_data; 92 }; 93 94 /* Cleanup function for struct iwl_mld_phy, will be called in restart */ 95 static inline void 96 iwl_mld_cleanup_link(struct iwl_mld *mld, struct iwl_mld_link *link) 97 { 98 struct iwl_probe_resp_data *probe_data; 99 100 probe_data = wiphy_dereference(mld->wiphy, link->probe_resp_data); 101 RCU_INIT_POINTER(link->probe_resp_data, NULL); 102 if (probe_data) 103 kfree_rcu(probe_data, rcu_head); 104 105 CLEANUP_STRUCT(link); 106 if (link->bcast_sta.sta_id != IWL_INVALID_STA) 107 iwl_mld_free_internal_sta(mld, &link->bcast_sta); 108 if (link->mcast_sta.sta_id != IWL_INVALID_STA) 109 iwl_mld_free_internal_sta(mld, &link->mcast_sta); 110 if (link->aux_sta.sta_id != IWL_INVALID_STA) 111 iwl_mld_free_internal_sta(mld, &link->aux_sta); 112 if (link->mon_sta.sta_id != IWL_INVALID_STA) 113 iwl_mld_free_internal_sta(mld, &link->mon_sta); 114 } 115 116 /* Convert a percentage from [0,100] to [0,255] */ 117 #define NORMALIZE_PERCENT_TO_255(percentage) ((percentage) * 256 / 100) 118 119 int iwl_mld_add_link(struct iwl_mld *mld, 120 struct ieee80211_bss_conf *bss_conf); 121 void iwl_mld_remove_link(struct iwl_mld *mld, 122 struct ieee80211_bss_conf *bss_conf); 123 int iwl_mld_activate_link(struct iwl_mld *mld, 124 struct ieee80211_bss_conf *link); 125 void iwl_mld_deactivate_link(struct iwl_mld *mld, 126 struct ieee80211_bss_conf *link); 127 int iwl_mld_change_link_omi_bw(struct iwl_mld *mld, 128 struct ieee80211_bss_conf *link, 129 enum ieee80211_sta_rx_bandwidth bw); 130 int iwl_mld_change_link_in_fw(struct iwl_mld *mld, 131 struct ieee80211_bss_conf *link, u32 changes); 132 void iwl_mld_handle_missed_beacon_notif(struct iwl_mld *mld, 133 struct iwl_rx_packet *pkt); 134 bool iwl_mld_cancel_missed_beacon_notif(struct iwl_mld *mld, 135 struct iwl_rx_packet *pkt, 136 u32 removed_link_id); 137 int iwl_mld_link_set_associated(struct iwl_mld *mld, struct ieee80211_vif *vif, 138 struct ieee80211_bss_conf *link); 139 140 unsigned int iwl_mld_get_link_grade(struct iwl_mld *mld, 141 struct ieee80211_bss_conf *link_conf); 142 143 unsigned int iwl_mld_get_chan_load(struct iwl_mld *mld, 144 struct ieee80211_bss_conf *link_conf); 145 146 int iwl_mld_get_chan_load_by_others(struct iwl_mld *mld, 147 struct ieee80211_bss_conf *link_conf, 148 bool expect_active_link); 149 void iwl_mld_handle_omi_status_notif(struct iwl_mld *mld, 150 struct iwl_rx_packet *pkt); 151 void iwl_mld_leave_omi_bw_reduction(struct iwl_mld *mld); 152 void iwl_mld_check_omi_bw_reduction(struct iwl_mld *mld); 153 void iwl_mld_omi_ap_changed_bw(struct iwl_mld *mld, 154 struct ieee80211_bss_conf *link_conf, 155 enum ieee80211_sta_rx_bandwidth bw); 156 157 #endif /* __iwl_mld_link_h__ */ 158