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