1 | // SPDX-License-Identifier: BSD-3-Clause-Clear |
2 | /* |
3 | * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. |
4 | * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. |
5 | */ |
6 | |
7 | #include "dp_mon.h" |
8 | #include "debug.h" |
9 | #include "dp_rx.h" |
10 | #include "dp_tx.h" |
11 | #include "peer.h" |
12 | |
13 | static void ath12k_dp_mon_rx_handle_ofdma_info(void *rx_tlv, |
14 | struct hal_rx_user_status *rx_user_status) |
15 | { |
16 | struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv; |
17 | |
18 | rx_user_status->ul_ofdma_user_v0_word0 = |
19 | __le32_to_cpu(ppdu_end_user->usr_resp_ref); |
20 | rx_user_status->ul_ofdma_user_v0_word1 = |
21 | __le32_to_cpu(ppdu_end_user->usr_resp_ref_ext); |
22 | } |
23 | |
24 | static void |
25 | ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats, |
26 | void *ppduinfo, |
27 | struct hal_rx_user_status *rx_user_status) |
28 | { |
29 | u32 mpdu_ok_byte_count = __le32_to_cpu(stats->mpdu_ok_cnt); |
30 | u32 mpdu_err_byte_count = __le32_to_cpu(stats->mpdu_err_cnt); |
31 | |
32 | rx_user_status->mpdu_ok_byte_count = |
33 | u32_get_bits(v: mpdu_ok_byte_count, |
34 | HAL_RX_PPDU_END_USER_STATS_MPDU_DELIM_OK_BYTE_COUNT); |
35 | rx_user_status->mpdu_err_byte_count = |
36 | u32_get_bits(v: mpdu_err_byte_count, |
37 | HAL_RX_PPDU_END_USER_STATS_MPDU_DELIM_ERR_BYTE_COUNT); |
38 | } |
39 | |
40 | static void |
41 | ath12k_dp_mon_rx_populate_mu_user_info(void *rx_tlv, |
42 | struct hal_rx_mon_ppdu_info *ppdu_info, |
43 | struct hal_rx_user_status *rx_user_status) |
44 | { |
45 | rx_user_status->ast_index = ppdu_info->ast_index; |
46 | rx_user_status->tid = ppdu_info->tid; |
47 | rx_user_status->tcp_ack_msdu_count = |
48 | ppdu_info->tcp_ack_msdu_count; |
49 | rx_user_status->tcp_msdu_count = |
50 | ppdu_info->tcp_msdu_count; |
51 | rx_user_status->udp_msdu_count = |
52 | ppdu_info->udp_msdu_count; |
53 | rx_user_status->other_msdu_count = |
54 | ppdu_info->other_msdu_count; |
55 | rx_user_status->frame_control = ppdu_info->frame_control; |
56 | rx_user_status->frame_control_info_valid = |
57 | ppdu_info->frame_control_info_valid; |
58 | rx_user_status->data_sequence_control_info_valid = |
59 | ppdu_info->data_sequence_control_info_valid; |
60 | rx_user_status->first_data_seq_ctrl = |
61 | ppdu_info->first_data_seq_ctrl; |
62 | rx_user_status->preamble_type = ppdu_info->preamble_type; |
63 | rx_user_status->ht_flags = ppdu_info->ht_flags; |
64 | rx_user_status->vht_flags = ppdu_info->vht_flags; |
65 | rx_user_status->he_flags = ppdu_info->he_flags; |
66 | rx_user_status->rs_flags = ppdu_info->rs_flags; |
67 | |
68 | rx_user_status->mpdu_cnt_fcs_ok = |
69 | ppdu_info->num_mpdu_fcs_ok; |
70 | rx_user_status->mpdu_cnt_fcs_err = |
71 | ppdu_info->num_mpdu_fcs_err; |
72 | memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0], |
73 | HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * |
74 | sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); |
75 | |
76 | ath12k_dp_mon_rx_populate_byte_count(stats: rx_tlv, ppduinfo: ppdu_info, rx_user_status); |
77 | } |
78 | |
79 | static void ath12k_dp_mon_parse_vht_sig_a(u8 *tlv_data, |
80 | struct hal_rx_mon_ppdu_info *ppdu_info) |
81 | { |
82 | struct hal_rx_vht_sig_a_info *vht_sig = |
83 | (struct hal_rx_vht_sig_a_info *)tlv_data; |
84 | u32 nsts, group_id, info0, info1; |
85 | u8 gi_setting; |
86 | |
87 | info0 = __le32_to_cpu(vht_sig->info0); |
88 | info1 = __le32_to_cpu(vht_sig->info1); |
89 | |
90 | ppdu_info->ldpc = u32_get_bits(v: info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); |
91 | ppdu_info->mcs = u32_get_bits(v: info1, HAL_RX_VHT_SIG_A_INFO_INFO1_MCS); |
92 | gi_setting = u32_get_bits(v: info1, HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING); |
93 | switch (gi_setting) { |
94 | case HAL_RX_VHT_SIG_A_NORMAL_GI: |
95 | ppdu_info->gi = HAL_RX_GI_0_8_US; |
96 | break; |
97 | case HAL_RX_VHT_SIG_A_SHORT_GI: |
98 | case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY: |
99 | ppdu_info->gi = HAL_RX_GI_0_4_US; |
100 | break; |
101 | } |
102 | |
103 | ppdu_info->is_stbc = u32_get_bits(v: info0, HAL_RX_VHT_SIG_A_INFO_INFO0_STBC); |
104 | nsts = u32_get_bits(v: info0, HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS); |
105 | if (ppdu_info->is_stbc && nsts > 0) |
106 | nsts = ((nsts + 1) >> 1) - 1; |
107 | |
108 | ppdu_info->nss = u32_get_bits(v: nsts, VHT_SIG_SU_NSS_MASK); |
109 | ppdu_info->bw = u32_get_bits(v: info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW); |
110 | ppdu_info->beamformed = u32_get_bits(v: info1, |
111 | HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED); |
112 | group_id = u32_get_bits(v: info0, HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID); |
113 | if (group_id == 0 || group_id == 63) |
114 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; |
115 | else |
116 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; |
117 | ppdu_info->vht_flag_values5 = group_id; |
118 | ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) | |
119 | ppdu_info->nss); |
120 | ppdu_info->vht_flag_values2 = ppdu_info->bw; |
121 | ppdu_info->vht_flag_values4 = |
122 | u32_get_bits(v: info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); |
123 | } |
124 | |
125 | static void ath12k_dp_mon_parse_ht_sig(u8 *tlv_data, |
126 | struct hal_rx_mon_ppdu_info *ppdu_info) |
127 | { |
128 | struct hal_rx_ht_sig_info *ht_sig = |
129 | (struct hal_rx_ht_sig_info *)tlv_data; |
130 | u32 info0 = __le32_to_cpu(ht_sig->info0); |
131 | u32 info1 = __le32_to_cpu(ht_sig->info1); |
132 | |
133 | ppdu_info->mcs = u32_get_bits(v: info0, HAL_RX_HT_SIG_INFO_INFO0_MCS); |
134 | ppdu_info->bw = u32_get_bits(v: info0, HAL_RX_HT_SIG_INFO_INFO0_BW); |
135 | ppdu_info->is_stbc = u32_get_bits(v: info1, HAL_RX_HT_SIG_INFO_INFO1_STBC); |
136 | ppdu_info->ldpc = u32_get_bits(v: info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING); |
137 | ppdu_info->gi = u32_get_bits(v: info1, HAL_RX_HT_SIG_INFO_INFO1_GI); |
138 | ppdu_info->nss = (ppdu_info->mcs >> 3); |
139 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; |
140 | } |
141 | |
142 | static void ath12k_dp_mon_parse_l_sig_b(u8 *tlv_data, |
143 | struct hal_rx_mon_ppdu_info *ppdu_info) |
144 | { |
145 | struct hal_rx_lsig_b_info *lsigb = |
146 | (struct hal_rx_lsig_b_info *)tlv_data; |
147 | u32 info0 = __le32_to_cpu(lsigb->info0); |
148 | u8 rate; |
149 | |
150 | rate = u32_get_bits(v: info0, HAL_RX_LSIG_B_INFO_INFO0_RATE); |
151 | switch (rate) { |
152 | case 1: |
153 | rate = HAL_RX_LEGACY_RATE_1_MBPS; |
154 | break; |
155 | case 2: |
156 | case 5: |
157 | rate = HAL_RX_LEGACY_RATE_2_MBPS; |
158 | break; |
159 | case 3: |
160 | case 6: |
161 | rate = HAL_RX_LEGACY_RATE_5_5_MBPS; |
162 | break; |
163 | case 4: |
164 | case 7: |
165 | rate = HAL_RX_LEGACY_RATE_11_MBPS; |
166 | break; |
167 | default: |
168 | rate = HAL_RX_LEGACY_RATE_INVALID; |
169 | } |
170 | |
171 | ppdu_info->rate = rate; |
172 | ppdu_info->cck_flag = 1; |
173 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; |
174 | } |
175 | |
176 | static void ath12k_dp_mon_parse_l_sig_a(u8 *tlv_data, |
177 | struct hal_rx_mon_ppdu_info *ppdu_info) |
178 | { |
179 | struct hal_rx_lsig_a_info *lsiga = |
180 | (struct hal_rx_lsig_a_info *)tlv_data; |
181 | u32 info0 = __le32_to_cpu(lsiga->info0); |
182 | u8 rate; |
183 | |
184 | rate = u32_get_bits(v: info0, HAL_RX_LSIG_A_INFO_INFO0_RATE); |
185 | switch (rate) { |
186 | case 8: |
187 | rate = HAL_RX_LEGACY_RATE_48_MBPS; |
188 | break; |
189 | case 9: |
190 | rate = HAL_RX_LEGACY_RATE_24_MBPS; |
191 | break; |
192 | case 10: |
193 | rate = HAL_RX_LEGACY_RATE_12_MBPS; |
194 | break; |
195 | case 11: |
196 | rate = HAL_RX_LEGACY_RATE_6_MBPS; |
197 | break; |
198 | case 12: |
199 | rate = HAL_RX_LEGACY_RATE_54_MBPS; |
200 | break; |
201 | case 13: |
202 | rate = HAL_RX_LEGACY_RATE_36_MBPS; |
203 | break; |
204 | case 14: |
205 | rate = HAL_RX_LEGACY_RATE_18_MBPS; |
206 | break; |
207 | case 15: |
208 | rate = HAL_RX_LEGACY_RATE_9_MBPS; |
209 | break; |
210 | default: |
211 | rate = HAL_RX_LEGACY_RATE_INVALID; |
212 | } |
213 | |
214 | ppdu_info->rate = rate; |
215 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; |
216 | } |
217 | |
218 | static void ath12k_dp_mon_parse_he_sig_b2_ofdma(u8 *tlv_data, |
219 | struct hal_rx_mon_ppdu_info *ppdu_info) |
220 | { |
221 | struct hal_rx_he_sig_b2_ofdma_info *he_sig_b2_ofdma = |
222 | (struct hal_rx_he_sig_b2_ofdma_info *)tlv_data; |
223 | u32 info0, value; |
224 | |
225 | info0 = __le32_to_cpu(he_sig_b2_ofdma->info0); |
226 | |
227 | ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_DCM_KNOWN | HE_CODING_KNOWN; |
228 | |
229 | /* HE-data2 */ |
230 | ppdu_info->he_data2 |= HE_TXBF_KNOWN; |
231 | |
232 | ppdu_info->mcs = u32_get_bits(v: info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS); |
233 | value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; |
234 | ppdu_info->he_data3 |= value; |
235 | |
236 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM); |
237 | value = value << HE_DCM_SHIFT; |
238 | ppdu_info->he_data3 |= value; |
239 | |
240 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING); |
241 | ppdu_info->ldpc = value; |
242 | value = value << HE_CODING_SHIFT; |
243 | ppdu_info->he_data3 |= value; |
244 | |
245 | /* HE-data4 */ |
246 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID); |
247 | value = value << HE_STA_ID_SHIFT; |
248 | ppdu_info->he_data4 |= value; |
249 | |
250 | ppdu_info->nss = u32_get_bits(v: info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS); |
251 | ppdu_info->beamformed = u32_get_bits(v: info0, |
252 | HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF); |
253 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; |
254 | } |
255 | |
256 | static void ath12k_dp_mon_parse_he_sig_b2_mu(u8 *tlv_data, |
257 | struct hal_rx_mon_ppdu_info *ppdu_info) |
258 | { |
259 | struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu = |
260 | (struct hal_rx_he_sig_b2_mu_info *)tlv_data; |
261 | u32 info0, value; |
262 | |
263 | info0 = __le32_to_cpu(he_sig_b2_mu->info0); |
264 | |
265 | ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_CODING_KNOWN; |
266 | |
267 | ppdu_info->mcs = u32_get_bits(v: info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS); |
268 | value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; |
269 | ppdu_info->he_data3 |= value; |
270 | |
271 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING); |
272 | ppdu_info->ldpc = value; |
273 | value = value << HE_CODING_SHIFT; |
274 | ppdu_info->he_data3 |= value; |
275 | |
276 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID); |
277 | value = value << HE_STA_ID_SHIFT; |
278 | ppdu_info->he_data4 |= value; |
279 | |
280 | ppdu_info->nss = u32_get_bits(v: info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS); |
281 | } |
282 | |
283 | static void ath12k_dp_mon_parse_he_sig_b1_mu(u8 *tlv_data, |
284 | struct hal_rx_mon_ppdu_info *ppdu_info) |
285 | { |
286 | struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu = |
287 | (struct hal_rx_he_sig_b1_mu_info *)tlv_data; |
288 | u32 info0 = __le32_to_cpu(he_sig_b1_mu->info0); |
289 | u16 ru_tones; |
290 | |
291 | ru_tones = u32_get_bits(v: info0, |
292 | HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION); |
293 | ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); |
294 | ppdu_info->he_RU[0] = ru_tones; |
295 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; |
296 | } |
297 | |
298 | static void ath12k_dp_mon_parse_he_sig_mu(u8 *tlv_data, |
299 | struct hal_rx_mon_ppdu_info *ppdu_info) |
300 | { |
301 | struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl = |
302 | (struct hal_rx_he_sig_a_mu_dl_info *)tlv_data; |
303 | u32 info0, info1, value; |
304 | u16 he_gi = 0, he_ltf = 0; |
305 | |
306 | info0 = __le32_to_cpu(he_sig_a_mu_dl->info0); |
307 | info1 = __le32_to_cpu(he_sig_a_mu_dl->info1); |
308 | |
309 | ppdu_info->he_mu_flags = 1; |
310 | |
311 | ppdu_info->he_data1 = HE_MU_FORMAT_TYPE; |
312 | ppdu_info->he_data1 |= |
313 | HE_BSS_COLOR_KNOWN | |
314 | HE_DL_UL_KNOWN | |
315 | HE_LDPC_EXTRA_SYMBOL_KNOWN | |
316 | HE_STBC_KNOWN | |
317 | HE_DATA_BW_RU_KNOWN | |
318 | HE_DOPPLER_KNOWN; |
319 | |
320 | ppdu_info->he_data2 = |
321 | HE_GI_KNOWN | |
322 | HE_LTF_SYMBOLS_KNOWN | |
323 | HE_PRE_FEC_PADDING_KNOWN | |
324 | HE_PE_DISAMBIGUITY_KNOWN | |
325 | HE_TXOP_KNOWN | |
326 | HE_MIDABLE_PERIODICITY_KNOWN; |
327 | |
328 | /* data3 */ |
329 | ppdu_info->he_data3 = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_BSS_COLOR); |
330 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_UL_FLAG); |
331 | value = value << HE_DL_UL_SHIFT; |
332 | ppdu_info->he_data3 |= value; |
333 | |
334 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_LDPC_EXTRA); |
335 | value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; |
336 | ppdu_info->he_data3 |= value; |
337 | |
338 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC); |
339 | value = value << HE_STBC_SHIFT; |
340 | ppdu_info->he_data3 |= value; |
341 | |
342 | /* data4 */ |
343 | ppdu_info->he_data4 = u32_get_bits(v: info0, |
344 | HAL_RX_HE_SIG_A_MU_DL_INFO0_SPATIAL_REUSE); |
345 | ppdu_info->he_data4 = value; |
346 | |
347 | /* data5 */ |
348 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); |
349 | ppdu_info->he_data5 = value; |
350 | ppdu_info->bw = value; |
351 | |
352 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_CP_LTF_SIZE); |
353 | switch (value) { |
354 | case 0: |
355 | he_gi = HE_GI_0_8; |
356 | he_ltf = HE_LTF_4_X; |
357 | break; |
358 | case 1: |
359 | he_gi = HE_GI_0_8; |
360 | he_ltf = HE_LTF_2_X; |
361 | break; |
362 | case 2: |
363 | he_gi = HE_GI_1_6; |
364 | he_ltf = HE_LTF_2_X; |
365 | break; |
366 | case 3: |
367 | he_gi = HE_GI_3_2; |
368 | he_ltf = HE_LTF_4_X; |
369 | break; |
370 | } |
371 | |
372 | ppdu_info->gi = he_gi; |
373 | value = he_gi << HE_GI_SHIFT; |
374 | ppdu_info->he_data5 |= value; |
375 | |
376 | value = he_ltf << HE_LTF_SIZE_SHIFT; |
377 | ppdu_info->he_data5 |= value; |
378 | |
379 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_NUM_LTF_SYMB); |
380 | value = (value << HE_LTF_SYM_SHIFT); |
381 | ppdu_info->he_data5 |= value; |
382 | |
383 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_FACTOR); |
384 | value = value << HE_PRE_FEC_PAD_SHIFT; |
385 | ppdu_info->he_data5 |= value; |
386 | |
387 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_PE_DISAM); |
388 | value = value << HE_PE_DISAMBIGUITY_SHIFT; |
389 | ppdu_info->he_data5 |= value; |
390 | |
391 | /*data6*/ |
392 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DOPPLER_INDICATION); |
393 | value = value << HE_DOPPLER_SHIFT; |
394 | ppdu_info->he_data6 |= value; |
395 | |
396 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_TXOP_DURATION); |
397 | value = value << HE_TXOP_SHIFT; |
398 | ppdu_info->he_data6 |= value; |
399 | |
400 | /* HE-MU Flags */ |
401 | /* HE-MU-flags1 */ |
402 | ppdu_info->he_flags1 = |
403 | HE_SIG_B_MCS_KNOWN | |
404 | HE_SIG_B_DCM_KNOWN | |
405 | HE_SIG_B_COMPRESSION_FLAG_1_KNOWN | |
406 | HE_SIG_B_SYM_NUM_KNOWN | |
407 | HE_RU_0_KNOWN; |
408 | |
409 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_MCS_OF_SIGB); |
410 | ppdu_info->he_flags1 |= value; |
411 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DCM_OF_SIGB); |
412 | value = value << HE_DCM_FLAG_1_SHIFT; |
413 | ppdu_info->he_flags1 |= value; |
414 | |
415 | /* HE-MU-flags2 */ |
416 | ppdu_info->he_flags2 = HE_BW_KNOWN; |
417 | |
418 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); |
419 | ppdu_info->he_flags2 |= value; |
420 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_COMP_MODE_SIGB); |
421 | value = value << HE_SIG_B_COMPRESSION_FLAG_2_SHIFT; |
422 | ppdu_info->he_flags2 |= value; |
423 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_NUM_SIGB_SYMB); |
424 | value = value - 1; |
425 | value = value << HE_NUM_SIG_B_SYMBOLS_SHIFT; |
426 | ppdu_info->he_flags2 |= value; |
427 | |
428 | ppdu_info->is_stbc = info1 & |
429 | HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC; |
430 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; |
431 | } |
432 | |
433 | static void ath12k_dp_mon_parse_he_sig_su(u8 *tlv_data, |
434 | struct hal_rx_mon_ppdu_info *ppdu_info) |
435 | { |
436 | struct hal_rx_he_sig_a_su_info *he_sig_a = |
437 | (struct hal_rx_he_sig_a_su_info *)tlv_data; |
438 | u32 info0, info1, value; |
439 | u32 dcm; |
440 | u8 he_dcm = 0, he_stbc = 0; |
441 | u16 he_gi = 0, he_ltf = 0; |
442 | |
443 | ppdu_info->he_flags = 1; |
444 | |
445 | info0 = __le32_to_cpu(he_sig_a->info0); |
446 | info1 = __le32_to_cpu(he_sig_a->info1); |
447 | |
448 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND); |
449 | if (value == 0) |
450 | ppdu_info->he_data1 = HE_TRIG_FORMAT_TYPE; |
451 | else |
452 | ppdu_info->he_data1 = HE_SU_FORMAT_TYPE; |
453 | |
454 | ppdu_info->he_data1 |= |
455 | HE_BSS_COLOR_KNOWN | |
456 | HE_BEAM_CHANGE_KNOWN | |
457 | HE_DL_UL_KNOWN | |
458 | HE_MCS_KNOWN | |
459 | HE_DCM_KNOWN | |
460 | HE_CODING_KNOWN | |
461 | HE_LDPC_EXTRA_SYMBOL_KNOWN | |
462 | HE_STBC_KNOWN | |
463 | HE_DATA_BW_RU_KNOWN | |
464 | HE_DOPPLER_KNOWN; |
465 | |
466 | ppdu_info->he_data2 |= |
467 | HE_GI_KNOWN | |
468 | HE_TXBF_KNOWN | |
469 | HE_PE_DISAMBIGUITY_KNOWN | |
470 | HE_TXOP_KNOWN | |
471 | HE_LTF_SYMBOLS_KNOWN | |
472 | HE_PRE_FEC_PADDING_KNOWN | |
473 | HE_MIDABLE_PERIODICITY_KNOWN; |
474 | |
475 | ppdu_info->he_data3 = u32_get_bits(v: info0, |
476 | HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR); |
477 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE); |
478 | value = value << HE_BEAM_CHANGE_SHIFT; |
479 | ppdu_info->he_data3 |= value; |
480 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG); |
481 | value = value << HE_DL_UL_SHIFT; |
482 | ppdu_info->he_data3 |= value; |
483 | |
484 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); |
485 | ppdu_info->mcs = value; |
486 | value = value << HE_TRANSMIT_MCS_SHIFT; |
487 | ppdu_info->he_data3 |= value; |
488 | |
489 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); |
490 | he_dcm = value; |
491 | value = value << HE_DCM_SHIFT; |
492 | ppdu_info->he_data3 |= value; |
493 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); |
494 | value = value << HE_CODING_SHIFT; |
495 | ppdu_info->he_data3 |= value; |
496 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA); |
497 | value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; |
498 | ppdu_info->he_data3 |= value; |
499 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); |
500 | he_stbc = value; |
501 | value = value << HE_STBC_SHIFT; |
502 | ppdu_info->he_data3 |= value; |
503 | |
504 | /* data4 */ |
505 | ppdu_info->he_data4 = u32_get_bits(v: info0, |
506 | HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE); |
507 | |
508 | /* data5 */ |
509 | value = u32_get_bits(v: info0, |
510 | HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); |
511 | ppdu_info->he_data5 = value; |
512 | ppdu_info->bw = value; |
513 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE); |
514 | switch (value) { |
515 | case 0: |
516 | he_gi = HE_GI_0_8; |
517 | he_ltf = HE_LTF_1_X; |
518 | break; |
519 | case 1: |
520 | he_gi = HE_GI_0_8; |
521 | he_ltf = HE_LTF_2_X; |
522 | break; |
523 | case 2: |
524 | he_gi = HE_GI_1_6; |
525 | he_ltf = HE_LTF_2_X; |
526 | break; |
527 | case 3: |
528 | if (he_dcm && he_stbc) { |
529 | he_gi = HE_GI_0_8; |
530 | he_ltf = HE_LTF_4_X; |
531 | } else { |
532 | he_gi = HE_GI_3_2; |
533 | he_ltf = HE_LTF_4_X; |
534 | } |
535 | break; |
536 | } |
537 | ppdu_info->gi = he_gi; |
538 | value = he_gi << HE_GI_SHIFT; |
539 | ppdu_info->he_data5 |= value; |
540 | value = he_ltf << HE_LTF_SIZE_SHIFT; |
541 | ppdu_info->ltf_size = he_ltf; |
542 | ppdu_info->he_data5 |= value; |
543 | |
544 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); |
545 | value = (value << HE_LTF_SYM_SHIFT); |
546 | ppdu_info->he_data5 |= value; |
547 | |
548 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR); |
549 | value = value << HE_PRE_FEC_PAD_SHIFT; |
550 | ppdu_info->he_data5 |= value; |
551 | |
552 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); |
553 | value = value << HE_TXBF_SHIFT; |
554 | ppdu_info->he_data5 |= value; |
555 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM); |
556 | value = value << HE_PE_DISAMBIGUITY_SHIFT; |
557 | ppdu_info->he_data5 |= value; |
558 | |
559 | /* data6 */ |
560 | value = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); |
561 | value++; |
562 | ppdu_info->he_data6 = value; |
563 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND); |
564 | value = value << HE_DOPPLER_SHIFT; |
565 | ppdu_info->he_data6 |= value; |
566 | value = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION); |
567 | value = value << HE_TXOP_SHIFT; |
568 | ppdu_info->he_data6 |= value; |
569 | |
570 | ppdu_info->mcs = |
571 | u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); |
572 | ppdu_info->bw = |
573 | u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); |
574 | ppdu_info->ldpc = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); |
575 | ppdu_info->is_stbc = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); |
576 | ppdu_info->beamformed = u32_get_bits(v: info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); |
577 | dcm = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); |
578 | ppdu_info->nss = u32_get_bits(v: info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); |
579 | ppdu_info->dcm = dcm; |
580 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; |
581 | } |
582 | |
583 | static enum hal_rx_mon_status |
584 | ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_base *ab, |
585 | struct ath12k_mon_data *pmon, |
586 | u32 tlv_tag, u8 *tlv_data, u32 userid) |
587 | { |
588 | struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; |
589 | u32 info[7]; |
590 | |
591 | switch (tlv_tag) { |
592 | case HAL_RX_PPDU_START: { |
593 | struct hal_rx_ppdu_start *ppdu_start = |
594 | (struct hal_rx_ppdu_start *)tlv_data; |
595 | |
596 | info[0] = __le32_to_cpu(ppdu_start->info0); |
597 | |
598 | ppdu_info->ppdu_id = |
599 | u32_get_bits(v: info[0], HAL_RX_PPDU_START_INFO0_PPDU_ID); |
600 | ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num); |
601 | ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts); |
602 | |
603 | if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) { |
604 | ppdu_info->last_ppdu_id = ppdu_info->ppdu_id; |
605 | ppdu_info->num_users = 0; |
606 | memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0, |
607 | HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * |
608 | sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); |
609 | } |
610 | break; |
611 | } |
612 | case HAL_RX_PPDU_END_USER_STATS: { |
613 | struct hal_rx_ppdu_end_user_stats *eu_stats = |
614 | (struct hal_rx_ppdu_end_user_stats *)tlv_data; |
615 | |
616 | info[0] = __le32_to_cpu(eu_stats->info0); |
617 | info[1] = __le32_to_cpu(eu_stats->info1); |
618 | info[2] = __le32_to_cpu(eu_stats->info2); |
619 | info[4] = __le32_to_cpu(eu_stats->info4); |
620 | info[5] = __le32_to_cpu(eu_stats->info5); |
621 | info[6] = __le32_to_cpu(eu_stats->info6); |
622 | |
623 | ppdu_info->ast_index = |
624 | u32_get_bits(v: info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX); |
625 | ppdu_info->fc_valid = |
626 | u32_get_bits(v: info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID); |
627 | ppdu_info->tid = |
628 | ffs(u32_get_bits(info[6], |
629 | HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP) |
630 | - 1); |
631 | ppdu_info->tcp_msdu_count = |
632 | u32_get_bits(v: info[4], |
633 | HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT); |
634 | ppdu_info->udp_msdu_count = |
635 | u32_get_bits(v: info[4], |
636 | HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT); |
637 | ppdu_info->other_msdu_count = |
638 | u32_get_bits(v: info[5], |
639 | HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT); |
640 | ppdu_info->tcp_ack_msdu_count = |
641 | u32_get_bits(v: info[5], |
642 | HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT); |
643 | ppdu_info->preamble_type = |
644 | u32_get_bits(v: info[1], |
645 | HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE); |
646 | ppdu_info->num_mpdu_fcs_ok = |
647 | u32_get_bits(v: info[1], |
648 | HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK); |
649 | ppdu_info->num_mpdu_fcs_err = |
650 | u32_get_bits(v: info[0], |
651 | HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR); |
652 | switch (ppdu_info->preamble_type) { |
653 | case HAL_RX_PREAMBLE_11N: |
654 | ppdu_info->ht_flags = 1; |
655 | break; |
656 | case HAL_RX_PREAMBLE_11AC: |
657 | ppdu_info->vht_flags = 1; |
658 | break; |
659 | case HAL_RX_PREAMBLE_11AX: |
660 | ppdu_info->he_flags = 1; |
661 | break; |
662 | default: |
663 | break; |
664 | } |
665 | |
666 | if (userid < HAL_MAX_UL_MU_USERS) { |
667 | struct hal_rx_user_status *rxuser_stats = |
668 | &ppdu_info->userstats[userid]; |
669 | ppdu_info->num_users += 1; |
670 | |
671 | ath12k_dp_mon_rx_handle_ofdma_info(rx_tlv: tlv_data, rx_user_status: rxuser_stats); |
672 | ath12k_dp_mon_rx_populate_mu_user_info(rx_tlv: tlv_data, ppdu_info, |
673 | rx_user_status: rxuser_stats); |
674 | } |
675 | ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]); |
676 | ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]); |
677 | break; |
678 | } |
679 | case HAL_RX_PPDU_END_USER_STATS_EXT: { |
680 | struct hal_rx_ppdu_end_user_stats_ext *eu_stats = |
681 | (struct hal_rx_ppdu_end_user_stats_ext *)tlv_data; |
682 | ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1); |
683 | ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2); |
684 | ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3); |
685 | ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4); |
686 | ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5); |
687 | ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6); |
688 | break; |
689 | } |
690 | case HAL_PHYRX_HT_SIG: |
691 | ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info); |
692 | break; |
693 | |
694 | case HAL_PHYRX_L_SIG_B: |
695 | ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); |
696 | break; |
697 | |
698 | case HAL_PHYRX_L_SIG_A: |
699 | ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); |
700 | break; |
701 | |
702 | case HAL_PHYRX_VHT_SIG_A: |
703 | ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); |
704 | break; |
705 | |
706 | case HAL_PHYRX_HE_SIG_A_SU: |
707 | ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); |
708 | break; |
709 | |
710 | case HAL_PHYRX_HE_SIG_A_MU_DL: |
711 | ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info); |
712 | break; |
713 | |
714 | case HAL_PHYRX_HE_SIG_B1_MU: |
715 | ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info); |
716 | break; |
717 | |
718 | case HAL_PHYRX_HE_SIG_B2_MU: |
719 | ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info); |
720 | break; |
721 | |
722 | case HAL_PHYRX_HE_SIG_B2_OFDMA: |
723 | ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); |
724 | break; |
725 | |
726 | case HAL_PHYRX_RSSI_LEGACY: { |
727 | struct hal_rx_phyrx_rssi_legacy_info * = |
728 | (struct hal_rx_phyrx_rssi_legacy_info *)tlv_data; |
729 | u32 reception_type = 0; |
730 | u32 = __le32_to_cpu(rssi->rsvd[0]); |
731 | |
732 | info[0] = __le32_to_cpu(rssi->info0); |
733 | |
734 | /* TODO: Please note that the combined rssi will not be accurate |
735 | * in MU case. Rssi in MU needs to be retrieved from |
736 | * PHYRX_OTHER_RECEIVE_INFO TLV. |
737 | */ |
738 | ppdu_info->rssi_comb = |
739 | u32_get_bits(v: info[0], |
740 | HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB); |
741 | reception_type = |
742 | u32_get_bits(v: rssi_legacy_info, |
743 | HAL_RX_PHYRX_RSSI_LEGACY_INFO_RSVD1_RECEPTION); |
744 | |
745 | switch (reception_type) { |
746 | case HAL_RECEPTION_TYPE_ULOFMDA: |
747 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; |
748 | break; |
749 | case HAL_RECEPTION_TYPE_ULMIMO: |
750 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; |
751 | break; |
752 | default: |
753 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; |
754 | break; |
755 | } |
756 | break; |
757 | } |
758 | case HAL_RXPCU_PPDU_END_INFO: { |
759 | struct hal_rx_ppdu_end_duration *ppdu_rx_duration = |
760 | (struct hal_rx_ppdu_end_duration *)tlv_data; |
761 | |
762 | info[0] = __le32_to_cpu(ppdu_rx_duration->info0); |
763 | ppdu_info->rx_duration = |
764 | u32_get_bits(v: info[0], HAL_RX_PPDU_END_DURATION); |
765 | ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]); |
766 | ppdu_info->tsft = (ppdu_info->tsft << 32) | |
767 | __le32_to_cpu(ppdu_rx_duration->rsvd0[0]); |
768 | break; |
769 | } |
770 | case HAL_RX_MPDU_START: { |
771 | struct hal_rx_mpdu_start *mpdu_start = |
772 | (struct hal_rx_mpdu_start *)tlv_data; |
773 | struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; |
774 | u16 peer_id; |
775 | |
776 | info[1] = __le32_to_cpu(mpdu_start->info1); |
777 | peer_id = u32_get_bits(v: info[1], HAL_RX_MPDU_START_INFO1_PEERID); |
778 | if (peer_id) |
779 | ppdu_info->peer_id = peer_id; |
780 | |
781 | ppdu_info->mpdu_len += u32_get_bits(v: info[1], |
782 | HAL_RX_MPDU_START_INFO2_MPDU_LEN); |
783 | if (userid < HAL_MAX_UL_MU_USERS) { |
784 | info[0] = __le32_to_cpu(mpdu_start->info0); |
785 | ppdu_info->userid = userid; |
786 | ppdu_info->ampdu_id[userid] = |
787 | u32_get_bits(v: info[0], HAL_RX_MPDU_START_INFO1_PEERID); |
788 | } |
789 | |
790 | mon_mpdu = kzalloc(size: sizeof(*mon_mpdu), GFP_ATOMIC); |
791 | if (!mon_mpdu) |
792 | return HAL_RX_MON_STATUS_PPDU_NOT_DONE; |
793 | |
794 | break; |
795 | } |
796 | case HAL_RX_MSDU_START: |
797 | /* TODO: add msdu start parsing logic */ |
798 | break; |
799 | case HAL_MON_BUF_ADDR: { |
800 | struct dp_rxdma_mon_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring; |
801 | struct dp_mon_packet_info *packet_info = |
802 | (struct dp_mon_packet_info *)tlv_data; |
803 | int buf_id = u32_get_bits(v: packet_info->cookie, |
804 | DP_RXDMA_BUF_COOKIE_BUF_ID); |
805 | struct sk_buff *msdu; |
806 | struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; |
807 | struct ath12k_skb_rxcb *rxcb; |
808 | |
809 | spin_lock_bh(lock: &buf_ring->idr_lock); |
810 | msdu = idr_remove(&buf_ring->bufs_idr, id: buf_id); |
811 | spin_unlock_bh(lock: &buf_ring->idr_lock); |
812 | |
813 | if (unlikely(!msdu)) { |
814 | ath12k_warn(ab, fmt: "monitor destination with invalid buf_id %d\n" , |
815 | buf_id); |
816 | return HAL_RX_MON_STATUS_PPDU_NOT_DONE; |
817 | } |
818 | |
819 | rxcb = ATH12K_SKB_RXCB(skb: msdu); |
820 | dma_unmap_single(ab->dev, rxcb->paddr, |
821 | msdu->len + skb_tailroom(msdu), |
822 | DMA_FROM_DEVICE); |
823 | |
824 | if (mon_mpdu->tail) |
825 | mon_mpdu->tail->next = msdu; |
826 | else |
827 | mon_mpdu->tail = msdu; |
828 | |
829 | ath12k_dp_mon_buf_replenish(ab, buf_ring, req_entries: 1); |
830 | |
831 | break; |
832 | } |
833 | case HAL_RX_MSDU_END: { |
834 | struct rx_msdu_end_qcn9274 *msdu_end = |
835 | (struct rx_msdu_end_qcn9274 *)tlv_data; |
836 | bool is_first_msdu_in_mpdu; |
837 | u16 msdu_end_info; |
838 | |
839 | msdu_end_info = __le16_to_cpu(msdu_end->info5); |
840 | is_first_msdu_in_mpdu = u32_get_bits(v: msdu_end_info, |
841 | RX_MSDU_END_INFO5_FIRST_MSDU); |
842 | if (is_first_msdu_in_mpdu) { |
843 | pmon->mon_mpdu->head = pmon->mon_mpdu->tail; |
844 | pmon->mon_mpdu->tail = NULL; |
845 | } |
846 | break; |
847 | } |
848 | case HAL_RX_MPDU_END: |
849 | list_add_tail(new: &pmon->mon_mpdu->list, head: &pmon->dp_rx_mon_mpdu_list); |
850 | break; |
851 | case HAL_DUMMY: |
852 | return HAL_RX_MON_STATUS_BUF_DONE; |
853 | case HAL_RX_PPDU_END_STATUS_DONE: |
854 | case 0: |
855 | return HAL_RX_MON_STATUS_PPDU_DONE; |
856 | default: |
857 | break; |
858 | } |
859 | |
860 | return HAL_RX_MON_STATUS_PPDU_NOT_DONE; |
861 | } |
862 | |
863 | static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar, struct sk_buff *msdu) |
864 | { |
865 | u32 rx_pkt_offset, l2_hdr_offset; |
866 | |
867 | rx_pkt_offset = ar->ab->hal.hal_desc_sz; |
868 | l2_hdr_offset = ath12k_dp_rx_h_l3pad(ab: ar->ab, |
869 | desc: (struct hal_rx_desc *)msdu->data); |
870 | skb_pull(skb: msdu, len: rx_pkt_offset + l2_hdr_offset); |
871 | } |
872 | |
873 | static struct sk_buff * |
874 | ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar, |
875 | u32 mac_id, struct sk_buff *head_msdu, |
876 | struct ieee80211_rx_status *rxs, bool *fcs_err) |
877 | { |
878 | struct ath12k_base *ab = ar->ab; |
879 | struct sk_buff *msdu, *mpdu_buf, *prev_buf; |
880 | struct hal_rx_desc *rx_desc; |
881 | u8 *hdr_desc, *dest, decap_format; |
882 | struct ieee80211_hdr_3addr *wh; |
883 | u32 err_bitmap; |
884 | |
885 | mpdu_buf = NULL; |
886 | |
887 | if (!head_msdu) |
888 | goto err_merge_fail; |
889 | |
890 | rx_desc = (struct hal_rx_desc *)head_msdu->data; |
891 | err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, desc: rx_desc); |
892 | |
893 | if (err_bitmap & HAL_RX_MPDU_ERR_FCS) |
894 | *fcs_err = true; |
895 | |
896 | decap_format = ath12k_dp_rx_h_decap_type(ab, desc: rx_desc); |
897 | |
898 | ath12k_dp_rx_h_ppdu(ar, rx_desc, rx_status: rxs); |
899 | |
900 | if (decap_format == DP_RX_DECAP_TYPE_RAW) { |
901 | ath12k_dp_mon_rx_msdus_set_payload(ar, msdu: head_msdu); |
902 | |
903 | prev_buf = head_msdu; |
904 | msdu = head_msdu->next; |
905 | |
906 | while (msdu) { |
907 | ath12k_dp_mon_rx_msdus_set_payload(ar, msdu); |
908 | |
909 | prev_buf = msdu; |
910 | msdu = msdu->next; |
911 | } |
912 | |
913 | prev_buf->next = NULL; |
914 | |
915 | skb_trim(skb: prev_buf, len: prev_buf->len - HAL_RX_FCS_LEN); |
916 | } else if (decap_format == DP_RX_DECAP_TYPE_NATIVE_WIFI) { |
917 | u8 qos_pkt = 0; |
918 | |
919 | rx_desc = (struct hal_rx_desc *)head_msdu->data; |
920 | hdr_desc = |
921 | ab->hal_rx_ops->rx_desc_get_msdu_payload(rx_desc); |
922 | |
923 | /* Base size */ |
924 | wh = (struct ieee80211_hdr_3addr *)hdr_desc; |
925 | |
926 | if (ieee80211_is_data_qos(fc: wh->frame_control)) |
927 | qos_pkt = 1; |
928 | |
929 | msdu = head_msdu; |
930 | |
931 | while (msdu) { |
932 | ath12k_dp_mon_rx_msdus_set_payload(ar, msdu); |
933 | if (qos_pkt) { |
934 | dest = skb_push(skb: msdu, len: sizeof(__le16)); |
935 | if (!dest) |
936 | goto err_merge_fail; |
937 | memcpy(dest, hdr_desc, sizeof(struct ieee80211_qos_hdr)); |
938 | } |
939 | prev_buf = msdu; |
940 | msdu = msdu->next; |
941 | } |
942 | dest = skb_put(skb: prev_buf, HAL_RX_FCS_LEN); |
943 | if (!dest) |
944 | goto err_merge_fail; |
945 | |
946 | ath12k_dbg(ab, ATH12K_DBG_DATA, |
947 | "mpdu_buf %pK mpdu_buf->len %u" , |
948 | prev_buf, prev_buf->len); |
949 | } else { |
950 | ath12k_dbg(ab, ATH12K_DBG_DATA, |
951 | "decap format %d is not supported!\n" , |
952 | decap_format); |
953 | goto err_merge_fail; |
954 | } |
955 | |
956 | return head_msdu; |
957 | |
958 | err_merge_fail: |
959 | if (mpdu_buf && decap_format != DP_RX_DECAP_TYPE_RAW) { |
960 | ath12k_dbg(ab, ATH12K_DBG_DATA, |
961 | "err_merge_fail mpdu_buf %pK" , mpdu_buf); |
962 | /* Free the head buffer */ |
963 | dev_kfree_skb_any(skb: mpdu_buf); |
964 | } |
965 | return NULL; |
966 | } |
967 | |
968 | static void |
969 | ath12k_dp_mon_rx_update_radiotap_he(struct hal_rx_mon_ppdu_info *rx_status, |
970 | u8 *rtap_buf) |
971 | { |
972 | u32 rtap_len = 0; |
973 | |
974 | put_unaligned_le16(val: rx_status->he_data1, p: &rtap_buf[rtap_len]); |
975 | rtap_len += 2; |
976 | |
977 | put_unaligned_le16(val: rx_status->he_data2, p: &rtap_buf[rtap_len]); |
978 | rtap_len += 2; |
979 | |
980 | put_unaligned_le16(val: rx_status->he_data3, p: &rtap_buf[rtap_len]); |
981 | rtap_len += 2; |
982 | |
983 | put_unaligned_le16(val: rx_status->he_data4, p: &rtap_buf[rtap_len]); |
984 | rtap_len += 2; |
985 | |
986 | put_unaligned_le16(val: rx_status->he_data5, p: &rtap_buf[rtap_len]); |
987 | rtap_len += 2; |
988 | |
989 | put_unaligned_le16(val: rx_status->he_data6, p: &rtap_buf[rtap_len]); |
990 | } |
991 | |
992 | static void |
993 | ath12k_dp_mon_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status, |
994 | u8 *rtap_buf) |
995 | { |
996 | u32 rtap_len = 0; |
997 | |
998 | put_unaligned_le16(val: rx_status->he_flags1, p: &rtap_buf[rtap_len]); |
999 | rtap_len += 2; |
1000 | |
1001 | put_unaligned_le16(val: rx_status->he_flags2, p: &rtap_buf[rtap_len]); |
1002 | rtap_len += 2; |
1003 | |
1004 | rtap_buf[rtap_len] = rx_status->he_RU[0]; |
1005 | rtap_len += 1; |
1006 | |
1007 | rtap_buf[rtap_len] = rx_status->he_RU[1]; |
1008 | rtap_len += 1; |
1009 | |
1010 | rtap_buf[rtap_len] = rx_status->he_RU[2]; |
1011 | rtap_len += 1; |
1012 | |
1013 | rtap_buf[rtap_len] = rx_status->he_RU[3]; |
1014 | } |
1015 | |
1016 | static void ath12k_dp_mon_update_radiotap(struct ath12k *ar, |
1017 | struct hal_rx_mon_ppdu_info *ppduinfo, |
1018 | struct sk_buff *mon_skb, |
1019 | struct ieee80211_rx_status *rxs) |
1020 | { |
1021 | struct ieee80211_supported_band *sband; |
1022 | u8 *ptr = NULL; |
1023 | u16 ampdu_id = ppduinfo->ampdu_id[ppduinfo->userid]; |
1024 | |
1025 | rxs->flag |= RX_FLAG_MACTIME_START; |
1026 | rxs->signal = ppduinfo->rssi_comb + ATH12K_DEFAULT_NOISE_FLOOR; |
1027 | rxs->nss = ppduinfo->nss + 1; |
1028 | |
1029 | if (ampdu_id) { |
1030 | rxs->flag |= RX_FLAG_AMPDU_DETAILS; |
1031 | rxs->ampdu_reference = ampdu_id; |
1032 | } |
1033 | |
1034 | if (ppduinfo->he_mu_flags) { |
1035 | rxs->flag |= RX_FLAG_RADIOTAP_HE_MU; |
1036 | rxs->encoding = RX_ENC_HE; |
1037 | ptr = skb_push(skb: mon_skb, len: sizeof(struct ieee80211_radiotap_he_mu)); |
1038 | ath12k_dp_mon_rx_update_radiotap_he_mu(rx_status: ppduinfo, rtap_buf: ptr); |
1039 | } else if (ppduinfo->he_flags) { |
1040 | rxs->flag |= RX_FLAG_RADIOTAP_HE; |
1041 | rxs->encoding = RX_ENC_HE; |
1042 | ptr = skb_push(skb: mon_skb, len: sizeof(struct ieee80211_radiotap_he)); |
1043 | ath12k_dp_mon_rx_update_radiotap_he(rx_status: ppduinfo, rtap_buf: ptr); |
1044 | rxs->rate_idx = ppduinfo->rate; |
1045 | } else if (ppduinfo->vht_flags) { |
1046 | rxs->encoding = RX_ENC_VHT; |
1047 | rxs->rate_idx = ppduinfo->rate; |
1048 | } else if (ppduinfo->ht_flags) { |
1049 | rxs->encoding = RX_ENC_HT; |
1050 | rxs->rate_idx = ppduinfo->rate; |
1051 | } else { |
1052 | rxs->encoding = RX_ENC_LEGACY; |
1053 | sband = &ar->mac.sbands[rxs->band]; |
1054 | rxs->rate_idx = ath12k_mac_hw_rate_to_idx(sband, hw_rate: ppduinfo->rate, |
1055 | cck: ppduinfo->cck_flag); |
1056 | } |
1057 | |
1058 | rxs->mactime = ppduinfo->tsft; |
1059 | } |
1060 | |
1061 | static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, |
1062 | struct sk_buff *msdu, |
1063 | struct ieee80211_rx_status *status) |
1064 | { |
1065 | static const struct ieee80211_radiotap_he known = { |
1066 | .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | |
1067 | IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN), |
1068 | .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN), |
1069 | }; |
1070 | struct ieee80211_rx_status *rx_status; |
1071 | struct ieee80211_radiotap_he *he = NULL; |
1072 | struct ieee80211_sta *pubsta = NULL; |
1073 | struct ath12k_peer *peer; |
1074 | struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(skb: msdu); |
1075 | u8 decap = DP_RX_DECAP_TYPE_RAW; |
1076 | bool is_mcbc = rxcb->is_mcbc; |
1077 | bool is_eapol_tkip = rxcb->is_eapol; |
1078 | |
1079 | if ((status->encoding == RX_ENC_HE) && !(status->flag & RX_FLAG_RADIOTAP_HE) && |
1080 | !(status->flag & RX_FLAG_SKIP_MONITOR)) { |
1081 | he = skb_push(skb: msdu, len: sizeof(known)); |
1082 | memcpy(he, &known, sizeof(known)); |
1083 | status->flag |= RX_FLAG_RADIOTAP_HE; |
1084 | } |
1085 | |
1086 | if (!(status->flag & RX_FLAG_ONLY_MONITOR)) |
1087 | decap = ath12k_dp_rx_h_decap_type(ab: ar->ab, desc: rxcb->rx_desc); |
1088 | spin_lock_bh(lock: &ar->ab->base_lock); |
1089 | peer = ath12k_dp_rx_h_find_peer(ab: ar->ab, msdu); |
1090 | if (peer && peer->sta) |
1091 | pubsta = peer->sta; |
1092 | spin_unlock_bh(lock: &ar->ab->base_lock); |
1093 | |
1094 | ath12k_dbg(ar->ab, ATH12K_DBG_DATA, |
1095 | "rx skb %pK len %u peer %pM %u %s %s%s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n" , |
1096 | msdu, |
1097 | msdu->len, |
1098 | peer ? peer->addr : NULL, |
1099 | rxcb->tid, |
1100 | (is_mcbc) ? "mcast" : "ucast" , |
1101 | (status->encoding == RX_ENC_LEGACY) ? "legacy" : "" , |
1102 | (status->encoding == RX_ENC_HT) ? "ht" : "" , |
1103 | (status->encoding == RX_ENC_VHT) ? "vht" : "" , |
1104 | (status->encoding == RX_ENC_HE) ? "he" : "" , |
1105 | (status->bw == RATE_INFO_BW_40) ? "40" : "" , |
1106 | (status->bw == RATE_INFO_BW_80) ? "80" : "" , |
1107 | (status->bw == RATE_INFO_BW_160) ? "160" : "" , |
1108 | (status->bw == RATE_INFO_BW_320) ? "320" : "" , |
1109 | status->enc_flags & RX_ENC_FLAG_SHORT_GI ? "sgi " : "" , |
1110 | status->rate_idx, |
1111 | status->nss, |
1112 | status->freq, |
1113 | status->band, status->flag, |
1114 | !!(status->flag & RX_FLAG_FAILED_FCS_CRC), |
1115 | !!(status->flag & RX_FLAG_MMIC_ERROR), |
1116 | !!(status->flag & RX_FLAG_AMSDU_MORE)); |
1117 | |
1118 | ath12k_dbg_dump(ab: ar->ab, mask: ATH12K_DBG_DP_RX, NULL, prefix: "dp rx msdu: " , |
1119 | buf: msdu->data, len: msdu->len); |
1120 | rx_status = IEEE80211_SKB_RXCB(skb: msdu); |
1121 | *rx_status = *status; |
1122 | |
1123 | /* TODO: trace rx packet */ |
1124 | |
1125 | /* PN for multicast packets are not validate in HW, |
1126 | * so skip 802.3 rx path |
1127 | * Also, fast_rx expects the STA to be authorized, hence |
1128 | * eapol packets are sent in slow path. |
1129 | */ |
1130 | if (decap == DP_RX_DECAP_TYPE_ETHERNET2_DIX && !is_eapol_tkip && |
1131 | !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED)) |
1132 | rx_status->flag |= RX_FLAG_8023; |
1133 | |
1134 | ieee80211_rx_napi(hw: ath12k_ar_to_hw(ar), sta: pubsta, skb: msdu, napi); |
1135 | } |
1136 | |
1137 | static int ath12k_dp_mon_rx_deliver(struct ath12k *ar, u32 mac_id, |
1138 | struct sk_buff *head_msdu, |
1139 | struct hal_rx_mon_ppdu_info *ppduinfo, |
1140 | struct napi_struct *napi) |
1141 | { |
1142 | struct ath12k_pdev_dp *dp = &ar->dp; |
1143 | struct sk_buff *mon_skb, *skb_next, *; |
1144 | struct ieee80211_rx_status *rxs = &dp->rx_status; |
1145 | bool fcs_err = false; |
1146 | |
1147 | mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mac_id, head_msdu, |
1148 | rxs, fcs_err: &fcs_err); |
1149 | if (!mon_skb) |
1150 | goto mon_deliver_fail; |
1151 | |
1152 | header = mon_skb; |
1153 | rxs->flag = 0; |
1154 | |
1155 | if (fcs_err) |
1156 | rxs->flag = RX_FLAG_FAILED_FCS_CRC; |
1157 | |
1158 | do { |
1159 | skb_next = mon_skb->next; |
1160 | if (!skb_next) |
1161 | rxs->flag &= ~RX_FLAG_AMSDU_MORE; |
1162 | else |
1163 | rxs->flag |= RX_FLAG_AMSDU_MORE; |
1164 | |
1165 | if (mon_skb == header) { |
1166 | header = NULL; |
1167 | rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN; |
1168 | } else { |
1169 | rxs->flag |= RX_FLAG_ALLOW_SAME_PN; |
1170 | } |
1171 | rxs->flag |= RX_FLAG_ONLY_MONITOR; |
1172 | ath12k_dp_mon_update_radiotap(ar, ppduinfo, mon_skb, rxs); |
1173 | ath12k_dp_mon_rx_deliver_msdu(ar, napi, msdu: mon_skb, status: rxs); |
1174 | mon_skb = skb_next; |
1175 | } while (mon_skb); |
1176 | rxs->flag = 0; |
1177 | |
1178 | return 0; |
1179 | |
1180 | mon_deliver_fail: |
1181 | mon_skb = head_msdu; |
1182 | while (mon_skb) { |
1183 | skb_next = mon_skb->next; |
1184 | dev_kfree_skb_any(skb: mon_skb); |
1185 | mon_skb = skb_next; |
1186 | } |
1187 | return -EINVAL; |
1188 | } |
1189 | |
1190 | static enum hal_rx_mon_status |
1191 | ath12k_dp_mon_parse_rx_dest(struct ath12k_base *ab, struct ath12k_mon_data *pmon, |
1192 | struct sk_buff *skb) |
1193 | { |
1194 | struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; |
1195 | struct hal_tlv_hdr *tlv; |
1196 | enum hal_rx_mon_status hal_status; |
1197 | u32 tlv_userid = 0; |
1198 | u16 tlv_tag, tlv_len; |
1199 | u8 *ptr = skb->data; |
1200 | |
1201 | memset(ppdu_info, 0, sizeof(struct hal_rx_mon_ppdu_info)); |
1202 | |
1203 | do { |
1204 | tlv = (struct hal_tlv_hdr *)ptr; |
1205 | tlv_tag = le32_get_bits(v: tlv->tl, HAL_TLV_HDR_TAG); |
1206 | tlv_len = le32_get_bits(v: tlv->tl, HAL_TLV_HDR_LEN); |
1207 | tlv_userid = le32_get_bits(v: tlv->tl, HAL_TLV_USR_ID); |
1208 | ptr += sizeof(*tlv); |
1209 | |
1210 | /* The actual length of PPDU_END is the combined length of many PHY |
1211 | * TLVs that follow. Skip the TLV header and |
1212 | * rx_rxpcu_classification_overview that follows the header to get to |
1213 | * next TLV. |
1214 | */ |
1215 | |
1216 | if (tlv_tag == HAL_RX_PPDU_END) |
1217 | tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview); |
1218 | |
1219 | hal_status = ath12k_dp_mon_rx_parse_status_tlv(ab, pmon, |
1220 | tlv_tag, tlv_data: ptr, userid: tlv_userid); |
1221 | ptr += tlv_len; |
1222 | ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); |
1223 | |
1224 | if ((ptr - skb->data) >= DP_RX_BUFFER_SIZE) |
1225 | break; |
1226 | |
1227 | } while (hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE); |
1228 | |
1229 | return hal_status; |
1230 | } |
1231 | |
1232 | enum hal_rx_mon_status |
1233 | ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, |
1234 | struct ath12k_mon_data *pmon, |
1235 | int mac_id, |
1236 | struct sk_buff *skb, |
1237 | struct napi_struct *napi) |
1238 | { |
1239 | struct ath12k_base *ab = ar->ab; |
1240 | struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; |
1241 | struct dp_mon_mpdu *tmp; |
1242 | struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; |
1243 | struct sk_buff *head_msdu, *tail_msdu; |
1244 | enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE; |
1245 | |
1246 | ath12k_dp_mon_parse_rx_dest(ab, pmon, skb); |
1247 | |
1248 | list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) { |
1249 | list_del(entry: &mon_mpdu->list); |
1250 | head_msdu = mon_mpdu->head; |
1251 | tail_msdu = mon_mpdu->tail; |
1252 | |
1253 | if (head_msdu && tail_msdu) { |
1254 | ath12k_dp_mon_rx_deliver(ar, mac_id, head_msdu, |
1255 | ppduinfo: ppdu_info, napi); |
1256 | } |
1257 | |
1258 | kfree(objp: mon_mpdu); |
1259 | } |
1260 | return hal_status; |
1261 | } |
1262 | |
1263 | int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, |
1264 | struct dp_rxdma_mon_ring *buf_ring, |
1265 | int req_entries) |
1266 | { |
1267 | struct hal_mon_buf_ring *mon_buf; |
1268 | struct sk_buff *skb; |
1269 | struct hal_srng *srng; |
1270 | dma_addr_t paddr; |
1271 | u32 cookie; |
1272 | int buf_id; |
1273 | |
1274 | srng = &ab->hal.srng_list[buf_ring->refill_buf_ring.ring_id]; |
1275 | spin_lock_bh(lock: &srng->lock); |
1276 | ath12k_hal_srng_access_begin(ab, srng); |
1277 | |
1278 | while (req_entries > 0) { |
1279 | skb = dev_alloc_skb(DP_RX_BUFFER_SIZE + DP_RX_BUFFER_ALIGN_SIZE); |
1280 | if (unlikely(!skb)) |
1281 | goto fail_alloc_skb; |
1282 | |
1283 | if (!IS_ALIGNED((unsigned long)skb->data, DP_RX_BUFFER_ALIGN_SIZE)) { |
1284 | skb_pull(skb, |
1285 | PTR_ALIGN(skb->data, DP_RX_BUFFER_ALIGN_SIZE) - |
1286 | skb->data); |
1287 | } |
1288 | |
1289 | paddr = dma_map_single(ab->dev, skb->data, |
1290 | skb->len + skb_tailroom(skb), |
1291 | DMA_FROM_DEVICE); |
1292 | |
1293 | if (unlikely(dma_mapping_error(ab->dev, paddr))) |
1294 | goto fail_free_skb; |
1295 | |
1296 | spin_lock_bh(lock: &buf_ring->idr_lock); |
1297 | buf_id = idr_alloc(&buf_ring->bufs_idr, ptr: skb, start: 0, |
1298 | end: buf_ring->bufs_max * 3, GFP_ATOMIC); |
1299 | spin_unlock_bh(lock: &buf_ring->idr_lock); |
1300 | |
1301 | if (unlikely(buf_id < 0)) |
1302 | goto fail_dma_unmap; |
1303 | |
1304 | mon_buf = ath12k_hal_srng_src_get_next_entry(ab, srng); |
1305 | if (unlikely(!mon_buf)) |
1306 | goto fail_idr_remove; |
1307 | |
1308 | ATH12K_SKB_RXCB(skb)->paddr = paddr; |
1309 | |
1310 | cookie = u32_encode_bits(v: buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); |
1311 | |
1312 | mon_buf->paddr_lo = cpu_to_le32(lower_32_bits(paddr)); |
1313 | mon_buf->paddr_hi = cpu_to_le32(upper_32_bits(paddr)); |
1314 | mon_buf->cookie = cpu_to_le64(cookie); |
1315 | |
1316 | req_entries--; |
1317 | } |
1318 | |
1319 | ath12k_hal_srng_access_end(ab, srng); |
1320 | spin_unlock_bh(lock: &srng->lock); |
1321 | return 0; |
1322 | |
1323 | fail_idr_remove: |
1324 | spin_lock_bh(lock: &buf_ring->idr_lock); |
1325 | idr_remove(&buf_ring->bufs_idr, id: buf_id); |
1326 | spin_unlock_bh(lock: &buf_ring->idr_lock); |
1327 | fail_dma_unmap: |
1328 | dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb), |
1329 | DMA_FROM_DEVICE); |
1330 | fail_free_skb: |
1331 | dev_kfree_skb_any(skb); |
1332 | fail_alloc_skb: |
1333 | ath12k_hal_srng_access_end(ab, srng); |
1334 | spin_unlock_bh(lock: &srng->lock); |
1335 | return -ENOMEM; |
1336 | } |
1337 | |
1338 | static struct dp_mon_tx_ppdu_info * |
1339 | ath12k_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data *pmon, |
1340 | unsigned int ppdu_id, |
1341 | enum dp_mon_tx_ppdu_info_type type) |
1342 | { |
1343 | struct dp_mon_tx_ppdu_info *tx_ppdu_info; |
1344 | |
1345 | if (type == DP_MON_TX_PROT_PPDU_INFO) { |
1346 | tx_ppdu_info = pmon->tx_prot_ppdu_info; |
1347 | |
1348 | if (tx_ppdu_info && !tx_ppdu_info->is_used) |
1349 | return tx_ppdu_info; |
1350 | kfree(objp: tx_ppdu_info); |
1351 | } else { |
1352 | tx_ppdu_info = pmon->tx_data_ppdu_info; |
1353 | |
1354 | if (tx_ppdu_info && !tx_ppdu_info->is_used) |
1355 | return tx_ppdu_info; |
1356 | kfree(objp: tx_ppdu_info); |
1357 | } |
1358 | |
1359 | /* allocate new tx_ppdu_info */ |
1360 | tx_ppdu_info = kzalloc(size: sizeof(*tx_ppdu_info), GFP_ATOMIC); |
1361 | if (!tx_ppdu_info) |
1362 | return NULL; |
1363 | |
1364 | tx_ppdu_info->is_used = 0; |
1365 | tx_ppdu_info->ppdu_id = ppdu_id; |
1366 | |
1367 | if (type == DP_MON_TX_PROT_PPDU_INFO) |
1368 | pmon->tx_prot_ppdu_info = tx_ppdu_info; |
1369 | else |
1370 | pmon->tx_data_ppdu_info = tx_ppdu_info; |
1371 | |
1372 | return tx_ppdu_info; |
1373 | } |
1374 | |
1375 | static struct dp_mon_tx_ppdu_info * |
1376 | ath12k_dp_mon_hal_tx_ppdu_info(struct ath12k_mon_data *pmon, |
1377 | u16 tlv_tag) |
1378 | { |
1379 | switch (tlv_tag) { |
1380 | case HAL_TX_FES_SETUP: |
1381 | case HAL_TX_FLUSH: |
1382 | case HAL_PCU_PPDU_SETUP_INIT: |
1383 | case HAL_TX_PEER_ENTRY: |
1384 | case HAL_TX_QUEUE_EXTENSION: |
1385 | case HAL_TX_MPDU_START: |
1386 | case HAL_TX_MSDU_START: |
1387 | case HAL_TX_DATA: |
1388 | case HAL_MON_BUF_ADDR: |
1389 | case HAL_TX_MPDU_END: |
1390 | case HAL_TX_LAST_MPDU_FETCHED: |
1391 | case HAL_TX_LAST_MPDU_END: |
1392 | case HAL_COEX_TX_REQ: |
1393 | case HAL_TX_RAW_OR_NATIVE_FRAME_SETUP: |
1394 | case HAL_SCH_CRITICAL_TLV_REFERENCE: |
1395 | case HAL_TX_FES_SETUP_COMPLETE: |
1396 | case HAL_TQM_MPDU_GLOBAL_START: |
1397 | case HAL_SCHEDULER_END: |
1398 | case HAL_TX_FES_STATUS_USER_PPDU: |
1399 | break; |
1400 | case HAL_TX_FES_STATUS_PROT: { |
1401 | if (!pmon->tx_prot_ppdu_info->is_used) |
1402 | pmon->tx_prot_ppdu_info->is_used = true; |
1403 | |
1404 | return pmon->tx_prot_ppdu_info; |
1405 | } |
1406 | } |
1407 | |
1408 | if (!pmon->tx_data_ppdu_info->is_used) |
1409 | pmon->tx_data_ppdu_info->is_used = true; |
1410 | |
1411 | return pmon->tx_data_ppdu_info; |
1412 | } |
1413 | |
1414 | #define 512 |
1415 | #define MAX_DUMMY_FRM_BODY 128 |
1416 | |
1417 | struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void) |
1418 | { |
1419 | struct sk_buff *skb; |
1420 | |
1421 | skb = dev_alloc_skb(MAX_MONITOR_HEADER + MAX_DUMMY_FRM_BODY); |
1422 | if (!skb) |
1423 | return NULL; |
1424 | |
1425 | skb_reserve(skb, MAX_MONITOR_HEADER); |
1426 | |
1427 | if (!IS_ALIGNED((unsigned long)skb->data, 4)) |
1428 | skb_pull(skb, PTR_ALIGN(skb->data, 4) - skb->data); |
1429 | |
1430 | return skb; |
1431 | } |
1432 | |
1433 | static int |
1434 | ath12k_dp_mon_tx_gen_cts2self_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) |
1435 | { |
1436 | struct sk_buff *skb; |
1437 | struct ieee80211_cts *cts; |
1438 | |
1439 | skb = ath12k_dp_mon_tx_alloc_skb(); |
1440 | if (!skb) |
1441 | return -ENOMEM; |
1442 | |
1443 | cts = (struct ieee80211_cts *)skb->data; |
1444 | memset(cts, 0, MAX_DUMMY_FRM_BODY); |
1445 | cts->frame_control = |
1446 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); |
1447 | cts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); |
1448 | memcpy(cts->ra, tx_ppdu_info->rx_status.addr1, sizeof(cts->ra)); |
1449 | |
1450 | skb_put(skb, len: sizeof(*cts)); |
1451 | tx_ppdu_info->tx_mon_mpdu->head = skb; |
1452 | tx_ppdu_info->tx_mon_mpdu->tail = NULL; |
1453 | list_add_tail(new: &tx_ppdu_info->tx_mon_mpdu->list, |
1454 | head: &tx_ppdu_info->dp_tx_mon_mpdu_list); |
1455 | |
1456 | return 0; |
1457 | } |
1458 | |
1459 | static int |
1460 | ath12k_dp_mon_tx_gen_rts_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) |
1461 | { |
1462 | struct sk_buff *skb; |
1463 | struct ieee80211_rts *rts; |
1464 | |
1465 | skb = ath12k_dp_mon_tx_alloc_skb(); |
1466 | if (!skb) |
1467 | return -ENOMEM; |
1468 | |
1469 | rts = (struct ieee80211_rts *)skb->data; |
1470 | memset(rts, 0, MAX_DUMMY_FRM_BODY); |
1471 | rts->frame_control = |
1472 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); |
1473 | rts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); |
1474 | memcpy(rts->ra, tx_ppdu_info->rx_status.addr1, sizeof(rts->ra)); |
1475 | memcpy(rts->ta, tx_ppdu_info->rx_status.addr2, sizeof(rts->ta)); |
1476 | |
1477 | skb_put(skb, len: sizeof(*rts)); |
1478 | tx_ppdu_info->tx_mon_mpdu->head = skb; |
1479 | tx_ppdu_info->tx_mon_mpdu->tail = NULL; |
1480 | list_add_tail(new: &tx_ppdu_info->tx_mon_mpdu->list, |
1481 | head: &tx_ppdu_info->dp_tx_mon_mpdu_list); |
1482 | |
1483 | return 0; |
1484 | } |
1485 | |
1486 | static int |
1487 | ath12k_dp_mon_tx_gen_3addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) |
1488 | { |
1489 | struct sk_buff *skb; |
1490 | struct ieee80211_qos_hdr *qhdr; |
1491 | |
1492 | skb = ath12k_dp_mon_tx_alloc_skb(); |
1493 | if (!skb) |
1494 | return -ENOMEM; |
1495 | |
1496 | qhdr = (struct ieee80211_qos_hdr *)skb->data; |
1497 | memset(qhdr, 0, MAX_DUMMY_FRM_BODY); |
1498 | qhdr->frame_control = |
1499 | cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); |
1500 | qhdr->duration_id = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); |
1501 | memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); |
1502 | memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); |
1503 | memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); |
1504 | |
1505 | skb_put(skb, len: sizeof(*qhdr)); |
1506 | tx_ppdu_info->tx_mon_mpdu->head = skb; |
1507 | tx_ppdu_info->tx_mon_mpdu->tail = NULL; |
1508 | list_add_tail(new: &tx_ppdu_info->tx_mon_mpdu->list, |
1509 | head: &tx_ppdu_info->dp_tx_mon_mpdu_list); |
1510 | |
1511 | return 0; |
1512 | } |
1513 | |
1514 | static int |
1515 | ath12k_dp_mon_tx_gen_4addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) |
1516 | { |
1517 | struct sk_buff *skb; |
1518 | struct dp_mon_qosframe_addr4 *qhdr; |
1519 | |
1520 | skb = ath12k_dp_mon_tx_alloc_skb(); |
1521 | if (!skb) |
1522 | return -ENOMEM; |
1523 | |
1524 | qhdr = (struct dp_mon_qosframe_addr4 *)skb->data; |
1525 | memset(qhdr, 0, MAX_DUMMY_FRM_BODY); |
1526 | qhdr->frame_control = |
1527 | cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); |
1528 | qhdr->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); |
1529 | memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); |
1530 | memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); |
1531 | memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); |
1532 | memcpy(qhdr->addr4, tx_ppdu_info->rx_status.addr4, ETH_ALEN); |
1533 | |
1534 | skb_put(skb, len: sizeof(*qhdr)); |
1535 | tx_ppdu_info->tx_mon_mpdu->head = skb; |
1536 | tx_ppdu_info->tx_mon_mpdu->tail = NULL; |
1537 | list_add_tail(new: &tx_ppdu_info->tx_mon_mpdu->list, |
1538 | head: &tx_ppdu_info->dp_tx_mon_mpdu_list); |
1539 | |
1540 | return 0; |
1541 | } |
1542 | |
1543 | static int |
1544 | ath12k_dp_mon_tx_gen_ack_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) |
1545 | { |
1546 | struct sk_buff *skb; |
1547 | struct dp_mon_frame_min_one *fbmhdr; |
1548 | |
1549 | skb = ath12k_dp_mon_tx_alloc_skb(); |
1550 | if (!skb) |
1551 | return -ENOMEM; |
1552 | |
1553 | fbmhdr = (struct dp_mon_frame_min_one *)skb->data; |
1554 | memset(fbmhdr, 0, MAX_DUMMY_FRM_BODY); |
1555 | fbmhdr->frame_control = |
1556 | cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_CFACK); |
1557 | memcpy(fbmhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); |
1558 | |
1559 | /* set duration zero for ack frame */ |
1560 | fbmhdr->duration = 0; |
1561 | |
1562 | skb_put(skb, len: sizeof(*fbmhdr)); |
1563 | tx_ppdu_info->tx_mon_mpdu->head = skb; |
1564 | tx_ppdu_info->tx_mon_mpdu->tail = NULL; |
1565 | list_add_tail(new: &tx_ppdu_info->tx_mon_mpdu->list, |
1566 | head: &tx_ppdu_info->dp_tx_mon_mpdu_list); |
1567 | |
1568 | return 0; |
1569 | } |
1570 | |
1571 | static int |
1572 | ath12k_dp_mon_tx_gen_prot_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) |
1573 | { |
1574 | int ret = 0; |
1575 | |
1576 | switch (tx_ppdu_info->rx_status.medium_prot_type) { |
1577 | case DP_MON_TX_MEDIUM_RTS_LEGACY: |
1578 | case DP_MON_TX_MEDIUM_RTS_11AC_STATIC_BW: |
1579 | case DP_MON_TX_MEDIUM_RTS_11AC_DYNAMIC_BW: |
1580 | ret = ath12k_dp_mon_tx_gen_rts_frame(tx_ppdu_info); |
1581 | break; |
1582 | case DP_MON_TX_MEDIUM_CTS2SELF: |
1583 | ret = ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); |
1584 | break; |
1585 | case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_3ADDR: |
1586 | ret = ath12k_dp_mon_tx_gen_3addr_qos_null_frame(tx_ppdu_info); |
1587 | break; |
1588 | case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_4ADDR: |
1589 | ret = ath12k_dp_mon_tx_gen_4addr_qos_null_frame(tx_ppdu_info); |
1590 | break; |
1591 | } |
1592 | |
1593 | return ret; |
1594 | } |
1595 | |
1596 | static enum dp_mon_tx_tlv_status |
1597 | ath12k_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, |
1598 | struct ath12k_mon_data *pmon, |
1599 | u16 tlv_tag, u8 *tlv_data, u32 userid) |
1600 | { |
1601 | struct dp_mon_tx_ppdu_info *tx_ppdu_info; |
1602 | enum dp_mon_tx_tlv_status status = DP_MON_TX_STATUS_PPDU_NOT_DONE; |
1603 | u32 info[7]; |
1604 | |
1605 | tx_ppdu_info = ath12k_dp_mon_hal_tx_ppdu_info(pmon, tlv_tag); |
1606 | |
1607 | switch (tlv_tag) { |
1608 | case HAL_TX_FES_SETUP: { |
1609 | struct hal_tx_fes_setup *tx_fes_setup = |
1610 | (struct hal_tx_fes_setup *)tlv_data; |
1611 | |
1612 | info[0] = __le32_to_cpu(tx_fes_setup->info0); |
1613 | tx_ppdu_info->ppdu_id = __le32_to_cpu(tx_fes_setup->schedule_id); |
1614 | tx_ppdu_info->num_users = |
1615 | u32_get_bits(v: info[0], HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); |
1616 | status = DP_MON_TX_FES_SETUP; |
1617 | break; |
1618 | } |
1619 | |
1620 | case HAL_TX_FES_STATUS_END: { |
1621 | struct hal_tx_fes_status_end *tx_fes_status_end = |
1622 | (struct hal_tx_fes_status_end *)tlv_data; |
1623 | u32 tst_15_0, tst_31_16; |
1624 | |
1625 | info[0] = __le32_to_cpu(tx_fes_status_end->info0); |
1626 | tst_15_0 = |
1627 | u32_get_bits(v: info[0], |
1628 | HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_15_0); |
1629 | tst_31_16 = |
1630 | u32_get_bits(v: info[0], |
1631 | HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_31_16); |
1632 | |
1633 | tx_ppdu_info->rx_status.ppdu_ts = (tst_15_0 | (tst_31_16 << 16)); |
1634 | status = DP_MON_TX_FES_STATUS_END; |
1635 | break; |
1636 | } |
1637 | |
1638 | case HAL_RX_RESPONSE_REQUIRED_INFO: { |
1639 | struct hal_rx_resp_req_info *rx_resp_req_info = |
1640 | (struct hal_rx_resp_req_info *)tlv_data; |
1641 | u32 addr_32; |
1642 | u16 addr_16; |
1643 | |
1644 | info[0] = __le32_to_cpu(rx_resp_req_info->info0); |
1645 | info[1] = __le32_to_cpu(rx_resp_req_info->info1); |
1646 | info[2] = __le32_to_cpu(rx_resp_req_info->info2); |
1647 | info[3] = __le32_to_cpu(rx_resp_req_info->info3); |
1648 | info[4] = __le32_to_cpu(rx_resp_req_info->info4); |
1649 | info[5] = __le32_to_cpu(rx_resp_req_info->info5); |
1650 | |
1651 | tx_ppdu_info->rx_status.ppdu_id = |
1652 | u32_get_bits(v: info[0], HAL_RX_RESP_REQ_INFO0_PPDU_ID); |
1653 | tx_ppdu_info->rx_status.reception_type = |
1654 | u32_get_bits(v: info[0], HAL_RX_RESP_REQ_INFO0_RECEPTION_TYPE); |
1655 | tx_ppdu_info->rx_status.rx_duration = |
1656 | u32_get_bits(v: info[1], HAL_RX_RESP_REQ_INFO1_DURATION); |
1657 | tx_ppdu_info->rx_status.mcs = |
1658 | u32_get_bits(v: info[1], HAL_RX_RESP_REQ_INFO1_RATE_MCS); |
1659 | tx_ppdu_info->rx_status.sgi = |
1660 | u32_get_bits(v: info[1], HAL_RX_RESP_REQ_INFO1_SGI); |
1661 | tx_ppdu_info->rx_status.is_stbc = |
1662 | u32_get_bits(v: info[1], HAL_RX_RESP_REQ_INFO1_STBC); |
1663 | tx_ppdu_info->rx_status.ldpc = |
1664 | u32_get_bits(v: info[1], HAL_RX_RESP_REQ_INFO1_LDPC); |
1665 | tx_ppdu_info->rx_status.is_ampdu = |
1666 | u32_get_bits(v: info[1], HAL_RX_RESP_REQ_INFO1_IS_AMPDU); |
1667 | tx_ppdu_info->rx_status.num_users = |
1668 | u32_get_bits(v: info[2], HAL_RX_RESP_REQ_INFO2_NUM_USER); |
1669 | |
1670 | addr_32 = u32_get_bits(v: info[3], HAL_RX_RESP_REQ_INFO3_ADDR1_31_0); |
1671 | addr_16 = u32_get_bits(v: info[3], HAL_RX_RESP_REQ_INFO4_ADDR1_47_32); |
1672 | ath12k_dp_get_mac_addr(addr_l32: addr_32, addr_h16: addr_16, addr: tx_ppdu_info->rx_status.addr1); |
1673 | |
1674 | addr_16 = u32_get_bits(v: info[4], HAL_RX_RESP_REQ_INFO4_ADDR1_15_0); |
1675 | addr_32 = u32_get_bits(v: info[5], HAL_RX_RESP_REQ_INFO5_ADDR1_47_16); |
1676 | ath12k_dp_get_mac_addr(addr_l32: addr_32, addr_h16: addr_16, addr: tx_ppdu_info->rx_status.addr2); |
1677 | |
1678 | if (tx_ppdu_info->rx_status.reception_type == 0) |
1679 | ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); |
1680 | status = DP_MON_RX_RESPONSE_REQUIRED_INFO; |
1681 | break; |
1682 | } |
1683 | |
1684 | case HAL_PCU_PPDU_SETUP_INIT: { |
1685 | struct hal_tx_pcu_ppdu_setup_init *ppdu_setup = |
1686 | (struct hal_tx_pcu_ppdu_setup_init *)tlv_data; |
1687 | u32 addr_32; |
1688 | u16 addr_16; |
1689 | |
1690 | info[0] = __le32_to_cpu(ppdu_setup->info0); |
1691 | info[1] = __le32_to_cpu(ppdu_setup->info1); |
1692 | info[2] = __le32_to_cpu(ppdu_setup->info2); |
1693 | info[3] = __le32_to_cpu(ppdu_setup->info3); |
1694 | info[4] = __le32_to_cpu(ppdu_setup->info4); |
1695 | info[5] = __le32_to_cpu(ppdu_setup->info5); |
1696 | info[6] = __le32_to_cpu(ppdu_setup->info6); |
1697 | |
1698 | /* protection frame address 1 */ |
1699 | addr_32 = u32_get_bits(v: info[1], |
1700 | HAL_TX_PPDU_SETUP_INFO1_PROT_FRAME_ADDR1_31_0); |
1701 | addr_16 = u32_get_bits(v: info[2], |
1702 | HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR1_47_32); |
1703 | ath12k_dp_get_mac_addr(addr_l32: addr_32, addr_h16: addr_16, addr: tx_ppdu_info->rx_status.addr1); |
1704 | |
1705 | /* protection frame address 2 */ |
1706 | addr_16 = u32_get_bits(v: info[2], |
1707 | HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR2_15_0); |
1708 | addr_32 = u32_get_bits(v: info[3], |
1709 | HAL_TX_PPDU_SETUP_INFO3_PROT_FRAME_ADDR2_47_16); |
1710 | ath12k_dp_get_mac_addr(addr_l32: addr_32, addr_h16: addr_16, addr: tx_ppdu_info->rx_status.addr2); |
1711 | |
1712 | /* protection frame address 3 */ |
1713 | addr_32 = u32_get_bits(v: info[4], |
1714 | HAL_TX_PPDU_SETUP_INFO4_PROT_FRAME_ADDR3_31_0); |
1715 | addr_16 = u32_get_bits(v: info[5], |
1716 | HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR3_47_32); |
1717 | ath12k_dp_get_mac_addr(addr_l32: addr_32, addr_h16: addr_16, addr: tx_ppdu_info->rx_status.addr3); |
1718 | |
1719 | /* protection frame address 4 */ |
1720 | addr_16 = u32_get_bits(v: info[5], |
1721 | HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR4_15_0); |
1722 | addr_32 = u32_get_bits(v: info[6], |
1723 | HAL_TX_PPDU_SETUP_INFO6_PROT_FRAME_ADDR4_47_16); |
1724 | ath12k_dp_get_mac_addr(addr_l32: addr_32, addr_h16: addr_16, addr: tx_ppdu_info->rx_status.addr4); |
1725 | |
1726 | status = u32_get_bits(v: info[0], |
1727 | HAL_TX_PPDU_SETUP_INFO0_MEDIUM_PROT_TYPE); |
1728 | break; |
1729 | } |
1730 | |
1731 | case HAL_TX_QUEUE_EXTENSION: { |
1732 | struct hal_tx_queue_exten *tx_q_exten = |
1733 | (struct hal_tx_queue_exten *)tlv_data; |
1734 | |
1735 | info[0] = __le32_to_cpu(tx_q_exten->info0); |
1736 | |
1737 | tx_ppdu_info->rx_status.frame_control = |
1738 | u32_get_bits(v: info[0], |
1739 | HAL_TX_Q_EXT_INFO0_FRAME_CTRL); |
1740 | tx_ppdu_info->rx_status.fc_valid = true; |
1741 | break; |
1742 | } |
1743 | |
1744 | case HAL_TX_FES_STATUS_START: { |
1745 | struct hal_tx_fes_status_start *tx_fes_start = |
1746 | (struct hal_tx_fes_status_start *)tlv_data; |
1747 | |
1748 | info[0] = __le32_to_cpu(tx_fes_start->info0); |
1749 | |
1750 | tx_ppdu_info->rx_status.medium_prot_type = |
1751 | u32_get_bits(v: info[0], |
1752 | HAL_TX_FES_STATUS_START_INFO0_MEDIUM_PROT_TYPE); |
1753 | break; |
1754 | } |
1755 | |
1756 | case HAL_TX_FES_STATUS_PROT: { |
1757 | struct hal_tx_fes_status_prot *tx_fes_status = |
1758 | (struct hal_tx_fes_status_prot *)tlv_data; |
1759 | u32 start_timestamp; |
1760 | u32 end_timestamp; |
1761 | |
1762 | info[0] = __le32_to_cpu(tx_fes_status->info0); |
1763 | info[1] = __le32_to_cpu(tx_fes_status->info1); |
1764 | |
1765 | start_timestamp = |
1766 | u32_get_bits(v: info[0], |
1767 | HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_15_0); |
1768 | start_timestamp |= |
1769 | u32_get_bits(v: info[0], |
1770 | HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_31_16) << 15; |
1771 | end_timestamp = |
1772 | u32_get_bits(v: info[1], |
1773 | HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_15_0); |
1774 | end_timestamp |= |
1775 | u32_get_bits(v: info[1], |
1776 | HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_31_16) << 15; |
1777 | tx_ppdu_info->rx_status.rx_duration = end_timestamp - start_timestamp; |
1778 | |
1779 | ath12k_dp_mon_tx_gen_prot_frame(tx_ppdu_info); |
1780 | break; |
1781 | } |
1782 | |
1783 | case HAL_TX_FES_STATUS_START_PPDU: |
1784 | case HAL_TX_FES_STATUS_START_PROT: { |
1785 | struct hal_tx_fes_status_start_prot *tx_fes_stat_start = |
1786 | (struct hal_tx_fes_status_start_prot *)tlv_data; |
1787 | u64 ppdu_ts; |
1788 | |
1789 | info[0] = __le32_to_cpu(tx_fes_stat_start->info0); |
1790 | |
1791 | tx_ppdu_info->rx_status.ppdu_ts = |
1792 | u32_get_bits(v: info[0], |
1793 | HAL_TX_FES_STAT_STRT_INFO0_PROT_TS_LOWER_32); |
1794 | ppdu_ts = (u32_get_bits(v: info[1], |
1795 | HAL_TX_FES_STAT_STRT_INFO1_PROT_TS_UPPER_32)); |
1796 | tx_ppdu_info->rx_status.ppdu_ts |= ppdu_ts << 32; |
1797 | break; |
1798 | } |
1799 | |
1800 | case HAL_TX_FES_STATUS_USER_PPDU: { |
1801 | struct hal_tx_fes_status_user_ppdu *tx_fes_usr_ppdu = |
1802 | (struct hal_tx_fes_status_user_ppdu *)tlv_data; |
1803 | |
1804 | info[0] = __le32_to_cpu(tx_fes_usr_ppdu->info0); |
1805 | |
1806 | tx_ppdu_info->rx_status.rx_duration = |
1807 | u32_get_bits(v: info[0], |
1808 | HAL_TX_FES_STAT_USR_PPDU_INFO0_DURATION); |
1809 | break; |
1810 | } |
1811 | |
1812 | case HAL_MACTX_HE_SIG_A_SU: |
1813 | ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info: &tx_ppdu_info->rx_status); |
1814 | break; |
1815 | |
1816 | case HAL_MACTX_HE_SIG_A_MU_DL: |
1817 | ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info: &tx_ppdu_info->rx_status); |
1818 | break; |
1819 | |
1820 | case HAL_MACTX_HE_SIG_B1_MU: |
1821 | ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info: &tx_ppdu_info->rx_status); |
1822 | break; |
1823 | |
1824 | case HAL_MACTX_HE_SIG_B2_MU: |
1825 | ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info: &tx_ppdu_info->rx_status); |
1826 | break; |
1827 | |
1828 | case HAL_MACTX_HE_SIG_B2_OFDMA: |
1829 | ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info: &tx_ppdu_info->rx_status); |
1830 | break; |
1831 | |
1832 | case HAL_MACTX_VHT_SIG_A: |
1833 | ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info: &tx_ppdu_info->rx_status); |
1834 | break; |
1835 | |
1836 | case HAL_MACTX_L_SIG_A: |
1837 | ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info: &tx_ppdu_info->rx_status); |
1838 | break; |
1839 | |
1840 | case HAL_MACTX_L_SIG_B: |
1841 | ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info: &tx_ppdu_info->rx_status); |
1842 | break; |
1843 | |
1844 | case HAL_RX_FRAME_BITMAP_ACK: { |
1845 | struct hal_rx_frame_bitmap_ack *fbm_ack = |
1846 | (struct hal_rx_frame_bitmap_ack *)tlv_data; |
1847 | u32 addr_32; |
1848 | u16 addr_16; |
1849 | |
1850 | info[0] = __le32_to_cpu(fbm_ack->info0); |
1851 | info[1] = __le32_to_cpu(fbm_ack->info1); |
1852 | |
1853 | addr_32 = u32_get_bits(v: info[0], |
1854 | HAL_RX_FBM_ACK_INFO0_ADDR1_31_0); |
1855 | addr_16 = u32_get_bits(v: info[1], |
1856 | HAL_RX_FBM_ACK_INFO1_ADDR1_47_32); |
1857 | ath12k_dp_get_mac_addr(addr_l32: addr_32, addr_h16: addr_16, addr: tx_ppdu_info->rx_status.addr1); |
1858 | |
1859 | ath12k_dp_mon_tx_gen_ack_frame(tx_ppdu_info); |
1860 | break; |
1861 | } |
1862 | |
1863 | case HAL_MACTX_PHY_DESC: { |
1864 | struct hal_tx_phy_desc *tx_phy_desc = |
1865 | (struct hal_tx_phy_desc *)tlv_data; |
1866 | |
1867 | info[0] = __le32_to_cpu(tx_phy_desc->info0); |
1868 | info[1] = __le32_to_cpu(tx_phy_desc->info1); |
1869 | info[2] = __le32_to_cpu(tx_phy_desc->info2); |
1870 | info[3] = __le32_to_cpu(tx_phy_desc->info3); |
1871 | |
1872 | tx_ppdu_info->rx_status.beamformed = |
1873 | u32_get_bits(v: info[0], |
1874 | HAL_TX_PHY_DESC_INFO0_BF_TYPE); |
1875 | tx_ppdu_info->rx_status.preamble_type = |
1876 | u32_get_bits(v: info[0], |
1877 | HAL_TX_PHY_DESC_INFO0_PREAMBLE_11B); |
1878 | tx_ppdu_info->rx_status.mcs = |
1879 | u32_get_bits(v: info[1], |
1880 | HAL_TX_PHY_DESC_INFO1_MCS); |
1881 | tx_ppdu_info->rx_status.ltf_size = |
1882 | u32_get_bits(v: info[3], |
1883 | HAL_TX_PHY_DESC_INFO3_LTF_SIZE); |
1884 | tx_ppdu_info->rx_status.nss = |
1885 | u32_get_bits(v: info[2], |
1886 | HAL_TX_PHY_DESC_INFO2_NSS); |
1887 | tx_ppdu_info->rx_status.chan_num = |
1888 | u32_get_bits(v: info[3], |
1889 | HAL_TX_PHY_DESC_INFO3_ACTIVE_CHANNEL); |
1890 | tx_ppdu_info->rx_status.bw = |
1891 | u32_get_bits(v: info[0], |
1892 | HAL_TX_PHY_DESC_INFO0_BANDWIDTH); |
1893 | break; |
1894 | } |
1895 | |
1896 | case HAL_TX_MPDU_START: { |
1897 | struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu; |
1898 | |
1899 | mon_mpdu = kzalloc(size: sizeof(*mon_mpdu), GFP_ATOMIC); |
1900 | if (!mon_mpdu) |
1901 | return DP_MON_TX_STATUS_PPDU_NOT_DONE; |
1902 | status = DP_MON_TX_MPDU_START; |
1903 | break; |
1904 | } |
1905 | |
1906 | case HAL_MON_BUF_ADDR: { |
1907 | struct dp_rxdma_mon_ring *buf_ring = &ab->dp.tx_mon_buf_ring; |
1908 | struct dp_mon_packet_info *packet_info = |
1909 | (struct dp_mon_packet_info *)tlv_data; |
1910 | int buf_id = u32_get_bits(v: packet_info->cookie, |
1911 | DP_RXDMA_BUF_COOKIE_BUF_ID); |
1912 | struct sk_buff *msdu; |
1913 | struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu; |
1914 | struct ath12k_skb_rxcb *rxcb; |
1915 | |
1916 | spin_lock_bh(lock: &buf_ring->idr_lock); |
1917 | msdu = idr_remove(&buf_ring->bufs_idr, id: buf_id); |
1918 | spin_unlock_bh(lock: &buf_ring->idr_lock); |
1919 | |
1920 | if (unlikely(!msdu)) { |
1921 | ath12k_warn(ab, fmt: "monitor destination with invalid buf_id %d\n" , |
1922 | buf_id); |
1923 | return DP_MON_TX_STATUS_PPDU_NOT_DONE; |
1924 | } |
1925 | |
1926 | rxcb = ATH12K_SKB_RXCB(skb: msdu); |
1927 | dma_unmap_single(ab->dev, rxcb->paddr, |
1928 | msdu->len + skb_tailroom(msdu), |
1929 | DMA_FROM_DEVICE); |
1930 | |
1931 | if (!mon_mpdu->head) |
1932 | mon_mpdu->head = msdu; |
1933 | else if (mon_mpdu->tail) |
1934 | mon_mpdu->tail->next = msdu; |
1935 | |
1936 | mon_mpdu->tail = msdu; |
1937 | |
1938 | ath12k_dp_mon_buf_replenish(ab, buf_ring, req_entries: 1); |
1939 | status = DP_MON_TX_BUFFER_ADDR; |
1940 | break; |
1941 | } |
1942 | |
1943 | case HAL_TX_MPDU_END: |
1944 | list_add_tail(new: &tx_ppdu_info->tx_mon_mpdu->list, |
1945 | head: &tx_ppdu_info->dp_tx_mon_mpdu_list); |
1946 | break; |
1947 | } |
1948 | |
1949 | return status; |
1950 | } |
1951 | |
1952 | enum dp_mon_tx_tlv_status |
1953 | ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, |
1954 | struct hal_tlv_hdr *tx_tlv, |
1955 | u8 *num_users) |
1956 | { |
1957 | u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; |
1958 | u32 info0; |
1959 | |
1960 | switch (tlv_tag) { |
1961 | case HAL_TX_FES_SETUP: { |
1962 | struct hal_tx_fes_setup *tx_fes_setup = |
1963 | (struct hal_tx_fes_setup *)tx_tlv; |
1964 | |
1965 | info0 = __le32_to_cpu(tx_fes_setup->info0); |
1966 | |
1967 | *num_users = u32_get_bits(v: info0, HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); |
1968 | tlv_status = DP_MON_TX_FES_SETUP; |
1969 | break; |
1970 | } |
1971 | |
1972 | case HAL_RX_RESPONSE_REQUIRED_INFO: { |
1973 | /* TODO: need to update *num_users */ |
1974 | tlv_status = DP_MON_RX_RESPONSE_REQUIRED_INFO; |
1975 | break; |
1976 | } |
1977 | } |
1978 | |
1979 | return tlv_status; |
1980 | } |
1981 | |
1982 | static void |
1983 | ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar, int mac_id, |
1984 | struct napi_struct *napi, |
1985 | struct dp_mon_tx_ppdu_info *tx_ppdu_info) |
1986 | { |
1987 | struct dp_mon_mpdu *tmp, *mon_mpdu; |
1988 | struct sk_buff *head_msdu; |
1989 | |
1990 | list_for_each_entry_safe(mon_mpdu, tmp, |
1991 | &tx_ppdu_info->dp_tx_mon_mpdu_list, list) { |
1992 | list_del(entry: &mon_mpdu->list); |
1993 | head_msdu = mon_mpdu->head; |
1994 | |
1995 | if (head_msdu) |
1996 | ath12k_dp_mon_rx_deliver(ar, mac_id, head_msdu, |
1997 | ppduinfo: &tx_ppdu_info->rx_status, napi); |
1998 | |
1999 | kfree(objp: mon_mpdu); |
2000 | } |
2001 | } |
2002 | |
2003 | enum hal_rx_mon_status |
2004 | ath12k_dp_mon_tx_parse_mon_status(struct ath12k *ar, |
2005 | struct ath12k_mon_data *pmon, |
2006 | int mac_id, |
2007 | struct sk_buff *skb, |
2008 | struct napi_struct *napi, |
2009 | u32 ppdu_id) |
2010 | { |
2011 | struct ath12k_base *ab = ar->ab; |
2012 | struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info; |
2013 | struct hal_tlv_hdr *tlv; |
2014 | u8 *ptr = skb->data; |
2015 | u16 tlv_tag; |
2016 | u16 tlv_len; |
2017 | u32 tlv_userid = 0; |
2018 | u8 num_user; |
2019 | u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; |
2020 | |
2021 | tx_prot_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, |
2022 | type: DP_MON_TX_PROT_PPDU_INFO); |
2023 | if (!tx_prot_ppdu_info) |
2024 | return -ENOMEM; |
2025 | |
2026 | tlv = (struct hal_tlv_hdr *)ptr; |
2027 | tlv_tag = le32_get_bits(v: tlv->tl, HAL_TLV_HDR_TAG); |
2028 | |
2029 | tlv_status = ath12k_dp_mon_tx_status_get_num_user(tlv_tag, tx_tlv: tlv, num_users: &num_user); |
2030 | if (tlv_status == DP_MON_TX_STATUS_PPDU_NOT_DONE || !num_user) |
2031 | return -EINVAL; |
2032 | |
2033 | tx_data_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, |
2034 | type: DP_MON_TX_DATA_PPDU_INFO); |
2035 | if (!tx_data_ppdu_info) |
2036 | return -ENOMEM; |
2037 | |
2038 | do { |
2039 | tlv = (struct hal_tlv_hdr *)ptr; |
2040 | tlv_tag = le32_get_bits(v: tlv->tl, HAL_TLV_HDR_TAG); |
2041 | tlv_len = le32_get_bits(v: tlv->tl, HAL_TLV_HDR_LEN); |
2042 | tlv_userid = le32_get_bits(v: tlv->tl, HAL_TLV_USR_ID); |
2043 | |
2044 | tlv_status = ath12k_dp_mon_tx_parse_status_tlv(ab, pmon, |
2045 | tlv_tag, tlv_data: ptr, |
2046 | userid: tlv_userid); |
2047 | ptr += tlv_len; |
2048 | ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); |
2049 | if ((ptr - skb->data) >= DP_TX_MONITOR_BUF_SIZE) |
2050 | break; |
2051 | } while (tlv_status != DP_MON_TX_FES_STATUS_END); |
2052 | |
2053 | ath12k_dp_mon_tx_process_ppdu_info(ar, mac_id, napi, tx_ppdu_info: tx_data_ppdu_info); |
2054 | ath12k_dp_mon_tx_process_ppdu_info(ar, mac_id, napi, tx_ppdu_info: tx_prot_ppdu_info); |
2055 | |
2056 | return tlv_status; |
2057 | } |
2058 | |
2059 | int ath12k_dp_mon_srng_process(struct ath12k *ar, int mac_id, int *budget, |
2060 | enum dp_monitor_mode monitor_mode, |
2061 | struct napi_struct *napi) |
2062 | { |
2063 | struct hal_mon_dest_desc *mon_dst_desc; |
2064 | struct ath12k_pdev_dp *pdev_dp = &ar->dp; |
2065 | struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; |
2066 | struct ath12k_base *ab = ar->ab; |
2067 | struct ath12k_dp *dp = &ab->dp; |
2068 | struct sk_buff *skb; |
2069 | struct ath12k_skb_rxcb *rxcb; |
2070 | struct dp_srng *mon_dst_ring; |
2071 | struct hal_srng *srng; |
2072 | struct dp_rxdma_mon_ring *buf_ring; |
2073 | u64 cookie; |
2074 | u32 ppdu_id; |
2075 | int num_buffs_reaped = 0, srng_id, buf_id; |
2076 | u8 dest_idx = 0, i; |
2077 | bool end_of_ppdu; |
2078 | struct hal_rx_mon_ppdu_info *ppdu_info; |
2079 | struct ath12k_peer *peer = NULL; |
2080 | |
2081 | ppdu_info = &pmon->mon_ppdu_info; |
2082 | memset(ppdu_info, 0, sizeof(*ppdu_info)); |
2083 | ppdu_info->peer_id = HAL_INVALID_PEERID; |
2084 | |
2085 | srng_id = ath12k_hw_mac_id_to_srng_id(hw: ab->hw_params, mac_id); |
2086 | |
2087 | if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) { |
2088 | mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id]; |
2089 | buf_ring = &dp->rxdma_mon_buf_ring; |
2090 | } else { |
2091 | mon_dst_ring = &pdev_dp->tx_mon_dst_ring[srng_id]; |
2092 | buf_ring = &dp->tx_mon_buf_ring; |
2093 | } |
2094 | |
2095 | srng = &ab->hal.srng_list[mon_dst_ring->ring_id]; |
2096 | |
2097 | spin_lock_bh(lock: &srng->lock); |
2098 | ath12k_hal_srng_access_begin(ab, srng); |
2099 | |
2100 | while (likely(*budget)) { |
2101 | *budget -= 1; |
2102 | mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng); |
2103 | if (unlikely(!mon_dst_desc)) |
2104 | break; |
2105 | |
2106 | cookie = le32_to_cpu(mon_dst_desc->cookie); |
2107 | buf_id = u32_get_bits(v: cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); |
2108 | |
2109 | spin_lock_bh(lock: &buf_ring->idr_lock); |
2110 | skb = idr_remove(&buf_ring->bufs_idr, id: buf_id); |
2111 | spin_unlock_bh(lock: &buf_ring->idr_lock); |
2112 | |
2113 | if (unlikely(!skb)) { |
2114 | ath12k_warn(ab, fmt: "monitor destination with invalid buf_id %d\n" , |
2115 | buf_id); |
2116 | goto move_next; |
2117 | } |
2118 | |
2119 | rxcb = ATH12K_SKB_RXCB(skb); |
2120 | dma_unmap_single(ab->dev, rxcb->paddr, |
2121 | skb->len + skb_tailroom(skb), |
2122 | DMA_FROM_DEVICE); |
2123 | |
2124 | pmon->dest_skb_q[dest_idx] = skb; |
2125 | dest_idx++; |
2126 | ppdu_id = le32_to_cpu(mon_dst_desc->ppdu_id); |
2127 | end_of_ppdu = le32_get_bits(v: mon_dst_desc->info0, |
2128 | HAL_MON_DEST_INFO0_END_OF_PPDU); |
2129 | if (!end_of_ppdu) |
2130 | continue; |
2131 | |
2132 | for (i = 0; i < dest_idx; i++) { |
2133 | skb = pmon->dest_skb_q[i]; |
2134 | |
2135 | if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) |
2136 | ath12k_dp_mon_rx_parse_mon_status(ar, pmon, mac_id, |
2137 | skb, napi); |
2138 | else |
2139 | ath12k_dp_mon_tx_parse_mon_status(ar, pmon, mac_id, |
2140 | skb, napi, ppdu_id); |
2141 | |
2142 | peer = ath12k_peer_find_by_id(ab, peer_id: ppdu_info->peer_id); |
2143 | |
2144 | if (!peer || !peer->sta) { |
2145 | ath12k_dbg(ab, ATH12K_DBG_DATA, |
2146 | "failed to find the peer with peer_id %d\n" , |
2147 | ppdu_info->peer_id); |
2148 | dev_kfree_skb_any(skb); |
2149 | continue; |
2150 | } |
2151 | |
2152 | dev_kfree_skb_any(skb); |
2153 | pmon->dest_skb_q[i] = NULL; |
2154 | } |
2155 | |
2156 | dest_idx = 0; |
2157 | move_next: |
2158 | ath12k_dp_mon_buf_replenish(ab, buf_ring, req_entries: 1); |
2159 | ath12k_hal_srng_src_get_next_entry(ab, srng); |
2160 | num_buffs_reaped++; |
2161 | } |
2162 | |
2163 | ath12k_hal_srng_access_end(ab, srng); |
2164 | spin_unlock_bh(lock: &srng->lock); |
2165 | |
2166 | return num_buffs_reaped; |
2167 | } |
2168 | |
2169 | static void |
2170 | ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_stats, |
2171 | struct hal_rx_mon_ppdu_info *ppdu_info, |
2172 | struct hal_rx_user_status *user_stats, |
2173 | u32 num_msdu) |
2174 | { |
2175 | u32 rate_idx = 0; |
2176 | u32 mcs_idx = (user_stats) ? user_stats->mcs : ppdu_info->mcs; |
2177 | u32 nss_idx = (user_stats) ? user_stats->nss - 1 : ppdu_info->nss - 1; |
2178 | u32 bw_idx = ppdu_info->bw; |
2179 | u32 gi_idx = ppdu_info->gi; |
2180 | |
2181 | if ((mcs_idx > HAL_RX_MAX_MCS_HE) || (nss_idx >= HAL_RX_MAX_NSS) || |
2182 | (bw_idx >= HAL_RX_BW_MAX) || (gi_idx >= HAL_RX_GI_MAX)) { |
2183 | return; |
2184 | } |
2185 | |
2186 | if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N || |
2187 | ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC) { |
2188 | rate_idx = mcs_idx * 8 + 8 * 10 * nss_idx; |
2189 | rate_idx += bw_idx * 2 + gi_idx; |
2190 | } else if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX) { |
2191 | gi_idx = ath12k_he_gi_to_nl80211_he_gi(sgi: ppdu_info->gi); |
2192 | rate_idx = mcs_idx * 12 + 12 * 12 * nss_idx; |
2193 | rate_idx += bw_idx * 3 + gi_idx; |
2194 | } else { |
2195 | return; |
2196 | } |
2197 | |
2198 | rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu; |
2199 | if (user_stats) |
2200 | rx_stats->byte_stats.rx_rate[rate_idx] += user_stats->mpdu_ok_byte_count; |
2201 | else |
2202 | rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len; |
2203 | } |
2204 | |
2205 | static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k *ar, |
2206 | struct ath12k_sta *arsta, |
2207 | struct hal_rx_mon_ppdu_info *ppdu_info) |
2208 | { |
2209 | struct ath12k_rx_peer_stats *rx_stats = arsta->rx_stats; |
2210 | u32 num_msdu; |
2211 | |
2212 | if (!rx_stats) |
2213 | return; |
2214 | |
2215 | arsta->rssi_comb = ppdu_info->rssi_comb; |
2216 | |
2217 | num_msdu = ppdu_info->tcp_msdu_count + ppdu_info->tcp_ack_msdu_count + |
2218 | ppdu_info->udp_msdu_count + ppdu_info->other_msdu_count; |
2219 | |
2220 | rx_stats->num_msdu += num_msdu; |
2221 | rx_stats->tcp_msdu_count += ppdu_info->tcp_msdu_count + |
2222 | ppdu_info->tcp_ack_msdu_count; |
2223 | rx_stats->udp_msdu_count += ppdu_info->udp_msdu_count; |
2224 | rx_stats->other_msdu_count += ppdu_info->other_msdu_count; |
2225 | |
2226 | if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A || |
2227 | ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) { |
2228 | ppdu_info->nss = 1; |
2229 | ppdu_info->mcs = HAL_RX_MAX_MCS; |
2230 | ppdu_info->tid = IEEE80211_NUM_TIDS; |
2231 | } |
2232 | |
2233 | if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX) |
2234 | rx_stats->coding_count[ppdu_info->ldpc] += num_msdu; |
2235 | |
2236 | if (ppdu_info->tid <= IEEE80211_NUM_TIDS) |
2237 | rx_stats->tid_count[ppdu_info->tid] += num_msdu; |
2238 | |
2239 | if (ppdu_info->preamble_type < HAL_RX_PREAMBLE_MAX) |
2240 | rx_stats->pream_cnt[ppdu_info->preamble_type] += num_msdu; |
2241 | |
2242 | if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX) |
2243 | rx_stats->reception_type[ppdu_info->reception_type] += num_msdu; |
2244 | |
2245 | if (ppdu_info->is_stbc) |
2246 | rx_stats->stbc_count += num_msdu; |
2247 | |
2248 | if (ppdu_info->beamformed) |
2249 | rx_stats->beamformed_count += num_msdu; |
2250 | |
2251 | if (ppdu_info->num_mpdu_fcs_ok > 1) |
2252 | rx_stats->ampdu_msdu_count += num_msdu; |
2253 | else |
2254 | rx_stats->non_ampdu_msdu_count += num_msdu; |
2255 | |
2256 | rx_stats->num_mpdu_fcs_ok += ppdu_info->num_mpdu_fcs_ok; |
2257 | rx_stats->num_mpdu_fcs_err += ppdu_info->num_mpdu_fcs_err; |
2258 | rx_stats->dcm_count += ppdu_info->dcm; |
2259 | |
2260 | rx_stats->rx_duration += ppdu_info->rx_duration; |
2261 | arsta->rx_duration = rx_stats->rx_duration; |
2262 | |
2263 | if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) { |
2264 | rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu; |
2265 | rx_stats->byte_stats.nss_count[ppdu_info->nss - 1] += ppdu_info->mpdu_len; |
2266 | } |
2267 | |
2268 | if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N && |
2269 | ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) { |
2270 | rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu; |
2271 | rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; |
2272 | /* To fit into rate table for HT packets */ |
2273 | ppdu_info->mcs = ppdu_info->mcs % 8; |
2274 | } |
2275 | |
2276 | if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC && |
2277 | ppdu_info->mcs <= HAL_RX_MAX_MCS_VHT) { |
2278 | rx_stats->pkt_stats.vht_mcs_count[ppdu_info->mcs] += num_msdu; |
2279 | rx_stats->byte_stats.vht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; |
2280 | } |
2281 | |
2282 | if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX && |
2283 | ppdu_info->mcs <= HAL_RX_MAX_MCS_HE) { |
2284 | rx_stats->pkt_stats.he_mcs_count[ppdu_info->mcs] += num_msdu; |
2285 | rx_stats->byte_stats.he_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len; |
2286 | } |
2287 | |
2288 | if ((ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A || |
2289 | ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) && |
2290 | ppdu_info->rate < HAL_RX_LEGACY_RATE_INVALID) { |
2291 | rx_stats->pkt_stats.legacy_count[ppdu_info->rate] += num_msdu; |
2292 | rx_stats->byte_stats.legacy_count[ppdu_info->rate] += ppdu_info->mpdu_len; |
2293 | } |
2294 | |
2295 | if (ppdu_info->gi < HAL_RX_GI_MAX) { |
2296 | rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu; |
2297 | rx_stats->byte_stats.gi_count[ppdu_info->gi] += ppdu_info->mpdu_len; |
2298 | } |
2299 | |
2300 | if (ppdu_info->bw < HAL_RX_BW_MAX) { |
2301 | rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu; |
2302 | rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len; |
2303 | } |
2304 | |
2305 | ath12k_dp_mon_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, |
2306 | NULL, num_msdu); |
2307 | } |
2308 | |
2309 | void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) |
2310 | { |
2311 | struct hal_rx_user_status *rx_user_status; |
2312 | u32 num_users, i, mu_ul_user_v0_word0, mu_ul_user_v0_word1, ru_size; |
2313 | |
2314 | if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_MIMO || |
2315 | ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || |
2316 | ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)) |
2317 | return; |
2318 | |
2319 | num_users = ppdu_info->num_users; |
2320 | if (num_users > HAL_MAX_UL_MU_USERS) |
2321 | num_users = HAL_MAX_UL_MU_USERS; |
2322 | |
2323 | for (i = 0; i < num_users; i++) { |
2324 | rx_user_status = &ppdu_info->userstats[i]; |
2325 | mu_ul_user_v0_word0 = |
2326 | rx_user_status->ul_ofdma_user_v0_word0; |
2327 | mu_ul_user_v0_word1 = |
2328 | rx_user_status->ul_ofdma_user_v0_word1; |
2329 | |
2330 | if (u32_get_bits(v: mu_ul_user_v0_word0, |
2331 | HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID) && |
2332 | !u32_get_bits(v: mu_ul_user_v0_word0, |
2333 | HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER)) { |
2334 | rx_user_status->mcs = |
2335 | u32_get_bits(v: mu_ul_user_v0_word1, |
2336 | HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS); |
2337 | rx_user_status->nss = |
2338 | u32_get_bits(v: mu_ul_user_v0_word1, |
2339 | HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS) + 1; |
2340 | |
2341 | rx_user_status->ofdma_info_valid = 1; |
2342 | rx_user_status->ul_ofdma_ru_start_index = |
2343 | u32_get_bits(v: mu_ul_user_v0_word1, |
2344 | HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START); |
2345 | |
2346 | ru_size = u32_get_bits(v: mu_ul_user_v0_word1, |
2347 | HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE); |
2348 | rx_user_status->ul_ofdma_ru_width = ru_size; |
2349 | rx_user_status->ul_ofdma_ru_size = ru_size; |
2350 | } |
2351 | rx_user_status->ldpc = u32_get_bits(v: mu_ul_user_v0_word1, |
2352 | HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC); |
2353 | } |
2354 | ppdu_info->ldpc = 1; |
2355 | } |
2356 | |
2357 | static void |
2358 | ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar, |
2359 | struct hal_rx_mon_ppdu_info *ppdu_info, |
2360 | u32 uid) |
2361 | { |
2362 | struct ath12k_sta *arsta = NULL; |
2363 | struct ath12k_rx_peer_stats *rx_stats = NULL; |
2364 | struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid]; |
2365 | struct ath12k_peer *peer; |
2366 | u32 num_msdu; |
2367 | |
2368 | if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF) |
2369 | return; |
2370 | |
2371 | peer = ath12k_peer_find_by_ast(ab: ar->ab, ast_hash: user_stats->ast_index); |
2372 | |
2373 | if (!peer) { |
2374 | ath12k_warn(ab: ar->ab, fmt: "peer ast idx %d can't be found\n" , |
2375 | user_stats->ast_index); |
2376 | return; |
2377 | } |
2378 | |
2379 | arsta = ath12k_sta_to_arsta(sta: peer->sta); |
2380 | rx_stats = arsta->rx_stats; |
2381 | |
2382 | if (!rx_stats) |
2383 | return; |
2384 | |
2385 | arsta->rssi_comb = ppdu_info->rssi_comb; |
2386 | |
2387 | num_msdu = user_stats->tcp_msdu_count + user_stats->tcp_ack_msdu_count + |
2388 | user_stats->udp_msdu_count + user_stats->other_msdu_count; |
2389 | |
2390 | rx_stats->num_msdu += num_msdu; |
2391 | rx_stats->tcp_msdu_count += user_stats->tcp_msdu_count + |
2392 | user_stats->tcp_ack_msdu_count; |
2393 | rx_stats->udp_msdu_count += user_stats->udp_msdu_count; |
2394 | rx_stats->other_msdu_count += user_stats->other_msdu_count; |
2395 | |
2396 | if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX) |
2397 | rx_stats->coding_count[ppdu_info->ldpc] += num_msdu; |
2398 | |
2399 | if (user_stats->tid <= IEEE80211_NUM_TIDS) |
2400 | rx_stats->tid_count[user_stats->tid] += num_msdu; |
2401 | |
2402 | if (user_stats->preamble_type < HAL_RX_PREAMBLE_MAX) |
2403 | rx_stats->pream_cnt[user_stats->preamble_type] += num_msdu; |
2404 | |
2405 | if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX) |
2406 | rx_stats->reception_type[ppdu_info->reception_type] += num_msdu; |
2407 | |
2408 | if (ppdu_info->is_stbc) |
2409 | rx_stats->stbc_count += num_msdu; |
2410 | |
2411 | if (ppdu_info->beamformed) |
2412 | rx_stats->beamformed_count += num_msdu; |
2413 | |
2414 | if (user_stats->mpdu_cnt_fcs_ok > 1) |
2415 | rx_stats->ampdu_msdu_count += num_msdu; |
2416 | else |
2417 | rx_stats->non_ampdu_msdu_count += num_msdu; |
2418 | |
2419 | rx_stats->num_mpdu_fcs_ok += user_stats->mpdu_cnt_fcs_ok; |
2420 | rx_stats->num_mpdu_fcs_err += user_stats->mpdu_cnt_fcs_err; |
2421 | rx_stats->dcm_count += ppdu_info->dcm; |
2422 | if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || |
2423 | ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO) |
2424 | rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu; |
2425 | |
2426 | rx_stats->rx_duration += ppdu_info->rx_duration; |
2427 | arsta->rx_duration = rx_stats->rx_duration; |
2428 | |
2429 | if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) { |
2430 | rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu; |
2431 | rx_stats->byte_stats.nss_count[user_stats->nss - 1] += |
2432 | user_stats->mpdu_ok_byte_count; |
2433 | } |
2434 | |
2435 | if (user_stats->preamble_type == HAL_RX_PREAMBLE_11AX && |
2436 | user_stats->mcs <= HAL_RX_MAX_MCS_HE) { |
2437 | rx_stats->pkt_stats.he_mcs_count[user_stats->mcs] += num_msdu; |
2438 | rx_stats->byte_stats.he_mcs_count[user_stats->mcs] += |
2439 | user_stats->mpdu_ok_byte_count; |
2440 | } |
2441 | |
2442 | if (ppdu_info->gi < HAL_RX_GI_MAX) { |
2443 | rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu; |
2444 | rx_stats->byte_stats.gi_count[ppdu_info->gi] += |
2445 | user_stats->mpdu_ok_byte_count; |
2446 | } |
2447 | |
2448 | if (ppdu_info->bw < HAL_RX_BW_MAX) { |
2449 | rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu; |
2450 | rx_stats->byte_stats.bw_count[ppdu_info->bw] += |
2451 | user_stats->mpdu_ok_byte_count; |
2452 | } |
2453 | |
2454 | ath12k_dp_mon_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, |
2455 | user_stats, num_msdu); |
2456 | } |
2457 | |
2458 | static void |
2459 | ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k *ar, |
2460 | struct hal_rx_mon_ppdu_info *ppdu_info) |
2461 | { |
2462 | u32 num_users, i; |
2463 | |
2464 | num_users = ppdu_info->num_users; |
2465 | if (num_users > HAL_MAX_UL_MU_USERS) |
2466 | num_users = HAL_MAX_UL_MU_USERS; |
2467 | |
2468 | for (i = 0; i < num_users; i++) |
2469 | ath12k_dp_mon_rx_update_user_stats(ar, ppdu_info, uid: i); |
2470 | } |
2471 | |
2472 | int ath12k_dp_mon_rx_process_stats(struct ath12k *ar, int mac_id, |
2473 | struct napi_struct *napi, int *budget) |
2474 | { |
2475 | struct ath12k_base *ab = ar->ab; |
2476 | struct ath12k_pdev_dp *pdev_dp = &ar->dp; |
2477 | struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; |
2478 | struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; |
2479 | struct ath12k_dp *dp = &ab->dp; |
2480 | struct hal_mon_dest_desc *mon_dst_desc; |
2481 | struct sk_buff *skb; |
2482 | struct ath12k_skb_rxcb *rxcb; |
2483 | struct dp_srng *mon_dst_ring; |
2484 | struct hal_srng *srng; |
2485 | struct dp_rxdma_mon_ring *buf_ring; |
2486 | struct ath12k_sta *arsta = NULL; |
2487 | struct ath12k_peer *peer; |
2488 | u64 cookie; |
2489 | int num_buffs_reaped = 0, srng_id, buf_id; |
2490 | u8 dest_idx = 0, i; |
2491 | bool end_of_ppdu; |
2492 | u32 hal_status; |
2493 | |
2494 | srng_id = ath12k_hw_mac_id_to_srng_id(hw: ab->hw_params, mac_id); |
2495 | mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id]; |
2496 | buf_ring = &dp->rxdma_mon_buf_ring; |
2497 | |
2498 | srng = &ab->hal.srng_list[mon_dst_ring->ring_id]; |
2499 | spin_lock_bh(lock: &srng->lock); |
2500 | ath12k_hal_srng_access_begin(ab, srng); |
2501 | |
2502 | while (likely(*budget)) { |
2503 | *budget -= 1; |
2504 | mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng); |
2505 | if (unlikely(!mon_dst_desc)) |
2506 | break; |
2507 | cookie = le32_to_cpu(mon_dst_desc->cookie); |
2508 | buf_id = u32_get_bits(v: cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); |
2509 | |
2510 | spin_lock_bh(lock: &buf_ring->idr_lock); |
2511 | skb = idr_remove(&buf_ring->bufs_idr, id: buf_id); |
2512 | spin_unlock_bh(lock: &buf_ring->idr_lock); |
2513 | |
2514 | if (unlikely(!skb)) { |
2515 | ath12k_warn(ab, fmt: "monitor destination with invalid buf_id %d\n" , |
2516 | buf_id); |
2517 | goto move_next; |
2518 | } |
2519 | |
2520 | rxcb = ATH12K_SKB_RXCB(skb); |
2521 | dma_unmap_single(ab->dev, rxcb->paddr, |
2522 | skb->len + skb_tailroom(skb), |
2523 | DMA_FROM_DEVICE); |
2524 | pmon->dest_skb_q[dest_idx] = skb; |
2525 | dest_idx++; |
2526 | end_of_ppdu = le32_get_bits(v: mon_dst_desc->info0, |
2527 | HAL_MON_DEST_INFO0_END_OF_PPDU); |
2528 | if (!end_of_ppdu) |
2529 | continue; |
2530 | |
2531 | for (i = 0; i < dest_idx; i++) { |
2532 | skb = pmon->dest_skb_q[i]; |
2533 | hal_status = ath12k_dp_mon_parse_rx_dest(ab, pmon, skb); |
2534 | |
2535 | if (ppdu_info->peer_id == HAL_INVALID_PEERID || |
2536 | hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { |
2537 | dev_kfree_skb_any(skb); |
2538 | continue; |
2539 | } |
2540 | |
2541 | rcu_read_lock(); |
2542 | spin_lock_bh(lock: &ab->base_lock); |
2543 | peer = ath12k_peer_find_by_id(ab, peer_id: ppdu_info->peer_id); |
2544 | if (!peer || !peer->sta) { |
2545 | ath12k_dbg(ab, ATH12K_DBG_DATA, |
2546 | "failed to find the peer with peer_id %d\n" , |
2547 | ppdu_info->peer_id); |
2548 | spin_unlock_bh(lock: &ab->base_lock); |
2549 | rcu_read_unlock(); |
2550 | dev_kfree_skb_any(skb); |
2551 | continue; |
2552 | } |
2553 | |
2554 | if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { |
2555 | arsta = ath12k_sta_to_arsta(sta: peer->sta); |
2556 | ath12k_dp_mon_rx_update_peer_su_stats(ar, arsta, |
2557 | ppdu_info); |
2558 | } else if ((ppdu_info->fc_valid) && |
2559 | (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { |
2560 | ath12k_dp_mon_rx_process_ulofdma(ppdu_info); |
2561 | ath12k_dp_mon_rx_update_peer_mu_stats(ar, ppdu_info); |
2562 | } |
2563 | |
2564 | spin_unlock_bh(lock: &ab->base_lock); |
2565 | rcu_read_unlock(); |
2566 | dev_kfree_skb_any(skb); |
2567 | memset(ppdu_info, 0, sizeof(*ppdu_info)); |
2568 | ppdu_info->peer_id = HAL_INVALID_PEERID; |
2569 | } |
2570 | |
2571 | dest_idx = 0; |
2572 | move_next: |
2573 | ath12k_dp_mon_buf_replenish(ab, buf_ring, req_entries: 1); |
2574 | ath12k_hal_srng_src_get_next_entry(ab, srng); |
2575 | num_buffs_reaped++; |
2576 | } |
2577 | |
2578 | ath12k_hal_srng_access_end(ab, srng); |
2579 | spin_unlock_bh(lock: &srng->lock); |
2580 | return num_buffs_reaped; |
2581 | } |
2582 | |
2583 | int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id, |
2584 | struct napi_struct *napi, int budget, |
2585 | enum dp_monitor_mode monitor_mode) |
2586 | { |
2587 | struct ath12k *ar = ath12k_ab_to_ar(ab, mac_id); |
2588 | int num_buffs_reaped = 0; |
2589 | |
2590 | if (!ar->monitor_started) |
2591 | ath12k_dp_mon_rx_process_stats(ar, mac_id, napi, budget: &budget); |
2592 | else |
2593 | num_buffs_reaped = ath12k_dp_mon_srng_process(ar, mac_id, budget: &budget, |
2594 | monitor_mode, napi); |
2595 | |
2596 | return num_buffs_reaped; |
2597 | } |
2598 | |