#ifndef __iwl_mld_link_h__
#define __iwl_mld_link_h__
#include <net/mac80211.h>
#include "mld.h"
#include "sta.h"
enum iwl_mld_link_chan_load_level {
LINK_CHAN_LOAD_LVL_NONE,
LINK_CHAN_LOAD_LVL1,
LINK_CHAN_LOAD_LVL2,
LINK_CHAN_LOAD_LVL3,
LINK_CHAN_LOAD_LVL_MAX = LINK_CHAN_LOAD_LVL3
};
struct iwl_probe_resp_data {
struct rcu_head rcu_head;
struct iwl_probe_resp_data_notif notif;
int noa_len;
};
struct iwl_mld_link {
struct rcu_head rcu_head;
struct_group(zeroed_on_hw_restart,
u8 fw_id;
bool active;
s8 avg_signal;
struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
struct ieee80211_chanctx_conf __rcu *chan_ctx;
bool he_ru_2mhz_block;
struct ieee80211_key_conf *tx_igtk;
struct ieee80211_key_conf __rcu *bigtks[2];
enum iwl_mld_link_chan_load_level chan_load_lvl;
);
struct iwl_mld_int_sta bcast_sta;
struct iwl_mld_int_sta mcast_sta;
struct iwl_mld_int_sta mon_sta;
int last_cqm_rssi_event;
struct ieee80211_key_conf *ap_early_keys[6];
u32 average_beacon_energy;
bool silent_deactivation;
struct iwl_probe_resp_data __rcu *probe_resp_data;
};
static inline void
iwl_mld_cleanup_link(struct iwl_mld *mld, struct iwl_mld_link *link)
{
struct iwl_probe_resp_data *probe_data;
probe_data = wiphy_dereference(mld->wiphy, link->probe_resp_data);
RCU_INIT_POINTER(link->probe_resp_data, NULL);
if (probe_data)
kfree_rcu(probe_data, rcu_head);
CLEANUP_STRUCT(link);
if (link->bcast_sta.sta_id != IWL_INVALID_STA)
iwl_mld_free_internal_sta(mld, &link->bcast_sta);
if (link->mcast_sta.sta_id != IWL_INVALID_STA)
iwl_mld_free_internal_sta(mld, &link->mcast_sta);
if (link->mon_sta.sta_id != IWL_INVALID_STA)
iwl_mld_free_internal_sta(mld, &link->mon_sta);
}
#define NORMALIZE_PERCENT_TO_255(percentage) ((percentage) * 256 / 100)
int iwl_mld_allocate_link_fw_id(struct iwl_mld *mld, u8 *fw_id,
struct ieee80211_bss_conf *mac80211_ptr);
int iwl_mld_send_link_cmd(struct iwl_mld *mld,
struct iwl_link_config_cmd *cmd,
enum iwl_ctxt_action action);
int iwl_mld_add_link(struct iwl_mld *mld,
struct ieee80211_bss_conf *bss_conf);
void iwl_mld_remove_link(struct iwl_mld *mld,
struct ieee80211_bss_conf *bss_conf);
int iwl_mld_activate_link(struct iwl_mld *mld,
struct ieee80211_bss_conf *link);
void iwl_mld_deactivate_link(struct iwl_mld *mld,
struct ieee80211_bss_conf *link);
int iwl_mld_change_link_in_fw(struct iwl_mld *mld,
struct ieee80211_bss_conf *link, u32 changes);
void iwl_mld_handle_missed_beacon_notif(struct iwl_mld *mld,
struct iwl_rx_packet *pkt);
bool iwl_mld_cancel_missed_beacon_notif(struct iwl_mld *mld,
struct iwl_rx_packet *pkt,
u32 removed_link_id);
int iwl_mld_link_set_associated(struct iwl_mld *mld, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link);
unsigned int iwl_mld_get_link_grade(struct iwl_mld *mld,
struct ieee80211_bss_conf *link_conf);
#if IS_ENABLED(CONFIG_IWLWIFI_KUNIT_TESTS)
s8 iwl_mld_get_dup_beacon_rssi_adjust(struct iwl_mld *mld,
struct ieee80211_bss_conf *link_conf);
s8 iwl_mld_get_psd_eirp_rssi_adjust(struct ieee80211_bss_conf *link_conf);
#endif
unsigned int iwl_mld_get_chan_load(struct iwl_mld *mld,
struct ieee80211_bss_conf *link_conf);
int iwl_mld_get_chan_load_from_element(struct iwl_mld *mld,
struct ieee80211_bss_conf *link_conf);
int iwl_mld_get_chan_load_by_others(struct iwl_mld *mld,
struct ieee80211_bss_conf *link_conf,
bool expect_active_link);
bool iwl_mld_chan_load_requires_scan(struct iwl_mld *mld,
struct ieee80211_bss_conf *link_conf,
u32 new_chan_load);
void iwl_mld_handle_beacon_filter_notif(struct iwl_mld *mld,
struct iwl_rx_packet *pkt);
#endif