xref: /wlan-driver/qcacld-3.0/core/dp/htt/htt_monitor_rx.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1 /*
2  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <qdf_mem.h>         /* qdf_mem_malloc,free, etc. */
21 #include <qdf_types.h>          /* qdf_print, bool */
22 #include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
23 #include <qdf_timer.h>		/* qdf_timer_free */
24 
25 #include <htt.h>                /* HTT_HL_RX_DESC_SIZE */
26 #include <ol_cfg.h>
27 #include <ol_rx.h>
28 #include <ol_htt_rx_api.h>
29 #include <htt_internal.h>       /* HTT_ASSERT, htt_pdev_t, HTT_RX_BUF_SIZE */
30 #include "regtable.h"
31 
32 #include <cds_ieee80211_common.h>   /* ieee80211_frame, ieee80211_qoscntl */
33 #include <cds_utils.h>
34 #include <wlan_policy_mgr_api.h>
35 #include "ol_txrx_types.h"
36 #ifdef DEBUG_DMA_DONE
37 #include <asm/barrier.h>
38 #include <wma_api.h>
39 #endif
40 #include <pktlog_ac_fmt.h>
41 
42 #define HTT_FCS_LEN (4)
43 
44 enum {
45 	HW_RX_DECAP_FORMAT_RAW = 0,
46 	HW_RX_DECAP_FORMAT_NWIFI,
47 	HW_RX_DECAP_FORMAT_8023,
48 	HW_RX_DECAP_FORMAT_ETH2,
49 };
50 
51 struct mon_rx_status g_ppdu_rx_status;
52 
53 /**
54  * htt_rx_mon_note_capture_channel() - Make note of channel to update in
55  * radiotap
56  * @pdev: handle to htt_pdev
57  * @mon_ch: capture channel number.
58  *
59  * Return: None
60  */
htt_rx_mon_note_capture_channel(htt_pdev_handle pdev,int mon_ch)61 void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch)
62 {
63 	struct mon_channel *ch_info = &pdev->mon_ch_info;
64 
65 	ch_info->ch_num = mon_ch;
66 	ch_info->ch_freq = cds_chan_to_freq(mon_ch);
67 }
68 
69 #ifndef CONFIG_HL_SUPPORT
70 /**
71  * htt_mon_rx_handle_amsdu_packet() - Handle consecutive fragments of amsdu
72  * @msdu: pointer to first msdu of amsdu
73  * @pdev: Handle to htt_pdev_handle
74  * @msg_word: Input and output variable, so pointer to HTT msg pointer
75  * @amsdu_len: remaining length of all N-1 msdu msdu's
76  * @frag_cnt: number of frags handled
77  *
78  * This function handles the (N-1) msdu's of amsdu, N'th msdu is already
79  * handled by calling function. N-1 msdu's are tied using frags_list.
80  * msdu_info field updated by FW indicates if this is last msdu. All the
81  * msdu's before last msdu will be of MAX payload.
82  *
83  * Return: 1 on success and 0 on failure.
84  */
85 static
htt_mon_rx_handle_amsdu_packet(qdf_nbuf_t msdu,htt_pdev_handle pdev,uint32_t ** msg_word,uint32_t amsdu_len,uint32_t * frag_cnt)86 int htt_mon_rx_handle_amsdu_packet(qdf_nbuf_t msdu, htt_pdev_handle pdev,
87 				   uint32_t **msg_word, uint32_t amsdu_len,
88 				   uint32_t *frag_cnt)
89 {
90 	qdf_nbuf_t frag_nbuf;
91 	qdf_nbuf_t prev_frag_nbuf;
92 	uint32_t len;
93 	uint32_t last_frag;
94 	qdf_dma_addr_t paddr;
95 
96 	*msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
97 	paddr = htt_rx_in_ord_paddr_get(*msg_word);
98 	frag_nbuf = htt_rx_in_order_netbuf_pop(pdev, paddr);
99 	if (qdf_unlikely(!frag_nbuf)) {
100 		qdf_print("netbuf pop failed!");
101 		return 0;
102 	}
103 	*frag_cnt = *frag_cnt + 1;
104 	last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)*msg_word)->
105 		msdu_info;
106 	qdf_nbuf_append_ext_list(msdu, frag_nbuf, amsdu_len);
107 	qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE);
108 	qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE);
109 	/* For msdu's other than parent will not have htt_host_rx_desc_base */
110 	len = QDF_MIN(amsdu_len, HTT_RX_BUF_SIZE);
111 	amsdu_len -= len;
112 	qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len);
113 
114 	HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
115 					QDF_TRACE_LEVEL_INFO_HIGH,
116 					qdf_nbuf_data(frag_nbuf),
117 					qdf_nbuf_len(frag_nbuf)));
118 	prev_frag_nbuf = frag_nbuf;
119 	while (!last_frag) {
120 		*msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
121 		paddr = htt_rx_in_ord_paddr_get(*msg_word);
122 		frag_nbuf = htt_rx_in_order_netbuf_pop(pdev, paddr);
123 		last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
124 			     *msg_word)->msdu_info;
125 
126 		if (qdf_unlikely(!frag_nbuf)) {
127 			qdf_print("netbuf pop failed!");
128 			prev_frag_nbuf->next = NULL;
129 			return 0;
130 		}
131 		*frag_cnt = *frag_cnt + 1;
132 		qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE);
133 		qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE);
134 
135 		len = QDF_MIN(amsdu_len, HTT_RX_BUF_SIZE);
136 		amsdu_len -= len;
137 		qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len);
138 		HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
139 						QDF_TRACE_LEVEL_INFO_HIGH,
140 						qdf_nbuf_data(frag_nbuf),
141 						qdf_nbuf_len(frag_nbuf)));
142 
143 		qdf_nbuf_set_next(prev_frag_nbuf, frag_nbuf);
144 		prev_frag_nbuf = frag_nbuf;
145 	}
146 	qdf_nbuf_set_next(prev_frag_nbuf, NULL);
147 	return 1;
148 }
149 
150 #define SHORT_PREAMBLE 1
151 #define LONG_PREAMBLE  0
152 #ifdef HELIUMPLUS
153 /**
154  * htt_rx_get_rate() - get rate info in terms of 500Kbps from htt_rx_desc
155  * @l_sig_rate_select: OFDM or CCK rate
156  * @l_sig_rate:
157  *
158  * If l_sig_rate_select is 0:
159  * 0x8: OFDM 48 Mbps
160  * 0x9: OFDM 24 Mbps
161  * 0xA: OFDM 12 Mbps
162  * 0xB: OFDM 6 Mbps
163  * 0xC: OFDM 54 Mbps
164  * 0xD: OFDM 36 Mbps
165  * 0xE: OFDM 18 Mbps
166  * 0xF: OFDM 9 Mbps
167  * If l_sig_rate_select is 1:
168  * 0x1:  DSSS 1 Mbps long preamble
169  * 0x2:  DSSS 2 Mbps long preamble
170  * 0x3:  CCK 5.5 Mbps long preamble
171  * 0x4:  CCK 11 Mbps long preamble
172  * 0x5:  DSSS 2 Mbps short preamble
173  * 0x6:  CCK 5.5 Mbps
174  * 0x7:  CCK 11 Mbps short  preamble
175  *
176  * Return: rate interms of 500Kbps.
177  */
htt_rx_get_rate(uint32_t l_sig_rate_select,uint32_t l_sig_rate,uint8_t * preamble)178 static unsigned char htt_rx_get_rate(uint32_t l_sig_rate_select,
179 				     uint32_t l_sig_rate, uint8_t *preamble)
180 {
181 	char ret = 0x0;
182 	*preamble = SHORT_PREAMBLE;
183 	if (l_sig_rate_select == 0) {
184 		switch (l_sig_rate) {
185 		case 0x8:
186 			ret = 0x60;
187 			break;
188 		case 0x9:
189 			ret = 0x30;
190 			break;
191 		case 0xA:
192 			ret = 0x18;
193 			break;
194 		case 0xB:
195 			ret = 0x0c;
196 			break;
197 		case 0xC:
198 			ret = 0x6c;
199 			break;
200 		case 0xD:
201 			ret = 0x48;
202 			break;
203 		case 0xE:
204 			ret = 0x24;
205 			break;
206 		case 0xF:
207 			ret = 0x12;
208 			break;
209 		default:
210 			break;
211 		}
212 	} else if (l_sig_rate_select == 1) {
213 		switch (l_sig_rate) {
214 		case 0x1:
215 			ret = 0x2;
216 			*preamble = LONG_PREAMBLE;
217 			break;
218 		case 0x2:
219 			ret = 0x4;
220 			*preamble = LONG_PREAMBLE;
221 			break;
222 		case 0x3:
223 			ret = 0xB;
224 			*preamble = LONG_PREAMBLE;
225 			break;
226 		case 0x4:
227 			ret = 0x16;
228 			*preamble = LONG_PREAMBLE;
229 			break;
230 		case 0x5:
231 			ret = 0x4;
232 			break;
233 		case 0x6:
234 			ret = 0xB;
235 			break;
236 		case 0x7:
237 			ret = 0x16;
238 			break;
239 		default:
240 			break;
241 		}
242 	} else {
243 		qdf_print("Invalid rate info\n");
244 	}
245 	return ret;
246 }
247 #else
248 /**
249  * htt_rx_get_rate() - get rate info in terms of 500Kbps from htt_rx_desc
250  * @l_sig_rate_select: OFDM or CCK rate
251  * @l_sig_rate:
252  *
253  * If l_sig_rate_select is 0:
254  * 0x8: OFDM 48 Mbps
255  * 0x9: OFDM 24 Mbps
256  * 0xA: OFDM 12 Mbps
257  * 0xB: OFDM 6 Mbps
258  * 0xC: OFDM 54 Mbps
259  * 0xD: OFDM 36 Mbps
260  * 0xE: OFDM 18 Mbps
261  * 0xF: OFDM 9 Mbps
262  * If l_sig_rate_select is 1:
263  * 0x8: CCK 11 Mbps long preamble
264  *  0x9: CCK 5.5 Mbps long preamble
265  * 0xA: CCK 2 Mbps long preamble
266  * 0xB: CCK 1 Mbps long preamble
267  * 0xC: CCK 11 Mbps short preamble
268  * 0xD: CCK 5.5 Mbps short preamble
269  * 0xE: CCK 2 Mbps short preamble
270  *
271  * Return: rate interms of 500Kbps.
272  */
htt_rx_get_rate(uint32_t l_sig_rate_select,uint32_t l_sig_rate,uint8_t * preamble)273 static unsigned char htt_rx_get_rate(uint32_t l_sig_rate_select,
274 				     uint32_t l_sig_rate, uint8_t *preamble)
275 {
276 	char ret = 0x0;
277 	*preamble = SHORT_PREAMBLE;
278 	if (l_sig_rate_select == 0) {
279 		switch (l_sig_rate) {
280 		case 0x8:
281 			ret = 0x60;
282 			break;
283 		case 0x9:
284 			ret = 0x30;
285 			break;
286 		case 0xA:
287 			ret = 0x18;
288 			break;
289 		case 0xB:
290 			ret = 0x0c;
291 			break;
292 		case 0xC:
293 			ret = 0x6c;
294 			break;
295 		case 0xD:
296 			ret = 0x48;
297 			break;
298 		case 0xE:
299 			ret = 0x24;
300 			break;
301 		case 0xF:
302 			ret = 0x12;
303 			break;
304 		default:
305 			break;
306 		}
307 	} else if (l_sig_rate_select == 1) {
308 		switch (l_sig_rate) {
309 		case 0x8:
310 			ret = 0x16;
311 			*preamble = LONG_PREAMBLE;
312 			break;
313 		case 0x9:
314 			ret = 0x0B;
315 			*preamble = LONG_PREAMBLE;
316 			break;
317 		case 0xA:
318 			ret = 0x4;
319 			*preamble = LONG_PREAMBLE;
320 			break;
321 		case 0xB:
322 			ret = 0x02;
323 			*preamble = LONG_PREAMBLE;
324 			break;
325 		case 0xC:
326 			ret = 0x16;
327 			break;
328 		case 0xD:
329 			ret = 0x0B;
330 			break;
331 		case 0xE:
332 			ret = 0x04;
333 			break;
334 		default:
335 			break;
336 		}
337 	} else {
338 		qdf_print("Invalid rate info\n");
339 	}
340 	return ret;
341 }
342 #endif /* HELIUMPLUS */
343 
344 /**
345  * htt_mon_rx_get_phy_info() - Get phy info
346  * @rx_desc: Pointer to struct htt_host_rx_desc_base
347  * @rx_status: Return variable updated with phy_info in rx_status
348  *
349  * Return: None
350  */
htt_mon_rx_get_phy_info(struct htt_host_rx_desc_base * rx_desc,struct mon_rx_status * rx_status)351 static void htt_mon_rx_get_phy_info(struct htt_host_rx_desc_base *rx_desc,
352 				    struct mon_rx_status *rx_status)
353 {
354 	uint8_t preamble = 0;
355 	uint8_t preamble_type = rx_desc->ppdu_start.preamble_type;
356 	uint8_t mcs = 0, nss = 0, sgi = 0, bw = 0, beamformed = 0;
357 	uint16_t vht_flags = 0, ht_flags = 0;
358 	uint32_t l_sig_rate_select = rx_desc->ppdu_start.l_sig_rate_select;
359 	uint32_t l_sig_rate = rx_desc->ppdu_start.l_sig_rate;
360 	bool is_stbc = 0, ldpc = 0;
361 
362 	switch (preamble_type) {
363 	case 4:
364 	/* legacy */
365 		rx_status->rate = htt_rx_get_rate(l_sig_rate_select, l_sig_rate,
366 						&preamble);
367 		break;
368 	case 8:
369 		is_stbc = ((VHT_SIG_A_2(rx_desc) >> 4) & 3);
370 		fallthrough;
371 	case 9:
372 		ht_flags = 1;
373 		sgi = (VHT_SIG_A_2(rx_desc) >> 7) & 0x01;
374 		bw = (VHT_SIG_A_1(rx_desc) >> 7) & 0x01;
375 		mcs = (VHT_SIG_A_1(rx_desc) & 0x7f);
376 		nss = mcs >> 3;
377 		beamformed =
378 			(VHT_SIG_A_2(rx_desc) >> 8) & 0x1;
379 		break;
380 	case 0x0c:
381 		is_stbc = (VHT_SIG_A_2(rx_desc) >> 3) & 1;
382 		ldpc = (VHT_SIG_A_2(rx_desc) >> 2) & 1;
383 		fallthrough;
384 	case 0x0d:
385 	{
386 		uint8_t gid_in_sig = ((VHT_SIG_A_1(rx_desc) >> 4) & 0x3f);
387 
388 		vht_flags = 1;
389 		sgi = VHT_SIG_A_2(rx_desc) & 0x01;
390 		bw = (VHT_SIG_A_1(rx_desc) & 0x03);
391 		if (gid_in_sig == 0 || gid_in_sig == 63) {
392 			/* SU case */
393 			mcs = (VHT_SIG_A_2(rx_desc) >> 4) &
394 				0xf;
395 			nss = (VHT_SIG_A_1(rx_desc) >> 10) &
396 				0x7;
397 		} else {
398 			/* MU case */
399 			uint8_t sta_user_pos =
400 				(uint8_t)((rx_desc->ppdu_start.reserved_4a >> 8)
401 					  & 0x3);
402 			mcs = (rx_desc->ppdu_start.vht_sig_b >> 16);
403 			if (bw >= 2)
404 				mcs >>= 3;
405 			else if (bw > 0)
406 				mcs >>= 1;
407 			mcs &= 0xf;
408 			nss = (((VHT_SIG_A_1(rx_desc) >> 10) +
409 				sta_user_pos * 3) & 0x7);
410 		}
411 		beamformed = (VHT_SIG_A_2(rx_desc) >> 8) & 0x1;
412 	}
413 		fallthrough;
414 	default:
415 		break;
416 	}
417 
418 	rx_status->mcs = mcs;
419 	rx_status->bw = bw;
420 	rx_status->nr_ant = nss;
421 	rx_status->is_stbc = is_stbc;
422 	rx_status->sgi = sgi;
423 	rx_status->ldpc = ldpc;
424 	rx_status->beamformed = beamformed;
425 	rx_status->vht_flag_values3[0] = mcs << 0x4 | (nss + 1);
426 	if (ht_flags)
427 		rx_status->ht_mcs = mcs;
428 	rx_status->ht_flags = ht_flags;
429 	rx_status->vht_flags = vht_flags;
430 	rx_status->rtap_flags |= ((preamble == SHORT_PREAMBLE) ? BIT(1) : 0);
431 	rx_status->vht_flag_values2 = bw;
432 }
433 
434 /**
435  * htt_mon_rx_get_rtap_flags() - Get radiotap flags
436  * @rx_desc: Pointer to struct htt_host_rx_desc_base
437  *
438  * Return: Bitmapped radiotap flags.
439  */
htt_mon_rx_get_rtap_flags(struct htt_host_rx_desc_base * rx_desc)440 static uint8_t htt_mon_rx_get_rtap_flags(struct htt_host_rx_desc_base *rx_desc)
441 {
442 	uint8_t rtap_flags = 0;
443 
444 	/* WEP40 || WEP104 || WEP128 */
445 	if (rx_desc->mpdu_start.encrypt_type == 0 ||
446 	    rx_desc->mpdu_start.encrypt_type == 1 ||
447 	    rx_desc->mpdu_start.encrypt_type == 3)
448 		rtap_flags |= BIT(2);
449 
450 	/* IEEE80211_RADIOTAP_F_FRAG */
451 	if (rx_desc->attention.fragment)
452 		rtap_flags |= BIT(3);
453 
454 	/* IEEE80211_RADIOTAP_F_FCS */
455 	rtap_flags |= BIT(4);
456 
457 	/* IEEE80211_RADIOTAP_F_BADFCS */
458 	if (rx_desc->mpdu_end.fcs_err)
459 		rtap_flags |= BIT(6);
460 
461 	return rtap_flags;
462 }
463 
htt_rx_mon_get_rx_status(htt_pdev_handle pdev,struct htt_host_rx_desc_base * rx_desc,struct mon_rx_status * rx_status)464 void htt_rx_mon_get_rx_status(htt_pdev_handle pdev,
465 			      struct htt_host_rx_desc_base *rx_desc,
466 			      struct mon_rx_status *rx_status)
467 {
468 	struct mon_channel *ch_info = &pdev->mon_ch_info;
469 
470 	rx_status->tsft = (u_int64_t)TSF_TIMESTAMP(rx_desc);
471 	rx_status->chan_freq = ch_info->ch_freq;
472 	rx_status->chan_num = ch_info->ch_num;
473 	htt_mon_rx_get_phy_info(rx_desc, rx_status);
474 	rx_status->rtap_flags |= htt_mon_rx_get_rtap_flags(rx_desc);
475 
476 	if (rx_desc->ppdu_start.l_sig_rate_select)
477 		rx_status->cck_flag = 1;
478 	else
479 		rx_status->ofdm_flag = 1;
480 
481 	rx_status->ant_signal_db = rx_desc->ppdu_start.rssi_comb;
482 	rx_status->rssi_comb = rx_desc->ppdu_start.rssi_comb;
483 	rx_status->chan_noise_floor = pdev->txrx_pdev->chan_noise_floor;
484 }
485 
486 /**
487  * htt_rx_mon_amsdu_rx_in_order_pop_ll() - Monitor mode HTT Rx in order pop
488  * function
489  * @pdev: Handle to htt_pdev_handle
490  * @rx_ind_msg: In order indication message.
491  * @head_msdu: Return variable pointing to head msdu.
492  * @tail_msdu: Return variable pointing to tail msdu.
493  *
494  * This function pops the msdu based on paddr:length of inorder indication
495  * message.
496  *
497  * Return: 1 for success, 0 on failure.
498  */
htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,qdf_nbuf_t rx_ind_msg,qdf_nbuf_t * head_msdu,qdf_nbuf_t * tail_msdu,uint32_t * replenish_cnt)499 int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
500 					qdf_nbuf_t rx_ind_msg,
501 					qdf_nbuf_t *head_msdu,
502 					qdf_nbuf_t *tail_msdu,
503 					uint32_t *replenish_cnt)
504 {
505 	qdf_nbuf_t msdu, next, prev = NULL;
506 	uint8_t *rx_ind_data;
507 	uint32_t *msg_word;
508 	uint32_t msdu_count;
509 	struct htt_host_rx_desc_base *rx_desc;
510 	uint32_t amsdu_len;
511 	uint32_t len;
512 	uint32_t last_frag;
513 	qdf_dma_addr_t paddr;
514 	static uint8_t preamble_type;
515 	static uint32_t vht_sig_a_1;
516 	static uint32_t vht_sig_a_2;
517 
518 	HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0);
519 
520 	rx_ind_data = qdf_nbuf_data(rx_ind_msg);
521 	msg_word = (uint32_t *)rx_ind_data;
522 
523 	*replenish_cnt = 0;
524 	HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
525 					QDF_TRACE_LEVEL_INFO_HIGH,
526 					(void *)rx_ind_data,
527 					(int)qdf_nbuf_len(rx_ind_msg)));
528 
529 	/* Get the total number of MSDUs */
530 	msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1));
531 	HTT_RX_CHECK_MSDU_COUNT(msdu_count);
532 
533 	msg_word = (uint32_t *)(rx_ind_data +
534 				 HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES);
535 	paddr = htt_rx_in_ord_paddr_get(msg_word);
536 	msdu = htt_rx_in_order_netbuf_pop(pdev, paddr);
537 
538 	if (qdf_unlikely(!msdu)) {
539 		qdf_print("netbuf pop failed!");
540 		*tail_msdu = NULL;
541 		return 0;
542 	}
543 	*replenish_cnt = *replenish_cnt + 1;
544 
545 	while (msdu_count > 0) {
546 		msdu_count--;
547 		/*
548 		 * Set the netbuf length to be the entire buffer length
549 		 * initially, so the unmap will unmap the entire buffer.
550 		 */
551 		qdf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE);
552 		qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE);
553 
554 		/*
555 		 * cache consistency has been taken care of by the
556 		 * qdf_nbuf_unmap
557 		 */
558 		rx_desc = htt_rx_desc(msdu);
559 		if ((unsigned int)(*(uint32_t *)&rx_desc->attention) &
560 				RX_DESC_ATTN_MPDU_LEN_ERR_BIT) {
561 			qdf_nbuf_free(msdu);
562 			last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
563 			     msg_word)->msdu_info;
564 			while (!last_frag) {
565 				msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
566 				paddr = htt_rx_in_ord_paddr_get(msg_word);
567 				msdu = htt_rx_in_order_netbuf_pop(pdev, paddr);
568 				last_frag = ((struct
569 					htt_rx_in_ord_paddr_ind_msdu_t *)
570 					msg_word)->msdu_info;
571 				if (qdf_unlikely(!msdu)) {
572 					qdf_print("netbuf pop failed!");
573 					return 0;
574 				}
575 				*replenish_cnt = *replenish_cnt + 1;
576 				qdf_nbuf_unmap(pdev->osdev, msdu,
577 					       QDF_DMA_FROM_DEVICE);
578 				qdf_nbuf_free(msdu);
579 			}
580 			msdu = prev;
581 			goto next_pop;
582 		}
583 
584 		if (!prev)
585 			(*head_msdu) = msdu;
586 		prev = msdu;
587 
588 		HTT_PKT_DUMP(htt_print_rx_desc(rx_desc));
589 
590 		/*
591 		 * Only the first mpdu has valid preamble type, so use it
592 		 * till the last mpdu is reached
593 		 */
594 		if (rx_desc->attention.first_mpdu) {
595 			preamble_type = rx_desc->ppdu_start.preamble_type;
596 			if (preamble_type == 8 || preamble_type == 9 ||
597 			    preamble_type == 0x0c || preamble_type == 0x0d) {
598 				vht_sig_a_1 = VHT_SIG_A_1(rx_desc);
599 				vht_sig_a_2 = VHT_SIG_A_2(rx_desc);
600 			}
601 		} else {
602 			rx_desc->ppdu_start.preamble_type = preamble_type;
603 			if (preamble_type == 8 || preamble_type == 9 ||
604 			    preamble_type == 0x0c || preamble_type == 0x0d) {
605 				VHT_SIG_A_1(rx_desc) = vht_sig_a_1;
606 				VHT_SIG_A_2(rx_desc) = vht_sig_a_2;
607 			}
608 		}
609 
610 		if (rx_desc->attention.last_mpdu) {
611 			preamble_type = 0;
612 			vht_sig_a_1 = 0;
613 			vht_sig_a_2 = 0;
614 		}
615 
616 		/*
617 		 * Make the netbuf's data pointer point to the payload rather
618 		 * than the descriptor.
619 		 */
620 		if (rx_desc->attention.first_mpdu) {
621 			memset(&g_ppdu_rx_status, 0,
622 			       sizeof(struct mon_rx_status));
623 			htt_rx_mon_get_rx_status(pdev, rx_desc,
624 						 &g_ppdu_rx_status);
625 		}
626 		/*
627 		 * For certain platform, 350 bytes of headroom is already
628 		 * appended to accommodate radiotap header but
629 		 * qdf_nbuf_update_radiotap() API again will try to create
630 		 * a room for radiotap header. To make our design simple
631 		 * let qdf_nbuf_update_radiotap() API create a room for radiotap
632 		 * header and update it, do qdf_nbuf_pull_head() operation and
633 		 * pull 350 bytes of headroom.
634 		 *
635 		 *
636 		 *
637 		 *               (SKB buffer)
638 		 * skb->head --> +-----------+ <-- skb->data
639 		 *               |           |     (Before pulling headroom)
640 		 *               |           |
641 		 *               |   HEAD    |  350 bytes of headroom
642 		 *               |           |
643 		 *               |           |
644 		 *               +-----------+ <-- skb->data
645 		 *               |           |     (After pulling headroom)
646 		 *               |           |
647 		 *               |   DATA    |
648 		 *               |           |
649 		 *               |           |
650 		 *               +-----------+
651 		 *               |           |
652 		 *               |           |
653 		 *               |   TAIL    |
654 		 *               |           |
655 		 *               |           |
656 		 *               +-----------+
657 		 *
658 		 */
659 		if (qdf_nbuf_head(msdu) == qdf_nbuf_data(msdu))
660 			qdf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION);
661 		qdf_nbuf_update_radiotap(&g_ppdu_rx_status, msdu,
662 					 HTT_RX_STD_DESC_RESERVATION);
663 		amsdu_len = HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_GET(*(msg_word +
664 						NEXT_FIELD_OFFSET_IN32));
665 
666 		/*
667 		 * MAX_RX_PAYLOAD_SZ when we have AMSDU packet. amsdu_len in
668 		 * which case is the total length of sum of all AMSDU's
669 		 */
670 		len = QDF_MIN(amsdu_len, MAX_RX_PAYLOAD_SZ);
671 		amsdu_len -= len;
672 		qdf_nbuf_trim_tail(msdu, HTT_RX_BUF_SIZE -
673 				   (RX_STD_DESC_SIZE + len));
674 
675 		HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
676 						QDF_TRACE_LEVEL_INFO_HIGH,
677 						qdf_nbuf_data(msdu),
678 						qdf_nbuf_len(msdu)));
679 		last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
680 			     msg_word)->msdu_info;
681 
682 		/* Handle amsdu packet */
683 		if (!last_frag) {
684 			/*
685 			 * For AMSDU packet msdu->len is sum of all the msdu's
686 			 * length, msdu->data_len is sum of length's of
687 			 * remaining msdu's other than parent.
688 			 */
689 			if (!htt_mon_rx_handle_amsdu_packet(msdu, pdev,
690 							    &msg_word,
691 							    amsdu_len,
692 							    replenish_cnt)) {
693 				qdf_print("failed to handle amsdu packet");
694 				return 0;
695 			}
696 		}
697 
698 next_pop:
699 		/* check if this is the last msdu */
700 		if (msdu_count) {
701 			msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
702 			paddr = htt_rx_in_ord_paddr_get(msg_word);
703 			next = htt_rx_in_order_netbuf_pop(pdev, paddr);
704 			if (qdf_unlikely(!next)) {
705 				qdf_print("netbuf pop failed!");
706 				*tail_msdu = NULL;
707 				return 0;
708 			}
709 			*replenish_cnt = *replenish_cnt + 1;
710 			if (msdu)
711 				qdf_nbuf_set_next(msdu, next);
712 			msdu = next;
713 		} else {
714 			*tail_msdu = msdu;
715 			if (msdu)
716 				qdf_nbuf_set_next(msdu, NULL);
717 		}
718 	}
719 
720 	return 1;
721 }
722 #endif /* CONFIG_HL_SUPPORT */
723 
724 #if defined(FEATURE_MONITOR_MODE_SUPPORT)
725 #if !defined(QCA6290_HEADERS_DEF) && !defined(QCA6390_HEADERS_DEF) && \
726     !defined(QCA6490_HEADERS_DEF) && !defined(QCA6750_HEADERS_DEF) && \
727     !defined(KIWI_HEADERS_DEF)
728 static void
htt_rx_parse_ppdu_start_status(struct htt_host_rx_desc_base * rx_desc,struct ieee80211_rx_status * rs)729 htt_rx_parse_ppdu_start_status(struct htt_host_rx_desc_base *rx_desc,
730 			       struct ieee80211_rx_status *rs)
731 {
732 	struct rx_ppdu_start *ppdu_start = &rx_desc->ppdu_start;
733 
734 	/* RSSI */
735 	rs->rs_rssi = ppdu_start->rssi_comb;
736 
737 	/* PHY rate */
738 	/*
739 	 * rs_ratephy coding
740 	 * [b3 - b0]
741 	 * 0 -> OFDM
742 	 * 1 -> CCK
743 	 * 2 -> HT
744 	 * 3 -> VHT
745 	 * OFDM / CCK
746 	 * [b7  - b4 ] => LSIG rate
747 	 * [b23 - b8 ] => service field
748 	 * (b'12 static/dynamic,
749 	 * b'14..b'13 BW for VHT)
750 	 * [b31 - b24 ] => Reserved
751 	 * HT / VHT
752 	 * [b15 - b4 ] => SIG A_2 12 LSBs
753 	 * [b31 - b16] => SIG A_1 16 LSBs
754 	 */
755 	if (ppdu_start->preamble_type == 0x4) {
756 		rs->rs_ratephy = ppdu_start->l_sig_rate_select;
757 		rs->rs_ratephy |= ppdu_start->l_sig_rate << 4;
758 		rs->rs_ratephy |= ppdu_start->service << 8;
759 	} else {
760 		rs->rs_ratephy = (ppdu_start->preamble_type & 0x4) ? 3 : 2;
761 #ifdef HELIUMPLUS
762 		rs->rs_ratephy |=
763 			(ppdu_start->ht_sig_vht_sig_ah_sig_a_2 & 0xFFF) << 4;
764 		rs->rs_ratephy |=
765 			(ppdu_start->ht_sig_vht_sig_ah_sig_a_1 & 0xFFFF) << 16;
766 #else
767 		rs->rs_ratephy |= (ppdu_start->ht_sig_vht_sig_a_2 & 0xFFF) << 4;
768 		rs->rs_ratephy |=
769 			(ppdu_start->ht_sig_vht_sig_a_1 & 0xFFFF) << 16;
770 #endif
771 	}
772 }
773 
774 /* Util fake function that has same prototype as qdf_nbuf_clone that just
775  * returns the same nbuf
776  */
htt_rx_qdf_noclone_buf(qdf_nbuf_t buf)777 static qdf_nbuf_t htt_rx_qdf_noclone_buf(qdf_nbuf_t buf)
778 {
779 	return buf;
780 }
781 
782 /* This function is used by montior mode code to restitch an MSDU list
783  * corresponding to an MPDU back into an MPDU by linking up the skbs.
784  */
785 qdf_nbuf_t
htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev,qdf_nbuf_t head_msdu,struct ieee80211_rx_status * rx_status,unsigned int clone_not_reqd)786 htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev,
787 				qdf_nbuf_t head_msdu,
788 				struct ieee80211_rx_status *rx_status,
789 				unsigned int clone_not_reqd)
790 {
791 	qdf_nbuf_t msdu, mpdu_buf, prev_buf, msdu_orig, head_frag_list_cloned;
792 	unsigned int decap_format, wifi_hdr_len, sec_hdr_len, msdu_llc_len,
793 		 mpdu_buf_len, decap_hdr_pull_bytes, frag_list_sum_len, dir,
794 		 is_amsdu, is_first_frag, amsdu_pad, msdu_len;
795 	struct htt_host_rx_desc_base *rx_desc;
796 	char *hdr_desc;
797 	unsigned char *dest;
798 	struct ieee80211_frame *wh;
799 	struct ieee80211_qoscntl *qos;
800 
801 	/* The nbuf has been pulled just beyond the status and points to the
802 	 * payload
803 	 */
804 	msdu_orig = head_msdu;
805 	rx_desc = htt_rx_desc(msdu_orig);
806 
807 	/* Fill out the rx_status from the PPDU start and end fields */
808 	if (rx_desc->attention.first_mpdu) {
809 		htt_rx_parse_ppdu_start_status(rx_desc, rx_status);
810 
811 		/* The timestamp is no longer valid - It will be valid only for
812 		 * the last MPDU
813 		 */
814 		rx_status->rs_tstamp.tsf = ~0;
815 	}
816 
817 	decap_format =
818 		GET_FIELD(&rx_desc->msdu_start, RX_MSDU_START_2_DECAP_FORMAT);
819 
820 	head_frag_list_cloned = NULL;
821 
822 	/* Easy case - The MSDU status indicates that this is a non-decapped
823 	 * packet in RAW mode.
824 	 * return
825 	 */
826 	if (decap_format == HW_RX_DECAP_FORMAT_RAW) {
827 		/* Note that this path might suffer from headroom unavailabilty,
828 		 * but the RX status is usually enough
829 		 */
830 		if (clone_not_reqd)
831 			mpdu_buf = htt_rx_qdf_noclone_buf(head_msdu);
832 		else
833 			mpdu_buf = qdf_nbuf_clone(head_msdu);
834 
835 		if (!mpdu_buf)
836 			goto mpdu_stitch_fail;
837 
838 		prev_buf = mpdu_buf;
839 
840 		frag_list_sum_len = 0;
841 		is_first_frag = 1;
842 		msdu_len = qdf_nbuf_len(mpdu_buf);
843 
844 		/* Drop the zero-length msdu */
845 		if (!msdu_len)
846 			goto mpdu_stitch_fail;
847 
848 		msdu_orig = qdf_nbuf_next(head_msdu);
849 
850 		while (msdu_orig) {
851 			/* TODO: intra AMSDU padding - do we need it ??? */
852 			if (clone_not_reqd)
853 				msdu = htt_rx_qdf_noclone_buf(msdu_orig);
854 			else
855 				msdu = qdf_nbuf_clone(msdu_orig);
856 
857 			if (!msdu)
858 				goto mpdu_stitch_fail;
859 
860 			if (is_first_frag) {
861 				is_first_frag = 0;
862 				head_frag_list_cloned = msdu;
863 			}
864 
865 			msdu_len = qdf_nbuf_len(msdu);
866 			/* Drop the zero-length msdu */
867 			if (!msdu_len)
868 				goto mpdu_stitch_fail;
869 
870 			frag_list_sum_len += msdu_len;
871 
872 			/* Maintain the linking of the cloned MSDUS */
873 			qdf_nbuf_set_next_ext(prev_buf, msdu);
874 
875 			/* Move to the next */
876 			prev_buf = msdu;
877 			msdu_orig = qdf_nbuf_next(msdu_orig);
878 		}
879 
880 		/* The last msdu length need be larger than HTT_FCS_LEN */
881 		if (msdu_len < HTT_FCS_LEN)
882 			goto mpdu_stitch_fail;
883 
884 		qdf_nbuf_trim_tail(prev_buf, HTT_FCS_LEN);
885 
886 		/* If there were more fragments to this RAW frame */
887 		if (head_frag_list_cloned) {
888 			qdf_nbuf_append_ext_list(mpdu_buf,
889 						 head_frag_list_cloned,
890 						 frag_list_sum_len);
891 		}
892 
893 		goto mpdu_stitch_done;
894 	}
895 
896 	/* Decap mode:
897 	 * Calculate the amount of header in decapped packet to knock off based
898 	 * on the decap type and the corresponding number of raw bytes to copy
899 	 * status header
900 	 */
901 
902 	hdr_desc = &rx_desc->rx_hdr_status[0];
903 
904 	/* Base size */
905 	wifi_hdr_len = sizeof(struct ieee80211_frame);
906 	wh = (struct ieee80211_frame *)hdr_desc;
907 
908 	dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
909 	if (dir == IEEE80211_FC1_DIR_DSTODS)
910 		wifi_hdr_len += 6;
911 
912 	is_amsdu = 0;
913 	if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) {
914 		qos = (struct ieee80211_qoscntl *)
915 		      (hdr_desc + wifi_hdr_len);
916 		wifi_hdr_len += 2;
917 
918 		is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU);
919 	}
920 
921 	/* TODO: Any security headers associated with MPDU */
922 	sec_hdr_len = 0;
923 
924 	/* MSDU related stuff LLC - AMSDU subframe header etc */
925 	msdu_llc_len = is_amsdu ? (14 + 8) : 8;
926 
927 	mpdu_buf_len = wifi_hdr_len + sec_hdr_len + msdu_llc_len;
928 
929 	/* "Decap" header to remove from MSDU buffer */
930 	decap_hdr_pull_bytes = 14;
931 
932 	/* Allocate a new nbuf for holding the 802.11 header retrieved from the
933 	 * status of the now decapped first msdu. Leave enough headroom for
934 	 * accommodating any radio-tap /prism like PHY header
935 	 */
936 #define HTT_MAX_MONITOR_HEADER (512)
937 	mpdu_buf = qdf_nbuf_alloc(pdev->osdev,
938 				  HTT_MAX_MONITOR_HEADER + mpdu_buf_len,
939 				  HTT_MAX_MONITOR_HEADER, 4, false);
940 
941 	if (!mpdu_buf)
942 		goto mpdu_stitch_fail;
943 
944 	/* Copy the MPDU related header and enc headers into the first buffer
945 	 * - Note that there can be a 2 byte pad between heaader and enc header
946 	 */
947 
948 	prev_buf = mpdu_buf;
949 	dest = qdf_nbuf_put_tail(prev_buf, wifi_hdr_len);
950 	if (!dest)
951 		goto mpdu_stitch_fail;
952 	qdf_mem_copy(dest, hdr_desc, wifi_hdr_len);
953 	hdr_desc += wifi_hdr_len;
954 
955 	/* NOTE - This padding is present only in the RAW header status - not
956 	 * when the MSDU data payload is in RAW format.
957 	 */
958 	/* Skip the "IV pad" */
959 	if (wifi_hdr_len & 0x3)
960 		hdr_desc += 2;
961 
962 	/* The first LLC len is copied into the MPDU buffer */
963 	frag_list_sum_len = 0;
964 	frag_list_sum_len -= msdu_llc_len;
965 
966 	msdu_orig = head_msdu;
967 	is_first_frag = 1;
968 	amsdu_pad = 0;
969 
970 	while (msdu_orig) {
971 		/* TODO: intra AMSDU padding - do we need it ??? */
972 		if (clone_not_reqd)
973 			msdu = htt_rx_qdf_noclone_buf(msdu_orig);
974 		else
975 			msdu = qdf_nbuf_clone(msdu_orig);
976 
977 		if (!msdu)
978 			goto mpdu_stitch_fail;
979 
980 		if (is_first_frag) {
981 			is_first_frag = 0;
982 			head_frag_list_cloned = msdu;
983 		} else {
984 			/* Maintain the linking of the cloned MSDUS */
985 			qdf_nbuf_set_next_ext(prev_buf, msdu);
986 
987 			/* Reload the hdr ptr only on non-first MSDUs */
988 			rx_desc = htt_rx_desc(msdu_orig);
989 			hdr_desc = &rx_desc->rx_hdr_status[0];
990 		}
991 
992 		/* Copy this buffers MSDU related status into the prev buffer */
993 		dest = qdf_nbuf_put_tail(prev_buf, msdu_llc_len + amsdu_pad);
994 		dest += amsdu_pad;
995 		qdf_mem_copy(dest, hdr_desc, msdu_llc_len);
996 
997 		/* Push the MSDU buffer beyond the decap header */
998 		qdf_nbuf_pull_head(msdu, decap_hdr_pull_bytes);
999 		frag_list_sum_len +=
1000 			msdu_llc_len + qdf_nbuf_len(msdu) + amsdu_pad;
1001 
1002 		/*
1003 		 * Set up intra-AMSDU pad to be added to start of next buffer -
1004 		 * AMSDU pad is 4 byte pad on AMSDU subframe
1005 		 */
1006 		amsdu_pad = (msdu_llc_len + qdf_nbuf_len(msdu)) & 0x3;
1007 		amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0;
1008 
1009 		/*
1010 		 * TODO FIXME How do we handle MSDUs that have fraglist - Should
1011 		 * probably iterate all the frags cloning them along the way and
1012 		 * and also updating the prev_buf pointer
1013 		 */
1014 
1015 		/* Move to the next */
1016 		prev_buf = msdu;
1017 		msdu_orig = qdf_nbuf_next(msdu_orig);
1018 	}
1019 
1020 	/* TODO: Convert this to suitable qdf routines */
1021 	qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list_cloned,
1022 				 frag_list_sum_len);
1023 
1024 mpdu_stitch_done:
1025 	/* Check if this buffer contains the PPDU end status for TSF */
1026 	if (rx_desc->attention.last_mpdu)
1027 #ifdef HELIUMPLUS
1028 		rx_status->rs_tstamp.tsf =
1029 			rx_desc->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32;
1030 #else
1031 		rx_status->rs_tstamp.tsf = rx_desc->ppdu_end.tsf_timestamp;
1032 #endif
1033 	/* All the nbufs have been linked into the ext list
1034 	 * and then unlink the nbuf list
1035 	 */
1036 	if (clone_not_reqd) {
1037 		msdu = head_msdu;
1038 		while (msdu) {
1039 			msdu_orig = msdu;
1040 			msdu = qdf_nbuf_next(msdu);
1041 			qdf_nbuf_set_next(msdu_orig, NULL);
1042 		}
1043 	}
1044 
1045 	return mpdu_buf;
1046 
1047 mpdu_stitch_fail:
1048 	/* Free these alloced buffers and the orig buffers in non-clone case */
1049 	if (!clone_not_reqd) {
1050 		/* Free the head buffer */
1051 		if (mpdu_buf)
1052 			qdf_nbuf_free(mpdu_buf);
1053 
1054 		/* Free the partial list */
1055 		while (head_frag_list_cloned) {
1056 			msdu = head_frag_list_cloned;
1057 			head_frag_list_cloned =
1058 				qdf_nbuf_next_ext(head_frag_list_cloned);
1059 			qdf_nbuf_free(msdu);
1060 		}
1061 	} else {
1062 		/* Free the alloced head buffer */
1063 		if (decap_format != HW_RX_DECAP_FORMAT_RAW)
1064 			if (mpdu_buf)
1065 				qdf_nbuf_free(mpdu_buf);
1066 
1067 		/* Free the orig buffers */
1068 		msdu = head_msdu;
1069 		while (msdu) {
1070 			msdu_orig = msdu;
1071 			msdu = qdf_nbuf_next(msdu);
1072 			qdf_nbuf_free(msdu_orig);
1073 		}
1074 	}
1075 
1076 	return NULL;
1077 }
1078 #endif
1079 #endif
1080