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 * @bigtks: BIGTKs of the AP. Only valid for STA mode.
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 * @average_beacon_energy: average beacon energy for beacons received during
44 * client connections
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 */
52 struct iwl_mld_link {
53 struct rcu_head rcu_head;
54
55 /* Add here fields that need clean up on restart */
56 struct_group(zeroed_on_hw_restart,
57 u8 fw_id;
58 bool active;
59 struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
60 struct ieee80211_chanctx_conf __rcu *chan_ctx;
61 bool he_ru_2mhz_block;
62 struct ieee80211_key_conf *igtk;
63 struct ieee80211_key_conf __rcu *bigtks[2];
64 );
65 /* And here fields that survive a fw restart */
66 struct iwl_mld_int_sta bcast_sta;
67 struct iwl_mld_int_sta mcast_sta;
68 struct iwl_mld_int_sta mon_sta;
69
70 /* we can only have 2 GTK + 2 IGTK + 2 BIGTK active at a time */
71 struct ieee80211_key_conf *ap_early_keys[6];
72 u32 average_beacon_energy;
73 bool silent_deactivation;
74 struct iwl_probe_resp_data __rcu *probe_resp_data;
75 };
76
77 /* Cleanup function for struct iwl_mld_link, will be called in restart */
78 static inline void
iwl_mld_cleanup_link(struct iwl_mld * mld,struct iwl_mld_link * link)79 iwl_mld_cleanup_link(struct iwl_mld *mld, struct iwl_mld_link *link)
80 {
81 struct iwl_probe_resp_data *probe_data;
82
83 probe_data = wiphy_dereference(mld->wiphy, link->probe_resp_data);
84 RCU_INIT_POINTER(link->probe_resp_data, NULL);
85 if (probe_data)
86 kfree_rcu(probe_data, rcu_head);
87
88 CLEANUP_STRUCT(link);
89 if (link->bcast_sta.sta_id != IWL_INVALID_STA)
90 iwl_mld_free_internal_sta(mld, &link->bcast_sta);
91 if (link->mcast_sta.sta_id != IWL_INVALID_STA)
92 iwl_mld_free_internal_sta(mld, &link->mcast_sta);
93 if (link->mon_sta.sta_id != IWL_INVALID_STA)
94 iwl_mld_free_internal_sta(mld, &link->mon_sta);
95 }
96
97 /* Convert a percentage from [0,100] to [0,255] */
98 #define NORMALIZE_PERCENT_TO_255(percentage) ((percentage) * 256 / 100)
99
100 int iwl_mld_add_link(struct iwl_mld *mld,
101 struct ieee80211_bss_conf *bss_conf);
102 void iwl_mld_remove_link(struct iwl_mld *mld,
103 struct ieee80211_bss_conf *bss_conf);
104 int iwl_mld_activate_link(struct iwl_mld *mld,
105 struct ieee80211_bss_conf *link);
106 void iwl_mld_deactivate_link(struct iwl_mld *mld,
107 struct ieee80211_bss_conf *link);
108 int iwl_mld_change_link_in_fw(struct iwl_mld *mld,
109 struct ieee80211_bss_conf *link, u32 changes);
110 void iwl_mld_handle_missed_beacon_notif(struct iwl_mld *mld,
111 struct iwl_rx_packet *pkt);
112 bool iwl_mld_cancel_missed_beacon_notif(struct iwl_mld *mld,
113 struct iwl_rx_packet *pkt,
114 u32 removed_link_id);
115 int iwl_mld_link_set_associated(struct iwl_mld *mld, struct ieee80211_vif *vif,
116 struct ieee80211_bss_conf *link);
117
118 unsigned int iwl_mld_get_link_grade(struct iwl_mld *mld,
119 struct ieee80211_bss_conf *link_conf);
120
121 unsigned int iwl_mld_get_chan_load(struct iwl_mld *mld,
122 struct ieee80211_bss_conf *link_conf);
123
124 int iwl_mld_get_chan_load_by_others(struct iwl_mld *mld,
125 struct ieee80211_bss_conf *link_conf,
126 bool expect_active_link);
127
128 void iwl_mld_handle_beacon_filter_notif(struct iwl_mld *mld,
129 struct iwl_rx_packet *pkt);
130
131 #endif /* __iwl_mld_link_h__ */
132