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
ath11k_cfr_update_phymode(struct ath11k * ar,enum wmi_phy_mode phymode)240 static inline void ath11k_cfr_update_phymode(struct ath11k *ar,
241 enum wmi_phy_mode phymode)
242 {
243 }
244
ath11k_cfr_init(struct ath11k_base * ab)245 static inline int ath11k_cfr_init(struct ath11k_base *ab)
246 {
247 return 0;
248 }
249
ath11k_cfr_deinit(struct ath11k_base * ab)250 static inline void ath11k_cfr_deinit(struct ath11k_base *ab)
251 {
252 }
253
ath11k_cfr_lut_update_paddr(struct ath11k * ar,dma_addr_t paddr,u32 buf_id)254 static inline void ath11k_cfr_lut_update_paddr(struct ath11k *ar,
255 dma_addr_t paddr, u32 buf_id)
256 {
257 }
258
ath11k_cfr_decrement_peer_count(struct ath11k * ar,struct ath11k_sta * arsta)259 static inline void ath11k_cfr_decrement_peer_count(struct ath11k *ar,
260 struct ath11k_sta *arsta)
261 {
262 }
263
ath11k_cfr_update_unassoc_pool_entry(struct ath11k * ar,const u8 * peer_mac)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
ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k * ar,const u8 * peer_mac)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
ath11k_cfr_update_unassoc_pool(struct ath11k * ar,struct ath11k_per_peer_cfr_capture * params,u8 * peer_mac)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
ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k * ar,struct ath11k_sta * arsta,struct ath11k_per_peer_cfr_capture * params,const u8 * peer_mac)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
ath11k_cfr_release_lut_entry(struct ath11k_look_up_table * lut)291 static inline void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut)
292 {
293 }
294
295 static inline
ath11k_cfr_get_dbring(struct ath11k * ar)296 struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar)
297 {
298 return NULL;
299 }
300
301 static inline
ath11k_process_cfr_capture_event(struct ath11k_base * ab,struct ath11k_cfr_peer_tx_param * params)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