diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath12k/core.h')
| -rw-r--r-- | drivers/net/wireless/ath/ath12k/core.h | 631 |
1 files changed, 534 insertions, 97 deletions
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index cdfd43a7321a..3c1e0069be1e 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_CORE_H @@ -14,7 +14,10 @@ #include <linux/dmi.h> #include <linux/ctype.h> #include <linux/firmware.h> +#include <linux/of_reserved_mem.h> #include <linux/panic_notifier.h> +#include <linux/average.h> +#include <linux/of.h> #include "qmi.h" #include "htc.h" #include "wmi.h" @@ -30,6 +33,7 @@ #include "acpi.h" #include "wow.h" #include "debugfs_htt_stats.h" +#include "coredump.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) @@ -51,8 +55,6 @@ #define ATH12K_INVALID_HW_MAC_ID 0xFF #define ATH12K_CONNECTION_LOSS_HZ (3 * HZ) -#define ATH12K_RX_RATE_TABLE_NUM 320 -#define ATH12K_RX_RATE_TABLE_11AX_NUM 576 #define ATH12K_MON_TIMER_INTERVAL 10 #define ATH12K_RESET_TIMEOUT_HZ (20 * HZ) @@ -62,6 +64,17 @@ #define ATH12K_RECONFIGURE_TIMEOUT_HZ (10 * HZ) #define ATH12K_RECOVER_START_TIMEOUT_HZ (20 * HZ) +#define ATH12K_MAX_DEVICES 3 +#define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_DEVICES * MAX_RADIOS) +#define ATH12K_INVALID_GROUP_ID 0xFF +#define ATH12K_INVALID_DEVICE_ID 0xFF + +#define ATH12K_MAX_MLO_PEERS 256 +#define ATH12K_MLO_PEER_ID_INVALID 0xFFFF + +#define ATH12K_INVALID_RSSI_FULL -1 +#define ATH12K_INVALID_RSSI_EMPTY -128 + enum ath12k_bdf_search { ATH12K_BDF_SEARCH_DEFAULT, ATH12K_BDF_SEARCH_BUS_AND_BOARD, @@ -78,6 +91,7 @@ enum wme_ac { #define ATH12K_HT_MCS_MAX 7 #define ATH12K_VHT_MCS_MAX 9 #define ATH12K_HE_MCS_MAX 11 +#define ATH12K_EHT_MCS_MAX 15 enum ath12k_crypt_mode { /* Only use hardware crypto engine */ @@ -94,9 +108,18 @@ static inline enum wme_ac ath12k_tid_to_ac(u32 tid) WME_AC_VO); } +static inline u64 ath12k_le32hilo_to_u64(__le32 hi, __le32 lo) +{ + u64 hi64 = le32_to_cpu(hi); + u64 lo64 = le32_to_cpu(lo); + + return (hi64 << 32) | lo64; +} + enum ath12k_skb_flags { ATH12K_SKB_HW_80211_ENCAP = BIT(0), ATH12K_SKB_CIPHER_SET = BIT(1), + ATH12K_SKB_MLO_STA = BIT(2), }; struct ath12k_skb_cb { @@ -106,6 +129,7 @@ struct ath12k_skb_cb { dma_addr_t paddr_ext_desc; u32 cipher; u8 flags; + u8 link_id; }; struct ath12k_skb_rxcb { @@ -118,17 +142,19 @@ struct ath12k_skb_rxcb { struct hal_rx_desc *rx_desc; u8 err_rel_src; u8 err_code; - u8 mac_id; + u8 hw_link_id; u8 unmapped; u8 is_frag; u8 tid; u16 peer_id; + bool is_end_of_ppdu; }; enum ath12k_hw_rev { ATH12K_HW_QCN9274_HW10, ATH12K_HW_QCN9274_HW20, - ATH12K_HW_WCN7850_HW20 + ATH12K_HW_WCN7850_HW20, + ATH12K_HW_IPQ5332_HW10, }; enum ath12k_firmware_mode { @@ -141,6 +167,7 @@ enum ath12k_firmware_mode { #define ATH12K_IRQ_NUM_MAX 57 #define ATH12K_EXT_IRQ_NUM_MAX 16 +#define ATH12K_MAX_TCL_RING_NUM 3 struct ath12k_ext_irq_grp { struct ath12k_base *ab; @@ -148,13 +175,39 @@ struct ath12k_ext_irq_grp { u32 num_irq; u32 grp_id; u64 timestamp; + bool napi_enabled; struct napi_struct napi; struct net_device *napi_ndev; }; +enum ath12k_smbios_cc_type { + /* disable country code setting from SMBIOS */ + ATH12K_SMBIOS_CC_DISABLE = 0, + + /* set country code by ANSI country name, based on ISO3166-1 alpha2 */ + ATH12K_SMBIOS_CC_ISO = 1, + + /* worldwide regdomain */ + ATH12K_SMBIOS_CC_WW = 2, +}; + struct ath12k_smbios_bdf { struct dmi_header hdr; - u32 padding; + u8 features_disabled; + + /* enum ath12k_smbios_cc_type */ + u8 country_code_flag; + + /* To set specific country, you need to set country code + * flag=ATH12K_SMBIOS_CC_ISO first, then if country is United + * States, then country code value = 0x5553 ("US",'U' = 0x55, 'S'= + * 0x53). To set country to INDONESIA, then country code value = + * 0x4944 ("IN", 'I'=0x49, 'D'=0x44). If country code flag = + * ATH12K_SMBIOS_CC_WW, then you can use worldwide regulatory + * setting. + */ + u16 cc_code; + u8 bdf_enabled; u8 bdf_ext[]; } __packed; @@ -199,8 +252,19 @@ enum ath12k_scan_state { ATH12K_SCAN_ABORTING, }; +enum ath12k_11d_state { + ATH12K_11D_IDLE, + ATH12K_11D_PREPARING, + ATH12K_11D_RUNNING, +}; + +enum ath12k_hw_group_flags { + ATH12K_GROUP_FLAG_REGISTERED, + ATH12K_GROUP_FLAG_UNREGISTER, +}; + enum ath12k_dev_flags { - ATH12K_CAC_RUNNING, + ATH12K_FLAG_CAC_RUNNING, ATH12K_FLAG_CRASH_FLUSH, ATH12K_FLAG_RAW_MODE, ATH12K_FLAG_HW_CRYPTO_DISABLED, @@ -211,6 +275,9 @@ enum ath12k_dev_flags { ATH12K_FLAG_HTC_SUSPEND_COMPLETE, ATH12K_FLAG_CE_IRQ_ENABLED, ATH12K_FLAG_EXT_IRQ_ENABLED, + ATH12K_FLAG_QMI_FW_READY_COMPLETE, + ATH12K_FLAG_FTM_SEGMENTED, + ATH12K_FLAG_FIXED_MEM_REGION, }; struct ath12k_tx_conf { @@ -220,8 +287,9 @@ struct ath12k_tx_conf { }; struct ath12k_key_conf { - bool changed; enum set_key_cmd cmd; + struct list_head list; + struct ieee80211_sta *sta; struct ieee80211_key_conf *key; }; @@ -238,10 +306,8 @@ struct ath12k_rekey_data { bool enable_offload; }; -struct ath12k_vif { +struct ath12k_link_vif { u32 vdev_id; - enum wmi_vdev_type vdev_type; - enum wmi_vdev_subtype vdev_subtype; u32 beacon_interval; u32 dtim_period; u16 ast_hash; @@ -251,13 +317,54 @@ struct ath12k_vif { u8 search_type; struct ath12k *ar; - struct ieee80211_vif *vif; int bank_id; u8 vdev_id_check_en; + bool beacon_prot; struct wmi_wmm_params_all_arg wmm_params; struct list_head list; + + bool is_created; + bool is_started; + bool is_up; + u8 bssid[ETH_ALEN]; + struct cfg80211_bitrate_mask bitrate_mask; + struct delayed_work connection_loss_work; + int num_legacy_stations; + int rtscts_prot_mode; + int txpower; + bool rsnie_present; + bool wpaie_present; + u8 vdev_stats_id; + u32 punct_bitmap; + u8 link_id; + struct ath12k_vif *ahvif; + struct ath12k_rekey_data rekey_data; + struct ath12k_link_stats link_stats; + spinlock_t link_stats_lock; /* Protects updates to link_stats */ + + u8 current_cntdown_counter; + + /* only used in station mode */ + bool is_sta_assoc_link; + + struct ath12k_reg_tpc_power_info reg_tpc_info; + + bool group_key_valid; + struct wmi_vdev_install_key_arg group_key; + bool pairwise_key_done; + u16 num_stations; + bool is_csa_in_progress; + struct wiphy_work bcn_tx_work; +}; + +struct ath12k_vif { + enum wmi_vdev_type vdev_type; + enum wmi_vdev_subtype vdev_subtype; + struct ieee80211_vif *vif; + struct ath12k_hw *ah; + union { struct { u32 uapsd; @@ -275,32 +382,29 @@ struct ath12k_vif { } ap; } u; - bool is_created; - bool is_started; - bool is_up; u32 aid; - u8 bssid[ETH_ALEN]; - struct cfg80211_bitrate_mask bitrate_mask; - struct delayed_work connection_loss_work; - int num_legacy_stations; - int rtscts_prot_mode; - int txpower; - bool rsnie_present; - bool wpaie_present; - struct ieee80211_chanctx_conf chanctx; u32 key_cipher; u8 tx_encap_type; - u8 vdev_stats_id; - u32 punct_bitmap; bool ps; - struct ath12k_vif_cache *cache; - struct ath12k_rekey_data rekey_data; + atomic_t mcbc_gsn; + + struct ath12k_link_vif deflink; + struct ath12k_link_vif __rcu *link[ATH12K_NUM_MAX_LINKS]; + struct ath12k_vif_cache *cache[IEEE80211_MLD_MAX_NUM_LINKS]; + /* indicates bitmap of link vif created in FW */ + u32 links_map; + /* Must be last - ends in a flexible-array member. + * + * FIXME: Driver should not copy struct ieee80211_chanctx_conf, + * especially because it has a flexible array. Find a better way. + */ + struct ieee80211_chanctx_conf chanctx; }; struct ath12k_vif_iter { u32 vdev_id; struct ath12k *ar; - struct ath12k_vif *arvif; + struct ath12k_link_vif *arvif; }; #define HAL_AST_IDX_INVALID 0xFFFF @@ -308,20 +412,22 @@ struct ath12k_vif_iter { #define HAL_RX_MAX_MCS_HT 31 #define HAL_RX_MAX_MCS_VHT 9 #define HAL_RX_MAX_MCS_HE 11 +#define HAL_RX_MAX_MCS_BE 15 #define HAL_RX_MAX_NSS 8 #define HAL_RX_MAX_NUM_LEGACY_RATES 12 -#define ATH12K_RX_RATE_TABLE_11AX_NUM 576 -#define ATH12K_RX_RATE_TABLE_NUM 320 + +#define ATH12K_SCAN_TIMEOUT_HZ (20 * HZ) struct ath12k_rx_peer_rate_stats { u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1]; u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1]; u64 he_mcs_count[HAL_RX_MAX_MCS_HE + 1]; + u64 be_mcs_count[HAL_RX_MAX_MCS_BE + 1]; u64 nss_count[HAL_RX_MAX_NSS]; u64 bw_count[HAL_RX_BW_MAX]; u64 gi_count[HAL_RX_GI_MAX]; u64 legacy_count[HAL_RX_MAX_NUM_LEGACY_RATES]; - u64 rx_rate[ATH12K_RX_RATE_TABLE_11AX_NUM]; + u64 rx_rate[HAL_RX_BW_MAX][HAL_RX_GI_MAX][HAL_RX_MAX_NSS][HAL_RX_MAX_MCS_HT + 1]; }; struct ath12k_rx_peer_stats { @@ -335,10 +441,6 @@ struct ath12k_rx_peer_stats { u64 non_ampdu_msdu_count; u64 stbc_count; u64 beamformed_count; - u64 mcs_count[HAL_RX_MAX_MCS + 1]; - u64 nss_count[HAL_RX_MAX_NSS]; - u64 bw_count[HAL_RX_BW_MAX]; - u64 gi_count[HAL_RX_GI_MAX]; u64 coding_count[HAL_RX_SU_MU_CODING_MAX]; u64 tid_count[IEEE80211_NUM_TIDS + 1]; u64 pream_cnt[HAL_RX_PREAMBLE_MAX]; @@ -435,32 +537,88 @@ struct ath12k_wbm_tx_stats { u64 wbm_tx_comp_stats[HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX]; }; -struct ath12k_sta { - struct ath12k_vif *arvif; +DECLARE_EWMA(avg_rssi, 10, 8) + +struct ath12k_link_sta { + struct ath12k_link_vif *arvif; + struct ath12k_sta *ahsta; + + /* link address similar to ieee80211_link_sta */ + u8 addr[ETH_ALEN]; /* the following are protected by ar->data_lock */ u32 changed; /* IEEE80211_RC_* */ u32 bw; u32 nss; u32 smps; - enum hal_pn_type pn_type; - struct work_struct update_wk; + struct wiphy_work update_wk; struct rate_info txrate; struct rate_info last_txrate; u64 rx_duration; u64 tx_duration; u8 rssi_comb; + struct ewma_avg_rssi avg_rssi; + u8 link_id; struct ath12k_rx_peer_stats *rx_stats; struct ath12k_wbm_tx_stats *wbm_tx_stats; u32 bw_prev; + u32 peer_nss; + s8 rssi_beacon; + s8 chain_signal[IEEE80211_MAX_CHAINS]; + + /* For now the assoc link will be considered primary */ + bool is_assoc_link; + + /* for firmware use only */ + u8 link_idx; + u32 tx_retry_failed; + u32 tx_retry_count; +}; + +struct ath12k_reoq_buf { + void *vaddr; + dma_addr_t paddr_aligned; + u32 size; }; -#define ATH12K_MIN_5G_FREQ 4150 -#define ATH12K_MIN_6G_FREQ 5925 -#define ATH12K_MAX_6G_FREQ 7115 +struct ath12k_sta { + struct ath12k_vif *ahvif; + enum hal_pn_type pn_type; + struct ath12k_link_sta deflink; + struct ath12k_link_sta __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS]; + /* indicates bitmap of link sta created in FW */ + u16 links_map; + u8 assoc_link_id; + u16 ml_peer_id; + u8 num_peer; + + enum ieee80211_sta_state state; + + struct ath12k_reoq_buf reoq_bufs[IEEE80211_NUM_TIDS + 1]; +}; + +#define ATH12K_HALF_20MHZ_BW 10 +#define ATH12K_2GHZ_MIN_CENTER 2412 +#define ATH12K_2GHZ_MAX_CENTER 2484 +#define ATH12K_5GHZ_MIN_CENTER 4900 +#define ATH12K_5GHZ_MAX_CENTER 5920 +#define ATH12K_6GHZ_MIN_CENTER 5935 +#define ATH12K_6GHZ_MAX_CENTER 7115 +#define ATH12K_MIN_2GHZ_FREQ (ATH12K_2GHZ_MIN_CENTER - ATH12K_HALF_20MHZ_BW - 1) +#define ATH12K_MAX_2GHZ_FREQ (ATH12K_2GHZ_MAX_CENTER + ATH12K_HALF_20MHZ_BW + 1) +#define ATH12K_MIN_5GHZ_FREQ (ATH12K_5GHZ_MIN_CENTER - ATH12K_HALF_20MHZ_BW) +#define ATH12K_MAX_5GHZ_FREQ (ATH12K_5GHZ_MAX_CENTER + ATH12K_HALF_20MHZ_BW) +#define ATH12K_MIN_6GHZ_FREQ (ATH12K_6GHZ_MIN_CENTER - ATH12K_HALF_20MHZ_BW) +#define ATH12K_MAX_6GHZ_FREQ (ATH12K_6GHZ_MAX_CENTER + ATH12K_HALF_20MHZ_BW) #define ATH12K_NUM_CHANS 101 -#define ATH12K_MAX_5G_CHAN 173 +#define ATH12K_MAX_5GHZ_CHAN 173 + +static inline bool ath12k_is_2ghz_channel_freq(u32 freq) +{ + return freq >= ATH12K_MIN_2GHZ_FREQ && + freq <= ATH12K_MAX_2GHZ_FREQ; +} enum ath12k_hw_state { ATH12K_HW_STATE_OFF, @@ -468,18 +626,26 @@ enum ath12k_hw_state { ATH12K_HW_STATE_RESTARTING, ATH12K_HW_STATE_RESTARTED, ATH12K_HW_STATE_WEDGED, + ATH12K_HW_STATE_TM, /* Add other states as required */ }; /* Antenna noise floor */ #define ATH12K_DEFAULT_NOISE_FLOOR -95 +struct ath12k_ftm_event_obj { + u32 data_pos; + u32 expected_seq; + u8 *eventdata; +}; + struct ath12k_fw_stats { u32 pdev_id; u32 stats_id; struct list_head pdevs; struct list_head vdevs; struct list_head bcn; + u32 num_vdev_recvd; }; struct ath12k_dbg_htt_stats { @@ -493,6 +659,12 @@ struct ath12k_debug { struct dentry *debugfs_pdev; struct dentry *debugfs_pdev_symlink; struct ath12k_dbg_htt_stats htt_stats; + enum wmi_halphy_ctrl_path_stats_id tpc_stats_type; + bool tpc_request; + struct completion tpc_complete; + struct wmi_tpc_stats_arg *tpc_stats; + u32 rx_filter; + bool extd_rx_stats; }; struct ath12k_per_peer_tx_stats { @@ -512,6 +684,15 @@ struct ath12k_per_peer_tx_stats { bool is_ampdu; }; +struct ath12k_pdev_rssi_offsets { + s32 temp_offset; + s8 min_nf_dbm; + /* Cache the sum here to avoid calculating it every time in hot path + * noise_floor = min_nf_dbm + temp_offset + */ + s32 noise_floor; +}; + #define ATH12K_FLUSH_TIMEOUT (5 * HZ) #define ATH12K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ) @@ -533,9 +714,10 @@ struct ath12k { struct delayed_work timeout; enum ath12k_scan_state state; bool is_roc; - int vdev_id; int roc_freq; bool roc_notify; + struct wiphy_work vdev_clean_wk; + struct ath12k_link_vif *arvif; } scan; struct { @@ -553,16 +735,13 @@ struct ath12k { u32 txpower_scale; u32 power_scale; u32 chan_tx_pwr; + u32 rts_threshold; u32 num_stations; u32 max_num_stations; - bool monitor_present; - /* To synchronize concurrent synchronous mac80211 callback operations, - * concurrent debugfs configuration and concurrent FW statistics events. - */ - struct mutex conf_mutex; + /* protects the radio specific data like debug stats, ppdu_stats_info stats, - * vdev_stop_status info, scan data, ath12k_sta info, ath12k_vif info, - * channel context data, survey info, test mode data. + * vdev_stop_status info, scan data, ath12k_sta info, ath12k_link_vif info, + * channel context data, survey info, test mode data, regd_channel_update_queue. */ spinlock_t data_lock; @@ -621,8 +800,10 @@ struct ath12k { struct completion bss_survey_done; struct work_struct regd_update_work; + struct work_struct regd_channel_update_work; + struct list_head regd_channel_update_queue; - struct work_struct wmi_mgmt_tx_work; + struct wiphy_work wmi_mgmt_tx_work; struct sk_buff_head wmi_mgmt_tx_queue; struct ath12k_wow wow; @@ -640,19 +821,39 @@ struct ath12k { #endif bool dfs_block_radar_events; - bool monitor_conf_enabled; bool monitor_vdev_created; bool monitor_started; int monitor_vdev_id; - u32 freq_low; - u32 freq_high; + struct wiphy_radio_freq_range freq_range; bool nlo_enabled; + + /* Protected by wiphy::mtx lock. */ + u32 vdev_id_11d_scan; + struct completion completed_11d_scan; + enum ath12k_11d_state state_11d; + u8 alpha2[REG_ALPHA2_LEN]; + bool regdom_set_by_user; + struct completion regd_update_completed; + + struct completion fw_stats_complete; + struct completion fw_stats_done; + + struct completion mlo_setup_done; + u32 mlo_setup_status; + u8 ftm_msgref; + struct ath12k_fw_stats fw_stats; + unsigned long last_tx_power_update; + + s8 max_allowed_tx_power; + struct ath12k_pdev_rssi_offsets rssi_info; }; struct ath12k_hw { struct ieee80211_hw *hw; + struct device *dev; + /* Protect the write operation of the hardware state ath12k_hw::state * between hardware start<=>reconfigure<=>stop transitions. */ @@ -660,8 +861,14 @@ struct ath12k_hw { enum ath12k_hw_state state; bool regd_updated; bool use_6ghz_regd; + u8 num_radio; + DECLARE_BITMAP(free_ml_peer_id_map, ATH12K_MAX_MLO_PEERS); + + /* protected by wiphy_lock() */ + struct list_head ml_peers; + /* Keep last */ struct ath12k radio[] __aligned(sizeof(void *)); }; @@ -696,6 +903,10 @@ struct ath12k_pdev_cap { u32 tx_chain_mask_shift; u32 rx_chain_mask_shift; struct ath12k_band_cap band[NUM_NL80211_BANDS]; + u32 eml_cap; + u32 mld_cap; + bool nss_ratio_enabled; + u8 nss_ratio_info; }; struct mlo_timestamp { @@ -730,7 +941,7 @@ struct ath12k_board_data { size_t len; }; -struct ath12k_soc_dp_tx_err_stats { +struct ath12k_device_dp_tx_err_stats { /* TCL Ring Descriptor unavailable */ u32 desc_na[DP_TCL_NUM_RING_MAX]; /* Other failures during dp_tx due to mem allocation failure @@ -739,28 +950,89 @@ struct ath12k_soc_dp_tx_err_stats { atomic_t misc_fail; }; -struct ath12k_soc_dp_stats { +struct ath12k_device_dp_stats { u32 err_ring_pkts; u32 invalid_rbm; u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX]; u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX]; u32 hal_reo_error[DP_REO_DST_RING_MAX]; - struct ath12k_soc_dp_tx_err_stats tx_err; -}; - -/** - * enum ath12k_link_capable_flags - link capable flags - * - * Single/Multi link capability information - * - * @ATH12K_INTRA_DEVICE_MLO_SUPPORT: SLO/MLO form between the radio, where all - * the links (radios) present within a device. - * @ATH12K_INTER_DEVICE_MLO_SUPPORT: SLO/MLO form between the radio, where all - * the links (radios) present across the devices. + struct ath12k_device_dp_tx_err_stats tx_err; + u32 reo_rx[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES]; + u32 rx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX][ATH12K_MAX_DEVICES]; + u32 tqm_rel_reason[MAX_TQM_RELEASE_REASON]; + u32 fw_tx_status[MAX_FW_TX_STATUS]; + u32 tx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX]; + u32 tx_enqueued[DP_TCL_NUM_RING_MAX]; + u32 tx_completed[DP_TCL_NUM_RING_MAX]; + u32 reo_excep_msdu_buf_type; +}; + +struct ath12k_reg_freq { + u32 start_freq; + u32 end_freq; +}; + +struct ath12k_mlo_memory { + struct target_mem_chunk chunk[ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01]; + int mlo_mem_size; + bool init_done; +}; + +struct ath12k_hw_link { + u8 device_id; + u8 pdev_idx; +}; + +/* Holds info on the group of devices that are registered as a single + * wiphy, protected with struct ath12k_hw_group::mutex. */ -enum ath12k_link_capable_flags { - ATH12K_INTRA_DEVICE_MLO_SUPPORT = BIT(0), - ATH12K_INTER_DEVICE_MLO_SUPPORT = BIT(1), +struct ath12k_hw_group { + struct list_head list; + u8 id; + u8 num_devices; + u8 num_probed; + u8 num_started; + unsigned long flags; + struct ath12k_base *ab[ATH12K_MAX_DEVICES]; + + /* protects access to this struct */ + struct mutex mutex; + + /* Holds information of wiphy (hw) registration. + * + * In Multi/Single Link Operation case, all pdevs are registered as + * a single wiphy. In other (legacy/Non-MLO) cases, each pdev is + * registered as separate wiphys. + */ + struct ath12k_hw *ah[ATH12K_GROUP_MAX_RADIO]; + u8 num_hw; + bool mlo_capable; + struct device_node *wsi_node[ATH12K_MAX_DEVICES]; + struct ath12k_mlo_memory mlo_mem; + struct ath12k_hw_link hw_links[ATH12K_GROUP_MAX_RADIO]; + bool hw_link_id_init_done; +}; + +/* Holds WSI info specific to each device, excluding WSI group info */ +struct ath12k_wsi_info { + u32 index; + u32 hw_link_id_base; +}; + +struct ath12k_dp_profile_params { + u32 tx_comp_ring_size; + u32 rxdma_monitor_buf_ring_size; + u32 rxdma_monitor_dst_ring_size; + u32 num_pool_tx_desc; + u32 rx_desc_count; +}; + +struct ath12k_mem_profile_based_param { + u32 num_vdevs; + u32 max_client_single; + u32 max_client_dbs; + u32 max_client_dbs_sbs; + struct ath12k_dp_profile_params dp_params; }; /* Master structure to hold the hw data which may be used in core module */ @@ -776,6 +1048,10 @@ struct ath12k_base { /* HW channel counters frequency value in hertz common to all MACs */ u32 cc_freq_hz; + struct ath12k_dump_file_data *dump_data; + size_t ath12k_coredump_len; + struct work_struct dump_work; + struct ath12k_htc htc; struct ath12k_dp dp; @@ -783,6 +1059,10 @@ struct ath12k_base { void __iomem *mem; unsigned long mem_len; + void __iomem *mem_ce; + u32 ce_remap_base_addr; + bool ce_remap; + struct { enum ath12k_bus bus; const struct ath12k_hif_ops *ops; @@ -822,15 +1102,6 @@ struct ath12k_base { struct ath12k_pdev __rcu *pdevs_active[MAX_RADIOS]; - /* Holds information of wiphy (hw) registration. - * - * In Multi/Single Link Operation case, all pdevs are registered as - * a single wiphy. In other (legacy/Non-MLO) cases, each pdev is - * registered as separate wiphys. - */ - struct ath12k_hw *ah[MAX_RADIOS]; - u8 num_hw; - struct ath12k_wmi_hal_reg_capabilities_ext_arg hal_reg_cap[MAX_RADIOS]; unsigned long long free_vdev_map; unsigned long long free_vdev_stats_id_map; @@ -860,9 +1131,11 @@ struct ath12k_base { */ struct ieee80211_regdomain *new_regd[MAX_RADIOS]; + struct ath12k_reg_info *reg_info[MAX_RADIOS]; + /* Current DFS Regulatory */ enum ath12k_dfs_region dfs_region; - struct ath12k_soc_dp_stats soc_stats; + struct ath12k_device_dp_stats device_stats; #ifdef CONFIG_ATH12K_DEBUGFS struct dentry *debugfs_soc; #endif @@ -880,6 +1153,8 @@ struct ath12k_base { /* continuous recovery fail count */ atomic_t fail_cont_count; unsigned long reset_fail_timeout; + struct work_struct update_11d_work; + u8 new_alpha2[2]; struct { /* protected by data_lock */ u32 fw_crash_counter; @@ -889,8 +1164,6 @@ struct ath12k_base { struct ath12k_dbring_cap *db_caps; u32 num_db_cap; - struct timer_list mon_reap_timer; - struct completion htc_suspend; u64 fw_soc_drop_count; @@ -920,17 +1193,11 @@ struct ath12k_base { size_t m3_len; DECLARE_BITMAP(fw_features, ATH12K_FW_FEATURE_COUNT); + bool fw_features_valid; } fw; const struct hal_rx_ops *hal_rx_ops; - /* mlo_capable_flags denotes the single/multi link operation - * capabilities of the Device. - * - * See enum ath12k_link_capable_flags - */ - u8 mlo_capable_flags; - struct completion restart_completed; #ifdef CONFIG_ACPI @@ -940,6 +1207,13 @@ struct ath12k_base { u32 func_bit; bool acpi_tas_enable; bool acpi_bios_sar_enable; + bool acpi_disable_11be; + bool acpi_disable_rfkill; + bool acpi_cca_enable; + bool acpi_band_edge_enable; + bool acpi_enable_bdf; + u32 bit_flag; + char bdf_string[ATH12K_ACPI_BDF_MAX_LEN]; u8 tas_cfg[ATH12K_ACPI_DSM_TAS_CFG_SIZE]; u8 tas_sar_power_table[ATH12K_ACPI_DSM_TAS_DATA_SIZE]; u8 bios_sar_data[ATH12K_ACPI_DSM_BIOS_SAR_DATA_SIZE]; @@ -952,6 +1226,21 @@ struct ath12k_base { struct notifier_block panic_nb; + struct ath12k_hw_group *ag; + struct ath12k_wsi_info wsi_info; + enum ath12k_firmware_mode fw_mode; + struct ath12k_ftm_event_obj ftm_event_obj; + bool hw_group_ref; + + /* Denote whether MLO is possible within the device */ + bool single_chip_mlo_support; + + struct ath12k_reg_freq reg_freq_2ghz; + struct ath12k_reg_freq reg_freq_5ghz; + struct ath12k_reg_freq reg_freq_6ghz; + const struct ath12k_mem_profile_based_param *profile_param; + enum ath12k_qmi_mem_mode target_mem_mode; + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; @@ -961,7 +1250,95 @@ struct ath12k_pdev_map { u8 pdev_idx; }; +struct ath12k_fw_stats_vdev { + struct list_head list; + + u32 vdev_id; + u32 beacon_snr; + u32 data_snr; + u32 num_tx_frames[WLAN_MAX_AC]; + u32 num_rx_frames; + u32 num_tx_frames_retries[WLAN_MAX_AC]; + u32 num_tx_frames_failures[WLAN_MAX_AC]; + u32 num_rts_fail; + u32 num_rts_success; + u32 num_rx_err; + u32 num_rx_discard; + u32 num_tx_not_acked; + u32 tx_rate_history[MAX_TX_RATE_VALUES]; + u32 beacon_rssi_history[MAX_TX_RATE_VALUES]; +}; + +struct ath12k_fw_stats_bcn { + struct list_head list; + + u32 vdev_id; + u32 tx_bcn_succ_cnt; + u32 tx_bcn_outage_cnt; +}; + +struct ath12k_fw_stats_pdev { + struct list_head list; + + /* PDEV stats */ + s32 ch_noise_floor; + u32 tx_frame_count; + u32 rx_frame_count; + u32 rx_clear_count; + u32 cycle_count; + u32 phy_err_count; + u32 chan_tx_power; + u32 ack_rx_bad; + u32 rts_bad; + u32 rts_good; + u32 fcs_bad; + u32 no_beacons; + u32 mib_int_count; + + /* PDEV TX stats */ + s32 comp_queued; + s32 comp_delivered; + s32 msdu_enqued; + s32 mpdu_enqued; + s32 wmm_drop; + s32 local_enqued; + s32 local_freed; + s32 hw_queued; + s32 hw_reaped; + s32 underrun; + s32 tx_abort; + s32 mpdus_requed; + u32 tx_ko; + u32 data_rc; + u32 self_triggers; + u32 sw_retry_failure; + u32 illgl_rate_phy_err; + u32 pdev_cont_xretry; + u32 pdev_tx_timeout; + u32 pdev_resets; + u32 stateless_tid_alloc_failure; + u32 phy_underrun; + u32 txop_ovf; + + /* PDEV RX stats */ + s32 mid_ppdu_route_change; + s32 status_rcvd; + s32 r0_frags; + s32 r1_frags; + s32 r2_frags; + s32 r3_frags; + s32 htt_msdus; + s32 htt_mpdus; + s32 loc_msdus; + s32 loc_mpdus; + s32 oversize_amsdu; + s32 phy_errs; + s32 phy_err_drop; + s32 mpdu_errs; +}; + int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab); +void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag); int ath12k_core_pre_init(struct ath12k_base *ab); int ath12k_core_init(struct ath12k_base *ath12k); void ath12k_core_deinit(struct ath12k_base *ath12k); @@ -982,12 +1359,22 @@ int ath12k_core_resume_early(struct ath12k_base *ab); int ath12k_core_resume(struct ath12k_base *ab); int ath12k_core_suspend(struct ath12k_base *ab); int ath12k_core_suspend_late(struct ath12k_base *ab); +void ath12k_core_hw_group_unassign(struct ath12k_base *ab); +u8 ath12k_get_num_partner_link(struct ath12k *ar); const struct firmware *ath12k_core_firmware_request(struct ath12k_base *ab, const char *filename); u32 ath12k_core_get_max_station_per_radio(struct ath12k_base *ab); u32 ath12k_core_get_max_peers_per_radio(struct ath12k_base *ab); -u32 ath12k_core_get_max_num_tids(struct ath12k_base *ab); + +void ath12k_core_hw_group_set_mlo_capable(struct ath12k_hw_group *ag); +void ath12k_fw_stats_init(struct ath12k *ar); +void ath12k_fw_stats_bcn_free(struct list_head *head); +void ath12k_fw_stats_free(struct ath12k_fw_stats *stats); +void ath12k_fw_stats_reset(struct ath12k *ar); +struct reserved_mem *ath12k_core_get_reserved_mem(struct ath12k_base *ab, + int index); +enum ath12k_qmi_mem_mode ath12k_core_get_memory_mode(struct ath12k_base *ab); static inline const char *ath12k_scan_state_str(enum ath12k_scan_state state) { @@ -1018,16 +1405,26 @@ static inline struct ath12k_skb_rxcb *ATH12K_SKB_RXCB(struct sk_buff *skb) return (struct ath12k_skb_rxcb *)skb->cb; } -static inline struct ath12k_vif *ath12k_vif_to_arvif(struct ieee80211_vif *vif) +static inline struct ath12k_vif *ath12k_vif_to_ahvif(struct ieee80211_vif *vif) { return (struct ath12k_vif *)vif->drv_priv; } -static inline struct ath12k_sta *ath12k_sta_to_arsta(struct ieee80211_sta *sta) +static inline struct ath12k_sta *ath12k_sta_to_ahsta(struct ieee80211_sta *sta) { return (struct ath12k_sta *)sta->drv_priv; } +static inline struct ieee80211_sta *ath12k_ahsta_to_sta(struct ath12k_sta *ahsta) +{ + return container_of((void *)ahsta, struct ieee80211_sta, drv_priv); +} + +static inline struct ieee80211_vif *ath12k_ahvif_to_vif(struct ath12k_vif *ahvif) +{ + return container_of((void *)ahvif, struct ieee80211_vif, drv_priv); +} + static inline struct ath12k *ath12k_ab_to_ar(struct ath12k_base *ab, int mac_id) { @@ -1038,8 +1435,16 @@ static inline void ath12k_core_create_firmware_path(struct ath12k_base *ab, const char *filename, void *buf, size_t buf_len) { - snprintf(buf, buf_len, "%s/%s/%s", ATH12K_FW_DIR, - ab->hw_params->fw.dir, filename); + const char *fw_name = NULL; + + of_property_read_string(ab->dev->of_node, "firmware-name", &fw_name); + + if (fw_name && strncmp(filename, "board", 5)) + snprintf(buf, buf_len, "%s/%s/%s/%s", ATH12K_FW_DIR, + ab->hw_params->fw.dir, fw_name, filename); + else + snprintf(buf, buf_len, "%s/%s/%s", ATH12K_FW_DIR, + ab->hw_params->fw.dir, filename); } static inline const char *ath12k_bus_str(enum ath12k_bus bus) @@ -1047,6 +1452,8 @@ static inline const char *ath12k_bus_str(enum ath12k_bus bus) switch (bus) { case ATH12K_BUS_PCI: return "pci"; + case ATH12K_BUS_AHB: + return "ahb"; } return "unknown"; @@ -1079,4 +1486,34 @@ static inline struct ieee80211_hw *ath12k_ar_to_hw(struct ath12k *ar) #define for_each_ar(ah, ar, index) \ for ((index) = 0; ((index) < (ah)->num_radio && \ ((ar) = &(ah)->radio[(index)])); (index)++) + +static inline struct ath12k_hw *ath12k_ag_to_ah(struct ath12k_hw_group *ag, int idx) +{ + return ag->ah[idx]; +} + +static inline void ath12k_ag_set_ah(struct ath12k_hw_group *ag, int idx, + struct ath12k_hw *ah) +{ + ag->ah[idx] = ah; +} + +static inline struct ath12k_hw_group *ath12k_ab_to_ag(struct ath12k_base *ab) +{ + return ab->ag; +} + +static inline struct ath12k_base *ath12k_ag_to_ab(struct ath12k_hw_group *ag, + u8 device_id) +{ + return ag->ab[device_id]; +} + +static inline s32 ath12k_pdev_get_noise_floor(struct ath12k *ar) +{ + lockdep_assert_held(&ar->data_lock); + + return ar->rssi_info.noise_floor; +} + #endif /* _CORE_H_ */ |
