summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath11k/cfr.h
blob: 94fcb706f2ef2f7cccfa369f9fdd8443182f1107 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
 * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
 */

#ifndef ATH11K_CFR_H
#define ATH11K_CFR_H

#include "dbring.h"
#include "wmi.h"

#define ATH11K_CFR_NUM_RESP_PER_EVENT   1
#define ATH11K_CFR_EVENT_TIMEOUT_MS     1
#define ATH11K_CFR_NUM_RING_ENTRIES     1

#define ATH11K_MAX_CFR_ENABLED_CLIENTS 10
#define CFR_MAX_LUT_ENTRIES 136

#define HOST_MAX_CHAINS 8

enum ath11k_cfr_correlate_event_type {
	ATH11K_CORRELATE_DBR_EVENT,
	ATH11K_CORRELATE_TX_EVENT,
};

struct ath11k_sta;
struct ath11k_per_peer_cfr_capture;

#define ATH11K_CFR_START_MAGIC 0xDEADBEAF
#define ATH11K_CFR_END_MAGIC 0xBEAFDEAD

#define VENDOR_QCA 0x8cfdf0
#define PLATFORM_TYPE_ARM 2

enum ath11k_cfr_meta_version {
	ATH11K_CFR_META_VERSION_NONE,
	ATH11K_CFR_META_VERSION_1,
	ATH11K_CFR_META_VERSION_2,
	ATH11K_CFR_META_VERSION_3,
	ATH11K_CFR_META_VERSION_4,
	ATH11K_CFR_META_VERSION_MAX = 0xFF,
};

enum ath11k_cfr_data_version {
	ATH11K_CFR_DATA_VERSION_NONE,
	ATH11K_CFR_DATA_VERSION_1,
	ATH11K_CFR_DATA_VERSION_MAX = 0xFF,
};

enum ath11k_cfr_capture_ack_mode {
	ATH11K_CFR_CAPTURE_LEGACY_ACK,
	ATH11K_CFR_CAPTURE_DUP_LEGACY_ACK,
	ATH11K_CFR_CAPTURE_HT_ACK,
	ATH11K_CFR_CAPTURE_VHT_ACK,

	/*Always keep this at last*/
	ATH11K_CFR_CAPTURE_INVALID_ACK
};

enum ath11k_cfr_correlate_status {
	ATH11K_CORRELATE_STATUS_RELEASE,
	ATH11K_CORRELATE_STATUS_HOLD,
	ATH11K_CORRELATE_STATUS_ERR,
};

enum ath11k_cfr_preamble_type {
	ATH11K_CFR_PREAMBLE_TYPE_LEGACY,
	ATH11K_CFR_PREAMBLE_TYPE_HT,
	ATH11K_CFR_PREAMBLE_TYPE_VHT,
};

struct ath11k_cfr_peer_tx_param {
	u32 capture_method;
	u32 vdev_id;
	u8 peer_mac_addr[ETH_ALEN];
	u32 primary_20mhz_chan;
	u32 bandwidth;
	u32 phy_mode;
	u32 band_center_freq1;
	u32 band_center_freq2;
	u32 spatial_streams;
	u32 correlation_info_1;
	u32 correlation_info_2;
	u32 status;
	u32 timestamp_us;
	u32 counter;
	u32 chain_rssi[WMI_MAX_CHAINS];
	u16 chain_phase[WMI_MAX_CHAINS];
	u32 cfo_measurement;
	u8 agc_gain[HOST_MAX_CHAINS];
	u32 rx_start_ts;
};

struct cfr_metadata {
	u8 peer_addr[ETH_ALEN];
	u8 status;
	u8 capture_bw;
	u8 channel_bw;
	u8 phy_mode;
	u16 prim20_chan;
	u16 center_freq1;
	u16 center_freq2;
	u8 capture_mode;
	u8 capture_type;
	u8 sts_count;
	u8 num_rx_chain;
	u32 timestamp;
	u32 length;
	u32 chain_rssi[HOST_MAX_CHAINS];
	u16 chain_phase[HOST_MAX_CHAINS];
	u32 cfo_measurement;
	u8 agc_gain[HOST_MAX_CHAINS];
	u32 rx_start_ts;
} __packed;

struct ath11k_csi_cfr_header {
	u32 start_magic_num;
	u32 vendorid;
	u8 cfr_metadata_version;
	u8 cfr_data_version;
	u8 chip_type;
	u8 platform_type;
	u32 cfr_metadata_len;
	struct cfr_metadata meta_data;
} __packed;

#define TONES_IN_20MHZ  256
#define TONES_IN_40MHZ  512
#define TONES_IN_80MHZ  1024
#define TONES_IN_160MHZ 2048 /* 160 MHz isn't supported yet */
#define TONES_INVALID   0

#define CFIR_DMA_HDR_INFO0_TAG GENMASK(7, 0)
#define CFIR_DMA_HDR_INFO0_LEN GENMASK(13, 8)

#define CFIR_DMA_HDR_INFO1_UPLOAD_DONE      GENMASK(0, 0)
#define CFIR_DMA_HDR_INFO1_CAPTURE_TYPE     GENMASK(3, 1)
#define CFIR_DMA_HDR_INFO1_PREAMBLE_TYPE    GENMASK(5, 4)
#define CFIR_DMA_HDR_INFO1_NSS              GENMASK(8, 6)
#define CFIR_DMA_HDR_INFO1_NUM_CHAINS       GENMASK(11, 9)
#define CFIR_DMA_HDR_INFO1_UPLOAD_PKT_BW    GENMASK(14, 12)
#define CFIR_DMA_HDR_INFO1_SW_PEER_ID_VALID GENMASK(15, 15)

struct ath11k_cfr_dma_hdr {
	u16 info0;
	u16 info1;
	u16 sw_peer_id;
	u16 phy_ppdu_id;
};

struct ath11k_look_up_table {
	bool dbr_recv;
	bool tx_recv;
	u8 *data;
	u32 data_len;
	u16 dbr_ppdu_id;
	u16 tx_ppdu_id;
	dma_addr_t dbr_address;
	struct ath11k_csi_cfr_header header;
	struct ath11k_cfr_dma_hdr hdr;
	u64 txrx_tstamp;
	u64 dbr_tstamp;
	u32 header_length;
	u32 payload_length;
	struct ath11k_dbring_element *buff;
};

struct cfr_unassoc_pool_entry {
	u8 peer_mac[ETH_ALEN];
	u32 period;
	bool is_valid;
};

struct ath11k_cfr {
	struct ath11k_dbring rx_ring;
	/* Protects cfr data */
	spinlock_t lock;
	/* Protect for lut entries */
	spinlock_t lut_lock;
	struct ath11k_look_up_table *lut;
	struct dentry *enable_cfr;
	struct dentry *cfr_unassoc;
	struct rchan *rfs_cfr_capture;
	u8 cfr_enabled_peer_cnt;
	u32 lut_num;
	u64 tx_evt_cnt;
	u64 dbr_evt_cnt;
	u64 release_cnt;
	u64 tx_peer_status_cfr_fail;
	u64 tx_evt_status_cfr_fail;
	u64 tx_dbr_lookup_fail;
	u64 last_success_tstamp;
	u64 flush_dbr_cnt;
	u64 clear_txrx_event;
	u64 cfr_dma_aborts;
	bool enabled;
	enum wmi_phy_mode phymode;
	struct cfr_unassoc_pool_entry unassoc_pool[ATH11K_MAX_CFR_ENABLED_CLIENTS];
};

enum ath11k_cfr_capture_method {
	ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME,
	ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME_WITH_PHASE,
	ATH11K_CFR_CAPTURE_METHOD_PROBE_RESP,
	ATH11K_CFR_CAPTURE_METHOD_MAX,
};

enum ath11k_cfr_capture_bw {
	ATH11K_CFR_CAPTURE_BW_20,
	ATH11K_CFR_CAPTURE_BW_40,
	ATH11K_CFR_CAPTURE_BW_80,
	ATH11K_CFR_CAPTURE_BW_MAX,
};

#ifdef CONFIG_ATH11K_CFR
int ath11k_cfr_init(struct ath11k_base *ab);
void ath11k_cfr_deinit(struct ath11k_base *ab);
void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr,
				 u32 buf_id);
void ath11k_cfr_decrement_peer_count(struct ath11k *ar,
				     struct ath11k_sta *arsta);
void ath11k_cfr_update_unassoc_pool_entry(struct ath11k *ar,
					  const u8 *peer_mac);
bool ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k *ar,
					    const u8 *peer_mac);
void ath11k_cfr_update_unassoc_pool(struct ath11k *ar,
				    struct ath11k_per_peer_cfr_capture *params,
				    u8 *peer_mac);
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);
struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar);
void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut);
int ath11k_process_cfr_capture_event(struct ath11k_base *ab,
				     struct ath11k_cfr_peer_tx_param *params);
void ath11k_cfr_update_phymode(struct ath11k *ar, enum wmi_phy_mode phymode);
#else
static inline void ath11k_cfr_update_phymode(struct ath11k *ar,
					     enum wmi_phy_mode phymode)
{
}

static inline int ath11k_cfr_init(struct ath11k_base *ab)
{
	return 0;
}

static inline void ath11k_cfr_deinit(struct ath11k_base *ab)
{
}

static inline void ath11k_cfr_lut_update_paddr(struct ath11k *ar,
					       dma_addr_t paddr, u32 buf_id)
{
}

static inline void ath11k_cfr_decrement_peer_count(struct ath11k *ar,
						   struct ath11k_sta *arsta)
{
}

static inline void ath11k_cfr_update_unassoc_pool_entry(struct ath11k *ar,
							const u8 *peer_mac)
{
}

static inline bool
ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k *ar, const u8 *peer_mac)
{
	return false;
}

static inline void
ath11k_cfr_update_unassoc_pool(struct ath11k *ar,
			       struct ath11k_per_peer_cfr_capture *params,
			       u8 *peer_mac)
{
}

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)
{
	return 0;
}

static inline void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut)
{
}

static inline
struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar)
{
	return NULL;
}

static inline
int ath11k_process_cfr_capture_event(struct ath11k_base *ab,
				     struct ath11k_cfr_peer_tx_param *params)
{
	return 0;
}
#endif /* CONFIG_ATH11K_CFR */
#endif /* ATH11K_CFR_H */