xref: /linux/drivers/net/wireless/intel/iwlwifi/mld/link.h (revision af2d6148d2a159e1a0862bce5a2c88c1618a2b27)
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  * @mon_sta: station used for TX injection in monitor interface.
43  * @link_id: over the air link ID
44  * @average_beacon_energy: average beacon energy for beacons received during
45  *	client connections
46  * @ap_early_keys: The firmware cannot install keys before bcast/mcast STAs,
47  *	but higher layers work differently, so we store the keys here for
48  *	later installation.
49  * @silent_deactivation: next deactivation needs to be silent.
50  * @probe_resp_data: data from FW notification to store NOA related data to be
51  *	inserted into probe response.
52  * @rx_omi: data for BW reduction with OMI
53  * @rx_omi.bw_in_progress: update is in progress (indicates target BW)
54  * @rx_omi.exit_ts: timestamp of last exit
55  * @rx_omi.finished_work: work for the delayed reaction to the firmware saying
56  *	the change was applied, and for then applying a new mode if it was
57  *	updated while waiting for firmware/AP settle delay.
58  * @rx_omi.desired_bw: desired bandwidth
59  * @rx_omi.last_max_bw: last maximum BW used by firmware, for AP BW changes
60  */
61 struct iwl_mld_link {
62 	struct rcu_head rcu_head;
63 
64 	/* Add here fields that need clean up on restart */
65 	struct_group(zeroed_on_hw_restart,
66 		u8 fw_id;
67 		bool active;
68 		struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
69 		struct ieee80211_chanctx_conf __rcu *chan_ctx;
70 		bool he_ru_2mhz_block;
71 		struct ieee80211_key_conf *igtk;
72 	);
73 	/* And here fields that survive a fw restart */
74 	struct ieee80211_vif *vif;
75 	struct iwl_mld_int_sta bcast_sta;
76 	struct iwl_mld_int_sta mcast_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 	u32 average_beacon_energy;
91 	bool silent_deactivation;
92 	struct iwl_probe_resp_data __rcu *probe_resp_data;
93 };
94 
95 /* Cleanup function for struct iwl_mld_link, will be called in restart */
96 static inline void
97 iwl_mld_cleanup_link(struct iwl_mld *mld, struct iwl_mld_link *link)
98 {
99 	struct iwl_probe_resp_data *probe_data;
100 
101 	probe_data = wiphy_dereference(mld->wiphy, link->probe_resp_data);
102 	RCU_INIT_POINTER(link->probe_resp_data, NULL);
103 	if (probe_data)
104 		kfree_rcu(probe_data, rcu_head);
105 
106 	CLEANUP_STRUCT(link);
107 	if (link->bcast_sta.sta_id != IWL_INVALID_STA)
108 		iwl_mld_free_internal_sta(mld, &link->bcast_sta);
109 	if (link->mcast_sta.sta_id != IWL_INVALID_STA)
110 		iwl_mld_free_internal_sta(mld, &link->mcast_sta);
111 	if (link->mon_sta.sta_id != IWL_INVALID_STA)
112 		iwl_mld_free_internal_sta(mld, &link->mon_sta);
113 }
114 
115 /* Convert a percentage from [0,100] to [0,255] */
116 #define NORMALIZE_PERCENT_TO_255(percentage) ((percentage) * 256 / 100)
117 
118 int iwl_mld_add_link(struct iwl_mld *mld,
119 		     struct ieee80211_bss_conf *bss_conf);
120 void iwl_mld_remove_link(struct iwl_mld *mld,
121 			 struct ieee80211_bss_conf *bss_conf);
122 int iwl_mld_activate_link(struct iwl_mld *mld,
123 			  struct ieee80211_bss_conf *link);
124 void iwl_mld_deactivate_link(struct iwl_mld *mld,
125 			     struct ieee80211_bss_conf *link);
126 int iwl_mld_change_link_omi_bw(struct iwl_mld *mld,
127 			       struct ieee80211_bss_conf *link,
128 			       enum ieee80211_sta_rx_bandwidth bw);
129 int iwl_mld_change_link_in_fw(struct iwl_mld *mld,
130 			      struct ieee80211_bss_conf *link, u32 changes);
131 void iwl_mld_handle_missed_beacon_notif(struct iwl_mld *mld,
132 					struct iwl_rx_packet *pkt);
133 bool iwl_mld_cancel_missed_beacon_notif(struct iwl_mld *mld,
134 					struct iwl_rx_packet *pkt,
135 					u32 removed_link_id);
136 int iwl_mld_link_set_associated(struct iwl_mld *mld, struct ieee80211_vif *vif,
137 				struct ieee80211_bss_conf *link);
138 
139 unsigned int iwl_mld_get_link_grade(struct iwl_mld *mld,
140 				    struct ieee80211_bss_conf *link_conf);
141 
142 unsigned int iwl_mld_get_chan_load(struct iwl_mld *mld,
143 				   struct ieee80211_bss_conf *link_conf);
144 
145 int iwl_mld_get_chan_load_by_others(struct iwl_mld *mld,
146 				    struct ieee80211_bss_conf *link_conf,
147 				    bool expect_active_link);
148 void iwl_mld_handle_omi_status_notif(struct iwl_mld *mld,
149 				     struct iwl_rx_packet *pkt);
150 void iwl_mld_leave_omi_bw_reduction(struct iwl_mld *mld);
151 void iwl_mld_check_omi_bw_reduction(struct iwl_mld *mld);
152 void iwl_mld_omi_ap_changed_bw(struct iwl_mld *mld,
153 			       struct ieee80211_bss_conf *link_conf,
154 			       enum ieee80211_sta_rx_bandwidth bw);
155 
156 void iwl_mld_handle_beacon_filter_notif(struct iwl_mld *mld,
157 					struct iwl_rx_packet *pkt);
158 
159 #endif /* __iwl_mld_link_h__ */
160