xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/nxp/mlan/mlan_uap_txrx.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file mlan_uap_txrx.c
2  *
3  *  @brief This file contains AP mode transmit and receive functions
4  *
5  *
6  *  Copyright 2009-2021 NXP
7  *
8  *  This software file (the File) is distributed by NXP
9  *  under the terms of the GNU General Public License Version 2, June 1991
10  *  (the License).  You may use, redistribute and/or modify the File in
11  *  accordance with the terms and conditions of the License, a copy of which
12  *  is available by writing to the Free Software Foundation, Inc.,
13  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
14  *  worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
15  *
16  *  THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
17  *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
18  *  ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
19  *  this warranty disclaimer.
20  *
21  */
22 
23 /********************************************************
24 Change log:
25     02/05/2009: initial version
26 ********************************************************/
27 
28 #include "mlan.h"
29 #include "mlan_util.h"
30 #include "mlan_fw.h"
31 #ifdef STA_SUPPORT
32 #include "mlan_join.h"
33 #endif
34 #include "mlan_main.h"
35 #include "mlan_uap.h"
36 #include "mlan_wmm.h"
37 #include "mlan_11n_aggr.h"
38 #include "mlan_11n_rxreorder.h"
39 #ifdef DRV_EMBEDDED_AUTHENTICATOR
40 #include "authenticator_api.h"
41 #endif
42 
43 /********************************************************
44 			Local Functions
45 ********************************************************/
46 
47 /**
48  *  @brief This function processes received packet and forwards it
49  *          to kernel/upper layer
50  *
51  *  @param pmadapter A pointer to mlan_adapter
52  *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
53  *
54  *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
55  */
wlan_upload_uap_rx_packet(pmlan_adapter pmadapter,pmlan_buffer pmbuf)56 static mlan_status wlan_upload_uap_rx_packet(pmlan_adapter pmadapter,
57 					     pmlan_buffer pmbuf)
58 {
59 	mlan_status ret = MLAN_STATUS_SUCCESS;
60 #ifdef DEBUG_LEVEL1
61 	pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
62 #endif
63 	PRxPD prx_pd;
64 	ENTER();
65 	prx_pd = (RxPD *)(pmbuf->pbuf + pmbuf->data_offset);
66 
67 	/* Chop off RxPD */
68 	pmbuf->data_len -= prx_pd->rx_pkt_offset;
69 	pmbuf->data_offset += prx_pd->rx_pkt_offset;
70 	pmbuf->pparent = MNULL;
71 
72 	DBG_HEXDUMP(MDAT_D, "uAP RxPD", (t_u8 *)prx_pd,
73 		    MIN(sizeof(RxPD), MAX_DATA_DUMP_LEN));
74 	DBG_HEXDUMP(MDAT_D, "uAP Rx Payload",
75 		    ((t_u8 *)prx_pd + prx_pd->rx_pkt_offset),
76 		    MIN(prx_pd->rx_pkt_length, MAX_DATA_DUMP_LEN));
77 
78 	pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle,
79 						  &pmbuf->out_ts_sec,
80 						  &pmbuf->out_ts_usec);
81 	PRINTM_NETINTF(MDATA, priv);
82 	PRINTM(MDATA, "%lu.%06lu : Data => kernel seq_num=%d tid=%d\n",
83 	       pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num,
84 	       prx_pd->priority);
85 	ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle,
86 						    pmbuf);
87 	if (ret == MLAN_STATUS_FAILURE) {
88 		PRINTM(MERROR,
89 		       "uAP Rx Error: moal_recv_packet returned error\n");
90 		pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
91 	}
92 
93 	if (ret != MLAN_STATUS_PENDING)
94 		pmadapter->ops.data_complete(pmadapter, pmbuf, ret);
95 #ifdef USB
96 	else if (IS_USB(pmadapter->card_type))
97 		pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle,
98 							MNULL,
99 							pmadapter->rx_data_ep,
100 							ret);
101 #endif
102 	LEAVE();
103 
104 	return ret;
105 }
106 
107 /**
108  *  @brief This function will check if unicast packet need be dropped
109  *
110  *  @param priv    A pointer to mlan_private
111  *  @param mac     mac address to find in station list table
112  *
113  *  @return	       MLAN_STATUS_FAILURE -- drop packet, otherwise forward to
114  * network stack
115  */
wlan_check_unicast_packet(mlan_private * priv,t_u8 * mac)116 static mlan_status wlan_check_unicast_packet(mlan_private *priv, t_u8 *mac)
117 {
118 	int j;
119 	sta_node *sta_ptr = MNULL;
120 	pmlan_adapter pmadapter = priv->adapter;
121 	pmlan_private pmpriv = MNULL;
122 	t_u8 pkt_type = 0;
123 	mlan_status ret = MLAN_STATUS_SUCCESS;
124 	ENTER();
125 	for (j = 0; j < MLAN_MAX_BSS_NUM; ++j) {
126 		pmpriv = pmadapter->priv[j];
127 		if (pmpriv) {
128 			if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA)
129 				continue;
130 			sta_ptr = wlan_get_station_entry(pmpriv, mac);
131 			if (sta_ptr) {
132 				if (pmpriv == priv)
133 					pkt_type = PKT_INTRA_UCAST;
134 				else
135 					pkt_type = PKT_INTER_UCAST;
136 				break;
137 			}
138 		}
139 	}
140 	if ((pkt_type == PKT_INTRA_UCAST) &&
141 	    (priv->pkt_fwd & PKT_FWD_INTRA_UCAST)) {
142 		PRINTM(MDATA, "Drop INTRA_UCAST packet\n");
143 		ret = MLAN_STATUS_FAILURE;
144 	} else if ((pkt_type == PKT_INTER_UCAST) &&
145 		   (priv->pkt_fwd & PKT_FWD_INTER_UCAST)) {
146 		PRINTM(MDATA, "Drop INTER_UCAST packet\n");
147 		ret = MLAN_STATUS_FAILURE;
148 	}
149 	LEAVE();
150 	return ret;
151 }
152 /********************************************************
153 			Global Functions
154 ********************************************************/
155 /**
156  *  @brief This function fill the txpd for tx packet
157  *
158  *  @param priv	   A pointer to mlan_private structure
159  *  @param pmbuf   A pointer to the mlan_buffer for process
160  *
161  *  @return        headptr or MNULL
162  */
wlan_ops_uap_process_txpd(t_void * priv,pmlan_buffer pmbuf)163 t_void *wlan_ops_uap_process_txpd(t_void *priv, pmlan_buffer pmbuf)
164 {
165 	pmlan_private pmpriv = (pmlan_private)priv;
166 	TxPD *plocal_tx_pd;
167 	t_u8 *head_ptr = MNULL;
168 	t_u32 pkt_type;
169 	t_u32 tx_control;
170 	t_u8 dst_mac[MLAN_MAC_ADDR_LENGTH];
171 
172 	ENTER();
173 
174 	if (!pmbuf->data_len) {
175 		PRINTM(MERROR, "uAP Tx Error: Invalid packet length: %d\n",
176 		       pmbuf->data_len);
177 		pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
178 		goto done;
179 	}
180 	if (pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA) {
181 		memcpy_ext(pmpriv->adapter, &pkt_type,
182 			   pmbuf->pbuf + pmbuf->data_offset, sizeof(pkt_type),
183 			   sizeof(pkt_type));
184 		memcpy_ext(pmpriv->adapter, &tx_control,
185 			   pmbuf->pbuf + pmbuf->data_offset + sizeof(pkt_type),
186 			   sizeof(tx_control), sizeof(tx_control));
187 		pmbuf->data_offset += sizeof(pkt_type) + sizeof(tx_control);
188 		pmbuf->data_len -= sizeof(pkt_type) + sizeof(tx_control);
189 	}
190 	if (pmbuf->data_offset <
191 	    (sizeof(TxPD) + pmpriv->intf_hr_len + DMA_ALIGNMENT)) {
192 		PRINTM(MERROR,
193 		       "not enough space for TxPD: headroom=%d pkt_len=%d, required=%d\n",
194 		       pmbuf->data_offset, pmbuf->data_len,
195 		       sizeof(TxPD) + pmpriv->intf_hr_len + DMA_ALIGNMENT);
196 		DBG_HEXDUMP(MDAT_D, "drop pkt",
197 			    pmbuf->pbuf + pmbuf->data_offset, pmbuf->data_len);
198 		pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
199 		goto done;
200 	}
201 
202 	/* head_ptr should be aligned */
203 	head_ptr = pmbuf->pbuf + pmbuf->data_offset - sizeof(TxPD) -
204 		   pmpriv->intf_hr_len;
205 	head_ptr = (t_u8 *)((t_ptr)head_ptr & ~((t_ptr)(DMA_ALIGNMENT - 1)));
206 
207 	plocal_tx_pd = (TxPD *)(head_ptr + pmpriv->intf_hr_len);
208 	memset(pmpriv->adapter, plocal_tx_pd, 0, sizeof(TxPD));
209 
210 	/* Set the BSS number to TxPD */
211 	plocal_tx_pd->bss_num = GET_BSS_NUM(pmpriv);
212 	plocal_tx_pd->bss_type = pmpriv->bss_type;
213 
214 	plocal_tx_pd->tx_pkt_length = (t_u16)pmbuf->data_len;
215 
216 	plocal_tx_pd->priority = (t_u8)pmbuf->priority;
217 	plocal_tx_pd->pkt_delay_2ms =
218 		wlan_wmm_compute_driver_packet_delay(pmpriv, pmbuf);
219 
220 	if (plocal_tx_pd->priority <
221 	    NELEMENTS(pmpriv->wmm.user_pri_pkt_tx_ctrl))
222 		/*
223 		 * Set the priority specific tx_control field, setting of 0 will
224 		 *   cause the default value to be used later in this function
225 		 */
226 		plocal_tx_pd->tx_control =
227 			pmpriv->wmm.user_pri_pkt_tx_ctrl[plocal_tx_pd->priority];
228 
229 	if (pmbuf->flags & MLAN_BUF_FLAG_TX_STATUS) {
230 		plocal_tx_pd->tx_control_1 |= pmbuf->tx_seq_num << 8;
231 		plocal_tx_pd->flags |= MRVDRV_TxPD_FLAGS_TX_PACKET_STATUS;
232 	}
233 
234 	/* Offset of actual data */
235 	plocal_tx_pd->tx_pkt_offset = (t_u16)(
236 		(t_ptr)pmbuf->pbuf + pmbuf->data_offset - (t_ptr)plocal_tx_pd);
237 
238 	if (!plocal_tx_pd->tx_control) {
239 		/* TxCtrl set by user or default */
240 		plocal_tx_pd->tx_control = pmpriv->pkt_tx_ctrl;
241 	}
242 
243 	if (pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA) {
244 		plocal_tx_pd->tx_pkt_type = (t_u16)pkt_type;
245 		plocal_tx_pd->tx_control = tx_control;
246 	}
247 
248 	if (pmbuf->flags & MLAN_BUF_FLAG_TX_CTRL) {
249 		if (pmbuf->u.tx_info.data_rate) {
250 			memcpy_ext(pmpriv->adapter, dst_mac,
251 				   pmbuf->pbuf + pmbuf->data_offset,
252 				   sizeof(dst_mac), sizeof(dst_mac));
253 			plocal_tx_pd->tx_control |=
254 				(wlan_ieee_rateid_to_mrvl_rateid(
255 					 pmpriv, pmbuf->u.tx_info.data_rate,
256 					 dst_mac)
257 				 << 16);
258 			plocal_tx_pd->tx_control |= TXPD_TXRATE_ENABLE;
259 		}
260 		plocal_tx_pd->tx_control_1 |= pmbuf->u.tx_info.channel << 21;
261 		if (pmbuf->u.tx_info.bw) {
262 			plocal_tx_pd->tx_control_1 |= pmbuf->u.tx_info.bw << 16;
263 			plocal_tx_pd->tx_control_1 |= TXPD_BW_ENABLE;
264 		}
265 		if (pmbuf->u.tx_info.tx_power.tp.hostctl)
266 			plocal_tx_pd->tx_control |=
267 				(t_u32)pmbuf->u.tx_info.tx_power.val;
268 		if (pmbuf->u.tx_info.retry_limit) {
269 			plocal_tx_pd->tx_control |= pmbuf->u.tx_info.retry_limit
270 						    << 8;
271 			plocal_tx_pd->tx_control |= TXPD_RETRY_ENABLE;
272 		}
273 	}
274 	if (pmbuf->flags & MLAN_BUF_FLAG_MC_AGGR_PKT) {
275 		tx_ctrl *ctrl = (tx_ctrl *)&plocal_tx_pd->tx_control;
276 		mc_tx_ctrl *mc_ctrl =
277 			(mc_tx_ctrl *)&plocal_tx_pd->pkt_delay_2ms;
278 		plocal_tx_pd->tx_pkt_type = PKT_TYPE_802DOT11_MC_AGGR;
279 		if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_START_CYCLE)
280 			ctrl->mc_cycle_start = MTRUE;
281 		else
282 			ctrl->mc_cycle_start = MFALSE;
283 		if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_END_CYCLE)
284 			ctrl->mc_cycle_end = MTRUE;
285 		else
286 			ctrl->mc_cycle_end = MFALSE;
287 		if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_START_AMPDU)
288 			ctrl->mc_ampdu_start = MTRUE;
289 		else
290 			ctrl->mc_ampdu_start = MFALSE;
291 		if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_END_AMPDU)
292 			ctrl->mc_ampdu_end = MTRUE;
293 		else
294 			ctrl->mc_ampdu_end = MFALSE;
295 		if (pmbuf->u.mc_tx_info.mc_pkt_flags & MC_FLAG_RETRY)
296 			ctrl->mc_pkt_retry = MTRUE;
297 		else
298 			ctrl->mc_pkt_retry = MFALSE;
299 		ctrl->bw = pmbuf->u.mc_tx_info.bandwidth & 0x7;
300 		ctrl->tx_rate = pmbuf->u.mc_tx_info.mcs_index & 0x1f;
301 		mc_ctrl->abs_tsf_expirytime =
302 			wlan_cpu_to_le32(pmbuf->u.mc_tx_info.pkt_expiry);
303 		mc_ctrl->mc_seq = wlan_cpu_to_le16(pmbuf->u.mc_tx_info.seq_num);
304 	}
305 
306 	endian_convert_TxPD(plocal_tx_pd);
307 
308 	/* Adjust the data offset and length to include TxPD in pmbuf */
309 	pmbuf->data_len += pmbuf->data_offset;
310 	pmbuf->data_offset = (t_u32)((t_ptr)head_ptr - (t_ptr)pmbuf->pbuf);
311 	pmbuf->data_len -= pmbuf->data_offset;
312 
313 done:
314 	LEAVE();
315 	return head_ptr;
316 }
317 
318 /**
319  *  @brief This function processes received packet and forwards it
320  *          to kernel/upper layer
321  *
322  *  @param adapter   A pointer to mlan_adapter
323  *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
324  *
325  *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
326  */
wlan_ops_uap_process_rx_packet(t_void * adapter,pmlan_buffer pmbuf)327 mlan_status wlan_ops_uap_process_rx_packet(t_void *adapter, pmlan_buffer pmbuf)
328 {
329 	pmlan_adapter pmadapter = (pmlan_adapter)adapter;
330 	mlan_status ret = MLAN_STATUS_SUCCESS;
331 	RxPD *prx_pd;
332 	wlan_mgmt_pkt *puap_pkt_hdr = MNULL;
333 
334 	RxPacketHdr_t *prx_pkt;
335 	pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
336 	t_u8 ta[MLAN_MAC_ADDR_LENGTH];
337 	t_u16 rx_pkt_type = 0;
338 	sta_node *sta_ptr = MNULL;
339 #ifdef DRV_EMBEDDED_AUTHENTICATOR
340 	t_u8 eapol_type[2] = {0x88, 0x8e};
341 #endif
342 	t_u16 adj_rx_rate = 0;
343 	t_u8 antenna = 0;
344 
345 	t_u32 last_rx_sec = 0;
346 	t_u32 last_rx_usec = 0;
347 	t_u8 ext_rate_info = 0;
348 
349 	ENTER();
350 
351 	prx_pd = (RxPD *)(pmbuf->pbuf + pmbuf->data_offset);
352 	/* Endian conversion */
353 	endian_convert_RxPD(prx_pd);
354 
355 	if (prx_pd->flags & RXPD_FLAG_EXTRA_HEADER) {
356 		endian_convert_RxPD_extra_header(
357 			(rxpd_extra_info *)((t_u8 *)prx_pd + sizeof(*prx_pd)));
358 	}
359 
360 	if (priv->adapter->pcard_info->v14_fw_api) {
361 		t_u8 rxpd_rate_info_orig = prx_pd->rate_info;
362 		prx_pd->rate_info = wlan_convert_v14_rx_rate_info(
363 			priv, rxpd_rate_info_orig);
364 		PRINTM(MINFO,
365 		       "UAP RX: v14_fw_api=%d rx_rate =%d rxpd_rate_info=0x%x->0x%x\n",
366 		       priv->adapter->pcard_info->v14_fw_api, prx_pd->rx_rate,
367 		       rxpd_rate_info_orig, prx_pd->rate_info);
368 	}
369 
370 	if (priv->rx_pkt_info) {
371 		ext_rate_info = (t_u8)(prx_pd->rx_info >> 16);
372 		pmbuf->u.rx_info.data_rate =
373 			wlan_index_to_data_rate(priv->adapter, prx_pd->rx_rate,
374 						prx_pd->rate_info,
375 						ext_rate_info);
376 		pmbuf->u.rx_info.channel =
377 			(prx_pd->rx_info & RXPD_CHAN_MASK) >> 5;
378 		pmbuf->u.rx_info.antenna = prx_pd->antenna;
379 		pmbuf->u.rx_info.rssi = prx_pd->snr - prx_pd->nf;
380 	}
381 
382 	rx_pkt_type = prx_pd->rx_pkt_type;
383 	prx_pkt = (RxPacketHdr_t *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);
384 
385 	PRINTM(MINFO,
386 	       "RX Data: data_len - prx_pd->rx_pkt_offset = %d - %d = %d\n",
387 	       pmbuf->data_len, prx_pd->rx_pkt_offset,
388 	       pmbuf->data_len - prx_pd->rx_pkt_offset);
389 
390 	if ((prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length) !=
391 	    (t_u16)pmbuf->data_len) {
392 		PRINTM(MERROR,
393 		       "Wrong rx packet: len=%d,rx_pkt_offset=%d,"
394 		       " rx_pkt_length=%d\n",
395 		       pmbuf->data_len, prx_pd->rx_pkt_offset,
396 		       prx_pd->rx_pkt_length);
397 		pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
398 		ret = MLAN_STATUS_FAILURE;
399 		pmadapter->ops.data_complete(pmadapter, pmbuf, ret);
400 		goto done;
401 	}
402 	pmbuf->data_len = prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length;
403 
404 	if (pmadapter->priv[pmbuf->bss_index]->mgmt_frame_passthru_mask &&
405 	    prx_pd->rx_pkt_type == PKT_TYPE_MGMT_FRAME) {
406 		/* Check if this is mgmt packet and needs to
407 		 * forwarded to app as an event
408 		 */
409 		puap_pkt_hdr = (wlan_mgmt_pkt *)((t_u8 *)prx_pd +
410 						 prx_pd->rx_pkt_offset);
411 		puap_pkt_hdr->frm_len = wlan_le16_to_cpu(puap_pkt_hdr->frm_len);
412 		if ((puap_pkt_hdr->wlan_header.frm_ctl &
413 		     IEEE80211_FC_MGMT_FRAME_TYPE_MASK) == 0)
414 			wlan_process_802dot11_mgmt_pkt(
415 				pmadapter->priv[pmbuf->bss_index],
416 				(t_u8 *)&puap_pkt_hdr->wlan_header,
417 				puap_pkt_hdr->frm_len + sizeof(wlan_mgmt_pkt) -
418 					sizeof(puap_pkt_hdr->frm_len),
419 				(RxPD *)prx_pd);
420 		pmadapter->ops.data_complete(pmadapter, pmbuf, ret);
421 		goto done;
422 	}
423 	if (rx_pkt_type != PKT_TYPE_BAR) {
424 		priv->rxpd_rate = prx_pd->rx_rate;
425 		priv->rxpd_rate_info = prx_pd->rate_info;
426 		priv->rxpd_rx_info = (t_u8)(prx_pd->rx_info >> 16);
427 
428 		if (priv->bss_type == MLAN_BSS_TYPE_UAP) {
429 			antenna = wlan_adjust_antenna(priv, (RxPD *)prx_pd);
430 			adj_rx_rate = wlan_adjust_data_rate(
431 				priv, priv->rxpd_rate, priv->rxpd_rate_info);
432 			pmadapter->callbacks.moal_hist_data_add(
433 				pmadapter->pmoal_handle, pmbuf->bss_index,
434 				adj_rx_rate, prx_pd->snr, prx_pd->nf, antenna);
435 		}
436 	}
437 
438 	sta_ptr = wlan_get_station_entry(priv, prx_pkt->eth803_hdr.src_addr);
439 	if (sta_ptr) {
440 		sta_ptr->snr = prx_pd->snr;
441 		sta_ptr->nf = prx_pd->nf;
442 		pmadapter->callbacks.moal_get_system_time(
443 			pmadapter->pmoal_handle, &last_rx_sec, &last_rx_usec);
444 		sta_ptr->stats.last_rx_in_msec =
445 			(t_u64)last_rx_sec * 1000 + (t_u64)last_rx_usec / 1000;
446 		if (rx_pkt_type != PKT_TYPE_BAR) {
447 			sta_ptr->stats.rx_packets++;
448 			sta_ptr->stats.rx_bytes += prx_pd->rx_pkt_length;
449 		}
450 	}
451 
452 #ifdef DRV_EMBEDDED_AUTHENTICATOR
453 	/**process eapol packet for uap*/
454 	if (IsAuthenticatorEnabled(priv->psapriv) &&
455 	    (!memcmp(pmadapter, &prx_pkt->eth803_hdr.h803_len, eapol_type,
456 		     sizeof(eapol_type)))) {
457 		ret = AuthenticatorProcessEapolPacket(
458 			priv->psapriv, ((t_u8 *)prx_pd + prx_pd->rx_pkt_offset),
459 			prx_pd->rx_pkt_length);
460 		if (ret == MLAN_STATUS_SUCCESS) {
461 			pmadapter->ops.data_complete(pmadapter, pmbuf, ret);
462 			goto done;
463 		}
464 	}
465 #endif
466 
467 	pmbuf->priority |= prx_pd->priority;
468 	memcpy_ext(pmadapter, ta, prx_pkt->eth803_hdr.src_addr,
469 		   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
470 	if ((rx_pkt_type != PKT_TYPE_BAR) && (prx_pd->priority < MAX_NUM_TID)) {
471 		sta_ptr = wlan_get_station_entry(priv, ta);
472 		if (sta_ptr) {
473 			sta_ptr->rx_seq[prx_pd->priority] = prx_pd->seq_num;
474 			sta_ptr->snr = prx_pd->snr;
475 			sta_ptr->nf = prx_pd->nf;
476 		}
477 	}
478 	/* check if UAP enable 11n */
479 	if ((!priv->is_11n_enabled && !priv->is_11ax_enabled) ||
480 	    (!wlan_11n_get_rxreorder_tbl((mlan_private *)priv, prx_pd->priority,
481 					 ta) &&
482 	     (prx_pd->rx_pkt_type != PKT_TYPE_AMSDU))) {
483 		if (priv->pkt_fwd)
484 			wlan_process_uap_rx_packet(priv, pmbuf);
485 		else
486 			wlan_upload_uap_rx_packet(pmadapter, pmbuf);
487 		goto done;
488 	}
489 	/* Reorder and send to OS */
490 	ret = mlan_11n_rxreorder_pkt(priv, prx_pd->seq_num, prx_pd->priority,
491 				     ta, (t_u8)prx_pd->rx_pkt_type,
492 				     (void *)pmbuf);
493 	if (ret || (rx_pkt_type == PKT_TYPE_BAR)) {
494 		pmadapter->ops.data_complete(pmadapter, pmbuf, ret);
495 	}
496 done:
497 	LEAVE();
498 	return ret;
499 }
500 
501 /**
502  *  @brief This function processes received packet and forwards it
503  *          to kernel/upper layer or send back to firmware
504  *
505  *  @param priv      A pointer to mlan_private
506  *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
507  *
508  *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
509  */
wlan_uap_recv_packet(mlan_private * priv,pmlan_buffer pmbuf)510 mlan_status wlan_uap_recv_packet(mlan_private *priv, pmlan_buffer pmbuf)
511 {
512 	pmlan_adapter pmadapter = priv->adapter;
513 	mlan_status ret = MLAN_STATUS_SUCCESS;
514 	RxPacketHdr_t *prx_pkt;
515 	pmlan_buffer newbuf = MNULL;
516 
517 	ENTER();
518 
519 	prx_pkt = (RxPacketHdr_t *)((t_u8 *)pmbuf->pbuf + pmbuf->data_offset);
520 
521 	DBG_HEXDUMP(MDAT_D, "uap_recv_packet", pmbuf->pbuf + pmbuf->data_offset,
522 		    MIN(pmbuf->data_len, MAX_DATA_DUMP_LEN));
523 
524 	PRINTM(MDATA, "AMSDU dest " MACSTR "\n",
525 	       MAC2STR(prx_pkt->eth803_hdr.dest_addr));
526 
527 	/* don't do packet forwarding in disconnected state */
528 	if (priv->media_connected == MFALSE)
529 		goto upload;
530 
531 	if (prx_pkt->eth803_hdr.dest_addr[0] & 0x01) {
532 		if (!(priv->pkt_fwd & PKT_FWD_INTRA_BCAST)) {
533 			/* Multicast pkt */
534 			newbuf =
535 				wlan_alloc_mlan_buffer(pmadapter,
536 						       MLAN_TX_DATA_BUF_SIZE_2K,
537 						       0, MOAL_MALLOC_BUFFER);
538 			if (newbuf) {
539 				newbuf->bss_index = pmbuf->bss_index;
540 				newbuf->buf_type = pmbuf->buf_type;
541 				newbuf->priority = pmbuf->priority;
542 				newbuf->in_ts_sec = pmbuf->in_ts_sec;
543 				newbuf->in_ts_usec = pmbuf->in_ts_usec;
544 				newbuf->data_offset =
545 					(sizeof(TxPD) + priv->intf_hr_len +
546 					 DMA_ALIGNMENT);
547 				util_scalar_increment(
548 					pmadapter->pmoal_handle,
549 					&pmadapter->pending_bridge_pkts,
550 					pmadapter->callbacks.moal_spin_lock,
551 					pmadapter->callbacks.moal_spin_unlock);
552 
553 				newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;
554 
555 				/* copy the data */
556 				memcpy_ext(pmadapter,
557 					   (t_u8 *)newbuf->pbuf +
558 						   newbuf->data_offset,
559 					   pmbuf->pbuf + pmbuf->data_offset,
560 					   pmbuf->data_len,
561 					   MLAN_TX_DATA_BUF_SIZE_2K);
562 				newbuf->data_len = pmbuf->data_len;
563 				wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
564 				if (util_scalar_read(
565 					    pmadapter->pmoal_handle,
566 					    &pmadapter->pending_bridge_pkts,
567 					    pmadapter->callbacks.moal_spin_lock,
568 					    pmadapter->callbacks
569 						    .moal_spin_unlock) >
570 				    RX_HIGH_THRESHOLD)
571 					wlan_drop_tx_pkts(priv);
572 				wlan_recv_event(
573 					priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
574 					MNULL);
575 			}
576 		}
577 	} else {
578 		if ((!(priv->pkt_fwd & PKT_FWD_INTRA_UCAST)) &&
579 		    (wlan_get_station_entry(priv,
580 					    prx_pkt->eth803_hdr.dest_addr))) {
581 			/* Intra BSS packet */
582 			newbuf =
583 				wlan_alloc_mlan_buffer(pmadapter,
584 						       MLAN_TX_DATA_BUF_SIZE_2K,
585 						       0, MOAL_MALLOC_BUFFER);
586 			if (newbuf) {
587 				newbuf->bss_index = pmbuf->bss_index;
588 				newbuf->buf_type = pmbuf->buf_type;
589 				newbuf->priority = pmbuf->priority;
590 				newbuf->in_ts_sec = pmbuf->in_ts_sec;
591 				newbuf->in_ts_usec = pmbuf->in_ts_usec;
592 				newbuf->data_offset =
593 					(sizeof(TxPD) + priv->intf_hr_len +
594 					 DMA_ALIGNMENT);
595 				util_scalar_increment(
596 					pmadapter->pmoal_handle,
597 					&pmadapter->pending_bridge_pkts,
598 					pmadapter->callbacks.moal_spin_lock,
599 					pmadapter->callbacks.moal_spin_unlock);
600 				newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;
601 
602 				/* copy the data */
603 				memcpy_ext(pmadapter,
604 					   (t_u8 *)newbuf->pbuf +
605 						   newbuf->data_offset,
606 					   pmbuf->pbuf + pmbuf->data_offset,
607 					   pmbuf->data_len,
608 					   MLAN_TX_DATA_BUF_SIZE_2K);
609 				newbuf->data_len = pmbuf->data_len;
610 				wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
611 				if (util_scalar_read(
612 					    pmadapter->pmoal_handle,
613 					    &pmadapter->pending_bridge_pkts,
614 					    pmadapter->callbacks.moal_spin_lock,
615 					    pmadapter->callbacks
616 						    .moal_spin_unlock) >
617 				    RX_HIGH_THRESHOLD)
618 					wlan_drop_tx_pkts(priv);
619 				wlan_recv_event(
620 					priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
621 					MNULL);
622 			}
623 			goto done;
624 		} else if (MLAN_STATUS_FAILURE ==
625 			   wlan_check_unicast_packet(
626 				   priv, prx_pkt->eth803_hdr.dest_addr)) {
627 			/* drop packet */
628 			PRINTM(MDATA, "Drop AMSDU dest " MACSTR "\n",
629 			       MAC2STR(prx_pkt->eth803_hdr.dest_addr));
630 			goto done;
631 		}
632 	}
633 upload:
634 	/** send packet to moal */
635 	ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle,
636 						    pmbuf);
637 done:
638 	LEAVE();
639 	return ret;
640 }
641 
642 /**
643  *  @brief This function processes received packet and forwards it
644  *          to kernel/upper layer or send back to firmware
645  *
646  *  @param priv      A pointer to mlan_private
647  *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
648  *
649  *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
650  */
wlan_process_uap_rx_packet(mlan_private * priv,pmlan_buffer pmbuf)651 mlan_status wlan_process_uap_rx_packet(mlan_private *priv, pmlan_buffer pmbuf)
652 {
653 	pmlan_adapter pmadapter = priv->adapter;
654 	mlan_status ret = MLAN_STATUS_SUCCESS;
655 	RxPD *prx_pd;
656 	RxPacketHdr_t *prx_pkt;
657 	pmlan_buffer newbuf = MNULL;
658 
659 	ENTER();
660 
661 	prx_pd = (RxPD *)(pmbuf->pbuf + pmbuf->data_offset);
662 	prx_pkt = (RxPacketHdr_t *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);
663 
664 	DBG_HEXDUMP(MDAT_D, "uAP RxPD", prx_pd,
665 		    MIN(sizeof(RxPD), MAX_DATA_DUMP_LEN));
666 	DBG_HEXDUMP(MDAT_D, "uAP Rx Payload",
667 		    ((t_u8 *)prx_pd + prx_pd->rx_pkt_offset),
668 		    MIN(prx_pd->rx_pkt_length, MAX_DATA_DUMP_LEN));
669 
670 	PRINTM(MINFO,
671 	       "RX Data: data_len - prx_pd->rx_pkt_offset = %d - %d = %d\n",
672 	       pmbuf->data_len, prx_pd->rx_pkt_offset,
673 	       pmbuf->data_len - prx_pd->rx_pkt_offset);
674 	PRINTM(MDATA, "Rx dest " MACSTR "\n",
675 	       MAC2STR(prx_pkt->eth803_hdr.dest_addr));
676 
677 	if (pmadapter->enable_net_mon) {
678 		pmbuf->flags |= MLAN_BUF_FLAG_NET_MONITOR;
679 		goto upload;
680 	}
681 
682 	/* don't do packet forwarding in disconnected state */
683 	/* don't do packet forwarding when packet > 1514 */
684 	if (priv->media_connected == MFALSE)
685 		goto upload;
686 
687 	if (prx_pkt->eth803_hdr.dest_addr[0] & 0x01) {
688 		if (!(priv->pkt_fwd & PKT_FWD_INTRA_BCAST)) {
689 			/* Multicast pkt */
690 			newbuf =
691 				wlan_alloc_mlan_buffer(pmadapter,
692 						       MLAN_TX_DATA_BUF_SIZE_2K,
693 						       0, MOAL_MALLOC_BUFFER);
694 			if (newbuf) {
695 				newbuf->bss_index = pmbuf->bss_index;
696 				newbuf->buf_type = pmbuf->buf_type;
697 				newbuf->priority = pmbuf->priority;
698 				newbuf->in_ts_sec = pmbuf->in_ts_sec;
699 				newbuf->in_ts_usec = pmbuf->in_ts_usec;
700 				newbuf->data_offset =
701 					(sizeof(TxPD) + priv->intf_hr_len +
702 					 DMA_ALIGNMENT);
703 				util_scalar_increment(
704 					pmadapter->pmoal_handle,
705 					&pmadapter->pending_bridge_pkts,
706 					pmadapter->callbacks.moal_spin_lock,
707 					pmadapter->callbacks.moal_spin_unlock);
708 				newbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;
709 
710 				/* copy the data, skip rxpd */
711 				memcpy_ext(pmadapter,
712 					   (t_u8 *)newbuf->pbuf +
713 						   newbuf->data_offset,
714 					   pmbuf->pbuf + pmbuf->data_offset +
715 						   prx_pd->rx_pkt_offset,
716 					   pmbuf->data_len -
717 						   prx_pd->rx_pkt_offset,
718 					   MLAN_TX_DATA_BUF_SIZE_2K);
719 				newbuf->data_len =
720 					pmbuf->data_len - prx_pd->rx_pkt_offset;
721 				wlan_wmm_add_buf_txqueue(pmadapter, newbuf);
722 				if (util_scalar_read(
723 					    pmadapter->pmoal_handle,
724 					    &pmadapter->pending_bridge_pkts,
725 					    pmadapter->callbacks.moal_spin_lock,
726 					    pmadapter->callbacks
727 						    .moal_spin_unlock) >
728 				    RX_HIGH_THRESHOLD)
729 					wlan_drop_tx_pkts(priv);
730 				wlan_recv_event(
731 					priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
732 					MNULL);
733 			}
734 		}
735 	} else {
736 		if ((!(priv->pkt_fwd & PKT_FWD_INTRA_UCAST)) &&
737 		    (wlan_get_station_entry(priv,
738 					    prx_pkt->eth803_hdr.dest_addr))) {
739 			/* Forwarding Intra-BSS packet */
740 #ifdef USB
741 			if (IS_USB(pmadapter->card_type)) {
742 				if (pmbuf->flags & MLAN_BUF_FLAG_RX_DEAGGR) {
743 					newbuf = wlan_alloc_mlan_buffer(
744 						pmadapter,
745 						MLAN_TX_DATA_BUF_SIZE_2K, 0,
746 						MOAL_MALLOC_BUFFER);
747 					if (newbuf) {
748 						newbuf->bss_index =
749 							pmbuf->bss_index;
750 						newbuf->buf_type =
751 							pmbuf->buf_type;
752 						newbuf->priority =
753 							pmbuf->priority;
754 						newbuf->in_ts_sec =
755 							pmbuf->in_ts_sec;
756 						newbuf->in_ts_usec =
757 							pmbuf->in_ts_usec;
758 						newbuf->data_offset =
759 							(sizeof(TxPD) +
760 							 priv->intf_hr_len +
761 							 DMA_ALIGNMENT);
762 						util_scalar_increment(
763 							pmadapter->pmoal_handle,
764 							&pmadapter->pending_bridge_pkts,
765 							pmadapter->callbacks
766 								.moal_spin_lock,
767 							pmadapter->callbacks
768 								.moal_spin_unlock);
769 						newbuf->flags |=
770 							MLAN_BUF_FLAG_BRIDGE_BUF;
771 
772 						/* copy the data, skip rxpd */
773 						memcpy_ext(
774 							pmadapter,
775 							(t_u8 *)newbuf->pbuf +
776 								newbuf->data_offset,
777 							pmbuf->pbuf +
778 								pmbuf->data_offset +
779 								prx_pd->rx_pkt_offset,
780 							pmbuf->data_len -
781 								prx_pd->rx_pkt_offset,
782 							pmbuf->data_len -
783 								prx_pd->rx_pkt_offset);
784 						newbuf->data_len =
785 							pmbuf->data_len -
786 							prx_pd->rx_pkt_offset;
787 						wlan_wmm_add_buf_txqueue(
788 							pmadapter, newbuf);
789 						if (util_scalar_read(
790 							    pmadapter->pmoal_handle,
791 							    &pmadapter->pending_bridge_pkts,
792 							    pmadapter->callbacks
793 								    .moal_spin_lock,
794 							    pmadapter->callbacks
795 								    .moal_spin_unlock) >
796 						    RX_HIGH_THRESHOLD)
797 							wlan_drop_tx_pkts(priv);
798 						wlan_recv_event(
799 							priv,
800 							MLAN_EVENT_ID_DRV_DEFER_HANDLING,
801 							MNULL);
802 					}
803 					pmadapter->callbacks.moal_recv_complete(
804 						pmadapter->pmoal_handle, pmbuf,
805 						pmadapter->rx_data_ep, ret);
806 					goto done;
807 				}
808 			}
809 #endif
810 			pmbuf->data_len -= prx_pd->rx_pkt_offset;
811 			pmbuf->data_offset += prx_pd->rx_pkt_offset;
812 			pmbuf->flags |= MLAN_BUF_FLAG_BRIDGE_BUF;
813 			util_scalar_increment(
814 				pmadapter->pmoal_handle,
815 				&pmadapter->pending_bridge_pkts,
816 				pmadapter->callbacks.moal_spin_lock,
817 				pmadapter->callbacks.moal_spin_unlock);
818 			wlan_wmm_add_buf_txqueue(pmadapter, pmbuf);
819 			if (util_scalar_read(
820 				    pmadapter->pmoal_handle,
821 				    &pmadapter->pending_bridge_pkts,
822 				    pmadapter->callbacks.moal_spin_lock,
823 				    pmadapter->callbacks.moal_spin_unlock) >
824 			    RX_HIGH_THRESHOLD)
825 				wlan_drop_tx_pkts(priv);
826 			wlan_recv_event(priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
827 					MNULL);
828 			goto done;
829 		} else if (MLAN_STATUS_FAILURE ==
830 			   wlan_check_unicast_packet(
831 				   priv, prx_pkt->eth803_hdr.dest_addr)) {
832 			PRINTM(MDATA, "Drop Pkts: Rx dest " MACSTR "\n",
833 			       MAC2STR(prx_pkt->eth803_hdr.dest_addr));
834 			pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
835 			pmadapter->ops.data_complete(pmadapter, pmbuf, ret);
836 			goto done;
837 		}
838 	}
839 
840 upload:
841 	/* Chop off RxPD */
842 	pmbuf->data_len -= prx_pd->rx_pkt_offset;
843 	pmbuf->data_offset += prx_pd->rx_pkt_offset;
844 	pmbuf->pparent = MNULL;
845 
846 	pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle,
847 						  &pmbuf->out_ts_sec,
848 						  &pmbuf->out_ts_usec);
849 	PRINTM_NETINTF(MDATA, priv);
850 	PRINTM(MDATA, "%lu.%06lu : Data => kernel seq_num=%d tid=%d\n",
851 	       pmbuf->out_ts_sec, pmbuf->out_ts_usec, prx_pd->seq_num,
852 	       prx_pd->priority);
853 	if (pmbuf->flags & MLAN_BUF_FLAG_NET_MONITOR) {
854 		// Use some rxpd space to save rxpd info for radiotap header
855 		// We should insure radiotap_info is not bigger than RxPD
856 		wlan_rxpdinfo_to_radiotapinfo(
857 			priv, (RxPD *)prx_pd,
858 			(radiotap_info *)(pmbuf->pbuf + pmbuf->data_offset -
859 					  sizeof(radiotap_info)));
860 	}
861 
862 	ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle,
863 						    pmbuf);
864 	if (ret == MLAN_STATUS_FAILURE) {
865 		PRINTM(MERROR,
866 		       "uAP Rx Error: moal_recv_packet returned error\n");
867 		pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
868 	}
869 
870 	if (ret != MLAN_STATUS_PENDING)
871 		pmadapter->ops.data_complete(pmadapter, pmbuf, ret);
872 #ifdef USB
873 	else if (IS_USB(pmadapter->card_type))
874 		pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle,
875 							MNULL,
876 							pmadapter->rx_data_ep,
877 							ret);
878 #endif
879 done:
880 	LEAVE();
881 	return ret;
882 }
883