xref: /linux/drivers/net/wireless/ath/ath11k/cfr.h (revision a34b0e4e21d6be3c3d620aa7f9dfbf0e9550c19e)
1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
2 /*
3  * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
4  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
5  */
6 
7 #ifndef ATH11K_CFR_H
8 #define ATH11K_CFR_H
9 
10 #include "dbring.h"
11 #include "wmi.h"
12 
13 #define ATH11K_CFR_NUM_RESP_PER_EVENT   1
14 #define ATH11K_CFR_EVENT_TIMEOUT_MS     1
15 #define ATH11K_CFR_NUM_RING_ENTRIES     1
16 
17 #define ATH11K_MAX_CFR_ENABLED_CLIENTS 10
18 #define CFR_MAX_LUT_ENTRIES 136
19 
20 #define HOST_MAX_CHAINS 8
21 
22 enum ath11k_cfr_correlate_event_type {
23 	ATH11K_CORRELATE_DBR_EVENT,
24 	ATH11K_CORRELATE_TX_EVENT,
25 };
26 
27 struct ath11k_sta;
28 struct ath11k_per_peer_cfr_capture;
29 
30 #define ATH11K_CFR_START_MAGIC 0xDEADBEAF
31 #define ATH11K_CFR_END_MAGIC 0xBEAFDEAD
32 
33 #define VENDOR_QCA 0x8cfdf0
34 #define PLATFORM_TYPE_ARM 2
35 
36 enum ath11k_cfr_meta_version {
37 	ATH11K_CFR_META_VERSION_NONE,
38 	ATH11K_CFR_META_VERSION_1,
39 	ATH11K_CFR_META_VERSION_2,
40 	ATH11K_CFR_META_VERSION_3,
41 	ATH11K_CFR_META_VERSION_4,
42 	ATH11K_CFR_META_VERSION_MAX = 0xFF,
43 };
44 
45 enum ath11k_cfr_data_version {
46 	ATH11K_CFR_DATA_VERSION_NONE,
47 	ATH11K_CFR_DATA_VERSION_1,
48 	ATH11K_CFR_DATA_VERSION_MAX = 0xFF,
49 };
50 
51 enum ath11k_cfr_capture_ack_mode {
52 	ATH11K_CFR_CAPTURE_LEGACY_ACK,
53 	ATH11K_CFR_CAPTURE_DUP_LEGACY_ACK,
54 	ATH11K_CFR_CAPTURE_HT_ACK,
55 	ATH11K_CFR_CAPTURE_VHT_ACK,
56 
57 	/*Always keep this at last*/
58 	ATH11K_CFR_CAPTURE_INVALID_ACK
59 };
60 
61 enum ath11k_cfr_correlate_status {
62 	ATH11K_CORRELATE_STATUS_RELEASE,
63 	ATH11K_CORRELATE_STATUS_HOLD,
64 	ATH11K_CORRELATE_STATUS_ERR,
65 };
66 
67 enum ath11k_cfr_preamble_type {
68 	ATH11K_CFR_PREAMBLE_TYPE_LEGACY,
69 	ATH11K_CFR_PREAMBLE_TYPE_HT,
70 	ATH11K_CFR_PREAMBLE_TYPE_VHT,
71 };
72 
73 struct ath11k_cfr_peer_tx_param {
74 	u32 capture_method;
75 	u32 vdev_id;
76 	u8 peer_mac_addr[ETH_ALEN];
77 	u32 primary_20mhz_chan;
78 	u32 bandwidth;
79 	u32 phy_mode;
80 	u32 band_center_freq1;
81 	u32 band_center_freq2;
82 	u32 spatial_streams;
83 	u32 correlation_info_1;
84 	u32 correlation_info_2;
85 	u32 status;
86 	u32 timestamp_us;
87 	u32 counter;
88 	u32 chain_rssi[WMI_MAX_CHAINS];
89 	u16 chain_phase[WMI_MAX_CHAINS];
90 	u32 cfo_measurement;
91 	u8 agc_gain[HOST_MAX_CHAINS];
92 	u32 rx_start_ts;
93 };
94 
95 struct cfr_metadata {
96 	u8 peer_addr[ETH_ALEN];
97 	u8 status;
98 	u8 capture_bw;
99 	u8 channel_bw;
100 	u8 phy_mode;
101 	u16 prim20_chan;
102 	u16 center_freq1;
103 	u16 center_freq2;
104 	u8 capture_mode;
105 	u8 capture_type;
106 	u8 sts_count;
107 	u8 num_rx_chain;
108 	u32 timestamp;
109 	u32 length;
110 	u32 chain_rssi[HOST_MAX_CHAINS];
111 	u16 chain_phase[HOST_MAX_CHAINS];
112 	u32 cfo_measurement;
113 	u8 agc_gain[HOST_MAX_CHAINS];
114 	u32 rx_start_ts;
115 } __packed;
116 
117 struct ath11k_csi_cfr_header {
118 	u32 start_magic_num;
119 	u32 vendorid;
120 	u8 cfr_metadata_version;
121 	u8 cfr_data_version;
122 	u8 chip_type;
123 	u8 platform_type;
124 	u32 cfr_metadata_len;
125 	struct cfr_metadata meta_data;
126 } __packed;
127 
128 #define TONES_IN_20MHZ  256
129 #define TONES_IN_40MHZ  512
130 #define TONES_IN_80MHZ  1024
131 #define TONES_IN_160MHZ 2048 /* 160 MHz isn't supported yet */
132 #define TONES_INVALID   0
133 
134 #define CFIR_DMA_HDR_INFO0_TAG GENMASK(7, 0)
135 #define CFIR_DMA_HDR_INFO0_LEN GENMASK(13, 8)
136 
137 #define CFIR_DMA_HDR_INFO1_UPLOAD_DONE      GENMASK(0, 0)
138 #define CFIR_DMA_HDR_INFO1_CAPTURE_TYPE     GENMASK(3, 1)
139 #define CFIR_DMA_HDR_INFO1_PREAMBLE_TYPE    GENMASK(5, 4)
140 #define CFIR_DMA_HDR_INFO1_NSS              GENMASK(8, 6)
141 #define CFIR_DMA_HDR_INFO1_NUM_CHAINS       GENMASK(11, 9)
142 #define CFIR_DMA_HDR_INFO1_UPLOAD_PKT_BW    GENMASK(14, 12)
143 #define CFIR_DMA_HDR_INFO1_SW_PEER_ID_VALID GENMASK(15, 15)
144 
145 struct ath11k_cfr_dma_hdr {
146 	u16 info0;
147 	u16 info1;
148 	u16 sw_peer_id;
149 	u16 phy_ppdu_id;
150 };
151 
152 struct ath11k_look_up_table {
153 	bool dbr_recv;
154 	bool tx_recv;
155 	u8 *data;
156 	u32 data_len;
157 	u16 dbr_ppdu_id;
158 	u16 tx_ppdu_id;
159 	dma_addr_t dbr_address;
160 	struct ath11k_csi_cfr_header header;
161 	struct ath11k_cfr_dma_hdr hdr;
162 	u64 txrx_tstamp;
163 	u64 dbr_tstamp;
164 	u32 header_length;
165 	u32 payload_length;
166 	struct ath11k_dbring_element *buff;
167 };
168 
169 struct cfr_unassoc_pool_entry {
170 	u8 peer_mac[ETH_ALEN];
171 	u32 period;
172 	bool is_valid;
173 };
174 
175 struct ath11k_cfr {
176 	struct ath11k_dbring rx_ring;
177 	/* Protects cfr data */
178 	spinlock_t lock;
179 	/* Protect for lut entries */
180 	spinlock_t lut_lock;
181 	struct ath11k_look_up_table *lut;
182 	struct dentry *enable_cfr;
183 	struct dentry *cfr_unassoc;
184 	struct rchan *rfs_cfr_capture;
185 	u8 cfr_enabled_peer_cnt;
186 	u32 lut_num;
187 	u64 tx_evt_cnt;
188 	u64 dbr_evt_cnt;
189 	u64 release_cnt;
190 	u64 tx_peer_status_cfr_fail;
191 	u64 tx_evt_status_cfr_fail;
192 	u64 tx_dbr_lookup_fail;
193 	u64 last_success_tstamp;
194 	u64 flush_dbr_cnt;
195 	u64 clear_txrx_event;
196 	u64 cfr_dma_aborts;
197 	bool enabled;
198 	enum wmi_phy_mode phymode;
199 	struct cfr_unassoc_pool_entry unassoc_pool[ATH11K_MAX_CFR_ENABLED_CLIENTS];
200 };
201 
202 enum ath11k_cfr_capture_method {
203 	ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME,
204 	ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME_WITH_PHASE,
205 	ATH11K_CFR_CAPTURE_METHOD_PROBE_RESP,
206 	ATH11K_CFR_CAPTURE_METHOD_MAX,
207 };
208 
209 enum ath11k_cfr_capture_bw {
210 	ATH11K_CFR_CAPTURE_BW_20,
211 	ATH11K_CFR_CAPTURE_BW_40,
212 	ATH11K_CFR_CAPTURE_BW_80,
213 	ATH11K_CFR_CAPTURE_BW_MAX,
214 };
215 
216 #ifdef CONFIG_ATH11K_CFR
217 int ath11k_cfr_init(struct ath11k_base *ab);
218 void ath11k_cfr_deinit(struct ath11k_base *ab);
219 void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr,
220 				 u32 buf_id);
221 void ath11k_cfr_decrement_peer_count(struct ath11k *ar,
222 				     struct ath11k_sta *arsta);
223 void ath11k_cfr_update_unassoc_pool_entry(struct ath11k *ar,
224 					  const u8 *peer_mac);
225 bool ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k *ar,
226 					    const u8 *peer_mac);
227 void ath11k_cfr_update_unassoc_pool(struct ath11k *ar,
228 				    struct ath11k_per_peer_cfr_capture *params,
229 				    u8 *peer_mac);
230 int ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar,
231 					 struct ath11k_sta *arsta,
232 					 struct ath11k_per_peer_cfr_capture *params,
233 					 const u8 *peer_mac);
234 struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar);
235 void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut);
236 int ath11k_process_cfr_capture_event(struct ath11k_base *ab,
237 				     struct ath11k_cfr_peer_tx_param *params);
238 void ath11k_cfr_update_phymode(struct ath11k *ar, enum wmi_phy_mode phymode);
239 #else
240 static inline void ath11k_cfr_update_phymode(struct ath11k *ar,
241 					     enum wmi_phy_mode phymode)
242 {
243 }
244 
245 static inline int ath11k_cfr_init(struct ath11k_base *ab)
246 {
247 	return 0;
248 }
249 
250 static inline void ath11k_cfr_deinit(struct ath11k_base *ab)
251 {
252 }
253 
254 static inline void ath11k_cfr_lut_update_paddr(struct ath11k *ar,
255 					       dma_addr_t paddr, u32 buf_id)
256 {
257 }
258 
259 static inline void ath11k_cfr_decrement_peer_count(struct ath11k *ar,
260 						   struct ath11k_sta *arsta)
261 {
262 }
263 
264 static inline void ath11k_cfr_update_unassoc_pool_entry(struct ath11k *ar,
265 							const u8 *peer_mac)
266 {
267 }
268 
269 static inline bool
270 ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k *ar, const u8 *peer_mac)
271 {
272 	return false;
273 }
274 
275 static inline void
276 ath11k_cfr_update_unassoc_pool(struct ath11k *ar,
277 			       struct ath11k_per_peer_cfr_capture *params,
278 			       u8 *peer_mac)
279 {
280 }
281 
282 static inline int
283 ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar,
284 				     struct ath11k_sta *arsta,
285 				     struct ath11k_per_peer_cfr_capture *params,
286 				     const u8 *peer_mac)
287 {
288 	return 0;
289 }
290 
291 static inline void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut)
292 {
293 }
294 
295 static inline
296 struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar)
297 {
298 	return NULL;
299 }
300 
301 static inline
302 int ath11k_process_cfr_capture_event(struct ath11k_base *ab,
303 				     struct ath11k_cfr_peer_tx_param *params)
304 {
305 	return 0;
306 }
307 #endif /* CONFIG_ATH11K_CFR */
308 #endif /* ATH11K_CFR_H */
309