diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/sta.h')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/sta.h | 136 |
1 files changed, 121 insertions, 15 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h index f1a4fc3e4038..a61d4f88125f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2021 Intel Corporation + * Copyright (C) 2012-2014, 2018-2022 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2016 Intel Deutschland GmbH */ @@ -331,14 +331,32 @@ struct iwl_mvm_rxq_dup_data { } ____cacheline_aligned_in_smp; /** + * struct iwl_mvm_link_sta - link specific parameters of a station + * @rcu_head: used for freeing the data + * @sta_id: the index of the station in the fw + * @lq_sta: holds rate scaling data, either for the case when RS is done in + * the driver - %rs_drv or in the FW - %rs_fw. + * @avg_energy: energy as reported by FW statistics notification + */ +struct iwl_mvm_link_sta { + struct rcu_head rcu_head; + u32 sta_id; + union { + struct iwl_lq_sta_rs_fw rs_fw; + struct iwl_lq_sta rs_drv; + } lq_sta; + + u8 avg_energy; +}; + +/** * struct iwl_mvm_sta - representation of a station in the driver - * @sta_id: the index of the station in the fw (will be replaced by id_n_color) * @tfd_queue_msk: the tfd queues used by the station * @mac_id_n_color: the MAC context this station is linked to * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for * tid. - * @max_agg_bufsize: the maximal size of the AGG buffer for this station * @sta_type: station type + * @authorized: indicates station is authorized * @sta_state: station state according to enum %ieee80211_sta_state * @bt_reduced_txpower: is reduced tx power enabled for this station * @next_status_eosp: the next reclaimed packet is a PS-Poll response and @@ -347,8 +365,6 @@ struct iwl_mvm_rxq_dup_data { * and from Tx response flow, it needs a spinlock. * @tid_data: per tid data + mgmt. Look at %iwl_mvm_tid_data. * @tid_to_baid: a simple map of TID to baid - * @lq_sta: holds rate scaling data, either for the case when RS is done in - * the driver - %rs_drv or in the FW - %rs_fw. * @reserved_queue: the queue reserved for this STA for DQA purposes * Every STA has is given one reserved queue to allow it to operate. If no * such queue can be guaranteed, the STA addition will fail. @@ -374,6 +390,12 @@ struct iwl_mvm_rxq_dup_data { * used during connection establishment (e.g. for the 4 way handshake * exchange). * @pairwise_cipher: used to feed iwlmei upon authorization + * @deflink: the default link station, for non-MLO STA, all link specific data + * is accessed via deflink (or link[0]). For MLO, it will hold data of the + * first added link STA. + * @link: per link sta entries. For non-MLO only link[0] holds data. For MLO, + * link[0] points to deflink and link[link_id] is allocated when new link + * sta is added. * * When mac80211 creates a station it reserves some space (hw->sta_data_size) * in the structure for use by driver. This structure is placed in that @@ -381,22 +403,17 @@ struct iwl_mvm_rxq_dup_data { * */ struct iwl_mvm_sta { - u32 sta_id; u32 tfd_queue_msk; u32 mac_id_n_color; u16 tid_disable_agg; - u16 max_agg_bufsize; - enum iwl_sta_type sta_type; + u8 sta_type; enum ieee80211_sta_state sta_state; bool bt_reduced_txpower; bool next_status_eosp; + bool authorized; spinlock_t lock; struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT + 1]; u8 tid_to_baid[IWL_MAX_TID_COUNT]; - union { - struct iwl_lq_sta_rs_fw rs_fw; - struct iwl_lq_sta rs_drv; - } lq_sta; struct ieee80211_vif *vif; struct iwl_mvm_key_pn __rcu *ptk_pn[4]; struct iwl_mvm_rxq_dup_data *dup_data; @@ -414,9 +431,11 @@ struct iwl_mvm_sta { bool sleeping; u8 agg_tids; u8 sleep_tx_count; - u8 avg_energy; u8 tx_ant; u32 pairwise_cipher; + + struct iwl_mvm_link_sta deflink; + struct iwl_mvm_link_sta __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS]; }; u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data); @@ -436,7 +455,7 @@ iwl_mvm_sta_from_mac80211(struct ieee80211_sta *sta) */ struct iwl_mvm_int_sta { u32 sta_id; - enum iwl_sta_type type; + u8 type; u32 tfd_queue_msk; }; @@ -452,6 +471,9 @@ struct iwl_mvm_int_sta { */ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, bool update, unsigned int flags); +int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm, enum nl80211_iftype iftype); +int iwl_mvm_sta_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, int sta_id, u8 sta_type); int iwl_mvm_add_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta); @@ -463,8 +485,13 @@ static inline int iwl_mvm_update_sta(struct iwl_mvm *mvm, return iwl_mvm_sta_send_to_fw(mvm, sta, true, 0); } +void iwl_mvm_realloc_queues_after_restart(struct iwl_mvm *mvm, + struct ieee80211_sta *sta); int iwl_mvm_wait_sta_queues_empty(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvm_sta); +bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_link_sta *link_sta, int *ret); int iwl_mvm_rm_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta); @@ -510,6 +537,8 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm, u32 lmac_id); int iwl_mvm_rm_aux_sta(struct iwl_mvm *mvm); int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); +void iwl_mvm_free_bcast_sta_queues(struct iwl_mvm *mvm, + struct ieee80211_vif *vif); int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int iwl_mvm_add_p2p_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); @@ -519,7 +548,7 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, u32 qmask, enum nl80211_iftype iftype, - enum iwl_sta_type type); + u8 type); void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta); int iwl_mvm_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); @@ -543,6 +572,7 @@ void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm, void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvmvif, bool disable); + void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif); void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk); int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, @@ -551,4 +581,80 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, void iwl_mvm_cancel_channel_switch(struct iwl_mvm *mvm, struct ieee80211_vif *vif, u32 mac_id); +/* Queues */ +int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, + struct ieee80211_sta *sta, + u8 sta_id, u8 tid, unsigned int timeout); + +/* Sta state */ +/** + * struct iwl_mvm_sta_state_ops - callbacks for the sta_state() ops + * + * Since the only difference between both MLD and + * non-MLD versions of sta_state() is these function calls, + * each version will send its specific function calls to + * %iwl_mvm_mac_sta_state_common(). + * + * @add_sta: pointer to the function that adds a new sta + * @update_sta: pointer to the function that updates a sta + * @rm_sta: pointer to the functions that removes a sta + * @mac_ctxt_changed: pointer to the function that handles a change in mac ctxt + */ +struct iwl_mvm_sta_state_ops { + int (*add_sta)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); + int (*update_sta)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); + int (*rm_sta)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); + int (*mac_ctxt_changed)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + bool force_assoc_off); +}; + +int iwl_mvm_mac_sta_state_common(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state, + struct iwl_mvm_sta_state_ops *callbacks); + +/* New MLD STA related APIs */ +/* STA */ +int iwl_mvm_mld_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf); +int iwl_mvm_mld_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf); +int iwl_mvm_mld_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf); +int iwl_mvm_mld_add_aux_sta(struct iwl_mvm *mvm, u32 lmac_id); +int iwl_mvm_mld_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf); +int iwl_mvm_mld_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); +int iwl_mvm_mld_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf); +int iwl_mvm_mld_rm_aux_sta(struct iwl_mvm *mvm); +int iwl_mvm_mld_add_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +int iwl_mvm_mld_update_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +int iwl_mvm_mld_rm_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +int iwl_mvm_mld_rm_sta_id(struct iwl_mvm *mvm, u8 sta_id); +int iwl_mvm_mld_update_sta_links(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + u16 old_links, u16 new_links); +u32 iwl_mvm_sta_fw_id_mask(struct iwl_mvm *mvm, struct ieee80211_sta *sta, + int filter_link_id); + +/* Queues */ +void iwl_mvm_mld_modify_all_sta_disable_tx(struct iwl_mvm *mvm, + struct iwl_mvm_vif *mvmvif, + bool disable); +void iwl_mvm_mld_sta_modify_disable_tx(struct iwl_mvm *mvm, + struct iwl_mvm_sta *mvm_sta, + bool disable); +void iwl_mvm_mld_sta_modify_disable_tx_ap(struct iwl_mvm *mvm, + struct ieee80211_sta *sta, + bool disable); #endif /* __sta_h__ */ |