xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8723ds/core/rtw_xmit.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2019 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _RTW_XMIT_C_
16 
17 #include <drv_types.h>
18 #include <hal_data.h>
19 
20 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
21 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
22 
_init_txservq(struct tx_servq * ptxservq)23 static void _init_txservq(struct tx_servq *ptxservq)
24 {
25 	_rtw_init_listhead(&ptxservq->tx_pending);
26 	_rtw_init_queue(&ptxservq->sta_pending);
27 	ptxservq->qcnt = 0;
28 }
29 
30 
_rtw_init_sta_xmit_priv(struct sta_xmit_priv * psta_xmitpriv)31 void	_rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
32 {
33 
34 
35 	_rtw_memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv));
36 
37 	_rtw_spinlock_init(&psta_xmitpriv->lock);
38 
39 	/* for(i = 0 ; i < MAX_NUMBLKS; i++) */
40 	/*	_init_txservq(&(psta_xmitpriv->blk_q[i])); */
41 
42 	_init_txservq(&psta_xmitpriv->be_q);
43 	_init_txservq(&psta_xmitpriv->bk_q);
44 	_init_txservq(&psta_xmitpriv->vi_q);
45 	_init_txservq(&psta_xmitpriv->vo_q);
46 #ifdef CONFIG_RTW_MGMT_QUEUE
47 	_init_txservq(&psta_xmitpriv->mgmt_q);
48 #endif
49 	_rtw_init_listhead(&psta_xmitpriv->legacy_dz);
50 	_rtw_init_listhead(&psta_xmitpriv->apsd);
51 
52 
53 }
54 
rtw_init_xmit_block(_adapter * padapter)55 void rtw_init_xmit_block(_adapter *padapter)
56 {
57 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
58 
59 	_rtw_spinlock_init(&dvobj->xmit_block_lock);
60 	dvobj->xmit_block = XMIT_BLOCK_NONE;
61 
62 }
rtw_free_xmit_block(_adapter * padapter)63 void rtw_free_xmit_block(_adapter *padapter)
64 {
65 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
66 
67 	_rtw_spinlock_free(&dvobj->xmit_block_lock);
68 }
69 
_rtw_init_xmit_priv(struct xmit_priv * pxmitpriv,_adapter * padapter)70 s32	_rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter)
71 {
72 	int i;
73 	struct xmit_buf *pxmitbuf;
74 	struct xmit_frame *pxframe;
75 	sint	res = _SUCCESS;
76 
77 
78 	/* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
79 	/* _rtw_memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); */
80 
81 	_rtw_spinlock_init(&pxmitpriv->lock);
82 	_rtw_spinlock_init(&pxmitpriv->lock_sctx);
83 	_rtw_init_sema(&pxmitpriv->xmit_sema, 0);
84 
85 	/*
86 	Please insert all the queue initializaiton using _rtw_init_queue below
87 	*/
88 
89 	pxmitpriv->adapter = padapter;
90 
91 	/* for(i = 0 ; i < MAX_NUMBLKS; i++) */
92 	/*	_rtw_init_queue(&pxmitpriv->blk_strms[i]); */
93 
94 	_rtw_init_queue(&pxmitpriv->be_pending);
95 	_rtw_init_queue(&pxmitpriv->bk_pending);
96 	_rtw_init_queue(&pxmitpriv->vi_pending);
97 	_rtw_init_queue(&pxmitpriv->vo_pending);
98 	_rtw_init_queue(&pxmitpriv->mgmt_pending);
99 
100 	/* _rtw_init_queue(&pxmitpriv->legacy_dz_queue); */
101 	/* _rtw_init_queue(&pxmitpriv->apsd_queue); */
102 
103 	_rtw_init_queue(&pxmitpriv->free_xmit_queue);
104 #ifdef CONFIG_LAYER2_ROAMING
105 	_rtw_init_queue(&pxmitpriv->rpkt_queue);
106 #endif
107 
108 	/*
109 	Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
110 	and initialize free_xmit_frame below.
111 	Please also apply  free_txobj to link_up all the xmit_frames...
112 	*/
113 
114 	pxmitpriv->pallocated_frame_buf = rtw_zvmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
115 
116 	if (pxmitpriv->pallocated_frame_buf  == NULL) {
117 		pxmitpriv->pxmit_frame_buf = NULL;
118 		res = _FAIL;
119 		goto exit;
120 	}
121 	pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_frame_buf), 4);
122 	/* pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - */
123 	/*						((SIZE_PTR) (pxmitpriv->pallocated_frame_buf) &3); */
124 
125 	pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
126 
127 	for (i = 0; i < NR_XMITFRAME; i++) {
128 		_rtw_init_listhead(&(pxframe->list));
129 
130 		pxframe->padapter = padapter;
131 		pxframe->frame_tag = NULL_FRAMETAG;
132 
133 		pxframe->pkt = NULL;
134 
135 		pxframe->buf_addr = NULL;
136 		pxframe->pxmitbuf = NULL;
137 
138 		rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue));
139 
140 		pxframe++;
141 	}
142 
143 	pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
144 
145 	pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
146 
147 
148 	/* init xmit_buf */
149 	_rtw_init_queue(&pxmitpriv->free_xmitbuf_queue);
150 	_rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue);
151 
152 	pxmitpriv->pallocated_xmitbuf = rtw_zvmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
153 
154 	if (pxmitpriv->pallocated_xmitbuf  == NULL) {
155 		res = _FAIL;
156 		goto exit;
157 	}
158 
159 	pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmitbuf), 4);
160 	/* pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - */
161 	/*						((SIZE_PTR) (pxmitpriv->pallocated_xmitbuf) &3); */
162 
163 	pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
164 
165 	for (i = 0; i < NR_XMITBUFF; i++) {
166 		_rtw_init_listhead(&pxmitbuf->list);
167 
168 		pxmitbuf->priv_data = NULL;
169 		pxmitbuf->padapter = padapter;
170 		pxmitbuf->buf_tag = XMITBUF_DATA;
171 
172 		/* Tx buf allocation may fail sometimes, so sleep and retry. */
173 		res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
174 		if (res == _FAIL) {
175 			rtw_msleep_os(10);
176 			res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
177 			if (res == _FAIL)
178 				goto exit;
179 		}
180 
181 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
182 		pxmitbuf->phead = pxmitbuf->pbuf;
183 		pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMITBUF_SZ;
184 		pxmitbuf->len = 0;
185 		pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
186 #endif
187 
188 		pxmitbuf->flags = XMIT_VO_QUEUE;
189 
190 		rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue));
191 #ifdef DBG_XMIT_BUF
192 		pxmitbuf->no = i;
193 #endif
194 
195 		pxmitbuf++;
196 
197 	}
198 
199 	pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
200 
201 	/* init xframe_ext queue,  the same count as extbuf */
202 	_rtw_init_queue(&pxmitpriv->free_xframe_ext_queue);
203 
204 	pxmitpriv->xframe_ext_alloc_addr = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4);
205 
206 	if (pxmitpriv->xframe_ext_alloc_addr  == NULL) {
207 		pxmitpriv->xframe_ext = NULL;
208 		res = _FAIL;
209 		goto exit;
210 	}
211 	pxmitpriv->xframe_ext = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->xframe_ext_alloc_addr), 4);
212 	pxframe = (struct xmit_frame *)pxmitpriv->xframe_ext;
213 
214 	for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
215 		_rtw_init_listhead(&(pxframe->list));
216 
217 		pxframe->padapter = padapter;
218 		pxframe->frame_tag = NULL_FRAMETAG;
219 
220 		pxframe->pkt = NULL;
221 
222 		pxframe->buf_addr = NULL;
223 		pxframe->pxmitbuf = NULL;
224 
225 		pxframe->ext_tag = 1;
226 
227 		rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xframe_ext_queue.queue));
228 
229 		pxframe++;
230 	}
231 	pxmitpriv->free_xframe_ext_cnt = NR_XMIT_EXTBUFF;
232 
233 	/* Init xmit extension buff */
234 	_rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
235 
236 	pxmitpriv->pallocated_xmit_extbuf = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4);
237 
238 	if (pxmitpriv->pallocated_xmit_extbuf  == NULL) {
239 		res = _FAIL;
240 		goto exit;
241 	}
242 
243 	pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmit_extbuf), 4);
244 
245 	pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
246 
247 	for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
248 		_rtw_init_listhead(&pxmitbuf->list);
249 
250 		pxmitbuf->priv_data = NULL;
251 		pxmitbuf->padapter = padapter;
252 		pxmitbuf->buf_tag = XMITBUF_MGNT;
253 
254 		res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ, _TRUE);
255 		if (res == _FAIL) {
256 			res = _FAIL;
257 			goto exit;
258 		}
259 
260 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
261 		pxmitbuf->phead = pxmitbuf->pbuf;
262 		pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMIT_EXTBUF_SZ;
263 		pxmitbuf->len = 0;
264 		pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
265 #endif
266 
267 		rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue));
268 #ifdef DBG_XMIT_BUF_EXT
269 		pxmitbuf->no = i;
270 #endif
271 		pxmitbuf++;
272 
273 	}
274 
275 	pxmitpriv->free_xmit_extbuf_cnt = NR_XMIT_EXTBUFF;
276 
277 	for (i = 0; i < CMDBUF_MAX; i++) {
278 		pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i];
279 		if (pxmitbuf) {
280 			_rtw_init_listhead(&pxmitbuf->list);
281 
282 			pxmitbuf->priv_data = NULL;
283 			pxmitbuf->padapter = padapter;
284 			pxmitbuf->buf_tag = XMITBUF_CMD;
285 
286 			res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ, _TRUE);
287 			if (res == _FAIL) {
288 				res = _FAIL;
289 				goto exit;
290 			}
291 
292 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
293 			pxmitbuf->phead = pxmitbuf->pbuf;
294 			pxmitbuf->pend = pxmitbuf->pbuf + MAX_CMDBUF_SZ;
295 			pxmitbuf->len = 0;
296 			pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
297 #endif
298 			pxmitbuf->alloc_sz = MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ;
299 		}
300 	}
301 
302 	rtw_alloc_hwxmits(padapter);
303 	rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
304 
305 	for (i = 0; i < 4; i++)
306 		pxmitpriv->wmm_para_seq[i] = i;
307 
308 #ifdef CONFIG_USB_HCI
309 	pxmitpriv->txirp_cnt = 1;
310 
311 	_rtw_init_sema(&(pxmitpriv->tx_retevt), 0);
312 
313 	/* per AC pending irp */
314 	pxmitpriv->beq_cnt = 0;
315 	pxmitpriv->bkq_cnt = 0;
316 	pxmitpriv->viq_cnt = 0;
317 	pxmitpriv->voq_cnt = 0;
318 #endif
319 
320 
321 #ifdef CONFIG_XMIT_ACK
322 	pxmitpriv->ack_tx = _FALSE;
323 	_rtw_mutex_init(&pxmitpriv->ack_tx_mutex);
324 	rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0);
325 #endif
326 
327 #ifdef CONFIG_TX_AMSDU
328 	rtw_init_timer(&(pxmitpriv->amsdu_vo_timer), padapter,
329 		rtw_amsdu_vo_timeout_handler, padapter);
330 	pxmitpriv->amsdu_vo_timeout = RTW_AMSDU_TIMER_UNSET;
331 
332 	rtw_init_timer(&(pxmitpriv->amsdu_vi_timer), padapter,
333 		rtw_amsdu_vi_timeout_handler, padapter);
334 	pxmitpriv->amsdu_vi_timeout = RTW_AMSDU_TIMER_UNSET;
335 
336 	rtw_init_timer(&(pxmitpriv->amsdu_be_timer), padapter,
337 		rtw_amsdu_be_timeout_handler, padapter);
338 	pxmitpriv->amsdu_be_timeout = RTW_AMSDU_TIMER_UNSET;
339 
340 	rtw_init_timer(&(pxmitpriv->amsdu_bk_timer), padapter,
341 		rtw_amsdu_bk_timeout_handler, padapter);
342 	pxmitpriv->amsdu_bk_timeout = RTW_AMSDU_TIMER_UNSET;
343 
344 	pxmitpriv->amsdu_debug_set_timer = 0;
345 	pxmitpriv->amsdu_debug_timeout = 0;
346 	pxmitpriv->amsdu_debug_coalesce_one = 0;
347 	pxmitpriv->amsdu_debug_coalesce_two = 0;
348 #endif
349 #ifdef DBG_TXBD_DESC_DUMP
350 	pxmitpriv->dump_txbd_desc = 0;
351 #endif
352 	rtw_init_xmit_block(padapter);
353 	rtw_hal_init_xmit_priv(padapter);
354 
355 exit:
356 
357 
358 	return res;
359 }
360 
361 void  rtw_mfree_xmit_priv_lock(struct xmit_priv *pxmitpriv);
rtw_mfree_xmit_priv_lock(struct xmit_priv * pxmitpriv)362 void  rtw_mfree_xmit_priv_lock(struct xmit_priv *pxmitpriv)
363 {
364 	_rtw_spinlock_free(&pxmitpriv->lock);
365 	_rtw_free_sema(&pxmitpriv->xmit_sema);
366 
367 	_rtw_spinlock_free(&pxmitpriv->be_pending.lock);
368 	_rtw_spinlock_free(&pxmitpriv->bk_pending.lock);
369 	_rtw_spinlock_free(&pxmitpriv->vi_pending.lock);
370 	_rtw_spinlock_free(&pxmitpriv->vo_pending.lock);
371 	_rtw_spinlock_free(&pxmitpriv->mgmt_pending.lock);
372 
373 	/* _rtw_spinlock_free(&pxmitpriv->legacy_dz_queue.lock); */
374 	/* _rtw_spinlock_free(&pxmitpriv->apsd_queue.lock); */
375 
376 	_rtw_spinlock_free(&pxmitpriv->free_xmit_queue.lock);
377 	_rtw_spinlock_free(&pxmitpriv->free_xmitbuf_queue.lock);
378 	_rtw_spinlock_free(&pxmitpriv->pending_xmitbuf_queue.lock);
379 }
380 
381 
_rtw_free_xmit_priv(struct xmit_priv * pxmitpriv)382 void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv)
383 {
384 	int i;
385 	_adapter *padapter = pxmitpriv->adapter;
386 	struct xmit_frame	*pxmitframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
387 	struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
388 
389 
390 	rtw_hal_free_xmit_priv(padapter);
391 
392 	rtw_mfree_xmit_priv_lock(pxmitpriv);
393 
394 	if (pxmitpriv->pxmit_frame_buf == NULL)
395 		goto out;
396 
397 	for (i = 0; i < NR_XMITFRAME; i++) {
398 		rtw_os_xmit_complete(padapter, pxmitframe);
399 
400 		pxmitframe++;
401 	}
402 
403 	for (i = 0; i < NR_XMITBUFF; i++) {
404 		rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
405 
406 		pxmitbuf++;
407 	}
408 
409 	if (pxmitpriv->pallocated_frame_buf)
410 		rtw_vmfree(pxmitpriv->pallocated_frame_buf, NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
411 
412 
413 	if (pxmitpriv->pallocated_xmitbuf)
414 		rtw_vmfree(pxmitpriv->pallocated_xmitbuf, NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
415 
416 	/* free xframe_ext queue,  the same count as extbuf */
417 	if ((pxmitframe = (struct xmit_frame *)pxmitpriv->xframe_ext)) {
418 		for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
419 			rtw_os_xmit_complete(padapter, pxmitframe);
420 			pxmitframe++;
421 		}
422 	}
423 	if (pxmitpriv->xframe_ext_alloc_addr)
424 		rtw_vmfree(pxmitpriv->xframe_ext_alloc_addr, NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4);
425 	_rtw_spinlock_free(&pxmitpriv->free_xframe_ext_queue.lock);
426 
427 	/* free xmit extension buff */
428 	_rtw_spinlock_free(&pxmitpriv->free_xmit_extbuf_queue.lock);
429 #ifdef CONFIG_LAYER2_ROAMING
430 	_rtw_spinlock_free(&pxmitpriv->rpkt_queue.lock);
431 #endif
432 	pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
433 	for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
434 		rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
435 
436 		pxmitbuf++;
437 	}
438 
439 	if (pxmitpriv->pallocated_xmit_extbuf)
440 		rtw_vmfree(pxmitpriv->pallocated_xmit_extbuf, NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4);
441 
442 	for (i = 0; i < CMDBUF_MAX; i++) {
443 		pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i];
444 		if (pxmitbuf != NULL)
445 			rtw_os_xmit_resource_free(padapter, pxmitbuf, MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ , _TRUE);
446 	}
447 
448 	rtw_free_hwxmits(padapter);
449 
450 #ifdef CONFIG_XMIT_ACK
451 	_rtw_mutex_free(&pxmitpriv->ack_tx_mutex);
452 #endif
453 	rtw_free_xmit_block(padapter);
454 out:
455 	return;
456 }
457 
rtw_get_tx_bw_mode(_adapter * adapter,struct sta_info * sta)458 u8 rtw_get_tx_bw_mode(_adapter *adapter, struct sta_info *sta)
459 {
460 	u8 bw;
461 
462 	bw = sta->cmn.bw_mode;
463 	if (MLME_STATE(adapter) & WIFI_ASOC_STATE) {
464 		if (adapter->mlmeextpriv.cur_channel <= 14)
465 			bw = rtw_min(bw, ADAPTER_TX_BW_2G(adapter));
466 		else
467 			bw = rtw_min(bw, ADAPTER_TX_BW_5G(adapter));
468 	}
469 
470 	return bw;
471 }
472 
rtw_get_adapter_tx_rate_bmp_by_bw(_adapter * adapter,u8 bw,u16 * r_bmp_cck_ofdm,u32 * r_bmp_ht,u64 * r_bmp_vht)473 void rtw_get_adapter_tx_rate_bmp_by_bw(_adapter *adapter, u8 bw, u16 *r_bmp_cck_ofdm, u32 *r_bmp_ht, u64 *r_bmp_vht)
474 {
475 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
476 	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
477 	u8 fix_bw = 0xFF;
478 	u16 bmp_cck_ofdm = 0;
479 	u32 bmp_ht = 0;
480 	u64 bmp_vht = 0;
481 	int i;
482 
483 	if (adapter->fix_rate != 0xFF && adapter->fix_bw != 0xFF)
484 		fix_bw = adapter->fix_bw;
485 
486 	/* TODO: adapter->fix_rate */
487 
488 	for (i = 0; i < macid_ctl->num; i++) {
489 		if (!rtw_macid_is_used(macid_ctl, i))
490 			continue;
491 		if (!rtw_macid_is_iface_specific(macid_ctl, i, adapter))
492 			continue;
493 
494 		if (bw == CHANNEL_WIDTH_20) /* CCK, OFDM always 20MHz */
495 			bmp_cck_ofdm |= macid_ctl->rate_bmp0[i] & 0x00000FFF;
496 
497 		/* bypass mismatch bandwidth for HT, VHT */
498 		if ((fix_bw != 0xFF && fix_bw != bw) || (fix_bw == 0xFF && macid_ctl->bw[i] != bw))
499 			continue;
500 
501 		if (macid_ctl->vht_en[i])
502 			bmp_vht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
503 		else
504 			bmp_ht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
505 	}
506 
507 	/* TODO: mlmeext->tx_rate*/
508 
509 	if (r_bmp_cck_ofdm)
510 		*r_bmp_cck_ofdm = bmp_cck_ofdm;
511 	if (r_bmp_ht)
512 		*r_bmp_ht = bmp_ht;
513 	if (r_bmp_vht)
514 		*r_bmp_vht = bmp_vht;
515 }
516 
rtw_get_shared_macid_tx_rate_bmp_by_bw(struct dvobj_priv * dvobj,u8 bw,u16 * r_bmp_cck_ofdm,u32 * r_bmp_ht,u64 * r_bmp_vht)517 void rtw_get_shared_macid_tx_rate_bmp_by_bw(struct dvobj_priv *dvobj, u8 bw, u16 *r_bmp_cck_ofdm, u32 *r_bmp_ht, u64 *r_bmp_vht)
518 {
519 	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
520 	u16 bmp_cck_ofdm = 0;
521 	u32 bmp_ht = 0;
522 	u64 bmp_vht = 0;
523 	int i;
524 
525 	for (i = 0; i < macid_ctl->num; i++) {
526 		if (!rtw_macid_is_used(macid_ctl, i))
527 			continue;
528 		if (!rtw_macid_is_iface_shared(macid_ctl, i))
529 			continue;
530 
531 		if (bw == CHANNEL_WIDTH_20) /* CCK, OFDM always 20MHz */
532 			bmp_cck_ofdm |= macid_ctl->rate_bmp0[i] & 0x00000FFF;
533 
534 		/* bypass mismatch bandwidth for HT, VHT */
535 		if (macid_ctl->bw[i] != bw)
536 			continue;
537 
538 		if (macid_ctl->vht_en[i])
539 			bmp_vht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
540 		else
541 			bmp_ht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
542 	}
543 
544 	if (r_bmp_cck_ofdm)
545 		*r_bmp_cck_ofdm = bmp_cck_ofdm;
546 	if (r_bmp_ht)
547 		*r_bmp_ht = bmp_ht;
548 	if (r_bmp_vht)
549 		*r_bmp_vht = bmp_vht;
550 }
551 
rtw_get_adapter_tx_rate_bmp(_adapter * adapter,u16 r_bmp_cck_ofdm[],u32 r_bmp_ht[],u64 r_bmp_vht[])552 void rtw_get_adapter_tx_rate_bmp(_adapter *adapter, u16 r_bmp_cck_ofdm[], u32 r_bmp_ht[], u64 r_bmp_vht[])
553 {
554 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
555 	u8 bw;
556 	u16 bmp_cck_ofdm, tmp_cck_ofdm;
557 	u32 bmp_ht, tmp_ht;
558 	u64 bmp_vht, tmp_vht;
559 	int i;
560 
561 	for (bw = CHANNEL_WIDTH_20; bw <= CHANNEL_WIDTH_160; bw++) {
562 		bmp_cck_ofdm = bmp_ht = bmp_vht = 0;
563 		if (hal_is_bw_support(adapter, bw)) {
564 			{
565 				rtw_get_adapter_tx_rate_bmp_by_bw(adapter, bw, &tmp_cck_ofdm, &tmp_ht, &tmp_vht);
566 				bmp_cck_ofdm |= tmp_cck_ofdm;
567 				bmp_ht |= tmp_ht;
568 				bmp_vht |= tmp_vht;
569 			}
570 			rtw_get_shared_macid_tx_rate_bmp_by_bw(dvobj, bw, &tmp_cck_ofdm, &tmp_ht, &tmp_vht);
571 			bmp_cck_ofdm |= tmp_cck_ofdm;
572 			bmp_ht |= tmp_ht;
573 			bmp_vht |= tmp_vht;
574 		}
575 		if (bw == CHANNEL_WIDTH_20)
576 			r_bmp_cck_ofdm[bw] = bmp_cck_ofdm;
577 		if (bw <= CHANNEL_WIDTH_40)
578 			r_bmp_ht[bw] = bmp_ht;
579 		if (bw <= CHANNEL_WIDTH_160)
580 			r_bmp_vht[bw] = bmp_vht;
581 	}
582 }
583 
rtw_update_tx_rate_bmp(struct dvobj_priv * dvobj)584 void rtw_update_tx_rate_bmp(struct dvobj_priv *dvobj)
585 {
586 	struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
587 	_adapter *adapter = dvobj_get_primary_adapter(dvobj);
588 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
589 	u8 bw;
590 	u16 bmp_cck_ofdm, tmp_cck_ofdm;
591 	u32 bmp_ht, tmp_ht, ori_bmp_ht[2];
592 	u64 bmp_vht, tmp_vht, ori_bmp_vht[4];
593 	int i;
594 
595 	for (bw = CHANNEL_WIDTH_20; bw <= CHANNEL_WIDTH_160; bw++) {
596 		/* backup the original ht & vht bmp */
597 		if (bw <= CHANNEL_WIDTH_40)
598 			ori_bmp_ht[bw] = rf_ctl->rate_bmp_ht_by_bw[bw];
599 		if (bw <= CHANNEL_WIDTH_160)
600 			ori_bmp_vht[bw] = rf_ctl->rate_bmp_vht_by_bw[bw];
601 
602 		bmp_cck_ofdm = bmp_ht = bmp_vht = 0;
603 		if (hal_is_bw_support(dvobj_get_primary_adapter(dvobj), bw)) {
604 			for (i = 0; i < dvobj->iface_nums; i++) {
605 				if (!dvobj->padapters[i])
606 					continue;
607 				rtw_get_adapter_tx_rate_bmp_by_bw(dvobj->padapters[i], bw, &tmp_cck_ofdm, &tmp_ht, &tmp_vht);
608 				bmp_cck_ofdm |= tmp_cck_ofdm;
609 				bmp_ht |= tmp_ht;
610 				bmp_vht |= tmp_vht;
611 			}
612 			rtw_get_shared_macid_tx_rate_bmp_by_bw(dvobj, bw, &tmp_cck_ofdm, &tmp_ht, &tmp_vht);
613 			bmp_cck_ofdm |= tmp_cck_ofdm;
614 			bmp_ht |= tmp_ht;
615 			bmp_vht |= tmp_vht;
616 		}
617 		if (bw == CHANNEL_WIDTH_20)
618 			rf_ctl->rate_bmp_cck_ofdm = bmp_cck_ofdm;
619 		if (bw <= CHANNEL_WIDTH_40)
620 			rf_ctl->rate_bmp_ht_by_bw[bw] = bmp_ht;
621 		if (bw <= CHANNEL_WIDTH_160)
622 			rf_ctl->rate_bmp_vht_by_bw[bw] = bmp_vht;
623 	}
624 
625 #if CONFIG_TXPWR_LIMIT
626 #ifndef DBG_HIGHEST_RATE_BMP_BW_CHANGE
627 #define DBG_HIGHEST_RATE_BMP_BW_CHANGE 0
628 #endif
629 
630 	if (hal_data->txpwr_limit_loaded) {
631 		u8 ori_highest_ht_rate_bw_bmp;
632 		u8 ori_highest_vht_rate_bw_bmp;
633 		u8 highest_rate_bw;
634 		u8 highest_rate_bw_bmp;
635 		u8 update_ht_rs = _FALSE;
636 		u8 update_vht_rs = _FALSE;
637 
638 		/* backup the original ht & vht highest bw bmp */
639 		ori_highest_ht_rate_bw_bmp = rf_ctl->highest_ht_rate_bw_bmp;
640 		ori_highest_vht_rate_bw_bmp = rf_ctl->highest_vht_rate_bw_bmp;
641 
642 		highest_rate_bw_bmp = BW_CAP_20M;
643 		highest_rate_bw = CHANNEL_WIDTH_20;
644 		for (bw = CHANNEL_WIDTH_20; bw <= CHANNEL_WIDTH_40; bw++) {
645 			if (rf_ctl->rate_bmp_ht_by_bw[highest_rate_bw] < rf_ctl->rate_bmp_ht_by_bw[bw]) {
646 				highest_rate_bw_bmp = ch_width_to_bw_cap(bw);
647 				highest_rate_bw = bw;
648 			} else if (rf_ctl->rate_bmp_ht_by_bw[highest_rate_bw] == rf_ctl->rate_bmp_ht_by_bw[bw])
649 				highest_rate_bw_bmp |= ch_width_to_bw_cap(bw);
650 		}
651 		rf_ctl->highest_ht_rate_bw_bmp = highest_rate_bw_bmp;
652 
653 		if (ori_highest_ht_rate_bw_bmp != rf_ctl->highest_ht_rate_bw_bmp
654 			|| largest_bit(ori_bmp_ht[highest_rate_bw]) != largest_bit(rf_ctl->rate_bmp_ht_by_bw[highest_rate_bw])
655 		) {
656 			if (DBG_HIGHEST_RATE_BMP_BW_CHANGE) {
657 				RTW_INFO("highest_ht_rate_bw_bmp:0x%02x=>0x%02x\n", ori_highest_ht_rate_bw_bmp, rf_ctl->highest_ht_rate_bw_bmp);
658 				RTW_INFO("rate_bmp_ht_by_bw[%u]:0x%08x=>0x%08x\n", highest_rate_bw, ori_bmp_ht[highest_rate_bw], rf_ctl->rate_bmp_ht_by_bw[highest_rate_bw]);
659 			}
660 			if (rf_ctl->rate_bmp_ht_by_bw[highest_rate_bw])
661 				update_ht_rs = _TRUE;
662 		}
663 
664 		highest_rate_bw_bmp = BW_CAP_20M;
665 		highest_rate_bw = CHANNEL_WIDTH_20;
666 		for (bw = CHANNEL_WIDTH_20; bw <= CHANNEL_WIDTH_160; bw++) {
667 			if (rf_ctl->rate_bmp_vht_by_bw[highest_rate_bw] < rf_ctl->rate_bmp_vht_by_bw[bw]) {
668 				highest_rate_bw_bmp = ch_width_to_bw_cap(bw);
669 				highest_rate_bw = bw;
670 			} else if (rf_ctl->rate_bmp_vht_by_bw[highest_rate_bw] == rf_ctl->rate_bmp_vht_by_bw[bw])
671 				highest_rate_bw_bmp |= ch_width_to_bw_cap(bw);
672 		}
673 		rf_ctl->highest_vht_rate_bw_bmp = highest_rate_bw_bmp;
674 
675 		if (ori_highest_vht_rate_bw_bmp != rf_ctl->highest_vht_rate_bw_bmp
676 			|| largest_bit_64(ori_bmp_vht[highest_rate_bw]) != largest_bit_64(rf_ctl->rate_bmp_vht_by_bw[highest_rate_bw])
677 		) {
678 			if (DBG_HIGHEST_RATE_BMP_BW_CHANGE) {
679 				RTW_INFO("highest_vht_rate_bw_bmp:0x%02x=>0x%02x\n", ori_highest_vht_rate_bw_bmp, rf_ctl->highest_vht_rate_bw_bmp);
680 				RTW_INFO("rate_bmp_vht_by_bw[%u]:0x%016llx=>0x%016llx\n", highest_rate_bw, ori_bmp_vht[highest_rate_bw], rf_ctl->rate_bmp_vht_by_bw[highest_rate_bw]);
681 			}
682 			if (rf_ctl->rate_bmp_vht_by_bw[highest_rate_bw])
683 				update_vht_rs = _TRUE;
684 		}
685 
686 		/* TODO: per rfpath and rate section handling? */
687 		if (update_ht_rs == _TRUE || update_vht_rs == _TRUE)
688 			rtw_hal_update_txpwr_level(adapter);
689 	}
690 #endif /* CONFIG_TXPWR_LIMIT */
691 }
692 
rtw_get_tx_bw_bmp_of_ht_rate(struct dvobj_priv * dvobj,u8 rate,u8 max_bw)693 u8 rtw_get_tx_bw_bmp_of_ht_rate(struct dvobj_priv *dvobj, u8 rate, u8 max_bw)
694 {
695 	struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
696 	u8 bw;
697 	u8 bw_bmp = 0;
698 	u32 rate_bmp;
699 
700 	if (!IS_HT_RATE(rate)) {
701 		rtw_warn_on(1);
702 		goto exit;
703 	}
704 
705 	rate_bmp = 1 << (rate - MGN_MCS0);
706 
707 	if (max_bw > CHANNEL_WIDTH_40)
708 		max_bw = CHANNEL_WIDTH_40;
709 
710 	for (bw = CHANNEL_WIDTH_20; bw <= max_bw; bw++) {
711 		/* RA may use lower rate for retry */
712 		if (rf_ctl->rate_bmp_ht_by_bw[bw] >= rate_bmp)
713 			bw_bmp |= ch_width_to_bw_cap(bw);
714 	}
715 
716 exit:
717 	return bw_bmp;
718 }
719 
rtw_get_tx_bw_bmp_of_vht_rate(struct dvobj_priv * dvobj,u8 rate,u8 max_bw)720 u8 rtw_get_tx_bw_bmp_of_vht_rate(struct dvobj_priv *dvobj, u8 rate, u8 max_bw)
721 {
722 	struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
723 	u8 bw;
724 	u8 bw_bmp = 0;
725 	u64 rate_bmp;
726 
727 	if (!IS_VHT_RATE(rate)) {
728 		rtw_warn_on(1);
729 		goto exit;
730 	}
731 
732 	rate_bmp = BIT_ULL(rate - MGN_VHT1SS_MCS0);
733 
734 	if (max_bw > CHANNEL_WIDTH_160)
735 		max_bw = CHANNEL_WIDTH_160;
736 
737 	for (bw = CHANNEL_WIDTH_20; bw <= max_bw; bw++) {
738 		/* RA may use lower rate for retry */
739 		if (rf_ctl->rate_bmp_vht_by_bw[bw] >= rate_bmp)
740 			bw_bmp |= ch_width_to_bw_cap(bw);
741 	}
742 
743 exit:
744 	return bw_bmp;
745 }
746 
rtw_adapter_get_oper_txpwr_max_mbm(_adapter * adapter,bool eirp)747 s16 rtw_adapter_get_oper_txpwr_max_mbm(_adapter *adapter, bool eirp)
748 {
749 	s16 mbm = -100 * MBM_PDBM;
750 
751 	if (MLME_IS_ASOC(adapter)) {
752 		struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
753 		u8 ch = mlmeext->cur_channel;
754 		u8 bw = mlmeext->cur_bwmode;
755 		u8 offset = mlmeext->cur_ch_offset;
756 		u8 cch = rtw_get_center_ch(ch, bw, offset);
757 		u8 hw_rate = MRateToHwRate(mlmeext->tx_rate);
758 		u16 bmp_cck_ofdm_by_bw[1] = {0};
759 		u32 bmp_ht_by_bw[2] = {0};
760 		u64 bmp_vht_by_bw[4] = {0};
761 		u16 bmp_cck_ofdm = 0;
762 		u32 bmp_ht = 0;
763 		u64 bmp_vht = 0;
764 		int i;
765 
766 		rtw_get_adapter_tx_rate_bmp(adapter, bmp_cck_ofdm_by_bw, bmp_ht_by_bw, bmp_vht_by_bw);
767 
768 		bmp_cck_ofdm |= bmp_cck_ofdm_by_bw[0];
769 		for (i = 0; i < 2; i++)
770 			bmp_ht |= bmp_ht_by_bw[i];
771 		for (i = 0; i < 4; i++)
772 			bmp_vht |= bmp_vht_by_bw[i];
773 
774 		if (IS_LEGACY_HRATE(hw_rate))
775 			bmp_cck_ofdm |= BIT(hw_rate);
776 		else if (IS_HT_HRATE(hw_rate))
777 			bmp_ht |= BIT(hw_rate - DESC_RATEMCS0);
778 		else if (IS_VHT_HRATE(hw_rate))
779 			bmp_vht |= BIT(hw_rate - DESC_RATEVHTSS1MCS0);
780 
781 		mbm = phy_get_txpwr_total_max_mbm(adapter
782 			, bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht, 0, eirp);
783 	}
784 
785 	return mbm;
786 }
787 
rtw_rfctl_get_oper_txpwr_max_mbm(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset,u8 ifbmp_mod,u8 if_op,bool eirp)788 s16 rtw_rfctl_get_oper_txpwr_max_mbm(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u8 ifbmp_mod, u8 if_op, bool eirp)
789 {
790 	struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
791 	_adapter *adapter = dvobj_get_primary_adapter(dvobj);
792 	s16 mbm = -100 * MBM_PDBM;
793 
794 	if (ch) {
795 		u8 cch = rtw_get_center_ch(ch, bw, offset);
796 		u16 bmp_cck_ofdm = 0;
797 		u32 bmp_ht = 0;
798 		u64 bmp_vht = 0;
799 		int i;
800 
801 		for (i = 0; i < dvobj->iface_nums; i++) {
802 			struct mlme_ext_priv *mlmeext;
803 			u8 hw_rate;
804 
805 			if (!dvobj->padapters[i])
806 				continue;
807 
808 			if (ifbmp_mod & BIT(i)) {
809 				if (!if_op)
810 					continue;
811 			} else if (!MLME_IS_ASOC(dvobj->padapters[i]))
812 				continue;
813 
814 			mlmeext = &(dvobj->padapters[i]->mlmeextpriv);
815 			hw_rate = MRateToHwRate(mlmeext->tx_rate);
816 
817 			if (IS_LEGACY_HRATE(hw_rate))
818 				bmp_cck_ofdm |= BIT(hw_rate);
819 			else if (IS_HT_HRATE(hw_rate))
820 				bmp_ht |= BIT(hw_rate - DESC_RATEMCS0);
821 			else if (IS_VHT_HRATE(hw_rate))
822 				bmp_vht |= BIT(hw_rate - DESC_RATEVHTSS1MCS0);
823 		}
824 
825 		bmp_cck_ofdm |= rfctl->rate_bmp_cck_ofdm;
826 		for (i = 0; i < 2; i++)
827 			bmp_ht |= rfctl->rate_bmp_ht_by_bw[i];
828 		for (i = 0; i < 4; i++)
829 			bmp_vht |= rfctl->rate_bmp_vht_by_bw[i];
830 
831 		mbm = phy_get_txpwr_total_max_mbm(adapter
832 			, bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht, 0, eirp);
833 	}
834 
835 	return mbm;
836 }
837 
rtw_get_oper_txpwr_max_mbm(struct dvobj_priv * dvobj,bool eirp)838 s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj, bool eirp)
839 {
840 	struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj);
841 	_adapter *adapter = dvobj_get_primary_adapter(dvobj);
842 	s16 mbm = -100 * MBM_PDBM;
843 	u8 ch = rfctl->op_ch, bw, offset;
844 
845 	if (rtw_get_bw_offset_by_op_class_ch(rfctl->op_class, ch, &bw, &offset))
846 		mbm = rtw_rfctl_get_oper_txpwr_max_mbm(rfctl, ch, bw, offset, 0, 0, eirp);
847 
848 	return mbm;
849 }
850 
rtw_rfctl_get_reg_max_txpwr_mbm(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset,bool eirp)851 s16 rtw_rfctl_get_reg_max_txpwr_mbm(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, bool eirp)
852 {
853 	struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
854 	struct registry_priv *regsty = dvobj_to_regsty(dvobj);
855 	_adapter *adapter = dvobj_get_primary_adapter(dvobj);
856 	s16 mbm = -100 * MBM_PDBM;
857 	u8 cch = rtw_get_center_ch(ch, bw, offset);
858 	u16 bmp_cck_ofdm = 0;
859 	u32 bmp_ht = 0;
860 	u64 bmp_vht = 0;
861 
862 	if (ch <= 14)
863 		bmp_cck_ofdm |= RATE_BMP_CCK;
864 
865 	/* TODO: NO OFDM? */
866 	bmp_cck_ofdm |= RATE_BMP_OFDM;
867 
868 #ifdef CONFIG_80211N_HT
869 	if (regsty->ht_enable && is_supported_ht(regsty->wireless_mode)) {
870 		switch (GET_HAL_TX_NSS(adapter)) {
871 		case 1:
872 			bmp_ht |= RATE_BMP_HT_1SS;
873 			break;
874 		case 2:
875 			bmp_ht |= RATE_BMP_HT_2SS | RATE_BMP_HT_1SS;
876 			break;
877 		case 3:
878 			bmp_ht |= RATE_BMP_HT_3SS | RATE_BMP_HT_2SS | RATE_BMP_HT_1SS;
879 			break;
880 		case 4:
881 			bmp_ht |= RATE_BMP_HT_4SS | RATE_BMP_HT_3SS | RATE_BMP_HT_2SS | RATE_BMP_HT_1SS;
882 			break;
883 		default:
884 			rtw_warn_on(1);
885 		}
886 	}
887 #endif
888 
889 #ifdef CONFIG_80211AC_VHT
890 	if (ch > 14 && REGSTY_IS_11AC_ENABLE(regsty) && is_supported_vht(regsty->wireless_mode)
891 		&& (!rfctl->country_ent || COUNTRY_CHPLAN_EN_11AC(rfctl->country_ent))
892 	) {
893 		switch (GET_HAL_TX_NSS(adapter)) {
894 		case 1:
895 			bmp_vht |= RATE_BMP_VHT_1SS;
896 			break;
897 		case 2:
898 			bmp_vht |= RATE_BMP_VHT_2SS | RATE_BMP_VHT_1SS;
899 			break;
900 		case 3:
901 			bmp_vht |= RATE_BMP_VHT_3SS | RATE_BMP_VHT_2SS | RATE_BMP_VHT_1SS;
902 			break;
903 		case 4:
904 			bmp_vht |= RATE_BMP_VHT_4SS | RATE_BMP_VHT_3SS | RATE_BMP_VHT_2SS | RATE_BMP_VHT_1SS;
905 			break;
906 		default:
907 			rtw_warn_on(1);
908 		}
909 	}
910 #endif
911 
912 	mbm = phy_get_txpwr_total_max_mbm(adapter
913 			, bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht, 1, eirp);
914 
915 	return mbm;
916 }
917 
query_ra_short_GI(struct sta_info * psta,u8 bw)918 u8 query_ra_short_GI(struct sta_info *psta, u8 bw)
919 {
920 	u8	sgi = _FALSE, sgi_20m = _FALSE, sgi_40m = _FALSE, sgi_80m = _FALSE;
921 
922 #ifdef CONFIG_80211N_HT
923 #ifdef CONFIG_80211AC_VHT
924 	if (psta->vhtpriv.vht_option)
925 		sgi_80m = psta->vhtpriv.sgi_80m;
926 #endif
927 	sgi_20m = psta->htpriv.sgi_20m;
928 	sgi_40m = psta->htpriv.sgi_40m;
929 #endif
930 
931 	switch (bw) {
932 	case CHANNEL_WIDTH_80:
933 		sgi = sgi_80m;
934 		break;
935 	case CHANNEL_WIDTH_40:
936 		sgi = sgi_40m;
937 		break;
938 	case CHANNEL_WIDTH_20:
939 	default:
940 		sgi = sgi_20m;
941 		break;
942 	}
943 
944 	return sgi;
945 }
946 
947 /* This function references driver insmond parameters to decide vcs mode. */
948 /* Driver insmond parameters: rtw_vrtl_carrier_sense and rtw_vcs_type */
validate_vcs(_adapter * padapter,u8 mode)949 static u8 validate_vcs(_adapter *padapter, u8  mode) {
950 
951 	u8 vcs_mode = NONE_VCS;
952 
953 	switch(padapter->registrypriv.vrtl_carrier_sense) {
954 
955 		case DISABLE_VCS:
956 			vcs_mode = NONE_VCS;
957 			break;
958 
959 		case ENABLE_VCS:
960 			vcs_mode = padapter->registrypriv.vcs_type;
961 			break;
962 
963 		case AUTO_VCS:
964 			vcs_mode = mode;
965 			break;
966 
967 		default:
968 			vcs_mode = NONE_VCS;
969 			break;
970 	}
971 
972 	return vcs_mode;
973 
974 }
975 
update_attrib_vcs_info(_adapter * padapter,struct xmit_frame * pxmitframe)976 static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe)
977 {
978 	u32	sz;
979 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
980 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
981 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
982 	#ifdef RTW_FORCE_CTS_TO_SELF_UNDER_LOW_RSSI
983 	s8	rssi = 0;
984 	struct sta_info	*psta = pattrib->psta;
985 	#endif
986 	/*
987 		if(pattrib->psta)
988 		{
989 			psta = pattrib->psta;
990 		}
991 		else
992 		{
993 			RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
994 			psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] );
995 		}
996 
997 		if(psta==NULL)
998 		{
999 			RTW_INFO("%s, psta==NUL\n", __func__);
1000 			return;
1001 		}
1002 
1003 		if(!(psta->state &WIFI_ASOC_STATE))
1004 		{
1005 			RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state);
1006 			return;
1007 		}
1008 	*/
1009 
1010 	if (pattrib->nr_frags != 1)
1011 		sz = padapter->xmitpriv.frag_len;
1012 	else /* no frag */
1013 		sz = pattrib->last_txcmdsz;
1014 
1015 	/* (1) RTS_Threshold is compared to the MPDU, not MSDU. */
1016 	/* (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame. */
1017 	/*		Other fragments are protected by previous fragment. */
1018 	/*		So we only need to check the length of first fragment. */
1019 	if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N  || padapter->registrypriv.wifi_spec) {
1020 		if (sz > padapter->registrypriv.rts_thresh)
1021 			pattrib->vcs_mode = RTS_CTS;
1022 		else {
1023 			if (pattrib->rtsen)
1024 				pattrib->vcs_mode = RTS_CTS;
1025 			else if (pattrib->cts2self)
1026 				pattrib->vcs_mode = CTS_TO_SELF;
1027 			else
1028 				pattrib->vcs_mode = NONE_VCS;
1029 		}
1030 	} else {
1031 		while (_TRUE) {
1032 #if 0 /* Todo */
1033 			/* check IOT action */
1034 			if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) {
1035 				pattrib->vcs_mode = CTS_TO_SELF;
1036 				pattrib->rts_rate = MGN_24M;
1037 				break;
1038 			} else if (pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS | HT_IOT_ACT_PURE_N_MODE)) {
1039 				pattrib->vcs_mode = RTS_CTS;
1040 				pattrib->rts_rate = MGN_24M;
1041 				break;
1042 			}
1043 #endif
1044 
1045 			/* IOT action */
1046 			if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && (pattrib->ampdu_en == _TRUE) &&
1047 			    (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
1048 				pattrib->vcs_mode = CTS_TO_SELF;
1049 				break;
1050 			}
1051 
1052 			/* check ERP protection */
1053 			if (pattrib->rtsen || pattrib->cts2self) {
1054 				if (pattrib->rtsen)
1055 					pattrib->vcs_mode = RTS_CTS;
1056 				else if (pattrib->cts2self)
1057 					pattrib->vcs_mode = CTS_TO_SELF;
1058 
1059 				break;
1060 			}
1061 
1062 			/* check HT op mode */
1063 			if (pattrib->ht_en) {
1064 				u8 HTOpMode = pmlmeinfo->HT_protection;
1065 				if ((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) ||
1066 				    (!pmlmeext->cur_bwmode && HTOpMode == 3)) {
1067 					pattrib->vcs_mode = RTS_CTS;
1068 					break;
1069 				}
1070 			}
1071 
1072 			/* check rts */
1073 			if (sz > padapter->registrypriv.rts_thresh) {
1074 				pattrib->vcs_mode = RTS_CTS;
1075 				break;
1076 			}
1077 
1078 			/* to do list: check MIMO power save condition. */
1079 
1080 			/* check AMPDU aggregation for TXOP */
1081 			if ((pattrib->ampdu_en == _TRUE) && (!IS_HARDWARE_TYPE_8812(padapter))) {
1082 				pattrib->vcs_mode = RTS_CTS;
1083 				break;
1084 			}
1085 
1086 			pattrib->vcs_mode = NONE_VCS;
1087 			break;
1088 		}
1089 		#ifdef RTW_FORCE_CTS_TO_SELF_UNDER_LOW_RSSI
1090 		/*RTStoCTS while let TP degree ,while enable full BW*/
1091 		if (psta != NULL) {
1092 			rssi = psta->cmn.rssi_stat.rssi;
1093 			if ((rssi < 18) && (pattrib->vcs_mode == RTS_CTS))
1094 				pattrib->vcs_mode = CTS_TO_SELF;
1095 		}
1096 		#endif
1097 	}
1098 
1099 	pattrib->vcs_mode = validate_vcs(padapter, pattrib->vcs_mode);
1100 
1101 	/* for debug : force driver control vrtl_carrier_sense. */
1102 	if (padapter->driver_vcs_en == 1) {
1103 		/* u8 driver_vcs_en; */ /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */
1104 		/* u8 driver_vcs_type; */ /* force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1. */
1105 		pattrib->vcs_mode = padapter->driver_vcs_type;
1106 	}
1107 
1108 }
1109 
1110 #ifdef CONFIG_WMMPS_STA
1111 /*
1112  * update_attrib_trigger_frame_info
1113  * For Station mode, if a specific TID of driver setting and an AP support uapsd function, the data
1114  * frame with corresponding TID will be a trigger frame when driver is in wmm power saving mode.
1115  *
1116  * Arguments:
1117  * @padapter: _adapter pointer.
1118  * @pattrib: pkt_attrib pointer.
1119  *
1120  * Auther: Arvin Liu
1121  * Date: 2017/06/05
1122  */
update_attrib_trigger_frame_info(_adapter * padapter,struct pkt_attrib * pattrib)1123 static void update_attrib_trigger_frame_info(_adapter *padapter, struct pkt_attrib *pattrib) {
1124 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1125 	struct pwrctrl_priv 	*pwrpriv = adapter_to_pwrctl(padapter);
1126 	struct qos_priv 	*pqospriv = &pmlmepriv->qospriv;
1127 	u8 trigger_frame_en = 0;
1128 
1129 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
1130 		if ((pwrpriv->pwr_mode == PS_MODE_MIN) || (pwrpriv->pwr_mode == PS_MODE_MAX)) {
1131 			if((pqospriv->uapsd_ap_supported) && ((pqospriv->uapsd_tid & BIT(pattrib->priority)) == _TRUE)) {
1132 				trigger_frame_en = 1;
1133 				RTW_INFO("[WMMPS]"FUNC_ADPT_FMT": This is a Trigger Frame\n", FUNC_ADPT_ARG(padapter));
1134 			}
1135 		}
1136 	}
1137 
1138 	pattrib->trigger_frame = trigger_frame_en;
1139 }
1140 #endif /* CONFIG_WMMPS_STA */
1141 
update_attrib_phy_info(_adapter * padapter,struct pkt_attrib * pattrib,struct sta_info * psta)1142 static void update_attrib_phy_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
1143 {
1144 	struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
1145 	u8 bw;
1146 
1147 	pattrib->rtsen = psta->rtsen;
1148 	pattrib->cts2self = psta->cts2self;
1149 
1150 	pattrib->mdata = 0;
1151 	pattrib->eosp = 0;
1152 	pattrib->triggered = 0;
1153 	pattrib->ampdu_spacing = 0;
1154 
1155 	/* ht_en, init rate, ,bw, ch_offset, sgi */
1156 
1157 	pattrib->raid = psta->cmn.ra_info.rate_id;
1158 
1159 	bw = rtw_get_tx_bw_mode(padapter, psta);
1160 	pattrib->bwmode = rtw_min(bw, mlmeext->cur_bwmode);
1161 	pattrib->sgi = query_ra_short_GI(psta, pattrib->bwmode);
1162 
1163 	pattrib->ldpc = psta->cmn.ldpc_en;
1164 	pattrib->stbc = psta->cmn.stbc_en;
1165 
1166 #ifdef CONFIG_80211N_HT
1167 	if(padapter->registrypriv.ht_enable &&
1168 		is_supported_ht(padapter->registrypriv.wireless_mode)) {
1169 		pattrib->ht_en = psta->htpriv.ht_option;
1170 		pattrib->ch_offset = psta->htpriv.ch_offset;
1171 		pattrib->ampdu_en = _FALSE;
1172 
1173 		if (padapter->driver_ampdu_spacing != 0xFF) /* driver control AMPDU Density for peer sta's rx */
1174 			pattrib->ampdu_spacing = padapter->driver_ampdu_spacing;
1175 		else
1176 			pattrib->ampdu_spacing = psta->htpriv.rx_ampdu_min_spacing;
1177 
1178 		/* check if enable ampdu */
1179 		if (pattrib->ht_en && psta->htpriv.ampdu_enable) {
1180 			if (psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) {
1181 				pattrib->ampdu_en = _TRUE;
1182 				if (psta->htpriv.tx_amsdu_enable == _TRUE)
1183 					pattrib->amsdu_ampdu_en = _TRUE;
1184 				else
1185 					pattrib->amsdu_ampdu_en = _FALSE;
1186 			}
1187 		}
1188 	}
1189 #endif /* CONFIG_80211N_HT */
1190 	/* if(pattrib->ht_en && psta->htpriv.ampdu_enable) */
1191 	/* { */
1192 	/*	if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) */
1193 	/*		pattrib->ampdu_en = _TRUE; */
1194 	/* }	 */
1195 
1196 #ifdef CONFIG_TDLS
1197 	if (pattrib->direct_link == _TRUE) {
1198 		psta = pattrib->ptdls_sta;
1199 
1200 		pattrib->raid = psta->cmn.ra_info.rate_id;
1201 #ifdef CONFIG_80211N_HT
1202 	if(padapter->registrypriv.ht_enable &&
1203 		is_supported_ht(padapter->registrypriv.wireless_mode)) {
1204 			pattrib->bwmode = rtw_get_tx_bw_mode(padapter, psta);
1205 			pattrib->ht_en = psta->htpriv.ht_option;
1206 			pattrib->ch_offset = psta->htpriv.ch_offset;
1207 			pattrib->sgi = query_ra_short_GI(psta, pattrib->bwmode);
1208 	}
1209 #endif /* CONFIG_80211N_HT */
1210 	}
1211 #endif /* CONFIG_TDLS */
1212 
1213 	pattrib->retry_ctrl = _FALSE;
1214 }
1215 
update_attrib_sec_info(_adapter * padapter,struct pkt_attrib * pattrib,struct sta_info * psta,enum eap_type eapol_type)1216 static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta, enum eap_type eapol_type)
1217 {
1218 	sint res = _SUCCESS;
1219 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1220 	struct security_priv *psecuritypriv = &padapter->securitypriv;
1221 	sint bmcast = IS_MCAST(pattrib->ra);
1222 
1223 	_rtw_memset(pattrib->dot118021x_UncstKey.skey,  0, 16);
1224 	_rtw_memset(pattrib->dot11tkiptxmickey.skey,  0, 16);
1225 	pattrib->mac_id = psta->cmn.mac_id;
1226 
1227 	/* Comment by Owen at 2020/05/19
1228 	 * Issue: RTK STA sends encrypted 4-way 4/4 when AP thinks the 4-way incomplete
1229 	 * In TCL pressure test, AP may resend 4-way 3/4 with new replay counter in 2 ms.
1230 	 * In this situation, STA sends unencrypted 4-way 4/4 with old replay counter after more
1231 	 * than 2 ms, followed by the encrypted 4-way 4/4 with new replay counter. Because the
1232 	 * AP only accepts unencrypted 4-way 4/4 with a new play counter, and the STA encrypts
1233 	 * each 4-way 4/4 at this time, the 4-way handshake cannot be completed.
1234 	 * So we modified that after STA receives unencrypted 4-way 1/4 and 4-way 3/4,
1235 	 * 4-way 2/4 and 4-way 4/4 sent by STA in the next 100 ms are not encrypted.
1236 	 */
1237 	if (psta->ieee8021x_blocked == _TRUE ||
1238 		((eapol_type == EAPOL_2_4 || eapol_type == EAPOL_4_4) &&
1239 		rtw_get_passing_time_ms(psta->resp_nonenc_eapol_key_starttime) <= 100)) {
1240 
1241 		if (eapol_type == EAPOL_2_4 || eapol_type == EAPOL_4_4)
1242 			RTW_INFO("Respond unencrypted eapol key\n");
1243 
1244 		pattrib->encrypt = 0;
1245 
1246 		if ((pattrib->ether_type != 0x888e) && (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _FALSE)) {
1247 #ifdef DBG_TX_DROP_FRAME
1248 			RTW_INFO("DBG_TX_DROP_FRAME %s psta->ieee8021x_blocked == _TRUE,  pattrib->ether_type(%04x) != 0x888e\n", __FUNCTION__, pattrib->ether_type);
1249 #endif
1250 			res = _FAIL;
1251 			goto exit;
1252 		}
1253 	} else {
1254 		GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
1255 
1256 #ifdef CONFIG_WAPI_SUPPORT
1257 		if (pattrib->ether_type == 0x88B4)
1258 			pattrib->encrypt = _NO_PRIVACY_;
1259 #endif
1260 
1261 		switch (psecuritypriv->dot11AuthAlgrthm) {
1262 		case dot11AuthAlgrthm_Open:
1263 		case dot11AuthAlgrthm_Shared:
1264 		case dot11AuthAlgrthm_Auto:
1265 			pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
1266 			break;
1267 		case dot11AuthAlgrthm_8021X:
1268 			if (bmcast)
1269 				pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
1270 			else
1271 				pattrib->key_idx = 0;
1272 			break;
1273 		default:
1274 			pattrib->key_idx = 0;
1275 			break;
1276 		}
1277 
1278 		/* For WPS 1.0 WEP, driver should not encrypt EAPOL Packet for WPS handshake. */
1279 		if (((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) && (pattrib->ether_type == 0x888e))
1280 			pattrib->encrypt = _NO_PRIVACY_;
1281 
1282 	}
1283 
1284 #ifdef CONFIG_TDLS
1285 	if (pattrib->direct_link == _TRUE) {
1286 		if (pattrib->encrypt > 0)
1287 			pattrib->encrypt = _AES_;
1288 	}
1289 #endif
1290 
1291 	switch (pattrib->encrypt) {
1292 	case _WEP40_:
1293 	case _WEP104_:
1294 		pattrib->iv_len = 4;
1295 		pattrib->icv_len = 4;
1296 		WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1297 		break;
1298 
1299 	case _TKIP_:
1300 		pattrib->iv_len = 8;
1301 		pattrib->icv_len = 4;
1302 
1303 		if (psecuritypriv->busetkipkey == _FAIL) {
1304 #ifdef DBG_TX_DROP_FRAME
1305 			RTW_INFO("DBG_TX_DROP_FRAME %s psecuritypriv->busetkipkey(%d)==_FAIL drop packet\n", __FUNCTION__, psecuritypriv->busetkipkey);
1306 #endif
1307 			res = _FAIL;
1308 			goto exit;
1309 		}
1310 
1311 		if (bmcast)
1312 			TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1313 		else
1314 			TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
1315 
1316 
1317 		_rtw_memcpy(pattrib->dot11tkiptxmickey.skey, psta->dot11tkiptxmickey.skey, 16);
1318 
1319 		break;
1320 
1321 	case _AES_:
1322 
1323 		pattrib->iv_len = 8;
1324 		pattrib->icv_len = 8;
1325 
1326 		if (bmcast)
1327 			AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1328 		else
1329 			AES_IV(pattrib->iv, psta->dot11txpn, 0);
1330 
1331 		break;
1332 
1333 	case _GCMP_:
1334 	case _GCMP_256_:
1335 
1336 		pattrib->iv_len = 8;
1337 		pattrib->icv_len = 16;
1338 
1339 		if (bmcast)
1340 			GCMP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1341 		else
1342 			GCMP_IV(pattrib->iv, psta->dot11txpn, 0);
1343 
1344 		break;
1345 
1346 	case _CCMP_256_:
1347 
1348 		pattrib->iv_len = 8;
1349 		pattrib->icv_len = 16;
1350 
1351 		if (bmcast)
1352 			GCMP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1353 		else
1354 			GCMP_IV(pattrib->iv, psta->dot11txpn, 0);
1355 
1356 		break;
1357 
1358 #ifdef CONFIG_WAPI_SUPPORT
1359 	case _SMS4_:
1360 		pattrib->iv_len = 18;
1361 		pattrib->icv_len = 16;
1362 		rtw_wapi_get_iv(padapter, pattrib->ra, pattrib->iv);
1363 		break;
1364 #endif
1365 	default:
1366 		pattrib->iv_len = 0;
1367 		pattrib->icv_len = 0;
1368 		break;
1369 	}
1370 
1371 	if (pattrib->encrypt > 0) {
1372 		_rtw_memcpy(pattrib->dot118021x_UncstKey.skey
1373 			, psta->dot118021x_UncstKey.skey
1374 			, (pattrib->encrypt & _SEC_TYPE_256_) ? 32 : 16);
1375 	}
1376 
1377 
1378 	if (pattrib->encrypt &&
1379 	    ((padapter->securitypriv.sw_encrypt == _TRUE) || (psecuritypriv->hw_decrypted == _FALSE))) {
1380 		pattrib->bswenc = _TRUE;
1381 	} else {
1382 		pattrib->bswenc = _FALSE;
1383 	}
1384 
1385 	pattrib->bmc_camid = padapter->securitypriv.dot118021x_bmc_cam_id;
1386 
1387 	if (pattrib->encrypt && bmcast && _rtw_camctl_chk_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
1388 		pattrib->bswenc = _TRUE;
1389 
1390 #ifdef CONFIG_WAPI_SUPPORT
1391 	if (pattrib->encrypt == _SMS4_)
1392 		pattrib->bswenc = _FALSE;
1393 #endif
1394 
1395 	if ((pattrib->encrypt) && (eapol_type == EAPOL_4_4))
1396 		pattrib->bswenc = _TRUE;
1397 
1398 exit:
1399 
1400 	return res;
1401 
1402 }
1403 
qos_acm(u8 acm_mask,u8 priority)1404 u8	qos_acm(u8 acm_mask, u8 priority)
1405 {
1406 	u8	change_priority = priority;
1407 
1408 	switch (priority) {
1409 	case 0:
1410 	case 3:
1411 		if (acm_mask & BIT(1))
1412 			change_priority = 1;
1413 		break;
1414 	case 1:
1415 	case 2:
1416 		break;
1417 	case 4:
1418 	case 5:
1419 		if (acm_mask & BIT(2))
1420 			change_priority = 0;
1421 		break;
1422 	case 6:
1423 	case 7:
1424 		if (acm_mask & BIT(3))
1425 			change_priority = 5;
1426 		break;
1427 	default:
1428 		RTW_INFO("qos_acm(): invalid pattrib->priority: %d!!!\n", priority);
1429 		break;
1430 	}
1431 
1432 	return change_priority;
1433 }
1434 
1435 /* refer to IEEE802.11-2016 Table R-3; Comply with IETF RFC4594 */
tos_to_up(u8 tos)1436 static u8 tos_to_up(u8 tos)
1437 {
1438 	u8 up = 0;
1439 	u8 dscp;
1440 	u8 mode = CONFIG_RTW_UP_MAPPING_RULE;
1441 
1442 
1443 	/* tos precedence mapping */
1444 	if (mode == 0) {
1445 		up = tos >> 5;
1446 		return up;
1447 	}
1448 
1449 	/* refer to IEEE802.11-2016 Table R-3;
1450 	 * DCSP 32(CS4) comply with IETF RFC4594
1451 	 */
1452 	dscp = (tos >> 2);
1453 
1454 	if ( dscp == 0 )
1455 		up = 0;
1456 	else if ( dscp >= 1 && dscp <= 9)
1457 		up = 1;
1458 	else if ( dscp >= 10 && dscp <= 16)
1459 		up = 2;
1460 	else if ( dscp >= 17 && dscp <= 23)
1461 		up = 3;
1462 	else if ( dscp >= 24 && dscp <= 31)
1463 		up = 4;
1464 	else if ( dscp >= 33 && dscp <= 40)
1465 		up = 5;
1466 	else if ((dscp >= 41 && dscp <= 47) || (dscp == 32))
1467 		up = 6;
1468 	else if ( dscp >= 48 && dscp <= 63)
1469 		up = 7;
1470 
1471 	return up;
1472 }
1473 
set_qos(_pkt * pkt,struct pkt_attrib * pattrib)1474 static void set_qos(_pkt *pkt, struct pkt_attrib *pattrib)
1475 {
1476 	s32 UserPriority = 0;
1477 
1478 	if (!pkt)
1479 		goto null_pkt;
1480 
1481 	/* get UserPriority from IP hdr */
1482 	if (pattrib->ether_type == 0x0800) {
1483 		struct pkt_file ppktfile;
1484 		struct ethhdr etherhdr;
1485 		struct iphdr ip_hdr;
1486 
1487 		_rtw_open_pktfile(pkt, &ppktfile);
1488 		_rtw_pktfile_read(&ppktfile, (unsigned char *)&etherhdr, ETH_HLEN);
1489 		_rtw_pktfile_read(&ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr));
1490 		/*		UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3; */
1491 		UserPriority = tos_to_up(ip_hdr.tos);
1492 	}
1493 	/*
1494 		else if (pattrib->ether_type == 0x888e) {
1495 
1496 
1497 			UserPriority = 7;
1498 		}
1499 	*/
1500 
1501 	#ifdef CONFIG_ICMP_VOQ
1502 	if(pattrib->icmp_pkt==1)/*use VO queue to send icmp packet*/
1503 		UserPriority = 7;
1504 	#endif
1505 	#ifdef CONFIG_IP_R_MONITOR
1506 	if (pattrib->ether_type == ETH_P_ARP)
1507 		UserPriority = 7;
1508 	#endif/*CONFIG_IP_R_MONITOR*/
1509 
1510 null_pkt:
1511 	pattrib->priority = UserPriority;
1512 	pattrib->hdrlen = XATTRIB_GET_WDS(pattrib) ? WLAN_HDR_A4_QOS_LEN : WLAN_HDR_A3_QOS_LEN;
1513 	pattrib->subtype = WIFI_QOS_DATA_TYPE;
1514 }
1515 
1516 #ifdef CONFIG_TDLS
rtw_check_tdls_established(_adapter * padapter,struct pkt_attrib * pattrib)1517 u8 rtw_check_tdls_established(_adapter *padapter, struct pkt_attrib *pattrib)
1518 {
1519 	pattrib->ptdls_sta = NULL;
1520 
1521 	pattrib->direct_link = _FALSE;
1522 	if (padapter->tdlsinfo.link_established == _TRUE) {
1523 		pattrib->ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
1524 #if 1
1525 		if ((pattrib->ptdls_sta != NULL) &&
1526 		    (pattrib->ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) &&
1527 		    (pattrib->ether_type != 0x0806)) {
1528 			pattrib->direct_link = _TRUE;
1529 			/* RTW_INFO("send ptk to "MAC_FMT" using direct link\n", MAC_ARG(pattrib->dst)); */
1530 		}
1531 #else
1532 		if (pattrib->ptdls_sta != NULL &&
1533 		    pattrib->ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
1534 			pattrib->direct_link = _TRUE;
1535 #if 0
1536 			RTW_INFO("send ptk to "MAC_FMT" using direct link\n", MAC_ARG(pattrib->dst));
1537 #endif
1538 		}
1539 
1540 		/* ARP frame may be helped by AP*/
1541 		if (pattrib->ether_type != 0x0806)
1542 			pattrib->direct_link = _FALSE;
1543 #endif
1544 	}
1545 
1546 	return pattrib->direct_link;
1547 }
1548 
update_tdls_attrib(_adapter * padapter,struct pkt_attrib * pattrib)1549 s32 update_tdls_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
1550 {
1551 
1552 	struct sta_info *psta = NULL;
1553 	struct sta_priv		*pstapriv = &padapter->stapriv;
1554 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
1555 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1556 	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;
1557 
1558 	s32 res = _SUCCESS;
1559 
1560 	psta = rtw_get_stainfo(pstapriv, pattrib->ra);
1561 	if (psta == NULL)	{
1562 		res = _FAIL;
1563 		goto exit;
1564 	}
1565 
1566 	pattrib->mac_id = psta->cmn.mac_id;
1567 	pattrib->psta = psta;
1568 	pattrib->ack_policy = 0;
1569 	/* get ether_hdr_len */
1570 	pattrib->pkt_hdrlen = ETH_HLEN;
1571 
1572 	pattrib->qos_en = psta->qos_option;
1573 
1574 	/* [TDLS] TODO: setup req/rsp should be AC_BK */
1575 	if (pqospriv->qos_option &&  psta->qos_option) {
1576 		pattrib->priority = 4;	/* tdls management frame should be AC_VI */
1577 		pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
1578 		pattrib->subtype = WIFI_QOS_DATA_TYPE;
1579 	} else {
1580 		pattrib->priority = 0;
1581 		pattrib->hdrlen = WLAN_HDR_A3_LEN;
1582 		pattrib->subtype = WIFI_DATA_TYPE;
1583 	}
1584 
1585 	/* TODO:_lock */
1586 	if (update_attrib_sec_info(padapter, pattrib, psta, NON_EAPOL) == _FAIL) {
1587 		res = _FAIL;
1588 		goto exit;
1589 	}
1590 
1591 	update_attrib_phy_info(padapter, pattrib, psta);
1592 
1593 
1594 exit:
1595 
1596 	return res;
1597 }
1598 
1599 #endif /* CONFIG_TDLS */
1600 
1601 /*get non-qos hw_ssn control register,mapping to REG_HW_SEQ 0,1,2,3*/
rtw_get_hwseq_no(_adapter * padapter)1602 inline u8 rtw_get_hwseq_no(_adapter *padapter)
1603 {
1604 	u8 hwseq_num = 0;
1605 
1606 #ifdef CONFIG_CONCURRENT_MODE
1607 	#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) \
1608 	    || defined(CONFIG_RTL8723F)
1609 	hwseq_num = padapter->iface_id;
1610 	if (hwseq_num > 3)
1611 		hwseq_num = 3;
1612 	#else
1613 	if (!is_primary_adapter(padapter))
1614 		hwseq_num = 1;
1615 	#endif
1616 #endif /* CONFIG_CONCURRENT_MODE */
1617 	return hwseq_num;
1618 }
1619 #ifdef CONFIG_LPS
1620 #define LPS_PT_NORMAL	0
1621 #define LPS_PT_SP		1/* only DHCP packets is as SPECIAL_PACKET*/
1622 #define LPS_PT_ICMP		2
1623 
1624 /*If EAPOL , ARP , OR DHCP packet, driver must be in active mode.*/
_rtw_lps_chk_packet_type(struct pkt_attrib * pattrib)1625 static u8 _rtw_lps_chk_packet_type(struct pkt_attrib *pattrib)
1626 {
1627 	u8 pkt_type = LPS_PT_NORMAL; /*normal data frame*/
1628 
1629 	#ifdef CONFIG_WAPI_SUPPORT
1630 	if ((pattrib->ether_type == 0x88B4) || (pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
1631 		pkt_type = LPS_PT_SP;
1632 	#else /* !CONFIG_WAPI_SUPPORT */
1633 
1634 	#ifndef CONFIG_LPS_NOT_LEAVE_FOR_ICMP
1635 	if (pattrib->icmp_pkt == 1)
1636 		pkt_type = LPS_PT_ICMP;
1637 	else
1638 	#endif
1639 		if (pattrib->dhcp_pkt == 1)
1640 			pkt_type = LPS_PT_SP;
1641 	#endif
1642 	return pkt_type;
1643 }
1644 #endif
update_attrib(_adapter * padapter,_pkt * pkt,struct pkt_attrib * pattrib)1645 static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib)
1646 {
1647 	uint i;
1648 	struct pkt_file pktfile;
1649 	struct sta_info *psta = NULL;
1650 	struct ethhdr etherhdr;
1651 
1652 	sint bmcast;
1653 	struct sta_priv		*pstapriv = &padapter->stapriv;
1654 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
1655 	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;
1656 	struct xmit_priv		*pxmitpriv = &padapter->xmitpriv;
1657 	sint res = _SUCCESS;
1658 	enum eap_type eapol_type = NON_EAPOL;
1659 #ifdef CONFIG_LPS
1660 	u8 pkt_type = 0;
1661 #endif
1662 
1663 	DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib);
1664 
1665 	_rtw_open_pktfile(pkt, &pktfile);
1666 	i = _rtw_pktfile_read(&pktfile, (u8 *)&etherhdr, ETH_HLEN);
1667 
1668 	pattrib->ether_type = ntohs(etherhdr.h_proto);
1669 
1670 	if (MLME_STATE(padapter) & (WIFI_AP_STATE | WIFI_MESH_STATE)) /* address resolve is done for ap/mesh */
1671 		goto get_sta_info;
1672 
1673 	_rtw_memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
1674 	_rtw_memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
1675 	_rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN);
1676 
1677 	if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1678 	    (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
1679 		_rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1680 		DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_adhoc);
1681 	} else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1682 		#ifdef CONFIG_TDLS
1683 		if (rtw_check_tdls_established(padapter, pattrib) == _TRUE)
1684 			_rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);	/* For TDLS direct link Tx, set ra to be same to dst */
1685 		else
1686 		#endif
1687 		{
1688 			_rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1689 			#ifdef CONFIG_RTW_WDS
1690 			if (adapter_use_wds(padapter)
1691 				&& _rtw_memcmp(pattrib->src, pattrib->ta, ETH_ALEN) == _FALSE
1692 			) {
1693 				pattrib->wds = 1;
1694 				if (IS_MCAST(pattrib->dst))
1695 					rtw_tx_wds_gptr_update(padapter, pattrib->src);
1696 			}
1697 			#endif
1698 		}
1699 		DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_sta);
1700 	} else
1701 		DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_unknown);
1702 
1703 get_sta_info:
1704 	bmcast = IS_MCAST(pattrib->ra);
1705 	if (bmcast) {
1706 		psta = rtw_get_bcmc_stainfo(padapter);
1707 		if (psta == NULL) { /* if we cannot get psta => drop the pkt */
1708 			DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sta);
1709 			#ifdef DBG_TX_DROP_FRAME
1710 			RTW_INFO("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __func__, MAC_ARG(pattrib->ra));
1711 			#endif
1712 			res = _FAIL;
1713 			goto exit;
1714 		}
1715 	} else {
1716 		psta = rtw_get_stainfo(pstapriv, pattrib->ra);
1717 		if (psta == NULL) { /* if we cannot get psta => drop the pkt */
1718 			DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_sta);
1719 			#ifdef DBG_TX_DROP_FRAME
1720 			RTW_INFO("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __func__, MAC_ARG(pattrib->ra));
1721 			#endif
1722 			res = _FAIL;
1723 			goto exit;
1724 		} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE && !(psta->state & WIFI_ASOC_STATE)) {
1725 			DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_ap_link);
1726 			res = _FAIL;
1727 			goto exit;
1728 		}
1729 
1730 		#ifdef CONFIG_RTW_WDS
1731 		if (XATTRIB_GET_WDS(pattrib) && !(psta->flags & WLAN_STA_WDS))
1732 			pattrib->wds = 0;
1733 		#endif
1734 	}
1735 
1736 	if (!(psta->state & WIFI_ASOC_STATE)) {
1737 		DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_link);
1738 		RTW_INFO("%s-"ADPT_FMT" psta("MAC_FMT")->state(0x%x) != WIFI_ASOC_STATE\n",
1739 			__func__, ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr), psta->state);
1740 		res = _FAIL;
1741 		goto exit;
1742 	}
1743 
1744 	pattrib->pktlen = pktfile.pkt_len;
1745 
1746 	/* TODO: 802.1Q VLAN header */
1747 	/* TODO: IPV6 */
1748 
1749 	if (ETH_P_IP == pattrib->ether_type) {
1750 		u8 ip[20];
1751 
1752 		_rtw_pktfile_read(&pktfile, ip, 20);
1753 
1754 		if (GET_IPV4_IHL(ip) * 4 > 20)
1755 			_rtw_pktfile_read(&pktfile, NULL, GET_IPV4_IHL(ip) - 20);
1756 
1757 		pattrib->icmp_pkt = 0;
1758 		pattrib->dhcp_pkt = 0;
1759 		pattrib->hipriority_pkt = 0;
1760 
1761 		if (GET_IPV4_PROTOCOL(ip) == 0x01) { /* ICMP */
1762 			pattrib->icmp_pkt = 1;
1763 			DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_icmp);
1764 
1765 		} else if (GET_IPV4_PROTOCOL(ip) == 0x11) { /* UDP */
1766 			u8 udp[24];
1767 
1768 			_rtw_pktfile_read(&pktfile, udp, 24);
1769 
1770 			if ((GET_UDP_SRC(udp) == 68 && GET_UDP_DST(udp) == 67)
1771 				|| (GET_UDP_SRC(udp) == 67 && GET_UDP_DST(udp) == 68)
1772 			) {
1773 				/* 67 : UDP BOOTP server, 68 : UDP BOOTP client */
1774 				if (pattrib->pktlen > 282) { /* MINIMUM_DHCP_PACKET_SIZE */
1775 					pattrib->dhcp_pkt = 1;
1776 					DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_dhcp);
1777 					if (0)
1778 						RTW_INFO("send DHCP packet\n");
1779 				}
1780 			}
1781 
1782 			/* WaveAgent packet, increase priority so that the system can read data in time */
1783 			if (((GET_UDP_SIG1(udp) == 0xcc) || (GET_UDP_SIG1(udp) == 0xdd)) &&
1784 				(GET_UDP_SIG2(udp) == 0xe2)) {
1785 				pattrib->hipriority_pkt = 1;
1786 			}
1787 
1788 		} else if (GET_IPV4_PROTOCOL(ip) == 0x06 /* TCP */
1789 			&& rtw_st_ctl_chk_reg_s_proto(&psta->st_ctl, 0x06) == _TRUE
1790 		) {
1791 			u8 tcp[20];
1792 
1793 			_rtw_pktfile_read(&pktfile, tcp, 20);
1794 
1795 			if (rtw_st_ctl_chk_reg_rule(&psta->st_ctl, padapter, IPV4_SRC(ip), TCP_SRC(tcp), IPV4_DST(ip), TCP_DST(tcp)) == _TRUE) {
1796 				if (GET_TCP_SYN(tcp) && GET_TCP_ACK(tcp)) {
1797 					session_tracker_add_cmd(padapter, psta
1798 						, IPV4_SRC(ip), TCP_SRC(tcp)
1799 						, IPV4_SRC(ip), TCP_DST(tcp));
1800 					if (DBG_SESSION_TRACKER)
1801 						RTW_INFO(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" SYN-ACK\n"
1802 							, FUNC_ADPT_ARG(padapter)
1803 							, IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp))
1804 							, IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp)));
1805 				}
1806 				if (GET_TCP_FIN(tcp)) {
1807 					session_tracker_del_cmd(padapter, psta
1808 						, IPV4_SRC(ip), TCP_SRC(tcp)
1809 						, IPV4_SRC(ip), TCP_DST(tcp));
1810 					if (DBG_SESSION_TRACKER)
1811 						RTW_INFO(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" FIN\n"
1812 							, FUNC_ADPT_ARG(padapter)
1813 							, IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp))
1814 							, IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp)));
1815 				}
1816 			}
1817 		}
1818 
1819 	} else if (0x888e == pattrib->ether_type)
1820 		eapol_type = parsing_eapol_packet(padapter, pktfile.cur_addr, psta, 1);
1821 #if defined (DBG_ARP_DUMP) || defined (DBG_IP_R_MONITOR)
1822 	else if (pattrib->ether_type == ETH_P_ARP) {
1823 		u8 arp[28] = {0};
1824 
1825 		_rtw_pktfile_read(&pktfile, arp, 28);
1826 		dump_arp_pkt(RTW_DBGDUMP, etherhdr.h_dest, etherhdr.h_source, arp, 1);
1827 	}
1828 #endif
1829 
1830 	if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
1831 		rtw_mi_set_scan_deny(padapter, 3000);
1832 
1833 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
1834 		pattrib->ether_type == ETH_P_ARP &&
1835 		!IS_MCAST(pattrib->dst)) {
1836 		rtw_mi_set_scan_deny(padapter, 1000);
1837 		rtw_mi_scan_abort(padapter, _FALSE); /*rtw_scan_abort_no_wait*/
1838 	}
1839 
1840 #ifdef CONFIG_LPS
1841 	pkt_type = _rtw_lps_chk_packet_type(pattrib);
1842 
1843 	if (pkt_type == LPS_PT_SP) {/*packet is as SPECIAL_PACKET*/
1844 		DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_active);
1845 		rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 0);
1846 	} else if (pkt_type == LPS_PT_ICMP)
1847 		rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 0);
1848 #endif /* CONFIG_LPS */
1849 
1850 #ifdef CONFIG_BEAMFORMING
1851 	update_attrib_txbf_info(padapter, pattrib, psta);
1852 #endif
1853 
1854 	/* TODO:_lock */
1855 	if (update_attrib_sec_info(padapter, pattrib, psta, eapol_type) == _FAIL) {
1856 		DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sec);
1857 		res = _FAIL;
1858 		goto exit;
1859 	}
1860 
1861 	/* get ether_hdr_len */
1862 	pattrib->pkt_hdrlen = ETH_HLEN;/* (pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; */ /* vlan tag */
1863 
1864 	pattrib->hdrlen = XATTRIB_GET_WDS(pattrib) ? WLAN_HDR_A4_LEN : WLAN_HDR_A3_LEN;
1865 	pattrib->subtype = WIFI_DATA_TYPE;
1866 	pattrib->qos_en = psta->qos_option;
1867 	pattrib->priority = 0;
1868 
1869 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE | WIFI_MESH_STATE
1870 		| WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)
1871 	) {
1872 		if (pattrib->qos_en) {
1873 			set_qos(pkt, pattrib);
1874 			#ifdef CONFIG_RTW_MESH
1875 			if (MLME_IS_MESH(padapter))
1876 				rtw_mesh_tx_set_whdr_mctrl_len(pattrib->mesh_frame_mode, pattrib);
1877 			#endif
1878 		}
1879 	} else {
1880 #ifdef CONFIG_TDLS
1881 		if (pattrib->direct_link == _TRUE) {
1882 			if (pattrib->qos_en)
1883 				set_qos(pkt, pattrib);
1884 		} else
1885 #endif
1886 		{
1887 			if (pqospriv->qos_option) {
1888 				set_qos(pkt, pattrib);
1889 
1890 				if (pmlmepriv->acm_mask != 0)
1891 					pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority);
1892 			}
1893 		}
1894 	}
1895 
1896 	update_attrib_phy_info(padapter, pattrib, psta);
1897 
1898 	/* RTW_INFO("%s ==> mac_id(%d)\n",__FUNCTION__,pattrib->mac_id ); */
1899 
1900 	pattrib->psta = psta;
1901 	/* TODO:_unlock */
1902 
1903 #ifdef CONFIG_AUTO_AP_MODE
1904 	if (psta->isrc && psta->pid > 0)
1905 		pattrib->pctrl = _TRUE;
1906 	else
1907 #endif
1908 		pattrib->pctrl = 0;
1909 
1910 	pattrib->ack_policy = 0;
1911 
1912 	if (bmcast)
1913 		pattrib->rate = psta->init_rate;
1914 
1915 
1916 #ifdef CONFIG_WMMPS_STA
1917 	update_attrib_trigger_frame_info(padapter, pattrib);
1918 #endif /* CONFIG_WMMPS_STA */
1919 
1920 	/* pattrib->priority = 5; */ /* force to used VI queue, for testing */
1921 	pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
1922 	rtw_set_tx_chksum_offload(pkt, pattrib);
1923 
1924 exit:
1925 
1926 
1927 	return res;
1928 }
1929 
xmitframe_addmic(_adapter * padapter,struct xmit_frame * pxmitframe)1930 static s32 xmitframe_addmic(_adapter *padapter, struct xmit_frame *pxmitframe)
1931 {
1932 	sint			curfragnum, length;
1933 	u8	*pframe, *payload, mic[8];
1934 	struct	mic_data		micdata;
1935 	/* struct	sta_info		*stainfo; */
1936 	struct	pkt_attrib	*pattrib = &pxmitframe->attrib;
1937 	struct	security_priv	*psecuritypriv = &padapter->securitypriv;
1938 	struct	xmit_priv		*pxmitpriv = &padapter->xmitpriv;
1939 	u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
1940 	u8 hw_hdr_offset = 0;
1941 	sint bmcst = IS_MCAST(pattrib->ra);
1942 
1943 	/*
1944 		if(pattrib->psta)
1945 		{
1946 			stainfo = pattrib->psta;
1947 		}
1948 		else
1949 		{
1950 			RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
1951 			stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
1952 		}
1953 
1954 		if(stainfo==NULL)
1955 		{
1956 			RTW_INFO("%s, psta==NUL\n", __func__);
1957 			return _FAIL;
1958 		}
1959 
1960 		if(!(stainfo->state &WIFI_ASOC_STATE))
1961 		{
1962 			RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, stainfo->state);
1963 			return _FAIL;
1964 		}
1965 	*/
1966 
1967 
1968 #ifdef CONFIG_USB_TX_AGGREGATION
1969 	hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);;
1970 #else
1971 #ifdef CONFIG_TX_EARLY_MODE
1972 	hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
1973 #else
1974 	hw_hdr_offset = TXDESC_OFFSET;
1975 #endif
1976 #endif
1977 
1978 	if (pattrib->encrypt == _TKIP_) { /* if(psecuritypriv->dot11PrivacyAlgrthm==_TKIP_PRIVACY_) */
1979 		/* encode mic code */
1980 		/* if(stainfo!= NULL) */
1981 		{
1982 			u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1983 
1984 			pframe = pxmitframe->buf_addr + hw_hdr_offset;
1985 
1986 			if (bmcst) {
1987 				if (_rtw_memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16) == _TRUE) {
1988 					/* DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); */
1989 					/* rtw_msleep_os(10); */
1990 					return _FAIL;
1991 				}
1992 				/* start to calculate the mic code */
1993 				rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
1994 			} else {
1995 				if (_rtw_memcmp(&pattrib->dot11tkiptxmickey.skey[0], null_key, 16) == _TRUE) {
1996 					/* DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); */
1997 					/* rtw_msleep_os(10); */
1998 					return _FAIL;
1999 				}
2000 				/* start to calculate the mic code */
2001 				rtw_secmicsetkey(&micdata, &pattrib->dot11tkiptxmickey.skey[0]);
2002 			}
2003 
2004 			if (pframe[1] & 1) { /* ToDS==1 */
2005 				rtw_secmicappend(&micdata, &pframe[16], 6);  /* DA */
2006 				if (pframe[1] & 2) /* From Ds==1 */
2007 					rtw_secmicappend(&micdata, &pframe[24], 6);
2008 				else
2009 					rtw_secmicappend(&micdata, &pframe[10], 6);
2010 			} else {	/* ToDS==0 */
2011 				rtw_secmicappend(&micdata, &pframe[4], 6);   /* DA */
2012 				if (pframe[1] & 2) /* From Ds==1 */
2013 					rtw_secmicappend(&micdata, &pframe[16], 6);
2014 				else
2015 					rtw_secmicappend(&micdata, &pframe[10], 6);
2016 
2017 			}
2018 
2019 			if (pattrib->qos_en)
2020 				priority[0] = (u8)pxmitframe->attrib.priority;
2021 
2022 
2023 			rtw_secmicappend(&micdata, &priority[0], 4);
2024 
2025 			payload = pframe;
2026 
2027 			for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
2028 				payload = (u8 *)RND4((SIZE_PTR)(payload));
2029 
2030 				payload = payload + pattrib->hdrlen + pattrib->iv_len;
2031 				if ((curfragnum + 1) == pattrib->nr_frags) {
2032 					length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0);
2033 					rtw_secmicappend(&micdata, payload, length);
2034 					payload = payload + length;
2035 				} else {
2036 					length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0);
2037 					rtw_secmicappend(&micdata, payload, length);
2038 					payload = payload + length + pattrib->icv_len;
2039 				}
2040 			}
2041 			rtw_secgetmic(&micdata, &(mic[0]));
2042 			/* add mic code  and add the mic code length in last_txcmdsz */
2043 
2044 			_rtw_memcpy(payload, &(mic[0]), 8);
2045 			pattrib->last_txcmdsz += 8;
2046 
2047 			payload = payload - pattrib->last_txcmdsz + 8;
2048 		}
2049 	}
2050 
2051 
2052 	return _SUCCESS;
2053 }
2054 
2055 /*#define DBG_TX_SW_ENCRYPTOR*/
2056 
xmitframe_swencrypt(_adapter * padapter,struct xmit_frame * pxmitframe)2057 static s32 xmitframe_swencrypt(_adapter *padapter, struct xmit_frame *pxmitframe)
2058 {
2059 
2060 	struct	pkt_attrib	*pattrib = &pxmitframe->attrib;
2061 	/* struct 	security_priv	*psecuritypriv=&padapter->securitypriv; */
2062 
2063 
2064 	/* if((psecuritypriv->sw_encrypt)||(pattrib->bswenc))	 */
2065 	if (pattrib->bswenc) {
2066 #ifdef DBG_TX_SW_ENCRYPTOR
2067 		RTW_INFO(ADPT_FMT" - sec_type:%s DO SW encryption\n",
2068 			ADPT_ARG(padapter), security_type_str(pattrib->encrypt));
2069 #endif
2070 
2071 		switch (pattrib->encrypt) {
2072 		case _WEP40_:
2073 		case _WEP104_:
2074 			rtw_wep_encrypt(padapter, (u8 *)pxmitframe);
2075 			break;
2076 		case _TKIP_:
2077 			rtw_tkip_encrypt(padapter, (u8 *)pxmitframe);
2078 			break;
2079 		case _AES_:
2080 		case _CCMP_256_:
2081 			rtw_aes_encrypt(padapter, (u8 *)pxmitframe);
2082 			break;
2083 		case _GCMP_:
2084 		case _GCMP_256_:
2085 			rtw_gcmp_encrypt(padapter, (u8 *)pxmitframe);
2086 			break;
2087 #ifdef CONFIG_WAPI_SUPPORT
2088 		case _SMS4_:
2089 			rtw_sms4_encrypt(padapter, (u8 *)pxmitframe);
2090 #endif
2091 		default:
2092 			break;
2093 		}
2094 
2095 	}
2096 
2097 
2098 	return _SUCCESS;
2099 }
2100 
rtw_make_wlanhdr(_adapter * padapter,u8 * hdr,struct pkt_attrib * pattrib)2101 s32 rtw_make_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib)
2102 {
2103 	u16 *qc;
2104 
2105 	struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr;
2106 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2107 	struct qos_priv *pqospriv = &pmlmepriv->qospriv;
2108 	u8 qos_option = _FALSE;
2109 	sint res = _SUCCESS;
2110 	u16 *fctrl = &pwlanhdr->frame_ctl;
2111 
2112 	/* struct sta_info *psta; */
2113 
2114 	/* sint bmcst = IS_MCAST(pattrib->ra); */
2115 
2116 
2117 	/*
2118 		psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2119 		if(pattrib->psta != psta)
2120 		{
2121 			RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
2122 			return;
2123 		}
2124 
2125 		if(psta==NULL)
2126 		{
2127 			RTW_INFO("%s, psta==NUL\n", __func__);
2128 			return _FAIL;
2129 		}
2130 
2131 		if(!(psta->state &WIFI_ASOC_STATE))
2132 		{
2133 			RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state);
2134 			return _FAIL;
2135 		}
2136 	*/
2137 
2138 	_rtw_memset(hdr, 0, WLANHDR_OFFSET);
2139 
2140 	set_frame_sub_type(fctrl, pattrib->subtype);
2141 
2142 	if (pattrib->subtype & WIFI_DATA_TYPE) {
2143 		if ((check_fwstate(pmlmepriv,  WIFI_STATION_STATE) == _TRUE)) {
2144 #ifdef CONFIG_TDLS
2145 			if (pattrib->direct_link == _TRUE) {
2146 				/* TDLS data transfer, ToDS=0, FrDs=0 */
2147 				_rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
2148 				_rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
2149 				_rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
2150 
2151 				if (pattrib->qos_en)
2152 					qos_option = _TRUE;
2153 			} else
2154 #endif /* CONFIG_TDLS */
2155 			{
2156 				#ifdef CONFIG_RTW_WDS
2157 				if (pattrib->wds) {
2158 					SetToDs(fctrl);
2159 					SetFrDs(fctrl);
2160 					_rtw_memcpy(pwlanhdr->addr1, pattrib->ra, ETH_ALEN);
2161 					_rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN);
2162 					_rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
2163 					_rtw_memcpy(pwlanhdr->addr4, pattrib->src, ETH_ALEN);
2164 				} else
2165 				#endif
2166 				{
2167 					/* to_ds = 1, fr_ds = 0; */
2168 					/* 1.Data transfer to AP */
2169 					/* 2.Arp pkt will relayed by AP */
2170 					SetToDs(fctrl);
2171 					_rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
2172 					_rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN);
2173 					_rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
2174 				}
2175 
2176 				if (pqospriv->qos_option)
2177 					qos_option = _TRUE;
2178 			}
2179 		} else if ((check_fwstate(pmlmepriv,  WIFI_AP_STATE) == _TRUE)) {
2180 			#ifdef CONFIG_RTW_WDS
2181 			if (pattrib->wds) {
2182 				SetToDs(fctrl);
2183 				SetFrDs(fctrl);
2184 				_rtw_memcpy(pwlanhdr->addr1, pattrib->ra, ETH_ALEN);
2185 				_rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN);
2186 				_rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
2187 				_rtw_memcpy(pwlanhdr->addr4, pattrib->src, ETH_ALEN);
2188 			} else
2189 			#endif
2190 			{
2191 				/* to_ds = 0, fr_ds = 1; */
2192 				SetFrDs(fctrl);
2193 				_rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
2194 				_rtw_memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN);
2195 				_rtw_memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
2196 			}
2197 
2198 			if (pattrib->qos_en)
2199 				qos_option = _TRUE;
2200 		} else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
2201 			(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
2202 			_rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
2203 			_rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN);
2204 			_rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
2205 
2206 			if (pattrib->qos_en)
2207 				qos_option = _TRUE;
2208 #ifdef CONFIG_RTW_MESH
2209 		} else if (check_fwstate(pmlmepriv, WIFI_MESH_STATE) == _TRUE) {
2210 			rtw_mesh_tx_build_whdr(padapter, pattrib, fctrl, pwlanhdr);
2211 			if (pattrib->qos_en)
2212 				qos_option = _TRUE;
2213 			else {
2214 				RTW_WARN("[%s] !qos_en in Mesh\n", __FUNCTION__);
2215 				res = _FAIL;
2216 				goto exit;
2217 			}
2218 #endif
2219 		} else {
2220 			res = _FAIL;
2221 			goto exit;
2222 		}
2223 
2224 		if (pattrib->mdata)
2225 			SetMData(fctrl);
2226 
2227 		if (pattrib->encrypt)
2228 			SetPrivacy(fctrl);
2229 
2230 		if (qos_option) {
2231 			qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
2232 
2233 			if (pattrib->priority)
2234 				SetPriority(qc, pattrib->priority);
2235 
2236 			SetEOSP(qc, pattrib->eosp);
2237 
2238 			SetAckpolicy(qc, pattrib->ack_policy);
2239 
2240 			if(pattrib->amsdu)
2241 				SetAMsdu(qc, pattrib->amsdu);
2242 #ifdef CONFIG_RTW_MESH
2243 			if (MLME_IS_MESH(padapter)) {
2244 				/* active: don't care, light sleep: 0, deep sleep: 1*/
2245 				set_mps_lv(qc, 0); //TBD
2246 
2247 				/* TBD: temporary set (rspi, eosp) = (0, 1) which means End MPSP */
2248 				set_rspi(qc, 0);
2249 				SetEOSP(qc, 1);
2250 
2251 				set_mctrl_present(qc, 1);
2252 			}
2253 #endif
2254 		}
2255 
2256 		/* TODO: fill HT Control Field */
2257 
2258 		/* Update Seq Num will be handled by f/w */
2259 		{
2260 			struct sta_info *psta;
2261 			psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2262 			if (pattrib->psta != psta) {
2263 				RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
2264 				return _FAIL;
2265 			}
2266 
2267 			if (psta == NULL) {
2268 				RTW_INFO("%s, psta==NUL\n", __func__);
2269 				return _FAIL;
2270 			}
2271 
2272 			if (!(psta->state & WIFI_ASOC_STATE)) {
2273 				RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state);
2274 				return _FAIL;
2275 			}
2276 
2277 
2278 			if (psta) {
2279 				psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
2280 				psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
2281 				pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
2282 
2283 				SetSeqNum(hdr, pattrib->seqnum);
2284 
2285 #ifdef CONFIG_80211N_HT
2286 #if 0 /* move into update_attrib_phy_info(). */
2287 				/* check if enable ampdu */
2288 				if (pattrib->ht_en && psta->htpriv.ampdu_enable) {
2289 					if (psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
2290 						pattrib->ampdu_en = _TRUE;
2291 				}
2292 #endif
2293 				/* re-check if enable ampdu by BA_starting_seqctrl */
2294 				if (pattrib->ampdu_en == _TRUE) {
2295 					u16 tx_seq;
2296 
2297 					tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
2298 
2299 					/* check BA_starting_seqctrl */
2300 					if (SN_LESS(pattrib->seqnum, tx_seq)) {
2301 						/* RTW_INFO("tx ampdu seqnum(%d) < tx_seq(%d)\n", pattrib->seqnum, tx_seq); */
2302 						pattrib->ampdu_en = _FALSE;/* AGG BK */
2303 					} else if (SN_EQUAL(pattrib->seqnum, tx_seq)) {
2304 						psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq + 1) & 0xfff;
2305 
2306 						pattrib->ampdu_en = _TRUE;/* AGG EN */
2307 					} else {
2308 						/* RTW_INFO("tx ampdu over run\n"); */
2309 						psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum + 1) & 0xfff;
2310 						pattrib->ampdu_en = _TRUE;/* AGG EN */
2311 					}
2312 
2313 				}
2314 #endif /* CONFIG_80211N_HT */
2315 			}
2316 		}
2317 
2318 	} else {
2319 
2320 	}
2321 
2322 exit:
2323 
2324 
2325 	return res;
2326 }
2327 
rtw_txframes_pending(_adapter * padapter)2328 s32 rtw_txframes_pending(_adapter *padapter)
2329 {
2330 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2331 
2332 	return ((_rtw_queue_empty(&pxmitpriv->be_pending) == _FALSE) ||
2333 		(_rtw_queue_empty(&pxmitpriv->bk_pending) == _FALSE) ||
2334 		(_rtw_queue_empty(&pxmitpriv->vi_pending) == _FALSE) ||
2335 		(_rtw_queue_empty(&pxmitpriv->vo_pending) == _FALSE)
2336 #ifdef CONFIG_RTW_MGMT_QUEUE
2337 		|| (_rtw_queue_empty(&pxmitpriv->mgmt_pending) == _FALSE)
2338 #endif
2339 		);
2340 }
2341 
rtw_txframes_sta_ac_pending(_adapter * padapter,struct pkt_attrib * pattrib)2342 s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib)
2343 {
2344 	struct sta_info *psta;
2345 	struct tx_servq *ptxservq;
2346 	int priority = pattrib->priority;
2347 	/*
2348 		if(pattrib->psta)
2349 		{
2350 			psta = pattrib->psta;
2351 		}
2352 		else
2353 		{
2354 			RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
2355 			psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
2356 		}
2357 	*/
2358 	psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2359 	if (pattrib->psta != psta) {
2360 		RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
2361 		return 0;
2362 	}
2363 
2364 	if (psta == NULL) {
2365 		RTW_INFO("%s, psta==NUL\n", __func__);
2366 		return 0;
2367 	}
2368 
2369 	if (!(psta->state & WIFI_ASOC_STATE)) {
2370 		RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state);
2371 		return 0;
2372 	}
2373 
2374 	switch (priority) {
2375 	case 1:
2376 	case 2:
2377 		ptxservq = &(psta->sta_xmitpriv.bk_q);
2378 		break;
2379 	case 4:
2380 	case 5:
2381 		ptxservq = &(psta->sta_xmitpriv.vi_q);
2382 		break;
2383 	case 6:
2384 	case 7:
2385 		ptxservq = &(psta->sta_xmitpriv.vo_q);
2386 		break;
2387 	case 0:
2388 	case 3:
2389 	default:
2390 		ptxservq = &(psta->sta_xmitpriv.be_q);
2391 		break;
2392 
2393 	}
2394 
2395 	return ptxservq->qcnt;
2396 }
2397 
2398 #ifdef CONFIG_TDLS
2399 
rtw_build_tdls_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe,struct tdls_txmgmt * ptxmgmt)2400 int rtw_build_tdls_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
2401 {
2402 	struct pkt_attrib *pattrib = &pxmitframe->attrib;
2403 	struct sta_info *ptdls_sta = NULL;
2404 	int res = _SUCCESS;
2405 
2406 	ptdls_sta = rtw_get_stainfo((&padapter->stapriv), pattrib->dst);
2407 	if (ptdls_sta == NULL) {
2408 		switch (ptxmgmt->action_code) {
2409 		case TDLS_DISCOVERY_REQUEST:
2410 		case TUNNELED_PROBE_REQ:
2411 		case TUNNELED_PROBE_RSP:
2412 			break;
2413 		default:
2414 			RTW_INFO("[TDLS] %s - Direct Link Peer = "MAC_FMT" not found for action = %d\n", __func__, MAC_ARG(pattrib->dst), ptxmgmt->action_code);
2415 			res = _FAIL;
2416 			goto exit;
2417 		}
2418 	}
2419 
2420 	switch (ptxmgmt->action_code) {
2421 	case TDLS_SETUP_REQUEST:
2422 		rtw_build_tdls_setup_req_ies(padapter, pxmitframe, pframe, ptxmgmt, ptdls_sta);
2423 		break;
2424 	case TDLS_SETUP_RESPONSE:
2425 		rtw_build_tdls_setup_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt, ptdls_sta);
2426 		break;
2427 	case TDLS_SETUP_CONFIRM:
2428 		rtw_build_tdls_setup_cfm_ies(padapter, pxmitframe, pframe, ptxmgmt, ptdls_sta);
2429 		break;
2430 	case TDLS_TEARDOWN:
2431 		rtw_build_tdls_teardown_ies(padapter, pxmitframe, pframe, ptxmgmt, ptdls_sta);
2432 		break;
2433 	case TDLS_DISCOVERY_REQUEST:
2434 		rtw_build_tdls_dis_req_ies(padapter, pxmitframe, pframe, ptxmgmt);
2435 		break;
2436 	case TDLS_PEER_TRAFFIC_INDICATION:
2437 		rtw_build_tdls_peer_traffic_indication_ies(padapter, pxmitframe, pframe, ptxmgmt, ptdls_sta);
2438 		break;
2439 #ifdef CONFIG_TDLS_CH_SW
2440 	case TDLS_CHANNEL_SWITCH_REQUEST:
2441 		rtw_build_tdls_ch_switch_req_ies(padapter, pxmitframe, pframe, ptxmgmt, ptdls_sta);
2442 		break;
2443 	case TDLS_CHANNEL_SWITCH_RESPONSE:
2444 		rtw_build_tdls_ch_switch_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt, ptdls_sta);
2445 		break;
2446 #endif
2447 	case TDLS_PEER_TRAFFIC_RESPONSE:
2448 		rtw_build_tdls_peer_traffic_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt, ptdls_sta);
2449 		break;
2450 #ifdef CONFIG_WFD
2451 	case TUNNELED_PROBE_REQ:
2452 		rtw_build_tunneled_probe_req_ies(padapter, pxmitframe, pframe);
2453 		break;
2454 	case TUNNELED_PROBE_RSP:
2455 		rtw_build_tunneled_probe_rsp_ies(padapter, pxmitframe, pframe);
2456 		break;
2457 #endif /* CONFIG_WFD */
2458 	default:
2459 		res = _FAIL;
2460 		break;
2461 	}
2462 
2463 exit:
2464 	return res;
2465 }
2466 
rtw_make_tdls_wlanhdr(_adapter * padapter,u8 * hdr,struct pkt_attrib * pattrib,struct tdls_txmgmt * ptxmgmt)2467 s32 rtw_make_tdls_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt)
2468 {
2469 	u16 *qc;
2470 	struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr;
2471 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2472 	struct qos_priv *pqospriv = &pmlmepriv->qospriv;
2473 	struct sta_priv	*pstapriv = &padapter->stapriv;
2474 	struct sta_info *psta = NULL, *ptdls_sta = NULL;
2475 	u8 tdls_seq = 0, baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2476 
2477 	sint res = _SUCCESS;
2478 	u16 *fctrl = &pwlanhdr->frame_ctl;
2479 
2480 
2481 	_rtw_memset(hdr, 0, WLANHDR_OFFSET);
2482 
2483 	set_frame_sub_type(fctrl, pattrib->subtype);
2484 
2485 	switch (ptxmgmt->action_code) {
2486 	case TDLS_SETUP_REQUEST:
2487 	case TDLS_SETUP_RESPONSE:
2488 	case TDLS_SETUP_CONFIRM:
2489 	case TDLS_PEER_TRAFFIC_INDICATION:
2490 	case TDLS_PEER_PSM_REQUEST:
2491 	case TUNNELED_PROBE_REQ:
2492 	case TUNNELED_PROBE_RSP:
2493 	case TDLS_DISCOVERY_REQUEST:
2494 		SetToDs(fctrl);
2495 		_rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
2496 		_rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
2497 		_rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
2498 		break;
2499 	case TDLS_CHANNEL_SWITCH_REQUEST:
2500 	case TDLS_CHANNEL_SWITCH_RESPONSE:
2501 	case TDLS_PEER_PSM_RESPONSE:
2502 	case TDLS_PEER_TRAFFIC_RESPONSE:
2503 		_rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
2504 		_rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
2505 		_rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
2506 		tdls_seq = 1;
2507 		break;
2508 	case TDLS_TEARDOWN:
2509 		if (ptxmgmt->status_code == _RSON_TDLS_TEAR_UN_RSN_) {
2510 			_rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
2511 			_rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
2512 			_rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
2513 			tdls_seq = 1;
2514 		} else {
2515 			SetToDs(fctrl);
2516 			_rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
2517 			_rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
2518 			_rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
2519 		}
2520 		break;
2521 	}
2522 
2523 	if (pattrib->encrypt)
2524 		SetPrivacy(fctrl);
2525 
2526 	if (ptxmgmt->action_code == TDLS_PEER_TRAFFIC_RESPONSE)
2527 		SetPwrMgt(fctrl);
2528 
2529 	if (pqospriv->qos_option) {
2530 		qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
2531 		if (pattrib->priority)
2532 			SetPriority(qc, pattrib->priority);
2533 		SetAckpolicy(qc, pattrib->ack_policy);
2534 	}
2535 
2536 	psta = pattrib->psta;
2537 
2538 	/* 1. update seq_num per link by sta_info */
2539 	/* 2. rewrite encrypt to _AES_, also rewrite iv_len, icv_len */
2540 	if (tdls_seq == 1) {
2541 		ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
2542 		if (ptdls_sta) {
2543 			ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
2544 			ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
2545 			pattrib->seqnum = ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority];
2546 			SetSeqNum(hdr, pattrib->seqnum);
2547 
2548 			if (pattrib->encrypt) {
2549 				pattrib->encrypt = _AES_;
2550 				pattrib->iv_len = 8;
2551 				pattrib->icv_len = 8;
2552 				pattrib->bswenc = _FALSE;
2553 			}
2554 			pattrib->mac_id = ptdls_sta->cmn.mac_id;
2555 		} else {
2556 			res = _FAIL;
2557 			goto exit;
2558 		}
2559 	} else if (psta) {
2560 		psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
2561 		psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
2562 		pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
2563 		SetSeqNum(hdr, pattrib->seqnum);
2564 	}
2565 
2566 
2567 exit:
2568 
2569 
2570 	return res;
2571 }
2572 
rtw_xmit_tdls_coalesce(_adapter * padapter,struct xmit_frame * pxmitframe,struct tdls_txmgmt * ptxmgmt)2573 s32 rtw_xmit_tdls_coalesce(_adapter *padapter, struct xmit_frame *pxmitframe, struct tdls_txmgmt *ptxmgmt)
2574 {
2575 	s32 llc_sz;
2576 
2577 	u8 *pframe, *mem_start;
2578 
2579 	struct sta_info		*psta;
2580 	struct sta_priv		*pstapriv = &padapter->stapriv;
2581 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
2582 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
2583 	u8 *pbuf_start;
2584 	s32 bmcst = IS_MCAST(pattrib->ra);
2585 	s32 res = _SUCCESS;
2586 
2587 
2588 	if (pattrib->psta)
2589 		psta = pattrib->psta;
2590 	else {
2591 		if (bmcst)
2592 			psta = rtw_get_bcmc_stainfo(padapter);
2593 		else
2594 			psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2595 	}
2596 
2597 	if (psta == NULL) {
2598 		res = _FAIL;
2599 		goto exit;
2600 	}
2601 
2602 	if (pxmitframe->buf_addr == NULL) {
2603 		res = _FAIL;
2604 		goto exit;
2605 	}
2606 
2607 	pbuf_start = pxmitframe->buf_addr;
2608 	mem_start = pbuf_start + TXDESC_OFFSET;
2609 
2610 	if (rtw_make_tdls_wlanhdr(padapter, mem_start, pattrib, ptxmgmt) == _FAIL) {
2611 		res = _FAIL;
2612 		goto exit;
2613 	}
2614 
2615 	pframe = mem_start;
2616 	pframe += pattrib->hdrlen;
2617 
2618 	/* adding icv, if necessary... */
2619 	if (pattrib->iv_len) {
2620 		if (psta != NULL) {
2621 			switch (pattrib->encrypt) {
2622 			case _WEP40_:
2623 			case _WEP104_:
2624 				WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2625 				break;
2626 			case _TKIP_:
2627 				if (bmcst)
2628 					TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2629 				else
2630 					TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
2631 				break;
2632 			case _AES_:
2633 				if (bmcst)
2634 					AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2635 				else
2636 					AES_IV(pattrib->iv, psta->dot11txpn, 0);
2637 				break;
2638 			}
2639 		}
2640 
2641 		_rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
2642 		pframe += pattrib->iv_len;
2643 
2644 	}
2645 
2646 	llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
2647 	pframe += llc_sz;
2648 
2649 	/* pattrib->pktlen will be counted in rtw_build_tdls_ies */
2650 	pattrib->pktlen = 0;
2651 
2652 	rtw_build_tdls_ies(padapter, pxmitframe, pframe, ptxmgmt);
2653 
2654 	if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2655 		pframe += pattrib->pktlen;
2656 		_rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2657 		pframe += pattrib->icv_len;
2658 	}
2659 
2660 	pattrib->nr_frags = 1;
2661 	pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + llc_sz +
2662 		((pattrib->bswenc) ? pattrib->icv_len : 0) + pattrib->pktlen;
2663 
2664 	if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
2665 		res = _FAIL;
2666 		goto exit;
2667 	}
2668 
2669 	xmitframe_swencrypt(padapter, pxmitframe);
2670 
2671 	update_attrib_vcs_info(padapter, pxmitframe);
2672 
2673 exit:
2674 
2675 
2676 	return res;
2677 }
2678 #endif /* CONFIG_TDLS */
2679 
2680 /*
2681  * Calculate wlan 802.11 packet MAX size from pkt_attrib
2682  * This function doesn't consider fragment case
2683  */
rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib * pattrib)2684 u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib)
2685 {
2686 	u32	len = 0;
2687 
2688 	len = pattrib->hdrlen /* WLAN Header */
2689 		+ pattrib->iv_len /* IV */
2690 		+ XATTRIB_GET_MCTRL_LEN(pattrib)
2691 		+ SNAP_SIZE + sizeof(u16) /* LLC */
2692 		+ pattrib->pktlen
2693 		+ (pattrib->encrypt == _TKIP_ ? 8 : 0) /* MIC */
2694 		+ (pattrib->bswenc ? pattrib->icv_len : 0) /* ICV */
2695 		;
2696 
2697 	return len;
2698 }
2699 
2700 #ifdef CONFIG_TX_AMSDU
check_amsdu(struct xmit_frame * pxmitframe)2701 s32 check_amsdu(struct xmit_frame *pxmitframe)
2702 {
2703 	struct pkt_attrib *pattrib;
2704 	struct sta_info *psta = NULL;
2705 	s32 ret = _TRUE;
2706 
2707 	if (!pxmitframe)
2708 		ret = _FALSE;
2709 
2710 	pattrib = &pxmitframe->attrib;
2711 
2712 	psta = rtw_get_stainfo(&pxmitframe->padapter->stapriv, &pattrib->ra[0]);
2713 	if (psta) {
2714 		if (psta->flags & WLAN_STA_AMSDU_DISABLE)
2715 			ret =_FALSE;
2716 	}
2717 	if (IS_MCAST(pattrib->ra))
2718 		ret = _FALSE;
2719 
2720 	if ((pattrib->ether_type == 0x888e) ||
2721 		(pattrib->ether_type == 0x0806) ||
2722 		(pattrib->ether_type == 0x88b4) ||
2723 		(pattrib->dhcp_pkt == 1))
2724 		ret = _FALSE;
2725 
2726 	if ((pattrib->encrypt == _WEP40_) ||
2727 	    (pattrib->encrypt == _WEP104_) ||
2728 	    (pattrib->encrypt == _TKIP_))
2729 		ret = _FALSE;
2730 
2731 	if (!pattrib->qos_en)
2732 		ret = _FALSE;
2733 
2734 	if (IS_AMSDU_AMPDU_NOT_VALID(pattrib))
2735 		ret = _FALSE;
2736 
2737 	return ret;
2738 }
2739 
check_amsdu_tx_support(_adapter * padapter)2740 s32 check_amsdu_tx_support(_adapter *padapter)
2741 {
2742 	struct dvobj_priv *pdvobjpriv;
2743 	int tx_amsdu;
2744 	int tx_amsdu_rate;
2745 	int current_tx_rate;
2746 	s32 ret = _FALSE;
2747 
2748 	pdvobjpriv = adapter_to_dvobj(padapter);
2749 	tx_amsdu = padapter->tx_amsdu;
2750 	tx_amsdu_rate = padapter->tx_amsdu_rate;
2751 	current_tx_rate = pdvobjpriv->traffic_stat.cur_tx_tp;
2752 
2753 	if (tx_amsdu == 1)
2754 		ret = _TRUE;
2755 	else if (tx_amsdu == 2 && (tx_amsdu_rate == 0 || current_tx_rate > tx_amsdu_rate))
2756 		ret = _TRUE;
2757 	else
2758 		ret = _FALSE;
2759 
2760 	return ret;
2761 }
2762 
rtw_xmitframe_coalesce_amsdu(_adapter * padapter,struct xmit_frame * pxmitframe,struct xmit_frame * pxmitframe_queue)2763 s32 rtw_xmitframe_coalesce_amsdu(_adapter *padapter, struct xmit_frame *pxmitframe, struct xmit_frame *pxmitframe_queue)
2764 {
2765 
2766 	struct pkt_file pktfile;
2767 	struct pkt_attrib *pattrib;
2768 	_pkt *pkt;
2769 
2770 	struct pkt_file pktfile_queue;
2771 	struct pkt_attrib *pattrib_queue;
2772 	_pkt *pkt_queue;
2773 
2774 	s32 llc_sz, mem_sz;
2775 
2776 	s32 padding = 0;
2777 
2778 	u8 *pframe, *mem_start;
2779 	u8 hw_hdr_offset;
2780 
2781 	u16* len;
2782 	u8 *pbuf_start;
2783 	s32 res = _SUCCESS;
2784 
2785 	if (pxmitframe->buf_addr == NULL) {
2786 		RTW_INFO("==> %s buf_addr==NULL\n", __FUNCTION__);
2787 		return _FAIL;
2788 	}
2789 
2790 
2791 	pbuf_start = pxmitframe->buf_addr;
2792 
2793 #ifdef CONFIG_USB_TX_AGGREGATION
2794 	hw_hdr_offset =  TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
2795 #else
2796 #ifdef CONFIG_TX_EARLY_MODE /* for SDIO && Tx Agg */
2797 	hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
2798 #else
2799 	hw_hdr_offset = TXDESC_OFFSET;
2800 #endif
2801 #endif
2802 
2803 	mem_start = pbuf_start + hw_hdr_offset; //for DMA
2804 
2805 	pattrib = &pxmitframe->attrib;
2806 
2807 	pattrib->amsdu = 1;
2808 
2809 	if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
2810 		RTW_INFO("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n");
2811 		res = _FAIL;
2812 		goto exit;
2813 	}
2814 
2815 	llc_sz = 0;
2816 
2817 	pframe = mem_start;
2818 
2819 	//SetMFrag(mem_start);
2820 	ClearMFrag(mem_start);
2821 
2822 	pframe += pattrib->hdrlen;
2823 
2824 	/* adding icv, if necessary... */
2825 	if (pattrib->iv_len) {
2826 		_rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len); // queue or new?
2827 
2828 		RTW_DBG("rtw_xmitframe_coalesce: keyid=%d pattrib->iv[3]=%.2x pframe=%.2x %.2x %.2x %.2x\n",
2829 			padapter->securitypriv.dot11PrivacyKeyIndex, pattrib->iv[3], *pframe, *(pframe + 1), *(pframe + 2), *(pframe + 3));
2830 
2831 		pframe += pattrib->iv_len;
2832 	}
2833 
2834 	pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len;
2835 
2836 	if(pxmitframe_queue)
2837 	{
2838 		pattrib_queue = &pxmitframe_queue->attrib;
2839 		pkt_queue = pxmitframe_queue->pkt;
2840 
2841 		_rtw_open_pktfile(pkt_queue, &pktfile_queue);
2842 		_rtw_pktfile_read(&pktfile_queue, NULL, pattrib_queue->pkt_hdrlen);
2843 
2844 		#ifdef CONFIG_RTW_MESH
2845 		if (MLME_IS_MESH(padapter)) {
2846 			/* mDA(6), mSA(6), len(2), mctrl */
2847 			_rtw_memcpy(pframe, pattrib_queue->mda, ETH_ALEN);
2848 			pframe += ETH_ALEN;
2849 			_rtw_memcpy(pframe, pattrib_queue->msa, ETH_ALEN);
2850 			pframe += ETH_ALEN;
2851 			len = (u16*)pframe;
2852 			pframe += 2;
2853 			rtw_mesh_tx_build_mctrl(padapter, pattrib_queue, pframe);
2854 			pframe += XATTRIB_GET_MCTRL_LEN(pattrib_queue);
2855 		} else
2856 		#endif
2857 		{
2858 			/* 802.3 MAC Header DA(6)  SA(6)  Len(2)*/
2859 			_rtw_memcpy(pframe, pattrib_queue->dst, ETH_ALEN);
2860 			pframe += ETH_ALEN;
2861 			_rtw_memcpy(pframe, pattrib_queue->src, ETH_ALEN);
2862 			pframe += ETH_ALEN;
2863 			len = (u16*)pframe;
2864 			pframe += 2;
2865 		}
2866 
2867 		llc_sz = rtw_put_snap(pframe, pattrib_queue->ether_type);
2868 		pframe += llc_sz;
2869 
2870 		mem_sz = _rtw_pktfile_read(&pktfile_queue, pframe, pattrib_queue->pktlen);
2871 		pframe += mem_sz;
2872 
2873 		*len = htons(XATTRIB_GET_MCTRL_LEN(pattrib_queue) + llc_sz + mem_sz);
2874 
2875 		//calc padding
2876 		padding = 4 - ((ETH_HLEN + XATTRIB_GET_MCTRL_LEN(pattrib_queue) + llc_sz + mem_sz) & (4-1));
2877 		if(padding == 4)
2878 			padding = 0;
2879 
2880 		//_rtw_memset(pframe,0xaa, padding);
2881 		pframe += padding;
2882 
2883 		pattrib->last_txcmdsz += ETH_HLEN + XATTRIB_GET_MCTRL_LEN(pattrib_queue) + llc_sz + mem_sz + padding ;
2884 	}
2885 
2886 	//2nd mpdu
2887 
2888 	pkt = pxmitframe->pkt;
2889 	_rtw_open_pktfile(pkt, &pktfile);
2890 	_rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
2891 
2892 #ifdef CONFIG_RTW_MESH
2893 	if (MLME_IS_MESH(padapter)) {
2894 		/* mDA(6), mSA(6), len(2), mctrl */
2895 		_rtw_memcpy(pframe, pattrib->mda, ETH_ALEN);
2896 		pframe += ETH_ALEN;
2897 		_rtw_memcpy(pframe, pattrib->msa, ETH_ALEN);
2898 		pframe += ETH_ALEN;
2899 		len = (u16*)pframe;
2900 		pframe += 2;
2901 		rtw_mesh_tx_build_mctrl(padapter, pattrib, pframe);
2902 		pframe += XATTRIB_GET_MCTRL_LEN(pattrib);
2903 	} else
2904 #endif
2905 	{
2906 		/* 802.3 MAC Header  DA(6)  SA(6)  Len(2) */
2907 		_rtw_memcpy(pframe, pattrib->dst, ETH_ALEN);
2908 		pframe += ETH_ALEN;
2909 		_rtw_memcpy(pframe, pattrib->src, ETH_ALEN);
2910 		pframe += ETH_ALEN;
2911 		len = (u16*)pframe;
2912 		pframe += 2;
2913 	}
2914 
2915 	llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
2916 	pframe += llc_sz;
2917 
2918 	mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
2919 
2920 	pframe += mem_sz;
2921 
2922 	*len = htons(XATTRIB_GET_MCTRL_LEN(pattrib) + llc_sz + mem_sz);
2923 
2924 	//the last ampdu has no padding
2925 	padding = 0;
2926 
2927 	pattrib->nr_frags = 1;
2928 
2929 	pattrib->last_txcmdsz += ETH_HLEN + XATTRIB_GET_MCTRL_LEN(pattrib) + llc_sz + mem_sz + padding +
2930 		((pattrib->bswenc) ? pattrib->icv_len : 0) ;
2931 
2932 	if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2933 		_rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2934 		pframe += pattrib->icv_len;
2935 	}
2936 
2937 	if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
2938 		RTW_INFO("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n");
2939 		res = _FAIL;
2940 		goto exit;
2941 	}
2942 
2943 	xmitframe_swencrypt(padapter, pxmitframe);
2944 
2945 	update_attrib_vcs_info(padapter, pxmitframe);
2946 
2947 exit:
2948 	return res;
2949 }
2950 #endif /* CONFIG_TX_AMSDU */
2951 
2952 /*
2953 
2954 This sub-routine will perform all the following:
2955 
2956 1. remove 802.3 header.
2957 2. create wlan_header, based on the info in pxmitframe
2958 3. append sta's iv/ext-iv
2959 4. append LLC
2960 5. move frag chunk from pframe to pxmitframe->mem
2961 6. apply sw-encrypt, if necessary.
2962 
2963 */
rtw_xmitframe_coalesce(_adapter * padapter,_pkt * pkt,struct xmit_frame * pxmitframe)2964 s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
2965 {
2966 	struct pkt_file pktfile;
2967 
2968 	s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
2969 
2970 	SIZE_PTR addr;
2971 
2972 	u8 *pframe, *mem_start;
2973 	u8 hw_hdr_offset;
2974 
2975 	/* struct sta_info		*psta; */
2976 	/* struct sta_priv		*pstapriv = &padapter->stapriv; */
2977 	/* struct mlme_priv	*pmlmepriv = &padapter->mlmepriv; */
2978 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
2979 
2980 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
2981 
2982 	u8 *pbuf_start;
2983 
2984 	s32 bmcst = IS_MCAST(pattrib->ra);
2985 	s32 res = _SUCCESS;
2986 
2987 
2988 	/*
2989 		if (pattrib->psta)
2990 		{
2991 			psta = pattrib->psta;
2992 		} else
2993 		{
2994 			RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
2995 			psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2996 		}
2997 
2998 		if(psta==NULL)
2999 		{
3000 
3001 			RTW_INFO("%s, psta==NUL\n", __func__);
3002 			return _FAIL;
3003 		}
3004 
3005 
3006 		if(!(psta->state &WIFI_ASOC_STATE))
3007 		{
3008 			RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state);
3009 			return _FAIL;
3010 		}
3011 	*/
3012 	if (pxmitframe->buf_addr == NULL) {
3013 		RTW_INFO("==> %s buf_addr==NULL\n", __FUNCTION__);
3014 		return _FAIL;
3015 	}
3016 
3017 	pbuf_start = pxmitframe->buf_addr;
3018 
3019 #ifdef CONFIG_USB_TX_AGGREGATION
3020 	hw_hdr_offset =  TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
3021 #else
3022 #ifdef CONFIG_TX_EARLY_MODE /* for SDIO && Tx Agg */
3023 	hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
3024 #else
3025 	hw_hdr_offset = TXDESC_OFFSET;
3026 #endif
3027 #endif
3028 
3029 	mem_start = pbuf_start +	hw_hdr_offset;
3030 
3031 	if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
3032 		RTW_INFO("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n");
3033 		res = _FAIL;
3034 		goto exit;
3035 	}
3036 
3037 	_rtw_open_pktfile(pkt, &pktfile);
3038 	_rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
3039 
3040 	frg_inx = 0;
3041 	frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
3042 
3043 	while (1) {
3044 		llc_sz = 0;
3045 
3046 		mpdu_len = frg_len;
3047 
3048 		pframe = mem_start;
3049 
3050 		SetMFrag(mem_start);
3051 
3052 		pframe += pattrib->hdrlen;
3053 		mpdu_len -= pattrib->hdrlen;
3054 
3055 		/* adding icv, if necessary... */
3056 		if (pattrib->iv_len) {
3057 #if 0
3058 			/* if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) */
3059 			/*	psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); */
3060 			/* else */
3061 			/*	psta = rtw_get_stainfo(pstapriv, pattrib->ra); */
3062 
3063 			if (psta != NULL) {
3064 				switch (pattrib->encrypt) {
3065 				case _WEP40_:
3066 				case _WEP104_:
3067 					WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
3068 					break;
3069 				case _TKIP_:
3070 					if (bmcst)
3071 						TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
3072 					else
3073 						TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
3074 					break;
3075 				case _AES_:
3076 					if (bmcst)
3077 						AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
3078 					else
3079 						AES_IV(pattrib->iv, psta->dot11txpn, 0);
3080 					break;
3081 #ifdef CONFIG_WAPI_SUPPORT
3082 				case _SMS4_:
3083 					rtw_wapi_get_iv(padapter, pattrib->ra, pattrib->iv);
3084 					break;
3085 #endif
3086 				}
3087 			}
3088 #endif
3089 			_rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
3090 
3091 
3092 			pframe += pattrib->iv_len;
3093 
3094 			mpdu_len -= pattrib->iv_len;
3095 		}
3096 
3097 		if (frg_inx == 0) {
3098 			#ifdef CONFIG_RTW_MESH
3099 			if (MLME_IS_MESH(padapter)) {
3100 				rtw_mesh_tx_build_mctrl(padapter, pattrib, pframe);
3101 				pframe += XATTRIB_GET_MCTRL_LEN(pattrib);
3102 				mpdu_len -= XATTRIB_GET_MCTRL_LEN(pattrib);
3103 			}
3104 			#endif
3105 
3106 			llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
3107 			pframe += llc_sz;
3108 			mpdu_len -= llc_sz;
3109 		}
3110 
3111 		if ((pattrib->icv_len > 0) && (pattrib->bswenc))
3112 			mpdu_len -= pattrib->icv_len;
3113 
3114 
3115 		if (bmcst) {
3116 			/* don't do fragment to broadcat/multicast packets */
3117 			mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
3118 		} else
3119 			mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len);
3120 
3121 		pframe += mem_sz;
3122 
3123 		if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
3124 			_rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
3125 			pframe += pattrib->icv_len;
3126 		}
3127 
3128 		frg_inx++;
3129 
3130 		if (bmcst || (rtw_endofpktfile(&pktfile) == _TRUE)) {
3131 			pattrib->nr_frags = frg_inx;
3132 
3133 			pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len +
3134 				((pattrib->nr_frags == 1) ? (XATTRIB_GET_MCTRL_LEN(pattrib) + llc_sz) : 0) +
3135 				((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz;
3136 
3137 			ClearMFrag(mem_start);
3138 
3139 			break;
3140 		}
3141 
3142 		addr = (SIZE_PTR)(pframe);
3143 
3144 		mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset;
3145 		_rtw_memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
3146 
3147 	}
3148 
3149 	if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
3150 		RTW_INFO("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n");
3151 		res = _FAIL;
3152 		goto exit;
3153 	}
3154 
3155 	xmitframe_swencrypt(padapter, pxmitframe);
3156 
3157 	if (bmcst == _FALSE)
3158 		update_attrib_vcs_info(padapter, pxmitframe);
3159 	else
3160 		pattrib->vcs_mode = NONE_VCS;
3161 
3162 exit:
3163 
3164 
3165 	return res;
3166 }
3167 
3168 #if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH)
3169 /*
3170  * CCMP encryption for unicast robust mgmt frame and broadcast group privicy action
3171  * BIP for broadcast robust mgmt frame
3172  */
rtw_mgmt_xmitframe_coalesce(_adapter * padapter,_pkt * pkt,struct xmit_frame * pxmitframe)3173 s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
3174 {
3175 #define DBG_MGMT_XMIT_COALESEC_DUMP 0
3176 #define DBG_MGMT_XMIT_BIP_DUMP 0
3177 #define DBG_MGMT_XMIT_ENC_DUMP 0
3178 
3179 	struct pkt_file pktfile;
3180 	s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
3181 	SIZE_PTR addr;
3182 	u8 *pframe, *mem_start = NULL, *tmp_buf = NULL;
3183 	u8 hw_hdr_offset, subtype ;
3184 	u8 category = 0xFF;
3185 	struct sta_info		*psta = NULL;
3186 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
3187 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
3188 	u8 *pbuf_start;
3189 	s32 bmcst = IS_MCAST(pattrib->ra);
3190 	s32 res = _FAIL;
3191 	u8 *BIP_AAD = NULL;
3192 	u8 *MGMT_body = NULL;
3193 
3194 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3195 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
3196 	struct rtw_ieee80211_hdr	*pwlanhdr;
3197 	u8 mme_cont[_MME_IE_LENGTH_ - 2];
3198 	u8 mme_clen;
3199 
3200 	_irqL irqL;
3201 	u32	ori_len;
3202 	union pn48 *pn = NULL;
3203 	enum security_type cipher = _NO_PRIVACY_;
3204 	u8 kid;
3205 
3206 	if (pxmitframe->buf_addr == NULL) {
3207 		RTW_WARN(FUNC_ADPT_FMT" pxmitframe->buf_addr\n"
3208 			, FUNC_ADPT_ARG(padapter));
3209 		return _FAIL;
3210 	}
3211 
3212 	mem_start = pframe = (u8 *)(pxmitframe->buf_addr) + TXDESC_OFFSET;
3213 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3214 	subtype = get_frame_sub_type(pframe); /* bit(7)~bit(2) */
3215 
3216 	/* check if robust mgmt frame */
3217 	if (subtype != WIFI_DEAUTH && subtype != WIFI_DISASSOC && subtype != WIFI_ACTION)
3218 		return _SUCCESS;
3219 	if (subtype == WIFI_ACTION) {
3220 		category = *(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3221 		if (CATEGORY_IS_NON_ROBUST(category))
3222 			return _SUCCESS;
3223 	}
3224 	if (!bmcst) {
3225 		if (pattrib->psta)
3226 			psta = pattrib->psta;
3227 		else
3228 			pattrib->psta = psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
3229 		if (psta == NULL) {
3230 			RTW_INFO(FUNC_ADPT_FMT" unicast sta == NULL\n", FUNC_ADPT_ARG(padapter));
3231 			return _FAIL;
3232 		}
3233 		if (!(psta->flags & WLAN_STA_MFP)) {
3234 			/* peer is not MFP capable, no need to encrypt */
3235 			return _SUCCESS;
3236 		}
3237 		if (psta->bpairwise_key_installed != _TRUE) {
3238 			RTW_INFO(FUNC_ADPT_FMT" PTK is not installed\n"
3239 				, FUNC_ADPT_ARG(padapter));
3240 			return _FAIL;
3241 		}
3242 	}
3243 
3244 	ori_len = BIP_AAD_SIZE + pattrib->pktlen + _MME_IE_LENGTH_;
3245 	tmp_buf = BIP_AAD = rtw_zmalloc(ori_len);
3246 	if (BIP_AAD == NULL)
3247 		return _FAIL;
3248 
3249 	_enter_critical_bh(&padapter->security_key_mutex, &irqL);
3250 
3251 	if (bmcst) {
3252 		if (subtype == WIFI_ACTION && CATEGORY_IS_GROUP_PRIVACY(category)) {
3253 			/* broadcast group privacy action frame */
3254 			#if DBG_MGMT_XMIT_COALESEC_DUMP
3255 			RTW_INFO(FUNC_ADPT_FMT" broadcast gp action(%u)\n"
3256 				, FUNC_ADPT_ARG(padapter), category);
3257 			#endif
3258 
3259 			if (pattrib->psta)
3260 				psta = pattrib->psta;
3261 			else
3262 				pattrib->psta = psta = rtw_get_bcmc_stainfo(padapter);
3263 			if (psta == NULL) {
3264 				RTW_INFO(FUNC_ADPT_FMT" broadcast sta == NULL\n"
3265 					, FUNC_ADPT_ARG(padapter));
3266 				goto xmitframe_coalesce_fail;
3267 			}
3268 			if (padapter->securitypriv.binstallGrpkey != _TRUE) {
3269 				RTW_INFO(FUNC_ADPT_FMT" GTK is not installed\n"
3270 					, FUNC_ADPT_ARG(padapter));
3271 				goto xmitframe_coalesce_fail;
3272 			}
3273 
3274 			pn = &psta->dot11txpn;
3275 			cipher = padapter->securitypriv.dot118021XGrpPrivacy;
3276 			kid = padapter->securitypriv.dot118021XGrpKeyid;
3277 		} else {
3278 			#ifdef CONFIG_IEEE80211W
3279 			/* broadcast robust mgmt frame, using BIP */
3280 			int frame_body_len;
3281 			u8 mic[16];
3282 
3283 			/* IGTK key is not install ex: mesh MFP without IGTK */
3284 			if (SEC_IS_BIP_KEY_INSTALLED(&padapter->securitypriv) != _TRUE)
3285 				goto xmitframe_coalesce_success;
3286 
3287 			#if DBG_MGMT_XMIT_COALESEC_DUMP
3288 			if (subtype == WIFI_DEAUTH)
3289 				RTW_INFO(FUNC_ADPT_FMT" braodcast deauth\n", FUNC_ADPT_ARG(padapter));
3290 			else if (subtype == WIFI_DISASSOC)
3291 				RTW_INFO(FUNC_ADPT_FMT" braodcast disassoc\n", FUNC_ADPT_ARG(padapter));
3292 			else if (subtype == WIFI_ACTION) {
3293 				RTW_INFO(FUNC_ADPT_FMT" braodcast action(%u)\n"
3294 					, FUNC_ADPT_ARG(padapter), category);
3295 			}
3296 			#endif
3297 
3298 			_rtw_memset(mme_cont, 0, _MME_IE_LENGTH_ - 2);
3299 			mme_clen = padapter->securitypriv.dot11wCipher == _BIP_CMAC_128_ ? 16 : 24;
3300 
3301 			MGMT_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
3302 			pframe += pattrib->pktlen;
3303 
3304 			/* octent 0 and 1 is key index ,BIP keyid is 4 or 5, LSB only need octent 0 */
3305 			mme_cont[0] = padapter->securitypriv.dot11wBIPKeyid;
3306 			/* increase PN and apply to packet */
3307 			padapter->securitypriv.dot11wBIPtxpn.val++;
3308 			RTW_PUT_LE64(&mme_cont[2], padapter->securitypriv.dot11wBIPtxpn.val);
3309 
3310 			/* add MME IE with MIC all zero, MME string doesn't include element id and length */
3311 			pframe = rtw_set_ie(pframe, _MME_IE_ , mme_clen , mme_cont, &(pattrib->pktlen));
3312 			pattrib->last_txcmdsz = pattrib->pktlen;
3313 			/* total frame length - header length */
3314 			frame_body_len = pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr);
3315 
3316 			/* conscruct AAD, copy frame control field */
3317 			_rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2);
3318 			ClearRetry(BIP_AAD);
3319 			ClearPwrMgt(BIP_AAD);
3320 			ClearMData(BIP_AAD);
3321 			/* conscruct AAD, copy address 1 to address 3 */
3322 			_rtw_memcpy(BIP_AAD + 2, GetAddr1Ptr((u8 *)pwlanhdr), 18);
3323 			/* copy management fram body */
3324 			_rtw_memcpy(BIP_AAD + BIP_AAD_SIZE, MGMT_body, frame_body_len);
3325 
3326 			#if DBG_MGMT_XMIT_BIP_DUMP
3327 			/* dump total packet include MME with zero MIC */
3328 			{
3329 				int i;
3330 				printk("Total packet: ");
3331 				for (i = 0; i < BIP_AAD_SIZE + frame_body_len; i++)
3332 					printk(" %02x ", BIP_AAD[i]);
3333 				printk("\n");
3334 			}
3335 			#endif
3336 
3337 			/* calculate mic */
3338 			if (rtw_calculate_bip_mic(padapter->securitypriv.dot11wCipher,
3339 				(u8 *)pwlanhdr, pattrib->pktlen,
3340 				padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey,
3341 				BIP_AAD, (BIP_AAD_SIZE + frame_body_len), mic) == _FAIL)
3342 				goto xmitframe_coalesce_fail;
3343 
3344 			#if DBG_MGMT_XMIT_BIP_DUMP
3345 			/* dump calculated mic result */
3346 			{
3347 				int i;
3348 				printk("Calculated mic result: ");
3349 				for (i = 0; i < 16; i++)
3350 					printk(" %02x ", mic[i]);
3351 				printk("\n");
3352 			}
3353 			#endif
3354 
3355 			/* copy right BIP mic value, total is 128bits, we use the 0~63 bits */
3356 			if (padapter->securitypriv.dot11wCipher == _BIP_CMAC_128_)
3357 				_rtw_memcpy(pframe - 8, mic, 8);
3358 			else
3359 				_rtw_memcpy(pframe - 16, mic, 16);
3360 
3361 			#if DBG_MGMT_XMIT_BIP_DUMP
3362 			/*dump all packet after mic ok */
3363 			{
3364 				int pp;
3365 				printk("pattrib->pktlen = %d\n", pattrib->pktlen);
3366 				for(pp=0;pp< pattrib->pktlen; pp++)
3367 					printk(" %02x ", mem_start[pp]);
3368 				printk("\n");
3369 			}
3370 			#endif
3371 
3372 			#endif /* CONFIG_IEEE80211W */
3373 
3374 			goto xmitframe_coalesce_success;
3375 		}
3376 	}
3377 	else {
3378 		/* unicast robust mgmt frame */
3379 		#if DBG_MGMT_XMIT_COALESEC_DUMP
3380 		if (subtype == WIFI_DEAUTH) {
3381 			RTW_INFO(FUNC_ADPT_FMT" unicast deauth to "MAC_FMT"\n"
3382 				, FUNC_ADPT_ARG(padapter), MAC_ARG(pattrib->ra));
3383 		} else if (subtype == WIFI_DISASSOC) {
3384 			RTW_INFO(FUNC_ADPT_FMT" unicast disassoc to "MAC_FMT"\n"
3385 				, FUNC_ADPT_ARG(padapter), MAC_ARG(pattrib->ra));
3386 		} else if (subtype == WIFI_ACTION) {
3387 			RTW_INFO(FUNC_ADPT_FMT" unicast action(%u) to "MAC_FMT"\n"
3388 				, FUNC_ADPT_ARG(padapter), category, MAC_ARG(pattrib->ra));
3389 		}
3390 		#endif
3391 
3392 		pn = &psta->dot11txpn;
3393 		cipher = psta->dot118021XPrivacy;
3394 		kid = 0;
3395 
3396 		_rtw_memcpy(pattrib->dot118021x_UncstKey.skey
3397 			, psta->dot118021x_UncstKey.skey
3398 			, (cipher & _SEC_TYPE_256_) ? 32 : 16);
3399 
3400 		/* To use wrong key */
3401 		if (pattrib->key_type == IEEE80211W_WRONG_KEY) {
3402 			RTW_INFO("use wrong key\n");
3403 			pattrib->dot118021x_UncstKey.skey[0] = 0xff;
3404 		}
3405 	}
3406 
3407 	#if DBG_MGMT_XMIT_ENC_DUMP
3408 	/* before encrypt dump the management packet content */
3409 	{
3410 		int i;
3411 		printk("Management pkt: ");
3412 		for(i=0; i<pattrib->pktlen; i++)
3413 		printk(" %02x ", pframe[i]);
3414 		printk("=======\n");
3415 	}
3416 	#endif
3417 
3418 	/* bakeup original management packet */
3419 	_rtw_memcpy(tmp_buf, pframe, pattrib->pktlen);
3420 	/* move to data portion */
3421 	pframe += pattrib->hdrlen;
3422 
3423 	if (pattrib->key_type != IEEE80211W_NO_KEY) {
3424 		pattrib->encrypt = cipher;
3425 		pattrib->bswenc = _TRUE;
3426 	}
3427 
3428 	/*
3429 	* 802.11w encrypted management packet must be:
3430 	* _AES_, _CCMP_256_, _GCMP_, _GCMP_256_
3431 	*/
3432 	switch (pattrib->encrypt) {
3433 	case _AES_:
3434 		pattrib->iv_len = 8;
3435 		pattrib->icv_len = 8;
3436 		AES_IV(pattrib->iv, (*pn), kid);
3437 		break;
3438 	case _CCMP_256_:
3439 		pattrib->iv_len = 8;
3440 		pattrib->icv_len = 16;
3441 		AES_IV(pattrib->iv, (*pn), kid);
3442 		break;
3443 	case _GCMP_:
3444 	case _GCMP_256_:
3445 		pattrib->iv_len = 8;
3446 		pattrib->icv_len = 16;
3447 		GCMP_IV(pattrib->iv, (*pn), kid);
3448 		break;
3449 	default:
3450 		goto xmitframe_coalesce_fail;
3451 	}
3452 
3453 	/* insert iv header into management frame */
3454 	_rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
3455 	pframe += pattrib->iv_len;
3456 	/* copy mgmt data portion after CCMP header */
3457 	_rtw_memcpy(pframe, tmp_buf + pattrib->hdrlen, pattrib->pktlen - pattrib->hdrlen);
3458 	/* move pframe to end of mgmt pkt */
3459 	pframe += pattrib->pktlen - pattrib->hdrlen;
3460 	/* add 8 bytes CCMP IV header to length */
3461 	pattrib->pktlen += pattrib->iv_len;
3462 
3463 	#if DBG_MGMT_XMIT_ENC_DUMP
3464 	/* dump management packet include AES IV header */
3465 	{
3466 		int i;
3467 		printk("Management pkt + IV: ");
3468 		/* for(i=0; i<pattrib->pktlen; i++) */
3469 
3470 		printk("@@@@@@@@@@@@@\n");
3471 	}
3472 	#endif
3473 
3474 	if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
3475 		_rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
3476 		pframe += pattrib->icv_len;
3477 	}
3478 	/* add 8 bytes MIC */
3479 	pattrib->pktlen += pattrib->icv_len;
3480 	/* set final tx command size */
3481 	pattrib->last_txcmdsz = pattrib->pktlen;
3482 
3483 	/* set protected bit must be beofre SW encrypt */
3484 	SetPrivacy(mem_start);
3485 
3486 	#if DBG_MGMT_XMIT_ENC_DUMP
3487 	/* dump management packet include AES header */
3488 	{
3489 		int i;
3490 		printk("prepare to enc Management pkt + IV: ");
3491 		for (i = 0; i < pattrib->pktlen; i++)
3492 			printk(" %02x ", mem_start[i]);
3493 		printk("@@@@@@@@@@@@@\n");
3494 	}
3495 	#endif
3496 
3497 	/* software encrypt */
3498 	xmitframe_swencrypt(padapter, pxmitframe);
3499 
3500 xmitframe_coalesce_success:
3501 	_exit_critical_bh(&padapter->security_key_mutex, &irqL);
3502 	rtw_mfree(BIP_AAD, ori_len);
3503 	return _SUCCESS;
3504 
3505 xmitframe_coalesce_fail:
3506 	_exit_critical_bh(&padapter->security_key_mutex, &irqL);
3507 	rtw_mfree(BIP_AAD, ori_len);
3508 
3509 	return _FAIL;
3510 }
3511 #endif /* defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH) */
3512 
3513 /* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
3514  * IEEE LLC/SNAP header contains 8 octets
3515  * First 3 octets comprise the LLC portion
3516  * SNAP portion, 5 octets, is divided into two fields:
3517  *	Organizationally Unique Identifier(OUI), 3 octets,
3518  *	type, defined by that organization, 2 octets.
3519  */
rtw_put_snap(u8 * data,u16 h_proto)3520 s32 rtw_put_snap(u8 *data, u16 h_proto)
3521 {
3522 	struct ieee80211_snap_hdr *snap;
3523 	u8 *oui;
3524 
3525 
3526 	snap = (struct ieee80211_snap_hdr *)data;
3527 	snap->dsap = 0xaa;
3528 	snap->ssap = 0xaa;
3529 	snap->ctrl = 0x03;
3530 
3531 	if (h_proto == 0x8137 || h_proto == 0x80f3)
3532 		oui = P802_1H_OUI;
3533 	else
3534 		oui = RFC1042_OUI;
3535 
3536 	snap->oui[0] = oui[0];
3537 	snap->oui[1] = oui[1];
3538 	snap->oui[2] = oui[2];
3539 
3540 	*(u16 *)(data + SNAP_SIZE) = htons(h_proto);
3541 
3542 
3543 	return SNAP_SIZE + sizeof(u16);
3544 }
3545 
rtw_update_protection(_adapter * padapter,u8 * ie,uint ie_len)3546 void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len)
3547 {
3548 
3549 	uint	protection;
3550 	u8	*perp;
3551 	sint	 erp_len;
3552 	struct	xmit_priv *pxmitpriv = &padapter->xmitpriv;
3553 	struct	registry_priv *pregistrypriv = &padapter->registrypriv;
3554 
3555 
3556 	switch (pxmitpriv->vcs_setting) {
3557 	case DISABLE_VCS:
3558 		pxmitpriv->vcs = NONE_VCS;
3559 		break;
3560 
3561 	case ENABLE_VCS:
3562 		break;
3563 
3564 	case AUTO_VCS:
3565 	default:
3566 		perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
3567 		if (perp == NULL)
3568 			pxmitpriv->vcs = NONE_VCS;
3569 		else {
3570 			protection = (*(perp + 2)) & BIT(1);
3571 			if (protection) {
3572 				if (pregistrypriv->vcs_type == RTS_CTS)
3573 					pxmitpriv->vcs = RTS_CTS;
3574 				else
3575 					pxmitpriv->vcs = CTS_TO_SELF;
3576 			} else
3577 				pxmitpriv->vcs = NONE_VCS;
3578 		}
3579 
3580 		break;
3581 
3582 	}
3583 
3584 
3585 }
3586 
rtw_count_tx_stats(PADAPTER padapter,struct xmit_frame * pxmitframe,int sz)3587 void rtw_count_tx_stats(PADAPTER padapter, struct xmit_frame *pxmitframe, int sz)
3588 {
3589 	struct sta_info *psta = NULL;
3590 	struct stainfo_stats *pstats = NULL;
3591 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
3592 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
3593 	u8	pkt_num = 1;
3594 
3595 	if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
3596 #if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3597 		pkt_num = pxmitframe->agg_num;
3598 #endif
3599 		pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pkt_num;
3600 
3601 		pxmitpriv->tx_pkts += pkt_num;
3602 
3603 		pxmitpriv->tx_bytes += sz;
3604 
3605 		psta = pxmitframe->attrib.psta;
3606 		if (psta) {
3607 			pstats = &psta->sta_stats;
3608 
3609 			pstats->tx_pkts += pkt_num;
3610 
3611 			pstats->tx_bytes += sz;
3612 			#if defined(CONFIG_CHECK_LEAVE_LPS) && defined(CONFIG_LPS_CHK_BY_TP)
3613 			if (adapter_to_pwrctl(padapter)->lps_chk_by_tp)
3614 				traffic_check_for_leave_lps_by_tp(padapter, _TRUE, psta);
3615 			#endif /* CONFIG_LPS */
3616 		}
3617 
3618 #ifdef CONFIG_CHECK_LEAVE_LPS
3619 		/* traffic_check_for_leave_lps(padapter, _TRUE); */
3620 #endif /* CONFIG_CHECK_LEAVE_LPS */
3621 
3622 	}
3623 }
3624 
__rtw_alloc_cmd_xmitbuf(struct xmit_priv * pxmitpriv,enum cmdbuf_type buf_type)3625 static struct xmit_buf *__rtw_alloc_cmd_xmitbuf(struct xmit_priv *pxmitpriv,
3626 		enum cmdbuf_type buf_type)
3627 {
3628 	struct xmit_buf *pxmitbuf =  NULL;
3629 
3630 
3631 	pxmitbuf = &pxmitpriv->pcmd_xmitbuf[buf_type];
3632 	if (pxmitbuf !=  NULL) {
3633 		pxmitbuf->priv_data = NULL;
3634 
3635 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3636 		pxmitbuf->len = 0;
3637 		pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
3638 		pxmitbuf->agg_num = 0;
3639 		pxmitbuf->pg_num = 0;
3640 #endif
3641 #ifdef CONFIG_PCI_HCI
3642 		pxmitbuf->len = 0;
3643 #ifdef CONFIG_TRX_BD_ARCH
3644 		/*pxmitbuf->buf_desc = NULL;*/
3645 #else
3646 		pxmitbuf->desc = NULL;
3647 #endif
3648 #endif
3649 
3650 		if (pxmitbuf->sctx) {
3651 			RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
3652 			rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
3653 		}
3654 	} else
3655 		RTW_INFO("%s fail, no xmitbuf available !!!\n", __func__);
3656 
3657 	return pxmitbuf;
3658 }
3659 
__rtw_alloc_cmdxmitframe(struct xmit_priv * pxmitpriv,enum cmdbuf_type buf_type)3660 struct xmit_frame *__rtw_alloc_cmdxmitframe(struct xmit_priv *pxmitpriv,
3661 		enum cmdbuf_type buf_type)
3662 {
3663 	struct xmit_frame		*pcmdframe;
3664 	struct xmit_buf		*pxmitbuf;
3665 
3666 	pcmdframe = rtw_alloc_xmitframe(pxmitpriv, 0);
3667 	if (pcmdframe == NULL) {
3668 		RTW_INFO("%s, alloc xmitframe fail\n", __FUNCTION__);
3669 		return NULL;
3670 	}
3671 
3672 	pxmitbuf = __rtw_alloc_cmd_xmitbuf(pxmitpriv, buf_type);
3673 	if (pxmitbuf == NULL) {
3674 		RTW_INFO("%s, alloc xmitbuf fail\n", __FUNCTION__);
3675 		rtw_free_xmitframe(pxmitpriv, pcmdframe);
3676 		return NULL;
3677 	}
3678 
3679 	pcmdframe->frame_tag = MGNT_FRAMETAG;
3680 
3681 	pcmdframe->pxmitbuf = pxmitbuf;
3682 
3683 	pcmdframe->buf_addr = pxmitbuf->pbuf;
3684 
3685 	/* initial memory to zero */
3686 	_rtw_memset(pcmdframe->buf_addr, 0, MAX_CMDBUF_SZ);
3687 
3688 	pxmitbuf->priv_data = pcmdframe;
3689 
3690 	return pcmdframe;
3691 
3692 }
3693 
rtw_alloc_xmitbuf_ext(struct xmit_priv * pxmitpriv)3694 struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
3695 {
3696 	_irqL irqL;
3697 	struct xmit_buf *pxmitbuf =  NULL;
3698 	_list *plist, *phead;
3699 	_queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
3700 
3701 
3702 	_enter_critical(&pfree_queue->lock, &irqL);
3703 
3704 	if (_rtw_queue_empty(pfree_queue) == _TRUE)
3705 		pxmitbuf = NULL;
3706 	else {
3707 
3708 		phead = get_list_head(pfree_queue);
3709 
3710 		plist = get_next(phead);
3711 
3712 		pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
3713 
3714 		rtw_list_delete(&(pxmitbuf->list));
3715 	}
3716 
3717 	if (pxmitbuf !=  NULL) {
3718 		pxmitpriv->free_xmit_extbuf_cnt--;
3719 #ifdef DBG_XMIT_BUF_EXT
3720 		RTW_INFO("DBG_XMIT_BUF_EXT ALLOC no=%d,  free_xmit_extbuf_cnt=%d\n", pxmitbuf->no, pxmitpriv->free_xmit_extbuf_cnt);
3721 #endif
3722 
3723 
3724 		pxmitbuf->priv_data = NULL;
3725 
3726 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3727 		pxmitbuf->len = 0;
3728 		pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
3729 		pxmitbuf->agg_num = 1;
3730 #endif
3731 #ifdef CONFIG_PCI_HCI
3732 		pxmitbuf->len = 0;
3733 #ifdef CONFIG_TRX_BD_ARCH
3734 		/*pxmitbuf->buf_desc = NULL;*/
3735 #else
3736 		pxmitbuf->desc = NULL;
3737 #endif
3738 #endif
3739 
3740 		if (pxmitbuf->sctx) {
3741 			RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
3742 			rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
3743 		}
3744 
3745 	}
3746 
3747 	_exit_critical(&pfree_queue->lock, &irqL);
3748 
3749 
3750 	return pxmitbuf;
3751 }
3752 
rtw_free_xmitbuf_ext(struct xmit_priv * pxmitpriv,struct xmit_buf * pxmitbuf)3753 s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
3754 {
3755 	_irqL irqL;
3756 	_queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
3757 
3758 
3759 	if (pxmitbuf == NULL)
3760 		return _FAIL;
3761 
3762 	_enter_critical(&pfree_queue->lock, &irqL);
3763 
3764 	rtw_list_delete(&pxmitbuf->list);
3765 
3766 	rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_queue));
3767 	pxmitpriv->free_xmit_extbuf_cnt++;
3768 #ifdef DBG_XMIT_BUF_EXT
3769 	RTW_INFO("DBG_XMIT_BUF_EXT FREE no=%d, free_xmit_extbuf_cnt=%d\n", pxmitbuf->no , pxmitpriv->free_xmit_extbuf_cnt);
3770 #endif
3771 
3772 	_exit_critical(&pfree_queue->lock, &irqL);
3773 
3774 
3775 	return _SUCCESS;
3776 }
3777 
rtw_alloc_xmitbuf(struct xmit_priv * pxmitpriv)3778 struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
3779 {
3780 	_irqL irqL;
3781 	struct xmit_buf *pxmitbuf =  NULL;
3782 	_list *plist, *phead;
3783 	_queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
3784 
3785 
3786 	/* RTW_INFO("+rtw_alloc_xmitbuf\n"); */
3787 
3788 	_enter_critical(&pfree_xmitbuf_queue->lock, &irqL);
3789 
3790 	if (_rtw_queue_empty(pfree_xmitbuf_queue) == _TRUE)
3791 		pxmitbuf = NULL;
3792 	else {
3793 
3794 		phead = get_list_head(pfree_xmitbuf_queue);
3795 
3796 		plist = get_next(phead);
3797 
3798 		pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
3799 
3800 		rtw_list_delete(&(pxmitbuf->list));
3801 	}
3802 
3803 	if (pxmitbuf !=  NULL) {
3804 		pxmitpriv->free_xmitbuf_cnt--;
3805 #ifdef DBG_XMIT_BUF
3806 		RTW_INFO("DBG_XMIT_BUF ALLOC no=%d,  free_xmitbuf_cnt=%d\n", pxmitbuf->no, pxmitpriv->free_xmitbuf_cnt);
3807 #endif
3808 		/* RTW_INFO("alloc, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); */
3809 
3810 		pxmitbuf->priv_data = NULL;
3811 
3812 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3813 		pxmitbuf->len = 0;
3814 		pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
3815 		pxmitbuf->agg_num = 0;
3816 		pxmitbuf->pg_num = 0;
3817 #endif
3818 #ifdef CONFIG_PCI_HCI
3819 		pxmitbuf->len = 0;
3820 #ifdef CONFIG_TRX_BD_ARCH
3821 		/*pxmitbuf->buf_desc = NULL;*/
3822 #else
3823 		pxmitbuf->desc = NULL;
3824 #endif
3825 #endif
3826 
3827 		if (pxmitbuf->sctx) {
3828 			RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
3829 			rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
3830 		}
3831 	}
3832 #ifdef DBG_XMIT_BUF
3833 	else
3834 		RTW_INFO("DBG_XMIT_BUF rtw_alloc_xmitbuf return NULL\n");
3835 #endif
3836 
3837 	_exit_critical(&pfree_xmitbuf_queue->lock, &irqL);
3838 
3839 
3840 	return pxmitbuf;
3841 }
3842 
rtw_free_xmitbuf(struct xmit_priv * pxmitpriv,struct xmit_buf * pxmitbuf)3843 s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
3844 {
3845 	_irqL irqL;
3846 	_queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
3847 
3848 
3849 	/* RTW_INFO("+rtw_free_xmitbuf\n"); */
3850 
3851 	if (pxmitbuf == NULL)
3852 		return _FAIL;
3853 
3854 	if (pxmitbuf->sctx) {
3855 		RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
3856 		rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
3857 	}
3858 
3859 	if (pxmitbuf->buf_tag == XMITBUF_CMD) {
3860 	} else if (pxmitbuf->buf_tag == XMITBUF_MGNT)
3861 		rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf);
3862 	else {
3863 		_enter_critical(&pfree_xmitbuf_queue->lock, &irqL);
3864 
3865 		rtw_list_delete(&pxmitbuf->list);
3866 
3867 		rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
3868 
3869 		pxmitpriv->free_xmitbuf_cnt++;
3870 		/* RTW_INFO("FREE, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); */
3871 #ifdef DBG_XMIT_BUF
3872 		RTW_INFO("DBG_XMIT_BUF FREE no=%d, free_xmitbuf_cnt=%d\n", pxmitbuf->no , pxmitpriv->free_xmitbuf_cnt);
3873 #endif
3874 		_exit_critical(&pfree_xmitbuf_queue->lock, &irqL);
3875 	}
3876 
3877 
3878 	return _SUCCESS;
3879 }
3880 
rtw_init_xmitframe(struct xmit_frame * pxframe)3881 void rtw_init_xmitframe(struct xmit_frame *pxframe)
3882 {
3883 	if (pxframe !=  NULL) { /* default value setting */
3884 		pxframe->buf_addr = NULL;
3885 		pxframe->pxmitbuf = NULL;
3886 
3887 		_rtw_memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
3888 		/* pxframe->attrib.psta = NULL; */
3889 
3890 		pxframe->frame_tag = DATA_FRAMETAG;
3891 
3892 #ifdef CONFIG_USB_HCI
3893 		pxframe->pkt = NULL;
3894 #ifdef USB_PACKET_OFFSET_SZ
3895 		pxframe->pkt_offset = (PACKET_OFFSET_SZ / 8);
3896 #else
3897 		pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */
3898 #endif
3899 
3900 #ifdef CONFIG_USB_TX_AGGREGATION
3901 		pxframe->agg_num = 1;
3902 #endif
3903 
3904 #endif /* #ifdef CONFIG_USB_HCI */
3905 
3906 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3907 		pxframe->pg_num = 1;
3908 		pxframe->agg_num = 1;
3909 #endif
3910 
3911 #ifdef CONFIG_XMIT_ACK
3912 		pxframe->ack_report = 0;
3913 #endif
3914 
3915 	}
3916 }
3917 
3918 /*
3919 Calling context:
3920 1. OS_TXENTRY
3921 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
3922 
3923 If we turn on USE_RXTHREAD, then, no need for critical section.
3924 Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
3925 
3926 Must be very very cautious...
3927 
3928 */
rtw_alloc_xmitframe(struct xmit_priv * pxmitpriv,u16 os_qid)3929 struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv, u16 os_qid)
3930 {
3931 	/*
3932 		Please remember to use all the osdep_service api,
3933 		and lock/unlock or _enter/_exit critical to protect
3934 		pfree_xmit_queue
3935 	*/
3936 
3937 	_irqL irqL;
3938 	struct xmit_frame *pxframe = NULL;
3939 	_list *plist, *phead;
3940 	_queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
3941 
3942 	_enter_critical_bh(&pfree_xmit_queue->lock, &irqL);
3943 
3944 	if (_rtw_queue_empty(pfree_xmit_queue) == _TRUE) {
3945 		pxframe =  NULL;
3946 	} else {
3947 		phead = get_list_head(pfree_xmit_queue);
3948 
3949 		plist = get_next(phead);
3950 
3951 		pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3952 
3953 		rtw_list_delete(&(pxframe->list));
3954 		pxmitpriv->free_xmitframe_cnt--;
3955 		pxframe->os_qid = os_qid;
3956 	}
3957 
3958 	_exit_critical_bh(&pfree_xmit_queue->lock, &irqL);
3959 
3960 	if (pxframe)
3961 		rtw_os_check_stop_queue(pxmitpriv->adapter, os_qid);
3962 
3963 	rtw_init_xmitframe(pxframe);
3964 
3965 
3966 	return pxframe;
3967 }
3968 
rtw_alloc_xmitframe_ext(struct xmit_priv * pxmitpriv)3969 struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv)
3970 {
3971 	_irqL irqL;
3972 	struct xmit_frame *pxframe = NULL;
3973 	_list *plist, *phead;
3974 	_queue *queue = &pxmitpriv->free_xframe_ext_queue;
3975 
3976 
3977 	_enter_critical_bh(&queue->lock, &irqL);
3978 
3979 	if (_rtw_queue_empty(queue) == _TRUE) {
3980 		pxframe =  NULL;
3981 	} else {
3982 		phead = get_list_head(queue);
3983 		plist = get_next(phead);
3984 		pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3985 
3986 		rtw_list_delete(&(pxframe->list));
3987 		pxmitpriv->free_xframe_ext_cnt--;
3988 	}
3989 
3990 	_exit_critical_bh(&queue->lock, &irqL);
3991 
3992 	rtw_init_xmitframe(pxframe);
3993 
3994 
3995 	return pxframe;
3996 }
3997 
rtw_alloc_xmitframe_once(struct xmit_priv * pxmitpriv)3998 struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv)
3999 {
4000 	struct xmit_frame *pxframe = NULL;
4001 	u8 *alloc_addr;
4002 
4003 	alloc_addr = rtw_zmalloc(sizeof(struct xmit_frame) + 4);
4004 
4005 	if (alloc_addr == NULL)
4006 		goto exit;
4007 
4008 	pxframe = (struct xmit_frame *)N_BYTE_ALIGMENT((SIZE_PTR)(alloc_addr), 4);
4009 	pxframe->alloc_addr = alloc_addr;
4010 
4011 	pxframe->padapter = pxmitpriv->adapter;
4012 	pxframe->frame_tag = NULL_FRAMETAG;
4013 
4014 	pxframe->pkt = NULL;
4015 
4016 	pxframe->buf_addr = NULL;
4017 	pxframe->pxmitbuf = NULL;
4018 
4019 	rtw_init_xmitframe(pxframe);
4020 
4021 	RTW_INFO("################## %s ##################\n", __func__);
4022 
4023 exit:
4024 	return pxframe;
4025 }
4026 
rtw_free_xmitframe(struct xmit_priv * pxmitpriv,struct xmit_frame * pxmitframe)4027 s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
4028 {
4029 	_irqL irqL;
4030 	_queue *queue = NULL;
4031 	_adapter *padapter = pxmitpriv->adapter;
4032 	_pkt *pndis_pkt = NULL;
4033 
4034 
4035 	if (pxmitframe == NULL) {
4036 		goto exit;
4037 	}
4038 
4039 	if (pxmitframe->pkt) {
4040 		pndis_pkt = pxmitframe->pkt;
4041 		pxmitframe->pkt = NULL;
4042 	}
4043 
4044 	if (pxmitframe->alloc_addr) {
4045 		RTW_INFO("################## %s with alloc_addr ##################\n", __func__);
4046 		rtw_mfree(pxmitframe->alloc_addr, sizeof(struct xmit_frame) + 4);
4047 		goto check_pkt_complete;
4048 	}
4049 
4050 	if (pxmitframe->ext_tag == 0)
4051 		queue = &pxmitpriv->free_xmit_queue;
4052 	else if (pxmitframe->ext_tag == 1)
4053 		queue = &pxmitpriv->free_xframe_ext_queue;
4054 	else
4055 		rtw_warn_on(1);
4056 
4057 	_enter_critical_bh(&queue->lock, &irqL);
4058 
4059 	rtw_list_delete(&pxmitframe->list);
4060 	rtw_list_insert_tail(&pxmitframe->list, get_list_head(queue));
4061 	if (pxmitframe->ext_tag == 0) {
4062 		pxmitpriv->free_xmitframe_cnt++;
4063 	} else if (pxmitframe->ext_tag == 1) {
4064 		pxmitpriv->free_xframe_ext_cnt++;
4065 	} else {
4066 	}
4067 
4068 	_exit_critical_bh(&queue->lock, &irqL);
4069 
4070 	if (queue == &pxmitpriv->free_xmit_queue)
4071 		rtw_os_check_wakup_queue(padapter, pxmitframe->os_qid);
4072 
4073 check_pkt_complete:
4074 
4075 	if (pndis_pkt)
4076 		rtw_os_pkt_complete(padapter, pndis_pkt);
4077 
4078 exit:
4079 
4080 
4081 	return _SUCCESS;
4082 }
4083 
4084 #ifdef CONFIG_RTW_MGMT_QUEUE
rtw_free_mgmt_xmitframe_queue(struct xmit_priv * pxmitpriv,_queue * mgmt_queue)4085 void rtw_free_mgmt_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *mgmt_queue)
4086 {
4087 	_irqL irqL;
4088 	_list	*plist, *phead;
4089 	struct xmit_frame *pxmitframe;
4090 
4091 	_enter_critical_bh(&(mgmt_queue->lock), &irqL);
4092 
4093 	phead = get_list_head(mgmt_queue);
4094 	plist = get_next(phead);
4095 
4096 	while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
4097 
4098 		pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
4099 		plist = get_next(plist);
4100 
4101 		#ifdef DBG_MGMT_QUEUE
4102 		RTW_INFO("%s seq_num = %u\n", __func__, pxmitframe->attrib.seqnum);
4103 		#endif
4104 
4105 		rtw_free_xmitbuf_ext(pxmitpriv, pxmitframe->pxmitbuf);
4106 		rtw_free_xmitframe(pxmitpriv, pxmitframe);
4107 	}
4108 	_exit_critical_bh(&(mgmt_queue->lock), &irqL);
4109 }
4110 
rtw_mgmt_xmitframe_enqueue(_adapter * padapter,struct xmit_frame * pxmitframe)4111 u8 rtw_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
4112 {
4113 	struct sta_info *psta;
4114 	struct tx_servq *ptxservq;
4115 	struct pkt_attrib *pattrib = &(pxmitframe->attrib);
4116 	struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4117 	struct hw_xmit *phwxmits = pxmitpriv->hwxmits;
4118 	u8 mgmt_idx = pxmitpriv->hwxmit_entry - 1;
4119 
4120 	DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class);
4121 
4122 	psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
4123 	if (pattrib->psta != psta) {
4124 		DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_sta);
4125 		RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
4126 		return _FAIL;
4127 	}
4128 
4129 	if (psta == NULL) {
4130 		DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_nosta);
4131 		RTW_INFO("rtw_xmit_classifier: psta == NULL\n");
4132 		return _FAIL;
4133 	}
4134 
4135 	if (!(psta->state & WIFI_ASOC_STATE)) {
4136 		DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_fwlink);
4137 		RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state);
4138 		return _FAIL;
4139 	}
4140 
4141 	ptxservq = &(psta->sta_xmitpriv.mgmt_q);
4142 
4143 	if (rtw_is_list_empty(&ptxservq->tx_pending))
4144 		rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmits[mgmt_idx].sta_queue));
4145 
4146 	rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
4147 	ptxservq->qcnt++;
4148 	phwxmits[mgmt_idx].accnt++;
4149 
4150 	return _SUCCESS;
4151 }
4152 #endif
4153 
rtw_free_xmitframe_queue(struct xmit_priv * pxmitpriv,_queue * pframequeue)4154 void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue)
4155 {
4156 	_irqL irqL;
4157 	_list	*plist, *phead;
4158 	struct	xmit_frame	*pxmitframe;
4159 
4160 
4161 	_enter_critical_bh(&(pframequeue->lock), &irqL);
4162 
4163 	phead = get_list_head(pframequeue);
4164 	plist = get_next(phead);
4165 
4166 	while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
4167 
4168 		pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
4169 
4170 		plist = get_next(plist);
4171 
4172 		rtw_free_xmitframe(pxmitpriv, pxmitframe);
4173 
4174 	}
4175 	_exit_critical_bh(&(pframequeue->lock), &irqL);
4176 
4177 }
4178 
rtw_xmitframe_enqueue(_adapter * padapter,struct xmit_frame * pxmitframe)4179 s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
4180 {
4181 	DBG_COUNTER(padapter->tx_logs.core_tx_enqueue);
4182 	if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) {
4183 		/*		pxmitframe->pkt = NULL; */
4184 		return _FAIL;
4185 	}
4186 
4187 	return _SUCCESS;
4188 }
4189 
dequeue_one_xmitframe(struct xmit_priv * pxmitpriv,struct hw_xmit * phwxmit,struct tx_servq * ptxservq,_queue * pframe_queue)4190 static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue)
4191 {
4192 	_list	*xmitframe_plist, *xmitframe_phead;
4193 	struct	xmit_frame	*pxmitframe = NULL;
4194 
4195 	xmitframe_phead = get_list_head(pframe_queue);
4196 	xmitframe_plist = get_next(xmitframe_phead);
4197 
4198 	while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
4199 		pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4200 
4201 		/* xmitframe_plist = get_next(xmitframe_plist); */
4202 
4203 		/*#ifdef RTK_DMP_PLATFORM
4204 		#ifdef CONFIG_USB_TX_AGGREGATION
4205 				if((ptxservq->qcnt>0) && (ptxservq->qcnt<=2))
4206 				{
4207 					pxmitframe = NULL;
4208 
4209 					tasklet_schedule(&pxmitpriv->xmit_tasklet);
4210 
4211 					break;
4212 				}
4213 		#endif
4214 		#endif*/
4215 		rtw_list_delete(&pxmitframe->list);
4216 
4217 		ptxservq->qcnt--;
4218 
4219 		/* rtw_list_insert_tail(&pxmitframe->list, &phwxmit->pending); */
4220 
4221 		/* ptxservq->qcnt--; */
4222 
4223 		break;
4224 
4225 		/* pxmitframe = NULL; */
4226 
4227 	}
4228 
4229 	return pxmitframe;
4230 }
4231 
get_one_xmitframe(struct xmit_priv * pxmitpriv,struct hw_xmit * phwxmit,struct tx_servq * ptxservq,_queue * pframe_queue)4232 static struct xmit_frame *get_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue)
4233 {
4234 	_list	*xmitframe_plist, *xmitframe_phead;
4235 	struct	xmit_frame	*pxmitframe = NULL;
4236 
4237 	xmitframe_phead = get_list_head(pframe_queue);
4238 	xmitframe_plist = get_next(xmitframe_phead);
4239 
4240 	while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
4241 		pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4242 		break;
4243 	}
4244 
4245 	return pxmitframe;
4246 }
4247 
rtw_get_xframe(struct xmit_priv * pxmitpriv,int * num_frame)4248 struct xmit_frame *rtw_get_xframe(struct xmit_priv *pxmitpriv, int *num_frame)
4249 {
4250 	_irqL irqL0;
4251 	_list *sta_plist, *sta_phead;
4252 	struct hw_xmit *phwxmit_i = pxmitpriv->hwxmits;
4253 #ifdef CONFIG_RTW_MGMT_QUEUE
4254 	/* This function gets xmit_frame from AC queue. */
4255 	/* When mgmt queue is used, AC queue index is (hwxmit_entry - 1) */
4256 	sint entry = pxmitpriv->hwxmit_entry - 1;
4257 #else
4258 	sint entry = pxmitpriv->hwxmit_entry;
4259 #endif
4260 	struct hw_xmit *phwxmit;
4261 	struct tx_servq *ptxservq = NULL;
4262 	_queue *pframe_queue = NULL;
4263 	struct xmit_frame *pxmitframe = NULL;
4264 	_adapter *padapter = pxmitpriv->adapter;
4265 	struct registry_priv	*pregpriv = &padapter->registrypriv;
4266 	int i, inx[4];
4267 
4268 	inx[0] = 0;
4269 	inx[1] = 1;
4270 	inx[2] = 2;
4271 	inx[3] = 3;
4272 
4273 	*num_frame = 0;
4274 
4275 	/*No amsdu when wifi_spec on*/
4276 	if (pregpriv->wifi_spec == 1) {
4277 		return NULL;
4278 	}
4279 
4280 	_enter_critical_bh(&pxmitpriv->lock, &irqL0);
4281 
4282 	for (i = 0; i < entry; i++) {
4283 		phwxmit = phwxmit_i + inx[i];
4284 
4285 		sta_phead = get_list_head(phwxmit->sta_queue);
4286 		sta_plist = get_next(sta_phead);
4287 
4288 		while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) {
4289 
4290 			ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
4291 			pframe_queue = &ptxservq->sta_pending;
4292 
4293 			if(ptxservq->qcnt)
4294 			{
4295 				*num_frame = ptxservq->qcnt;
4296 				pxmitframe = get_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
4297 				goto exit;
4298 			}
4299 			sta_plist = get_next(sta_plist);
4300 		}
4301 	}
4302 
4303 exit:
4304 
4305 	_exit_critical_bh(&pxmitpriv->lock, &irqL0);
4306 
4307 	return pxmitframe;
4308 }
4309 
4310 #ifdef CONFIG_RTW_MGMT_QUEUE
rtw_dequeue_mgmt_xframe(struct xmit_priv * pxmitpriv)4311 struct xmit_frame *rtw_dequeue_mgmt_xframe(struct xmit_priv *pxmitpriv)
4312 {
4313 	_irqL irqL0;
4314 	_list *sta_plist, *sta_phead;
4315 	struct hw_xmit *mgmt_hwxmit;
4316 	struct tx_servq *ptxservq = NULL;
4317 	_queue *pframe_queue = NULL;
4318 	struct xmit_frame *pxmitframe = NULL;
4319 	u8 mgmt_entry = pxmitpriv->hwxmit_entry - 1;
4320 
4321 	_enter_critical_bh(&pxmitpriv->lock, &irqL0);
4322 
4323 	/* management queue */
4324 	mgmt_hwxmit = (pxmitpriv->hwxmits) + mgmt_entry;
4325 
4326 	sta_phead = get_list_head(mgmt_hwxmit->sta_queue);
4327 	sta_plist = get_next(sta_phead);
4328 
4329 	while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) {
4330 
4331 		ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
4332 
4333 		pframe_queue = &ptxservq->sta_pending;
4334 
4335 		pxmitframe = dequeue_one_xmitframe(pxmitpriv, mgmt_hwxmit, ptxservq, pframe_queue);
4336 
4337 		#ifdef DBG_MGMT_QUEUE
4338 		RTW_INFO("%s dequeue mgmt frame (seq_num = %u) to TX\n", __func__, pxmitframe->attrib.seqnum);
4339 		#endif
4340 
4341 		if (pxmitframe) {
4342 			mgmt_hwxmit->accnt--;
4343 
4344 			/* Remove sta node when there is no pending packets. */
4345 			if (_rtw_queue_empty(pframe_queue)) /* must be done after get_next and before break */
4346 				rtw_list_delete(&ptxservq->tx_pending);
4347 
4348 			goto exit;
4349 		}
4350 		sta_plist = get_next(sta_plist);
4351 	}
4352 exit:
4353 	_exit_critical_bh(&pxmitpriv->lock, &irqL0);
4354 
4355 	return pxmitframe;
4356 }
4357 #endif
4358 
rtw_dequeue_xframe(struct xmit_priv * pxmitpriv,struct hw_xmit * phwxmit_i,sint entry)4359 struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry)
4360 {
4361 	_irqL irqL0;
4362 	_list *sta_plist, *sta_phead;
4363 	struct hw_xmit *phwxmit;
4364 	struct tx_servq *ptxservq = NULL;
4365 	_queue *pframe_queue = NULL;
4366 	struct xmit_frame *pxmitframe = NULL;
4367 	_adapter *padapter = pxmitpriv->adapter;
4368 	struct registry_priv *pregpriv = &padapter->registrypriv;
4369 	int i, inx[4];
4370 #ifdef CONFIG_RTW_MGMT_QUEUE
4371 	/* This function gets xmit_frame from AC queue. */
4372 	/* When mgmt queue is used, AC queue index is (hwxmit_entry - 1) */
4373 	entry--;
4374 #endif
4375 	inx[0] = 0;
4376 	inx[1] = 1;
4377 	inx[2] = 2;
4378 	inx[3] = 3;
4379 
4380 	if (pregpriv->wifi_spec == 1) {
4381 		int j;
4382 #if 0
4383 		if (flags < XMIT_QUEUE_ENTRY) {
4384 			/* priority exchange according to the completed xmitbuf flags. */
4385 			inx[flags] = 0;
4386 			inx[0] = flags;
4387 		}
4388 #endif
4389 
4390 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_PCI_HCI)
4391 		for (j = 0; j < 4; j++)
4392 			inx[j] = pxmitpriv->wmm_para_seq[j];
4393 #endif
4394 	}
4395 
4396 	_enter_critical_bh(&pxmitpriv->lock, &irqL0);
4397 
4398 	for (i = 0; i < entry; i++) {
4399 		phwxmit = phwxmit_i + inx[i];
4400 
4401 		/* _enter_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
4402 
4403 		sta_phead = get_list_head(phwxmit->sta_queue);
4404 		sta_plist = get_next(sta_phead);
4405 
4406 		while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) {
4407 
4408 			ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
4409 
4410 			pframe_queue = &ptxservq->sta_pending;
4411 
4412 			pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
4413 
4414 			if (pxmitframe) {
4415 				phwxmit->accnt--;
4416 
4417 				/* Remove sta node when there is no pending packets. */
4418 				if (_rtw_queue_empty(pframe_queue)) /* must be done after get_next and before break */
4419 					rtw_list_delete(&ptxservq->tx_pending);
4420 
4421 				/* _exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
4422 
4423 				goto exit;
4424 			}
4425 
4426 			sta_plist = get_next(sta_plist);
4427 
4428 		}
4429 
4430 		/* _exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
4431 
4432 	}
4433 
4434 exit:
4435 
4436 	_exit_critical_bh(&pxmitpriv->lock, &irqL0);
4437 
4438 	return pxmitframe;
4439 }
4440 
rtw_get_sta_pending(_adapter * padapter,struct sta_info * psta,sint up,u8 * ac)4441 struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac)
4442 {
4443 	struct tx_servq *ptxservq = NULL;
4444 
4445 
4446 	switch (up) {
4447 	case 1:
4448 	case 2:
4449 		ptxservq = &(psta->sta_xmitpriv.bk_q);
4450 		*(ac) = 3;
4451 		break;
4452 
4453 	case 4:
4454 	case 5:
4455 		ptxservq = &(psta->sta_xmitpriv.vi_q);
4456 		*(ac) = 1;
4457 		break;
4458 
4459 	case 6:
4460 	case 7:
4461 		ptxservq = &(psta->sta_xmitpriv.vo_q);
4462 		*(ac) = 0;
4463 		break;
4464 
4465 	case 0:
4466 	case 3:
4467 	default:
4468 		ptxservq = &(psta->sta_xmitpriv.be_q);
4469 		*(ac) = 2;
4470 		break;
4471 
4472 	}
4473 
4474 
4475 	return ptxservq;
4476 }
4477 
4478 /*
4479  * Will enqueue pxmitframe to the proper queue,
4480  * and indicate it to xx_pending list.....
4481  */
rtw_xmit_classifier(_adapter * padapter,struct xmit_frame * pxmitframe)4482 s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe)
4483 {
4484 	/* _irqL irqL0; */
4485 	u8	ac_index;
4486 	struct sta_info	*psta;
4487 	struct tx_servq	*ptxservq;
4488 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
4489 	struct hw_xmit	*phwxmits =  padapter->xmitpriv.hwxmits;
4490 	sint res = _SUCCESS;
4491 
4492 
4493 	DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class);
4494 
4495 	/*
4496 		if (pattrib->psta) {
4497 			psta = pattrib->psta;
4498 		} else {
4499 			RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
4500 			psta = rtw_get_stainfo(pstapriv, pattrib->ra);
4501 		}
4502 	*/
4503 
4504 	psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
4505 	if (pattrib->psta != psta) {
4506 		DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_sta);
4507 		RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
4508 		return _FAIL;
4509 	}
4510 
4511 	if (psta == NULL) {
4512 		DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_nosta);
4513 		res = _FAIL;
4514 		RTW_INFO("rtw_xmit_classifier: psta == NULL\n");
4515 		goto exit;
4516 	}
4517 
4518 	if (!(psta->state & WIFI_ASOC_STATE)) {
4519 		DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_fwlink);
4520 		RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state);
4521 		return _FAIL;
4522 	}
4523 
4524 	ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
4525 
4526 	/* _enter_critical(&pstapending->lock, &irqL0); */
4527 
4528 	if (rtw_is_list_empty(&ptxservq->tx_pending))
4529 		rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
4530 
4531 	/* _enter_critical(&ptxservq->sta_pending.lock, &irqL1); */
4532 
4533 	rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
4534 	ptxservq->qcnt++;
4535 	phwxmits[ac_index].accnt++;
4536 
4537 	/* _exit_critical(&ptxservq->sta_pending.lock, &irqL1); */
4538 
4539 	/* _exit_critical(&pstapending->lock, &irqL0); */
4540 
4541 exit:
4542 
4543 
4544 	return res;
4545 }
4546 
rtw_alloc_hwxmits(_adapter * padapter)4547 void rtw_alloc_hwxmits(_adapter *padapter)
4548 {
4549 	struct hw_xmit *hwxmits;
4550 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4551 
4552 	pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
4553 
4554 	pxmitpriv->hwxmits = NULL;
4555 
4556 	pxmitpriv->hwxmits = (struct hw_xmit *)rtw_zmalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry);
4557 
4558 	if (pxmitpriv->hwxmits == NULL) {
4559 		RTW_INFO("alloc hwxmits fail!...\n");
4560 		return;
4561 	}
4562 
4563 	hwxmits = pxmitpriv->hwxmits;
4564 
4565 	rtw_warn_on(pxmitpriv->hwxmit_entry < 4);
4566 
4567 	/* pxmitpriv->vo_txqueue.head = 0; */
4568 	/* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */
4569 	hwxmits[0].sta_queue = &pxmitpriv->vo_pending;
4570 
4571 	/* pxmitpriv->vi_txqueue.head = 0; */
4572 	/* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */
4573 	hwxmits[1].sta_queue = &pxmitpriv->vi_pending;
4574 
4575 	/* pxmitpriv->be_txqueue.head = 0; */
4576 	/* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */
4577 	hwxmits[2].sta_queue = &pxmitpriv->be_pending;
4578 
4579 	/* pxmitpriv->bk_txqueue.head = 0; */
4580 	/* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
4581 	hwxmits[3].sta_queue = &pxmitpriv->bk_pending;
4582 
4583 #ifdef CONFIG_RTW_MGMT_QUEUE
4584 	hwxmits[4].sta_queue = &pxmitpriv->mgmt_pending;
4585 #endif
4586 
4587 }
4588 
rtw_free_hwxmits(_adapter * padapter)4589 void rtw_free_hwxmits(_adapter *padapter)
4590 {
4591 	struct hw_xmit *hwxmits;
4592 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4593 
4594 	hwxmits = pxmitpriv->hwxmits;
4595 	if (hwxmits)
4596 		rtw_mfree((u8 *)hwxmits, (sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry));
4597 }
4598 
rtw_init_hwxmits(struct hw_xmit * phwxmit,sint entry)4599 void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry)
4600 {
4601 	sint i;
4602 	for (i = 0; i < entry; i++, phwxmit++) {
4603 		/* _rtw_spinlock_init(&phwxmit->xmit_lock); */
4604 		/* _rtw_init_listhead(&phwxmit->pending);		 */
4605 		/* phwxmit->txcmdcnt = 0; */
4606 		phwxmit->accnt = 0;
4607 	}
4608 }
4609 
4610 #ifdef CONFIG_BR_EXT
rtw_br_client_tx(_adapter * padapter,struct sk_buff ** pskb)4611 int rtw_br_client_tx(_adapter *padapter, struct sk_buff **pskb)
4612 {
4613 	struct sk_buff *skb = *pskb;
4614 	_irqL irqL;
4615 	/* if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) */
4616 	{
4617 		void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb);
4618 		int res, is_vlan_tag = 0, i, do_nat25 = 1;
4619 		unsigned short vlan_hdr = 0;
4620 		void *br_port = NULL;
4621 
4622 		/* mac_clone_handle_frame(priv, skb); */
4623 
4624 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
4625 		br_port = padapter->pnetdev->br_port;
4626 #else   /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
4627 		rcu_read_lock();
4628 		br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
4629 		rcu_read_unlock();
4630 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
4631 		_enter_critical_bh(&padapter->br_ext_lock, &irqL);
4632 		if (!(skb->data[0] & 1) &&
4633 		    br_port &&
4634 		    memcmp(skb->data + MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
4635 		    *((unsigned short *)(skb->data + MACADDRLEN * 2)) != __constant_htons(ETH_P_8021Q) &&
4636 		    *((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP) &&
4637 		    !memcmp(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN) && padapter->scdb_entry) {
4638 			memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
4639 			padapter->scdb_entry->ageing_timer = jiffies;
4640 			_exit_critical_bh(&padapter->br_ext_lock, &irqL);
4641 		} else
4642 			/* if (!priv->pmib->ethBrExtInfo.nat25_disable)		 */
4643 		{
4644 			/*			if (priv->dev->br_port &&
4645 			 *				 !memcmp(skb->data+MACADDRLEN, priv->br_mac, MACADDRLEN)) { */
4646 #if 1
4647 			if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q)) {
4648 				is_vlan_tag = 1;
4649 				vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2));
4650 				for (i = 0; i < 6; i++)
4651 					*((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2));
4652 				skb_pull(skb, 4);
4653 			}
4654 			/* if SA == br_mac && skb== IP  => copy SIP to br_ip ?? why */
4655 			if (!memcmp(skb->data + MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
4656 			    (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP)))
4657 				memcpy(padapter->br_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4);
4658 
4659 			if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP)) {
4660 				if (memcmp(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN)) {
4661 					void *scdb_findEntry(_adapter *priv, unsigned char *macAddr, unsigned char *ipAddr);
4662 
4663 					padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter,
4664 						skb->data + MACADDRLEN, skb->data + WLAN_ETHHDR_LEN + 12);
4665 					if (padapter->scdb_entry != NULL) {
4666 						memcpy(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN);
4667 						memcpy(padapter->scdb_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4);
4668 						padapter->scdb_entry->ageing_timer = jiffies;
4669 						do_nat25 = 0;
4670 					}
4671 				} else {
4672 					if (padapter->scdb_entry) {
4673 						padapter->scdb_entry->ageing_timer = jiffies;
4674 						do_nat25 = 0;
4675 					} else {
4676 						memset(padapter->scdb_mac, 0, MACADDRLEN);
4677 						memset(padapter->scdb_ip, 0, 4);
4678 					}
4679 				}
4680 			}
4681 			_exit_critical_bh(&padapter->br_ext_lock, &irqL);
4682 #endif /* 1 */
4683 			if (do_nat25) {
4684 				int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method);
4685 				if (nat25_db_handle(padapter, skb, NAT25_CHECK) == 0) {
4686 					struct sk_buff *newskb;
4687 
4688 					if (is_vlan_tag) {
4689 						skb_push(skb, 4);
4690 						for (i = 0; i < 6; i++)
4691 							*((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2));
4692 						*((unsigned short *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q);
4693 						*((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr;
4694 					}
4695 
4696 					newskb = rtw_skb_copy(skb);
4697 					if (newskb == NULL) {
4698 						/* priv->ext_stats.tx_drops++; */
4699 						DEBUG_ERR("TX DROP: rtw_skb_copy fail!\n");
4700 						/* goto stop_proc; */
4701 						return -1;
4702 					}
4703 					rtw_skb_free(skb);
4704 
4705 					*pskb = skb = newskb;
4706 					if (is_vlan_tag) {
4707 						vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2));
4708 						for (i = 0; i < 6; i++)
4709 							*((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2));
4710 						skb_pull(skb, 4);
4711 					}
4712 				}
4713 
4714 				if (skb_is_nonlinear(skb))
4715 					DEBUG_ERR("%s(): skb_is_nonlinear!!\n", __FUNCTION__);
4716 
4717 
4718 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
4719 				res = skb_linearize(skb, GFP_ATOMIC);
4720 #else	/* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) */
4721 				res = skb_linearize(skb);
4722 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) */
4723 				if (res < 0) {
4724 					DEBUG_ERR("TX DROP: skb_linearize fail!\n");
4725 					/* goto free_and_stop; */
4726 					return -1;
4727 				}
4728 
4729 				res = nat25_db_handle(padapter, skb, NAT25_INSERT);
4730 				if (res < 0) {
4731 					if (res == -2) {
4732 						/* priv->ext_stats.tx_drops++; */
4733 						DEBUG_ERR("TX DROP: nat25_db_handle fail!\n");
4734 						/* goto free_and_stop; */
4735 						return -1;
4736 
4737 					}
4738 					/* we just print warning message and let it go */
4739 					/* DEBUG_WARN("%s()-%d: nat25_db_handle INSERT Warning!\n", __FUNCTION__, __LINE__); */
4740 					/* return -1; */ /* return -1 will cause system crash on 2011/08/30! */
4741 					return 0;
4742 				}
4743 			}
4744 
4745 			memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
4746 
4747 			dhcp_flag_bcast(padapter, skb);
4748 
4749 			if (is_vlan_tag) {
4750 				skb_push(skb, 4);
4751 				for (i = 0; i < 6; i++)
4752 					*((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2));
4753 				*((unsigned short *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q);
4754 				*((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr;
4755 			}
4756 		}
4757 #if 0
4758 		else {
4759 			if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q))
4760 				is_vlan_tag = 1;
4761 
4762 			if (is_vlan_tag) {
4763 				if (ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A_VALN(skb->data))
4764 					memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
4765 			} else {
4766 				if (ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A(skb->data))
4767 					memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
4768 			}
4769 		}
4770 #endif /* 0 */
4771 
4772 		/* check if SA is equal to our MAC */
4773 		if (memcmp(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN)) {
4774 			/* priv->ext_stats.tx_drops++; */
4775 			DEBUG_ERR("TX DROP: untransformed frame SA:%02X%02X%02X%02X%02X%02X!\n",
4776 				skb->data[6], skb->data[7], skb->data[8], skb->data[9], skb->data[10], skb->data[11]);
4777 			/* goto free_and_stop; */
4778 			return -1;
4779 		}
4780 	}
4781 	return 0;
4782 }
4783 #endif /* CONFIG_BR_EXT */
4784 
rtw_get_ff_hwaddr(struct xmit_frame * pxmitframe)4785 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
4786 {
4787 	u32 addr;
4788 	struct pkt_attrib *pattrib = &pxmitframe->attrib;
4789 
4790 	switch (pattrib->qsel) {
4791 	case 0:
4792 	case 3:
4793 		addr = BE_QUEUE_INX;
4794 		break;
4795 	case 1:
4796 	case 2:
4797 		addr = BK_QUEUE_INX;
4798 		break;
4799 	case 4:
4800 	case 5:
4801 		addr = VI_QUEUE_INX;
4802 		break;
4803 	case 6:
4804 	case 7:
4805 		addr = VO_QUEUE_INX;
4806 		break;
4807 	case 0x10:
4808 		addr = BCN_QUEUE_INX;
4809 		break;
4810 	case 0x11: /* BC/MC in PS (HIQ) */
4811 		addr = HIGH_QUEUE_INX;
4812 		break;
4813 	case 0x13:
4814 		addr = TXCMD_QUEUE_INX;
4815 		break;
4816 	case 0x12:
4817 	default:
4818 		addr = MGT_QUEUE_INX;
4819 		break;
4820 
4821 	}
4822 
4823 	return addr;
4824 
4825 }
4826 
do_queue_select(_adapter * padapter,struct pkt_attrib * pattrib)4827 static void do_queue_select(_adapter	*padapter, struct pkt_attrib *pattrib)
4828 {
4829 	u8 qsel;
4830 
4831 	qsel = pattrib->priority;
4832 
4833 #ifdef CONFIG_MCC_MODE
4834 	if (MCC_EN(padapter)) {
4835 		/* Under MCC */
4836 		if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC)) {
4837 			if (padapter->mcc_adapterpriv.role == MCC_ROLE_GO
4838 			    || padapter->mcc_adapterpriv.role == MCC_ROLE_AP) {
4839 				pattrib->qsel = QSLT_VO; /* AP interface VO queue */
4840 				pattrib->priority  = QSLT_VO;
4841 			} else {
4842 				pattrib->qsel = QSLT_BE; /* STA interface BE queue */
4843 				pattrib->priority  = QSLT_BE;
4844 			}
4845 		} else
4846 			/* Not Under MCC */
4847 			pattrib->qsel = qsel;
4848 	} else
4849 		/* Not enable MCC */
4850 		pattrib->qsel = qsel;
4851 #else /* !CONFIG_MCC_MODE */
4852 	pattrib->qsel = qsel;
4853 #endif /* CONFIG_MCC_MODE */
4854 
4855 	/* high priority packet */
4856 	if (pattrib->hipriority_pkt) {
4857 		pattrib->qsel = QSLT_VO;
4858 		pattrib->priority  = QSLT_VO;
4859 	}
4860 }
4861 
4862 /*
4863  * The main transmit(tx) entry
4864  *
4865  * Return
4866  *	1	enqueue
4867  *	0	success, hardware will handle this xmit frame(packet)
4868  *	<0	fail
4869  */
4870  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
rtw_monitor_xmit_entry(struct sk_buff * skb,struct net_device * ndev)4871 s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
4872 {
4873 	u16 frame_ctl;
4874 	struct ieee80211_radiotap_header rtap_hdr;
4875 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4876 	struct pkt_file pktfile;
4877 	struct rtw_ieee80211_hdr *pwlanhdr;
4878 	struct pkt_attrib	*pattrib;
4879 	struct xmit_frame		*pmgntframe;
4880 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
4881 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
4882 	unsigned char	*pframe;
4883 	u8 dummybuf[32];
4884 	int len = skb->len, rtap_len;
4885 
4886 
4887 	rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
4888 
4889 #ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL
4890 	if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
4891 		goto fail;
4892 
4893 	_rtw_open_pktfile((_pkt *)skb, &pktfile);
4894 	_rtw_pktfile_read(&pktfile, (u8 *)(&rtap_hdr), sizeof(struct ieee80211_radiotap_header));
4895 	rtap_len = ieee80211_get_radiotap_len((u8 *)(&rtap_hdr));
4896 	if (unlikely(rtap_hdr.it_version))
4897 		goto fail;
4898 
4899 	if (unlikely(skb->len < rtap_len))
4900 		goto fail;
4901 
4902 	if (rtap_len != 12) {
4903 		RTW_INFO("radiotap len (should be 14): %d\n", rtap_len);
4904 		goto fail;
4905 	}
4906 	_rtw_pktfile_read(&pktfile, dummybuf, rtap_len-sizeof(struct ieee80211_radiotap_header));
4907 	len = len - rtap_len;
4908 #endif
4909 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4910 	if (pmgntframe == NULL) {
4911 		rtw_udelay_os(500);
4912 		goto fail;
4913 	}
4914 
4915 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4916 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4917 //	_rtw_memcpy(pframe, (void *)checking, len);
4918 	_rtw_pktfile_read(&pktfile, pframe, len);
4919 
4920 
4921 	/* Check DATA/MGNT frames */
4922 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4923 	frame_ctl = le16_to_cpu(pwlanhdr->frame_ctl);
4924 	if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
4925 
4926 		pattrib = &pmgntframe->attrib;
4927 		update_monitor_frame_attrib(padapter, pattrib);
4928 
4929 		if (is_broadcast_mac_addr(pwlanhdr->addr3) || is_broadcast_mac_addr(pwlanhdr->addr1))
4930 			pattrib->rate = MGN_24M;
4931 
4932 	} else {
4933 
4934 		pattrib = &pmgntframe->attrib;
4935 		update_mgntframe_attrib(padapter, pattrib);
4936 
4937 	}
4938 	pattrib->retry_ctrl = _FALSE;
4939 	pattrib->pktlen = len;
4940 	pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4941 	pattrib->seqnum = pmlmeext->mgnt_seq;
4942 	pmlmeext->mgnt_seq++;
4943 	pattrib->last_txcmdsz = pattrib->pktlen;
4944 
4945 	dump_mgntframe(padapter, pmgntframe);
4946 
4947 fail:
4948 	rtw_skb_free(skb);
4949 	return 0;
4950 }
4951 #endif
4952 
4953 /*
4954  *
4955  * Return _TRUE when frame has been put to queue, otherwise return _FALSE.
4956  */
xmit_enqueue(struct _ADAPTER * a,struct xmit_frame * frame)4957 static u8 xmit_enqueue(struct _ADAPTER *a, struct xmit_frame *frame)
4958 {
4959 	struct sta_info *sta = NULL;
4960 	struct pkt_attrib *attrib = NULL;
4961 	_irqL irqL;
4962 	_list *head;
4963 	u8 ret = _TRUE;
4964 
4965 
4966 	attrib = &frame->attrib;
4967 	sta = attrib->psta;
4968 	if (!sta)
4969 		return _FALSE;
4970 
4971 	_enter_critical_bh(&sta->tx_queue.lock, &irqL);
4972 
4973 	head = get_list_head(&sta->tx_queue);
4974 
4975 	if ((rtw_is_list_empty(head) == _TRUE) && (!sta->tx_q_enable)) {
4976 		ret = _FALSE;
4977 		goto exit;
4978 	}
4979 
4980 	rtw_list_insert_tail(&frame->list, head);
4981 	RTW_INFO(FUNC_ADPT_FMT ": en-queue tx pkt for macid=%d\n",
4982 		 FUNC_ADPT_ARG(a), sta->cmn.mac_id);
4983 
4984 exit:
4985 	_exit_critical_bh(&sta->tx_queue.lock, &irqL);
4986 
4987 	return ret;
4988 }
4989 
xmit_dequeue(struct sta_info * sta)4990 static void xmit_dequeue(struct sta_info *sta)
4991 {
4992 	struct _ADAPTER *a;
4993 	_irqL irqL;
4994 	_list *head, *list;
4995 	struct xmit_frame *frame;
4996 
4997 
4998 	a = sta->padapter;
4999 
5000 	_enter_critical_bh(&sta->tx_queue.lock, &irqL);
5001 
5002 	head = get_list_head(&sta->tx_queue);
5003 
5004 	do {
5005 		if (rtw_is_list_empty(head) == _TRUE)
5006 			break;
5007 
5008 		list = get_next(head);
5009 		rtw_list_delete(list);
5010 		frame = LIST_CONTAINOR(list, struct xmit_frame, list);
5011 		RTW_INFO(FUNC_ADPT_FMT ": de-queue tx frame of macid=%d\n",
5012 			 FUNC_ADPT_ARG(a), sta->cmn.mac_id);
5013 
5014 		rtw_hal_xmit(a, frame);
5015 	} while (1);
5016 
5017 	_exit_critical_bh(&sta->tx_queue.lock, &irqL);
5018 }
5019 
rtw_xmit_dequeue_callback(_workitem * work)5020 void rtw_xmit_dequeue_callback(_workitem *work)
5021 {
5022 	struct sta_info *sta;
5023 
5024 
5025 	sta = container_of(work, struct sta_info, tx_q_work);
5026 	xmit_dequeue(sta);
5027 }
5028 
rtw_xmit_queue_set(struct sta_info * sta)5029 void rtw_xmit_queue_set(struct sta_info *sta)
5030 {
5031 	_irqL irqL;
5032 
5033 	_enter_critical_bh(&sta->tx_queue.lock, &irqL);
5034 
5035 	if (sta->tx_q_enable) {
5036 		RTW_WARN(FUNC_ADPT_FMT ": duplicated set!\n",
5037 			 FUNC_ADPT_ARG(sta->padapter));
5038 		goto exit;
5039 	}
5040 	sta->tx_q_enable = 1;
5041 	RTW_INFO(FUNC_ADPT_FMT ": enable queue TX for macid=%d\n",
5042 		 FUNC_ADPT_ARG(sta->padapter), sta->cmn.mac_id);
5043 
5044 exit:
5045 	_exit_critical_bh(&sta->tx_queue.lock, &irqL);
5046 }
5047 
rtw_xmit_queue_clear(struct sta_info * sta)5048 void rtw_xmit_queue_clear(struct sta_info *sta)
5049 {
5050 	_irqL irqL;
5051 
5052 	_enter_critical_bh(&sta->tx_queue.lock, &irqL);
5053 
5054 	if (!sta->tx_q_enable) {
5055 		RTW_WARN(FUNC_ADPT_FMT ": tx queue for macid=%d "
5056 			 "not be enabled!\n",
5057 			 FUNC_ADPT_ARG(sta->padapter), sta->cmn.mac_id);
5058 		goto exit;
5059 	}
5060 
5061 	sta->tx_q_enable = 0;
5062 	RTW_INFO(FUNC_ADPT_FMT ": disable queue TX for macid=%d\n",
5063 		 FUNC_ADPT_ARG(sta->padapter), sta->cmn.mac_id);
5064 
5065 	_set_workitem(&sta->tx_q_work);
5066 
5067 exit:
5068 	_exit_critical_bh(&sta->tx_queue.lock, &irqL);
5069 }
5070 
5071 /*
5072  * The main transmit(tx) entry post handle
5073  *
5074  * Return
5075  *	1	enqueue
5076  *	0	success, hardware will handle this xmit frame(packet)
5077  *	<0	fail
5078  */
rtw_xmit_posthandle(_adapter * padapter,struct xmit_frame * pxmitframe,_pkt * pkt)5079 s32 rtw_xmit_posthandle(_adapter *padapter, struct xmit_frame *pxmitframe, _pkt *pkt)
5080 {
5081 #ifdef CONFIG_AP_MODE
5082 	_irqL irqL0;
5083 #endif
5084 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5085 	s32 res;
5086 
5087 	res = update_attrib(padapter, pkt, &pxmitframe->attrib);
5088 
5089 #ifdef CONFIG_MCC_MODE
5090 	/* record data kernel TX to driver to check MCC concurrent TX */
5091 	rtw_hal_mcc_calc_tx_bytes_from_kernel(padapter, pxmitframe->attrib.pktlen);
5092 #endif /* CONFIG_MCC_MODE */
5093 
5094 #ifdef CONFIG_WAPI_SUPPORT
5095 	if (pxmitframe->attrib.ether_type != 0x88B4) {
5096 		if (rtw_wapi_drop_for_key_absent(padapter, pxmitframe->attrib.ra)) {
5097 			WAPI_TRACE(WAPI_RX, "drop for key absend when tx\n");
5098 			res = _FAIL;
5099 		}
5100 	}
5101 #endif
5102 	if (res == _FAIL) {
5103 		/*RTW_INFO("%s-"ADPT_FMT" update attrib fail\n", __func__, ADPT_ARG(padapter));*/
5104 #ifdef DBG_TX_DROP_FRAME
5105 		RTW_INFO("DBG_TX_DROP_FRAME %s update attrib fail\n", __FUNCTION__);
5106 #endif
5107 		rtw_free_xmitframe(pxmitpriv, pxmitframe);
5108 		return -1;
5109 	}
5110 	pxmitframe->pkt = pkt;
5111 
5112 	rtw_led_tx_control(padapter, pxmitframe->attrib.dst);
5113 
5114 	do_queue_select(padapter, &pxmitframe->attrib);
5115 
5116 #ifdef CONFIG_AP_MODE
5117 	_enter_critical_bh(&pxmitpriv->lock, &irqL0);
5118 	if (xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE) {
5119 		_exit_critical_bh(&pxmitpriv->lock, &irqL0);
5120 		DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue);
5121 		return 1;
5122 	}
5123 	_exit_critical_bh(&pxmitpriv->lock, &irqL0);
5124 #endif
5125 
5126 	if (xmit_enqueue(padapter, pxmitframe) == _TRUE)
5127 		return 1;
5128 
5129 	/* pre_xmitframe */
5130 	if (rtw_hal_xmit(padapter, pxmitframe) == _FALSE)
5131 		return 1;
5132 
5133 	return 0;
5134 }
5135 
5136 /*
5137  * The main transmit(tx) entry
5138  *
5139  * Return
5140  *	1	enqueue
5141  *	0	success, hardware will handle this xmit frame(packet)
5142  *	<0	fail
5143  */
rtw_xmit(_adapter * padapter,_pkt ** ppkt,u16 os_qid)5144 s32 rtw_xmit(_adapter *padapter, _pkt **ppkt, u16 os_qid)
5145 {
5146 	static systime start = 0;
5147 	static u32 drop_cnt = 0;
5148 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5149 	struct xmit_frame *pxmitframe = NULL;
5150 	s32 res;
5151 #ifdef CONFIG_LAYER2_ROAMING
5152 	struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
5153 	struct sk_buff *skb = (struct sk_buff *)(*ppkt);
5154 	_irqL irqL;
5155 #endif
5156 
5157 	DBG_COUNTER(padapter->tx_logs.core_tx);
5158 
5159 	if (IS_CH_WAITING(adapter_to_rfctl(padapter)))
5160 		return -1;
5161 
5162 	if ((rtw_linked_check(padapter) == _FALSE)
5163 #ifdef CONFIG_LAYER2_ROAMING
5164 		&&(!padapter->mlmepriv.roam_network)
5165 #endif
5166 	   )
5167 		return -1;
5168 
5169 	if (start == 0)
5170 		start = rtw_get_current_time();
5171 
5172 	pxmitframe = rtw_alloc_xmitframe(pxmitpriv, os_qid);
5173 
5174 	if (rtw_get_passing_time_ms(start) > 2000) {
5175 		if (drop_cnt)
5176 			RTW_INFO("DBG_TX_DROP_FRAME %s no more pxmitframe, drop_cnt:%u\n", __FUNCTION__, drop_cnt);
5177 		start = rtw_get_current_time();
5178 		drop_cnt = 0;
5179 	}
5180 
5181 	if (pxmitframe == NULL) {
5182 		drop_cnt++;
5183 		/*RTW_INFO("%s-"ADPT_FMT" no more xmitframe\n", __func__, ADPT_ARG(padapter));*/
5184 		DBG_COUNTER(padapter->tx_logs.core_tx_err_pxmitframe);
5185 		return -1;
5186 	}
5187 
5188 #ifdef CONFIG_BR_EXT
5189 	if (!adapter_use_wds(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) {
5190 		void *br_port = NULL;
5191 
5192 		#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
5193 		br_port = padapter->pnetdev->br_port;
5194 		#else
5195 		rcu_read_lock();
5196 		br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
5197 		rcu_read_unlock();
5198 		#endif
5199 
5200 		if (br_port) {
5201 			res = rtw_br_client_tx(padapter, ppkt);
5202 			if (res == -1) {
5203 				rtw_free_xmitframe(pxmitpriv, pxmitframe);
5204 				DBG_COUNTER(padapter->tx_logs.core_tx_err_brtx);
5205 				return -1;
5206 			}
5207 		}
5208 	}
5209 #endif /* CONFIG_BR_EXT */
5210 #ifdef CONFIG_LAYER2_ROAMING
5211 	if ((pmlmepriv->roam_network) && (skb->protocol != htons(0x888e))) {	/* eapol never enqueue.*/
5212 		pxmitframe->pkt = *ppkt;
5213 		rtw_list_delete(&pxmitframe->list);
5214 		_enter_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL);
5215 		rtw_list_insert_tail(&(pxmitframe->list), get_list_head(&(pxmitpriv->rpkt_queue)));
5216 		_exit_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL);
5217 		return 1;
5218 	}
5219 #endif
5220 
5221 #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH)
5222 	if (MLME_STATE(padapter) & (WIFI_AP_STATE | WIFI_MESH_STATE)) {
5223 		_list b2u_list;
5224 
5225 		#ifdef CONFIG_RTW_MESH
5226 		if (MLME_IS_MESH(padapter))
5227 			res = rtw_mesh_addr_resolve(padapter, os_qid, pxmitframe, *ppkt, &b2u_list);
5228 		else
5229 		#endif
5230 			res = rtw_ap_addr_resolve(padapter, os_qid, pxmitframe, *ppkt, &b2u_list);
5231 		if (res == RTW_RA_RESOLVING)
5232 			return 1;
5233 		if (res == _FAIL)
5234 			return -1;
5235 
5236 		#if CONFIG_RTW_DATA_BMC_TO_UC
5237 		if (!rtw_is_list_empty(&b2u_list)) {
5238 			_list *list = get_next(&b2u_list);
5239 			struct xmit_frame *b2uframe;
5240 
5241 			while ((rtw_end_of_queue_search(&b2u_list, list)) == _FALSE) {
5242 				b2uframe = LIST_CONTAINOR(list, struct xmit_frame, list);
5243 				list = get_next(list);
5244 				rtw_list_delete(&b2uframe->list);
5245 
5246 				b2uframe->pkt = rtw_os_pkt_copy(*ppkt);
5247 				if (!b2uframe->pkt) {
5248 					if (res == RTW_BMC_NO_NEED)
5249 						res = _SUCCESS;
5250 					rtw_free_xmitframe(pxmitpriv, b2uframe);
5251 					continue;
5252 				}
5253 
5254 				rtw_xmit_posthandle(padapter, b2uframe, b2uframe->pkt);
5255 			}
5256 		}
5257 		#endif
5258 
5259 		if (res == RTW_BMC_NO_NEED) {
5260 			rtw_free_xmitframe(&padapter->xmitpriv, pxmitframe);
5261 			return 0;
5262 		}
5263 	}
5264 #endif /* defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) */
5265 
5266 	pxmitframe->pkt = NULL; /* let rtw_xmit_posthandle not to free pkt inside */
5267 	res = rtw_xmit_posthandle(padapter, pxmitframe, *ppkt);
5268 
5269 	return res;
5270 }
5271 
5272 #ifdef CONFIG_TDLS
xmitframe_enqueue_for_tdls_sleeping_sta(_adapter * padapter,struct xmit_frame * pxmitframe)5273 sint xmitframe_enqueue_for_tdls_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
5274 {
5275 	sint ret = _FALSE;
5276 
5277 	_irqL irqL;
5278 	struct sta_info *ptdls_sta = NULL;
5279 	struct sta_priv *pstapriv = &padapter->stapriv;
5280 	struct pkt_attrib *pattrib = &pxmitframe->attrib;
5281 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5282 	int i;
5283 
5284 	ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
5285 	if (ptdls_sta == NULL)
5286 		return ret;
5287 	else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
5288 
5289 		if (pattrib->triggered == 1) {
5290 			ret = _TRUE;
5291 			return ret;
5292 		}
5293 
5294 		_enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
5295 
5296 		if (ptdls_sta->state & WIFI_SLEEP_STATE) {
5297 			rtw_list_delete(&pxmitframe->list);
5298 
5299 			/* _enter_critical_bh(&psta->sleep_q.lock, &irqL);	 */
5300 
5301 			rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptdls_sta->sleep_q));
5302 
5303 			ptdls_sta->sleepq_len++;
5304 			ptdls_sta->sleepq_ac_len++;
5305 
5306 			/* indicate 4-AC queue bit in TDLS peer traffic indication */
5307 			switch (pattrib->priority) {
5308 			case 1:
5309 			case 2:
5310 				ptdls_sta->uapsd_bk |= BIT(1);
5311 				break;
5312 			case 4:
5313 			case 5:
5314 				ptdls_sta->uapsd_vi |= BIT(1);
5315 				break;
5316 			case 6:
5317 			case 7:
5318 				ptdls_sta->uapsd_vo |= BIT(1);
5319 				break;
5320 			case 0:
5321 			case 3:
5322 			default:
5323 				ptdls_sta->uapsd_be |= BIT(1);
5324 				break;
5325 			}
5326 
5327 			/* Transmit TDLS PTI via AP */
5328 			if (ptdls_sta->sleepq_len == 1)
5329 				rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_ISSUE_PTI);
5330 
5331 			ret = _TRUE;
5332 		}
5333 
5334 		_exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
5335 	}
5336 
5337 	return ret;
5338 
5339 }
5340 #endif /* CONFIG_TDLS */
5341 
5342 #define RTW_HIQ_FILTER_ALLOW_ALL 0
5343 #define RTW_HIQ_FILTER_ALLOW_SPECIAL 1
5344 #define RTW_HIQ_FILTER_DENY_ALL 2
5345 
xmitframe_hiq_filter(struct xmit_frame * xmitframe)5346 inline bool xmitframe_hiq_filter(struct xmit_frame *xmitframe)
5347 {
5348 	bool allow = _FALSE;
5349 	_adapter *adapter = xmitframe->padapter;
5350 	struct registry_priv *registry = &adapter->registrypriv;
5351 
5352 	if (adapter->registrypriv.wifi_spec == 1)
5353 		allow = _TRUE;
5354 	else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_SPECIAL) {
5355 
5356 		struct pkt_attrib *attrib = &xmitframe->attrib;
5357 
5358 		if (attrib->ether_type == 0x0806
5359 		    || attrib->ether_type == 0x888e
5360 #ifdef CONFIG_WAPI_SUPPORT
5361 		    || attrib->ether_type == 0x88B4
5362 #endif
5363 		    || attrib->dhcp_pkt
5364 		   ) {
5365 			if (0)
5366 				RTW_INFO(FUNC_ADPT_FMT" ether_type:0x%04x%s\n", FUNC_ADPT_ARG(xmitframe->padapter)
5367 					, attrib->ether_type, attrib->dhcp_pkt ? " DHCP" : "");
5368 			allow = _TRUE;
5369 		}
5370 	} else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_ALL)
5371 		allow = _TRUE;
5372 	else if (registry->hiq_filter == RTW_HIQ_FILTER_DENY_ALL)
5373 		allow = _FALSE;
5374 	else
5375 		rtw_warn_on(1);
5376 
5377 	return allow;
5378 }
5379 
5380 #if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS)
5381 #ifdef CONFIG_RTW_MGMT_QUEUE
mgmt_xmitframe_enqueue_for_sleeping_sta(_adapter * padapter,struct xmit_frame * pxmitframe)5382 u8 mgmt_xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
5383 {
5384 	_irqL irqL;
5385 	struct pkt_attrib *pattrib = &pxmitframe->attrib;
5386 	struct sta_info *psta = pattrib->psta;
5387 	struct sta_priv *pstapriv = &padapter->stapriv;
5388 	bool update_tim = _FALSE;
5389 	u8 ret = _TRUE;
5390 
5391 	if (is_broadcast_mac_addr(pattrib->ra) || pattrib->ps_dontq)
5392 		return _FALSE;
5393 
5394 	if (psta == NULL) {
5395 		RTW_INFO("%s, psta==NUL, pattrib->ra:"MAC_FMT"\n",
5396 				    __func__, MAC_ARG(pattrib->ra));
5397 		return _FALSE;
5398 	}
5399 
5400 	if (!(psta->state & WIFI_ASOC_STATE)) {
5401 		DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_link);
5402 		RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state);
5403 		return _FALSE;
5404 	}
5405 
5406 	_enter_critical_bh(&psta->mgmt_sleep_q.lock, &irqL);
5407 
5408 	if (psta->state & WIFI_SLEEP_STATE &&
5409 		rtw_tim_map_is_set(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid)) {
5410 
5411 		rtw_list_delete(&pxmitframe->list);
5412 		rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->mgmt_sleep_q));
5413 		psta->mgmt_sleepq_len++;
5414 
5415 		#ifdef DBG_MGMT_QUEUE
5416 			RTW_INFO("%s attrib->ra:"MAC_FMT" seq_num = %u, subtype = 0x%x\n",
5417 			__func__, MAC_ARG(pattrib->ra), pattrib->seqnum, pattrib->subtype);
5418 		#endif
5419 
5420 		if (!(rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid)))
5421 			update_tim = _TRUE;
5422 
5423 		rtw_tim_map_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid);
5424 
5425 		/* upate BCN for TIM IE */
5426 		if (update_tim == _TRUE)
5427 			_update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "buffer mgmt frame");
5428 
5429 		ret = RTW_QUEUE_MGMT;
5430 		DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_ucast);
5431 	}
5432 
5433 	_exit_critical_bh(&psta->mgmt_sleep_q.lock, &irqL);
5434 
5435 	return ret;
5436 }
5437 
dequeue_mgmt_xmitframe_to_sleepq(_adapter * padapter,struct sta_info * psta,_queue * pframequeue)5438 static void dequeue_mgmt_xmitframe_to_sleepq(_adapter *padapter, struct sta_info *psta, _queue *pframequeue)
5439 {
5440 	sint ret;
5441 	_list	*plist, *phead;
5442 	struct tx_servq *ptxservq;
5443 	struct pkt_attrib *pattrib;
5444 	struct xmit_frame *pxmitframe;
5445 	struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5446 	struct hw_xmit *phwxmits = pxmitpriv->hwxmits;
5447 	u8 mgmt_idx = pxmitpriv->hwxmit_entry - 1;
5448 
5449 	phead = get_list_head(pframequeue);
5450 	plist = get_next(phead);
5451 
5452 	while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
5453 		pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
5454 		plist = get_next(plist);
5455 
5456 		pattrib = &pxmitframe->attrib;
5457 		pattrib->triggered = 0;
5458 
5459 		ret = mgmt_xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
5460 
5461 		if (ret == RTW_QUEUE_MGMT) {
5462 			ptxservq = &(psta->sta_xmitpriv.mgmt_q);
5463 			ptxservq->qcnt--;
5464 			phwxmits[mgmt_idx].accnt--;
5465 		} else {
5466 			/* RTW_INFO("xmitframe_enqueue_for_sleeping_sta return _FALSE\n"); */
5467 		}
5468 	}
5469 }
5470 #endif
5471 
xmitframe_enqueue_for_sleeping_sta(_adapter * padapter,struct xmit_frame * pxmitframe)5472 sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
5473 {
5474 	_irqL irqL;
5475 	sint ret = _FALSE;
5476 	struct sta_info *psta = NULL;
5477 	struct sta_priv *pstapriv = &padapter->stapriv;
5478 	struct pkt_attrib *pattrib = &pxmitframe->attrib;
5479 	sint bmcst = IS_MCAST(pattrib->ra);
5480 	bool update_tim = _FALSE;
5481 #ifdef CONFIG_TDLS
5482 
5483 	if (padapter->tdlsinfo.link_established == _TRUE)
5484 		ret = xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pxmitframe);
5485 #endif /* CONFIG_TDLS */
5486 
5487 	if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter)) {
5488 		DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_fwstate);
5489 		return ret;
5490 	}
5491 	/*
5492 		if(pattrib->psta)
5493 		{
5494 			psta = pattrib->psta;
5495 		}
5496 		else
5497 		{
5498 			RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
5499 			psta=rtw_get_stainfo(pstapriv, pattrib->ra);
5500 		}
5501 	*/
5502 	psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
5503 	if (pattrib->psta != psta) {
5504 		DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_sta);
5505 		RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
5506 		return _FALSE;
5507 	}
5508 
5509 	if (psta == NULL) {
5510 		DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_nosta);
5511 		RTW_INFO("%s, psta==NUL\n", __func__);
5512 		return _FALSE;
5513 	}
5514 
5515 	if (!(psta->state & WIFI_ASOC_STATE)) {
5516 		DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_link);
5517 		RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state);
5518 		return _FALSE;
5519 	}
5520 
5521 	if (pattrib->triggered == 1) {
5522 		DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_trigger);
5523 		/* RTW_INFO("directly xmit pspoll_triggered packet\n"); */
5524 
5525 		/* pattrib->triggered=0; */
5526 		if (bmcst && xmitframe_hiq_filter(pxmitframe) == _TRUE)
5527 			pattrib->qsel = QSLT_HIGH;/* HIQ */
5528 
5529 		return ret;
5530 	}
5531 
5532 
5533 	if (bmcst) {
5534 		_enter_critical_bh(&psta->sleep_q.lock, &irqL);
5535 
5536 		if (rtw_tim_map_anyone_be_set(padapter, pstapriv->sta_dz_bitmap)) { /* if anyone sta is in ps mode */
5537 			/* pattrib->qsel = QSLT_HIGH; */ /* HIQ */
5538 
5539 			rtw_list_delete(&pxmitframe->list);
5540 
5541 			/*_enter_critical_bh(&psta->sleep_q.lock, &irqL);*/
5542 
5543 			rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
5544 
5545 			psta->sleepq_len++;
5546 
5547 			if (!(rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, 0)))
5548 				update_tim = _TRUE;
5549 
5550 			rtw_tim_map_set(padapter, pstapriv->tim_bitmap, 0);
5551 			rtw_tim_map_set(padapter, pstapriv->sta_dz_bitmap, 0);
5552 
5553 			/* RTW_INFO("enqueue, sq_len=%d\n", psta->sleepq_len); */
5554 			/* RTW_INFO_DUMP("enqueue, tim=", pstapriv->tim_bitmap, pstapriv->aid_bmp_len); */
5555 			if (update_tim == _TRUE) {
5556 				if (is_broadcast_mac_addr(pattrib->ra))
5557 					_update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "buffer BC");
5558 				else
5559 					_update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "buffer MC");
5560 			} else
5561 				chk_bmc_sleepq_cmd(padapter);
5562 
5563 			/*_exit_critical_bh(&psta->sleep_q.lock, &irqL);*/
5564 
5565 			ret = _TRUE;
5566 
5567 			DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_mcast);
5568 		}
5569 
5570 		_exit_critical_bh(&psta->sleep_q.lock, &irqL);
5571 
5572 		return ret;
5573 
5574 	}
5575 
5576 
5577 	_enter_critical_bh(&psta->sleep_q.lock, &irqL);
5578 
5579 	if (psta->state & WIFI_SLEEP_STATE) {
5580 		u8 wmmps_ac = 0;
5581 
5582 		if (rtw_tim_map_is_set(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid)) {
5583 			rtw_list_delete(&pxmitframe->list);
5584 
5585 			/* _enter_critical_bh(&psta->sleep_q.lock, &irqL);	 */
5586 
5587 			rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
5588 
5589 			psta->sleepq_len++;
5590 
5591 			switch (pattrib->priority) {
5592 			case 1:
5593 			case 2:
5594 				wmmps_ac = psta->uapsd_bk & BIT(0);
5595 				break;
5596 			case 4:
5597 			case 5:
5598 				wmmps_ac = psta->uapsd_vi & BIT(0);
5599 				break;
5600 			case 6:
5601 			case 7:
5602 				wmmps_ac = psta->uapsd_vo & BIT(0);
5603 				break;
5604 			case 0:
5605 			case 3:
5606 			default:
5607 				wmmps_ac = psta->uapsd_be & BIT(0);
5608 				break;
5609 			}
5610 
5611 			if (wmmps_ac)
5612 				psta->sleepq_ac_len++;
5613 
5614 			if (((psta->has_legacy_ac) && (!wmmps_ac)) || ((!psta->has_legacy_ac) && (wmmps_ac))) {
5615 				if (!(rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid)))
5616 					update_tim = _TRUE;
5617 
5618 				rtw_tim_map_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid);
5619 
5620 				/* RTW_INFO("enqueue, sq_len=%d\n", psta->sleepq_len); */
5621 				/* RTW_INFO_DUMP("enqueue, tim=", pstapriv->tim_bitmap, pstapriv->aid_bmp_len); */
5622 
5623 				if (update_tim == _TRUE) {
5624 					/* RTW_INFO("sleepq_len==1, update BCNTIM\n"); */
5625 					/* upate BCN for TIM IE */
5626 					_update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "buffer UC");
5627 				}
5628 			}
5629 
5630 			/* _exit_critical_bh(&psta->sleep_q.lock, &irqL);			 */
5631 
5632 			/* if(psta->sleepq_len > (NR_XMITFRAME>>3)) */
5633 			/* { */
5634 			/*	wakeup_sta_to_xmit(padapter, psta); */
5635 			/* }	 */
5636 
5637 			ret = _TRUE;
5638 
5639 			DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_ucast);
5640 		}
5641 
5642 	}
5643 
5644 	_exit_critical_bh(&psta->sleep_q.lock, &irqL);
5645 
5646 	return ret;
5647 
5648 }
5649 
dequeue_xmitframes_to_sleeping_queue(_adapter * padapter,struct sta_info * psta,_queue * pframequeue)5650 static void dequeue_xmitframes_to_sleeping_queue(_adapter *padapter, struct sta_info *psta, _queue *pframequeue)
5651 {
5652 	sint ret;
5653 	_list	*plist, *phead;
5654 	u8	ac_index;
5655 	struct tx_servq	*ptxservq;
5656 	struct pkt_attrib	*pattrib;
5657 	struct xmit_frame	*pxmitframe;
5658 	struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
5659 
5660 	phead = get_list_head(pframequeue);
5661 	plist = get_next(phead);
5662 
5663 	while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
5664 		pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
5665 
5666 		plist = get_next(plist);
5667 
5668 		pattrib = &pxmitframe->attrib;
5669 
5670 		pattrib->triggered = 0;
5671 
5672 		ret = xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
5673 
5674 		if (_TRUE == ret) {
5675 			ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
5676 
5677 			ptxservq->qcnt--;
5678 			phwxmits[ac_index].accnt--;
5679 		} else {
5680 			/* RTW_INFO("xmitframe_enqueue_for_sleeping_sta return _FALSE\n"); */
5681 		}
5682 
5683 	}
5684 
5685 }
5686 
stop_sta_xmit(_adapter * padapter,struct sta_info * psta)5687 void stop_sta_xmit(_adapter *padapter, struct sta_info *psta)
5688 {
5689 	_irqL irqL0;
5690 	struct sta_info *psta_bmc;
5691 	struct sta_xmit_priv *pstaxmitpriv;
5692 	struct sta_priv *pstapriv = &padapter->stapriv;
5693 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5694 
5695 	pstaxmitpriv = &psta->sta_xmitpriv;
5696 
5697 	/* for BC/MC Frames */
5698 	psta_bmc = rtw_get_bcmc_stainfo(padapter);
5699 	if (!psta_bmc)
5700 		rtw_warn_on(1);
5701 
5702 	_enter_critical_bh(&pxmitpriv->lock, &irqL0);
5703 
5704 	psta->state |= WIFI_SLEEP_STATE;
5705 
5706 #ifdef CONFIG_TDLS
5707 	if (!(psta->tdls_sta_state & TDLS_LINKED_STATE))
5708 #endif /* CONFIG_TDLS */
5709 		rtw_tim_map_set(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid);
5710 
5711 #ifdef CONFIG_RTW_MGMT_QUEUE
5712 	dequeue_mgmt_xmitframe_to_sleepq(padapter, psta, &pstaxmitpriv->mgmt_q.sta_pending);
5713 	rtw_list_delete(&(pstaxmitpriv->mgmt_q.tx_pending));
5714 #endif
5715 
5716 	dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
5717 	rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));
5718 	dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
5719 	rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));
5720 	dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
5721 	rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
5722 	dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
5723 	rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));
5724 
5725 	if (psta_bmc != NULL
5726 		#ifdef CONFIG_TDLS
5727 		&& !(psta->tdls_sta_state & TDLS_LINKED_STATE)
5728 		#endif
5729 	)
5730 	{
5731 		/* for BC/MC Frames */
5732 		pstaxmitpriv = &psta_bmc->sta_xmitpriv;
5733 		dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->vo_q.sta_pending);
5734 		rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));
5735 		dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->vi_q.sta_pending);
5736 		rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));
5737 		dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending);
5738 		rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
5739 		dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->bk_q.sta_pending);
5740 		rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));
5741 	}
5742 	_exit_critical_bh(&pxmitpriv->lock, &irqL0);
5743 
5744 
5745 }
5746 
wakeup_sta_to_xmit(_adapter * padapter,struct sta_info * psta)5747 void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta)
5748 {
5749 	_irqL irqL;
5750 	u8 update_mask = 0, wmmps_ac = 0;
5751 	struct sta_info *psta_bmc;
5752 	_list	*xmitframe_plist, *xmitframe_phead;
5753 	struct xmit_frame *pxmitframe = NULL;
5754 	struct sta_priv *pstapriv = &padapter->stapriv;
5755 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5756 
5757 	psta_bmc = rtw_get_bcmc_stainfo(padapter);
5758 
5759 
5760 	/* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
5761 	_enter_critical_bh(&pxmitpriv->lock, &irqL);
5762 
5763 #ifdef CONFIG_RTW_MGMT_QUEUE
5764 	/* management queue */
5765 	xmitframe_phead = get_list_head(&psta->mgmt_sleep_q);
5766 	xmitframe_plist = get_next(xmitframe_phead);
5767 
5768 	while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
5769 		pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
5770 
5771 		xmitframe_plist = get_next(xmitframe_plist);
5772 
5773 		rtw_list_delete(&pxmitframe->list);
5774 
5775 		#ifdef DBG_MGMT_QUEUE
5776 		RTW_INFO("%s seq_num = %u, subtype = 0x%x\n",
5777 				__func__, pxmitframe->attrib.seqnum, pxmitframe->attrib.subtype);
5778 		#endif
5779 
5780 		psta->mgmt_sleepq_len--;
5781 
5782 		pxmitframe->attrib.triggered = 1;
5783 
5784 		rtw_hal_mgmt_xmitframe_enqueue(padapter, pxmitframe);
5785 	}
5786 #endif /* CONFIG_RTW_MGMT_QUEUE */
5787 
5788 	/* AC queue */
5789 	xmitframe_phead = get_list_head(&psta->sleep_q);
5790 	xmitframe_plist = get_next(xmitframe_phead);
5791 
5792 	while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
5793 		pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
5794 
5795 		xmitframe_plist = get_next(xmitframe_plist);
5796 
5797 		rtw_list_delete(&pxmitframe->list);
5798 
5799 		switch (pxmitframe->attrib.priority) {
5800 		case 1:
5801 		case 2:
5802 			wmmps_ac = psta->uapsd_bk & BIT(1);
5803 			break;
5804 		case 4:
5805 		case 5:
5806 			wmmps_ac = psta->uapsd_vi & BIT(1);
5807 			break;
5808 		case 6:
5809 		case 7:
5810 			wmmps_ac = psta->uapsd_vo & BIT(1);
5811 			break;
5812 		case 0:
5813 		case 3:
5814 		default:
5815 			wmmps_ac = psta->uapsd_be & BIT(1);
5816 			break;
5817 		}
5818 
5819 		psta->sleepq_len--;
5820 		if (psta->sleepq_len > 0)
5821 			pxmitframe->attrib.mdata = 1;
5822 		else
5823 			pxmitframe->attrib.mdata = 0;
5824 
5825 		if (wmmps_ac) {
5826 			psta->sleepq_ac_len--;
5827 			if (psta->sleepq_ac_len > 0) {
5828 				pxmitframe->attrib.mdata = 1;
5829 				pxmitframe->attrib.eosp = 0;
5830 			} else {
5831 				pxmitframe->attrib.mdata = 0;
5832 				pxmitframe->attrib.eosp = 1;
5833 			}
5834 		}
5835 
5836 		pxmitframe->attrib.triggered = 1;
5837 
5838 		/*
5839 				_exit_critical_bh(&psta->sleep_q.lock, &irqL);
5840 				if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
5841 				{
5842 					rtw_os_xmit_complete(padapter, pxmitframe);
5843 				}
5844 				_enter_critical_bh(&psta->sleep_q.lock, &irqL);
5845 		*/
5846 		rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
5847 
5848 
5849 	}
5850 
5851 	if (psta->sleepq_len == 0
5852 #ifdef CONFIG_RTW_MGMT_QUEUE
5853 		&& psta->mgmt_sleepq_len == 0
5854 #endif
5855 	) {
5856 #ifdef CONFIG_TDLS
5857 		if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
5858 			if (psta->state & WIFI_SLEEP_STATE)
5859 				psta->state ^= WIFI_SLEEP_STATE;
5860 
5861 			_exit_critical_bh(&pxmitpriv->lock, &irqL);
5862 			return;
5863 		}
5864 #endif /* CONFIG_TDLS */
5865 
5866 		if (rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid)) {
5867 			/* RTW_INFO("wakeup to xmit, qlen==0\n"); */
5868 			/* RTW_INFO_DUMP("update_BCNTIM, tim=", pstapriv->tim_bitmap, pstapriv->aid_bmp_len); */
5869 			/* upate BCN for TIM IE */
5870 			/* update_BCNTIM(padapter); */
5871 			update_mask = BIT(0);
5872 		}
5873 
5874 		rtw_tim_map_clear(padapter, pstapriv->tim_bitmap, psta->cmn.aid);
5875 
5876 		if (psta->state & WIFI_SLEEP_STATE)
5877 			psta->state ^= WIFI_SLEEP_STATE;
5878 
5879 		if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
5880 			RTW_INFO("%s alive check\n", __func__);
5881 			psta->expire_to = pstapriv->expire_to;
5882 			psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
5883 		}
5884 
5885 		rtw_tim_map_clear(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid);
5886 	}
5887 
5888 	/* for BC/MC Frames */
5889 	if (!psta_bmc)
5890 		goto _exit;
5891 
5892 	if (!(rtw_tim_map_anyone_be_set_exclude_aid0(padapter, pstapriv->sta_dz_bitmap))) { /* no any sta in ps mode */
5893 		xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
5894 		xmitframe_plist = get_next(xmitframe_phead);
5895 
5896 		while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
5897 			pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
5898 
5899 			xmitframe_plist = get_next(xmitframe_plist);
5900 
5901 			rtw_list_delete(&pxmitframe->list);
5902 
5903 			psta_bmc->sleepq_len--;
5904 			if (psta_bmc->sleepq_len > 0)
5905 				pxmitframe->attrib.mdata = 1;
5906 			else
5907 				pxmitframe->attrib.mdata = 0;
5908 
5909 
5910 			pxmitframe->attrib.triggered = 1;
5911 			/*
5912 						_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
5913 						if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
5914 						{
5915 							rtw_os_xmit_complete(padapter, pxmitframe);
5916 						}
5917 						_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
5918 
5919 			*/
5920 			rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
5921 
5922 		}
5923 
5924 		if (psta_bmc->sleepq_len == 0) {
5925 			if (rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, 0)) {
5926 				/* RTW_INFO("wakeup to xmit, qlen==0\n"); */
5927 				/* RTW_INFO_DUMP("update_BCNTIM, tim=", pstapriv->tim_bitmap, pstapriv->aid_bmp_len); */
5928 				/* upate BCN for TIM IE */
5929 				/* update_BCNTIM(padapter); */
5930 				update_mask |= BIT(1);
5931 			}
5932 			rtw_tim_map_clear(padapter, pstapriv->tim_bitmap, 0);
5933 			rtw_tim_map_clear(padapter, pstapriv->sta_dz_bitmap, 0);
5934 		}
5935 
5936 	}
5937 
5938 _exit:
5939 
5940 	/* _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);	 */
5941 	_exit_critical_bh(&pxmitpriv->lock, &irqL);
5942 
5943 	if (update_mask) {
5944 		/* update_BCNTIM(padapter); */
5945 		if ((update_mask & (BIT(0) | BIT(1))) == (BIT(0) | BIT(1)))
5946 			_update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "clear UC&BMC");
5947 		else if ((update_mask & BIT(1)) == BIT(1))
5948 			_update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "clear BMC");
5949 		else
5950 			_update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "clear UC");
5951 	}
5952 }
5953 
xmit_delivery_enabled_frames(_adapter * padapter,struct sta_info * psta)5954 void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta)
5955 {
5956 	_irqL irqL;
5957 	u8 wmmps_ac = 0;
5958 	_list	*xmitframe_plist, *xmitframe_phead;
5959 	struct xmit_frame *pxmitframe = NULL;
5960 	struct sta_priv *pstapriv = &padapter->stapriv;
5961 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5962 
5963 
5964 	/* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
5965 	_enter_critical_bh(&pxmitpriv->lock, &irqL);
5966 
5967 	xmitframe_phead = get_list_head(&psta->sleep_q);
5968 	xmitframe_plist = get_next(xmitframe_phead);
5969 
5970 	while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
5971 		pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
5972 
5973 		xmitframe_plist = get_next(xmitframe_plist);
5974 
5975 		switch (pxmitframe->attrib.priority) {
5976 		case 1:
5977 		case 2:
5978 			wmmps_ac = psta->uapsd_bk & BIT(1);
5979 			break;
5980 		case 4:
5981 		case 5:
5982 			wmmps_ac = psta->uapsd_vi & BIT(1);
5983 			break;
5984 		case 6:
5985 		case 7:
5986 			wmmps_ac = psta->uapsd_vo & BIT(1);
5987 			break;
5988 		case 0:
5989 		case 3:
5990 		default:
5991 			wmmps_ac = psta->uapsd_be & BIT(1);
5992 			break;
5993 		}
5994 
5995 		if (!wmmps_ac)
5996 			continue;
5997 
5998 		rtw_list_delete(&pxmitframe->list);
5999 
6000 		psta->sleepq_len--;
6001 		psta->sleepq_ac_len--;
6002 
6003 		if (psta->sleepq_ac_len > 0) {
6004 			pxmitframe->attrib.mdata = 1;
6005 			pxmitframe->attrib.eosp = 0;
6006 		} else {
6007 			pxmitframe->attrib.mdata = 0;
6008 			pxmitframe->attrib.eosp = 1;
6009 		}
6010 
6011 		pxmitframe->attrib.triggered = 1;
6012 		rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
6013 
6014 		if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) {
6015 #ifdef CONFIG_TDLS
6016 			if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
6017 				/* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
6018 				goto exit;
6019 			}
6020 #endif /* CONFIG_TDLS */
6021 			rtw_tim_map_clear(padapter, pstapriv->tim_bitmap, psta->cmn.aid);
6022 
6023 			/* RTW_INFO("wakeup to xmit, qlen==0\n"); */
6024 			/* RTW_INFO_DUMP("update_BCNTIM, tim=", pstapriv->tim_bitmap, pstapriv->aid_bmp_len); */
6025 			/* upate BCN for TIM IE */
6026 			/* update_BCNTIM(padapter); */
6027 			update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0);
6028 			/* update_mask = BIT(0); */
6029 		}
6030 
6031 	}
6032 
6033 #ifdef CONFIG_TDLS
6034 exit:
6035 #endif
6036 	/* _exit_critical_bh(&psta->sleep_q.lock, &irqL);	 */
6037 	_exit_critical_bh(&pxmitpriv->lock, &irqL);
6038 
6039 	return;
6040 }
6041 
6042 #endif /* defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) */
6043 
6044 #ifdef CONFIG_XMIT_THREAD_MODE
enqueue_pending_xmitbuf(struct xmit_priv * pxmitpriv,struct xmit_buf * pxmitbuf)6045 void enqueue_pending_xmitbuf(
6046 	struct xmit_priv *pxmitpriv,
6047 	struct xmit_buf *pxmitbuf)
6048 {
6049 	_irqL irql;
6050 	_queue *pqueue;
6051 	_adapter *pri_adapter = pxmitpriv->adapter;
6052 
6053 	pqueue = &pxmitpriv->pending_xmitbuf_queue;
6054 
6055 	_enter_critical_bh(&pqueue->lock, &irql);
6056 	rtw_list_delete(&pxmitbuf->list);
6057 	rtw_list_insert_tail(&pxmitbuf->list, get_list_head(pqueue));
6058 	_exit_critical_bh(&pqueue->lock, &irql);
6059 
6060 #if defined(CONFIG_SDIO_HCI) && defined(CONFIG_CONCURRENT_MODE)
6061 	pri_adapter = GET_PRIMARY_ADAPTER(pri_adapter);
6062 #endif /*SDIO_HCI + CONCURRENT*/
6063 	_rtw_up_sema(&(pri_adapter->xmitpriv.xmit_sema));
6064 }
6065 
enqueue_pending_xmitbuf_to_head(struct xmit_priv * pxmitpriv,struct xmit_buf * pxmitbuf)6066 void enqueue_pending_xmitbuf_to_head(
6067 	struct xmit_priv *pxmitpriv,
6068 	struct xmit_buf *pxmitbuf)
6069 {
6070 	_irqL irql;
6071 	_queue *pqueue = &pxmitpriv->pending_xmitbuf_queue;
6072 
6073 	_enter_critical_bh(&pqueue->lock, &irql);
6074 	rtw_list_delete(&pxmitbuf->list);
6075 	rtw_list_insert_head(&pxmitbuf->list, get_list_head(pqueue));
6076 	_exit_critical_bh(&pqueue->lock, &irql);
6077 }
6078 
dequeue_pending_xmitbuf(struct xmit_priv * pxmitpriv)6079 struct xmit_buf *dequeue_pending_xmitbuf(
6080 	struct xmit_priv *pxmitpriv)
6081 {
6082 	_irqL irql;
6083 	struct xmit_buf *pxmitbuf;
6084 	_queue *pqueue;
6085 
6086 
6087 	pxmitbuf = NULL;
6088 	pqueue = &pxmitpriv->pending_xmitbuf_queue;
6089 
6090 	_enter_critical_bh(&pqueue->lock, &irql);
6091 
6092 	if (_rtw_queue_empty(pqueue) == _FALSE) {
6093 		_list *plist, *phead;
6094 
6095 		phead = get_list_head(pqueue);
6096 		plist = get_next(phead);
6097 		pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
6098 		rtw_list_delete(&pxmitbuf->list);
6099 	}
6100 
6101 	_exit_critical_bh(&pqueue->lock, &irql);
6102 
6103 	return pxmitbuf;
6104 }
6105 
dequeue_pending_xmitbuf_ext(struct xmit_priv * pxmitpriv)6106 static struct xmit_buf *dequeue_pending_xmitbuf_ext(
6107 	struct xmit_priv *pxmitpriv)
6108 {
6109 	_irqL irql;
6110 	struct xmit_buf *pxmitbuf;
6111 	_queue *pqueue;
6112 
6113 	pxmitbuf = NULL;
6114 	pqueue = &pxmitpriv->pending_xmitbuf_queue;
6115 
6116 	_enter_critical_bh(&pqueue->lock, &irql);
6117 
6118 	if (_rtw_queue_empty(pqueue) == _FALSE) {
6119 		_list *plist, *phead;
6120 
6121 		phead = get_list_head(pqueue);
6122 		plist = phead;
6123 		do {
6124 			plist = get_next(plist);
6125 			if (plist == phead)
6126 				break;
6127 
6128 			pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
6129 
6130 			if (pxmitbuf->buf_tag == XMITBUF_MGNT) {
6131 				rtw_list_delete(&pxmitbuf->list);
6132 				break;
6133 			}
6134 			pxmitbuf = NULL;
6135 		} while (1);
6136 	}
6137 
6138 	_exit_critical_bh(&pqueue->lock, &irql);
6139 
6140 	return pxmitbuf;
6141 }
6142 
select_and_dequeue_pending_xmitbuf(_adapter * padapter)6143 struct xmit_buf *select_and_dequeue_pending_xmitbuf(_adapter *padapter)
6144 {
6145 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6146 	struct xmit_buf *pxmitbuf = NULL;
6147 
6148 	if (_TRUE == rtw_is_xmit_blocked(padapter))
6149 		return pxmitbuf;
6150 
6151 	pxmitbuf = dequeue_pending_xmitbuf_ext(pxmitpriv);
6152 	if (pxmitbuf == NULL && rtw_xmit_ac_blocked(padapter) != _TRUE)
6153 		pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
6154 
6155 	return pxmitbuf;
6156 }
6157 
check_pending_xmitbuf(struct xmit_priv * pxmitpriv)6158 sint check_pending_xmitbuf(
6159 	struct xmit_priv *pxmitpriv)
6160 {
6161 	_irqL irql;
6162 	_queue *pqueue;
6163 	sint	ret = _FALSE;
6164 
6165 	pqueue = &pxmitpriv->pending_xmitbuf_queue;
6166 
6167 	_enter_critical_bh(&pqueue->lock, &irql);
6168 
6169 	if (_rtw_queue_empty(pqueue) == _FALSE)
6170 		ret = _TRUE;
6171 
6172 	_exit_critical_bh(&pqueue->lock, &irql);
6173 
6174 	return ret;
6175 }
6176 
rtw_xmit_thread(thread_context context)6177 thread_return rtw_xmit_thread(thread_context context)
6178 {
6179 	s32 err;
6180 	PADAPTER padapter;
6181 #ifdef RTW_XMIT_THREAD_HIGH_PRIORITY
6182 #ifdef PLATFORM_LINUX
6183 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
6184 	sched_set_fifo_low(current);
6185 #else
6186 	struct sched_param param = { .sched_priority = 1 };
6187 
6188 	sched_setscheduler(current, SCHED_FIFO, &param);
6189 #endif
6190 #endif /* PLATFORM_LINUX */
6191 #endif /* RTW_XMIT_THREAD_HIGH_PRIORITY */
6192 
6193 	err = _SUCCESS;
6194 	padapter = (PADAPTER)context;
6195 
6196 	thread_enter("RTW_XMIT_THREAD");
6197 
6198 	do {
6199 		err = rtw_hal_xmit_thread_handler(padapter);
6200 		flush_signals_thread();
6201 	} while (_SUCCESS == err);
6202 
6203 	RTW_INFO(FUNC_ADPT_FMT " Exit\n", FUNC_ADPT_ARG(padapter));
6204 
6205 	rtw_thread_wait_stop();
6206 
6207 	return 0;
6208 }
6209 #endif
6210 
6211 #ifdef DBG_XMIT_BLOCK
dump_xmit_block(void * sel,_adapter * padapter)6212 void dump_xmit_block(void *sel, _adapter *padapter)
6213 {
6214 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
6215 
6216 	RTW_PRINT_SEL(sel, "[XMIT-BLOCK] xmit_block :0x%02x\n", dvobj->xmit_block);
6217 	if (dvobj->xmit_block & XMIT_BLOCK_REDLMEM)
6218 		RTW_PRINT_SEL(sel, "Reason:%s\n", "XMIT_BLOCK_REDLMEM");
6219 	if (dvobj->xmit_block & XMIT_BLOCK_SUSPEND)
6220 		RTW_PRINT_SEL(sel, "Reason:%s\n", "XMIT_BLOCK_SUSPEND");
6221 	if (dvobj->xmit_block == XMIT_BLOCK_NONE)
6222 		RTW_PRINT_SEL(sel, "Reason:%s\n", "XMIT_BLOCK_NONE");
6223 }
dump_xmit_block_info(void * sel,const char * fun_name,_adapter * padapter)6224 void dump_xmit_block_info(void *sel, const char *fun_name, _adapter *padapter)
6225 {
6226 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
6227 
6228 	RTW_INFO("\n"ADPT_FMT" call %s\n", ADPT_ARG(padapter), fun_name);
6229 	dump_xmit_block(sel, padapter);
6230 }
6231 #define DBG_XMIT_BLOCK_DUMP(adapter)	dump_xmit_block_info(RTW_DBGDUMP, __func__, adapter)
6232 #endif
6233 
rtw_set_xmit_block(_adapter * padapter,enum XMIT_BLOCK_REASON reason)6234 void rtw_set_xmit_block(_adapter *padapter, enum XMIT_BLOCK_REASON reason)
6235 {
6236 	_irqL irqL;
6237 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
6238 
6239 	_enter_critical_bh(&dvobj->xmit_block_lock, &irqL);
6240 	dvobj->xmit_block |= reason;
6241 	_exit_critical_bh(&dvobj->xmit_block_lock, &irqL);
6242 
6243 	#ifdef DBG_XMIT_BLOCK
6244 	DBG_XMIT_BLOCK_DUMP(padapter);
6245 	#endif
6246 }
6247 
rtw_clr_xmit_block(_adapter * padapter,enum XMIT_BLOCK_REASON reason)6248 void rtw_clr_xmit_block(_adapter *padapter, enum XMIT_BLOCK_REASON reason)
6249 {
6250 	_irqL irqL;
6251 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
6252 
6253 	_enter_critical_bh(&dvobj->xmit_block_lock, &irqL);
6254 	dvobj->xmit_block &= ~reason;
6255 	_exit_critical_bh(&dvobj->xmit_block_lock, &irqL);
6256 
6257 	#ifdef DBG_XMIT_BLOCK
6258 	DBG_XMIT_BLOCK_DUMP(padapter);
6259 	#endif
6260 }
rtw_is_xmit_blocked(_adapter * padapter)6261 bool rtw_is_xmit_blocked(_adapter *padapter)
6262 {
6263 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
6264 
6265 	#ifdef DBG_XMIT_BLOCK
6266 	DBG_XMIT_BLOCK_DUMP(padapter);
6267 	#endif
6268 	return ((dvobj->xmit_block) ? _TRUE : _FALSE);
6269 }
6270 
rtw_xmit_ac_blocked(_adapter * adapter)6271 bool rtw_xmit_ac_blocked(_adapter *adapter)
6272 {
6273 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
6274 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
6275 	_adapter *iface;
6276 	struct mlme_ext_priv *mlmeext;
6277 	bool blocked = _FALSE;
6278 	int i;
6279 #ifdef DBG_CONFIG_ERROR_DETECT
6280 #ifdef DBG_CONFIG_ERROR_RESET
6281 #ifdef CONFIG_USB_HCI
6282 	if (rtw_hal_sreset_inprogress(adapter) == _TRUE) {
6283 		blocked = _TRUE;
6284 		goto exit;
6285 	}
6286 #endif/* #ifdef CONFIG_USB_HCI */
6287 #endif/* #ifdef DBG_CONFIG_ERROR_RESET */
6288 #endif/* #ifdef DBG_CONFIG_ERROR_DETECT */
6289 
6290 	if (rfctl->offch_state != OFFCHS_NONE
6291 		#if CONFIG_DFS
6292 		|| IS_RADAR_DETECTED(rfctl) || rfctl->csa_ch
6293 		#endif
6294 	) {
6295 		blocked = _TRUE;
6296 		goto exit;
6297 	}
6298 
6299 	for (i = 0; i < dvobj->iface_nums; i++) {
6300 		iface = dvobj->padapters[i];
6301 		mlmeext = &iface->mlmeextpriv;
6302 
6303 		/* check scan state */
6304 		if (mlmeext_scan_state(mlmeext) != SCAN_DISABLE
6305 			&& mlmeext_scan_state(mlmeext) != SCAN_BACK_OP
6306 		) {
6307 			blocked = _TRUE;
6308 			goto exit;
6309 		}
6310 
6311 		if (mlmeext_scan_state(mlmeext) == SCAN_BACK_OP
6312 			&& !mlmeext_chk_scan_backop_flags(mlmeext, SS_BACKOP_TX_RESUME)
6313 		) {
6314 			blocked = _TRUE;
6315 			goto exit;
6316 		}
6317 	}
6318 
6319 #ifdef CONFIG_MCC_MODE
6320 	if (MCC_EN(adapter)) {
6321 		if (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC)) {
6322 			if (MCC_STOP(adapter)) {
6323 				blocked = _TRUE;
6324 				goto exit;
6325 			}
6326 		}
6327 	}
6328 #endif /*  CONFIG_MCC_MODE */
6329 
6330 exit:
6331 	return blocked;
6332 }
6333 
6334 #ifdef CONFIG_TX_AMSDU
rtw_amsdu_vo_timeout_handler(void * FunctionContext)6335 void rtw_amsdu_vo_timeout_handler(void *FunctionContext)
6336 {
6337 	_adapter *adapter = (_adapter *)FunctionContext;
6338 
6339 	adapter->xmitpriv.amsdu_vo_timeout = RTW_AMSDU_TIMER_TIMEOUT;
6340 
6341 	tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
6342 }
6343 
rtw_amsdu_vi_timeout_handler(void * FunctionContext)6344 void rtw_amsdu_vi_timeout_handler(void *FunctionContext)
6345 {
6346 	_adapter *adapter = (_adapter *)FunctionContext;
6347 
6348 	adapter->xmitpriv.amsdu_vi_timeout = RTW_AMSDU_TIMER_TIMEOUT;
6349 
6350 	tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
6351 }
6352 
rtw_amsdu_be_timeout_handler(void * FunctionContext)6353 void rtw_amsdu_be_timeout_handler(void *FunctionContext)
6354 {
6355 	_adapter *adapter = (_adapter *)FunctionContext;
6356 
6357 	adapter->xmitpriv.amsdu_be_timeout = RTW_AMSDU_TIMER_TIMEOUT;
6358 
6359 	if (printk_ratelimit())
6360 		RTW_INFO("%s Timeout!\n",__FUNCTION__);
6361 
6362 	tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
6363 }
6364 
rtw_amsdu_bk_timeout_handler(void * FunctionContext)6365 void rtw_amsdu_bk_timeout_handler(void *FunctionContext)
6366 {
6367 	_adapter *adapter = (_adapter *)FunctionContext;
6368 
6369 	adapter->xmitpriv.amsdu_bk_timeout = RTW_AMSDU_TIMER_TIMEOUT;
6370 
6371 	tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
6372 }
6373 
rtw_amsdu_get_timer_status(_adapter * padapter,u8 priority)6374 u8 rtw_amsdu_get_timer_status(_adapter *padapter, u8 priority)
6375 {
6376 	struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
6377 
6378 	u8 status =  RTW_AMSDU_TIMER_UNSET;
6379 
6380 	switch(priority)
6381 	{
6382 		case 1:
6383 		case 2:
6384 			status = pxmitpriv->amsdu_bk_timeout;
6385 			break;
6386 		case 4:
6387 		case 5:
6388 			status = pxmitpriv->amsdu_vi_timeout;
6389 			break;
6390 		case 6:
6391 		case 7:
6392 			status = pxmitpriv->amsdu_vo_timeout;
6393 			break;
6394 		case 0:
6395 		case 3:
6396 		default:
6397 			status = pxmitpriv->amsdu_be_timeout;
6398 			break;
6399 	}
6400 	return status;
6401 }
6402 
rtw_amsdu_set_timer_status(_adapter * padapter,u8 priority,u8 status)6403 void rtw_amsdu_set_timer_status(_adapter *padapter, u8 priority, u8 status)
6404 {
6405 	struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
6406 
6407 	switch(priority)
6408 	{
6409 		case 1:
6410 		case 2:
6411 			pxmitpriv->amsdu_bk_timeout = status;
6412 			break;
6413 		case 4:
6414 		case 5:
6415 			pxmitpriv->amsdu_vi_timeout = status;
6416 			break;
6417 		case 6:
6418 		case 7:
6419 			pxmitpriv->amsdu_vo_timeout = status;
6420 			break;
6421 		case 0:
6422 		case 3:
6423 		default:
6424 			pxmitpriv->amsdu_be_timeout = status;
6425 			break;
6426 	}
6427 }
6428 
rtw_amsdu_set_timer(_adapter * padapter,u8 priority)6429 void rtw_amsdu_set_timer(_adapter *padapter, u8 priority)
6430 {
6431 	struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
6432 
6433 	_timer* amsdu_timer = NULL;
6434 
6435 	switch(priority)
6436 	{
6437 		case 1:
6438 		case 2:
6439 			amsdu_timer = &pxmitpriv->amsdu_bk_timer;
6440 			break;
6441 		case 4:
6442 		case 5:
6443 			amsdu_timer = &pxmitpriv->amsdu_vi_timer;
6444 			break;
6445 		case 6:
6446 		case 7:
6447 			amsdu_timer = &pxmitpriv->amsdu_vo_timer;
6448 			break;
6449 		case 0:
6450 		case 3:
6451 		default:
6452 			amsdu_timer = &pxmitpriv->amsdu_be_timer;
6453 			break;
6454 	}
6455 	_set_timer(amsdu_timer, 1);
6456 }
6457 
rtw_amsdu_cancel_timer(_adapter * padapter,u8 priority)6458 void rtw_amsdu_cancel_timer(_adapter *padapter, u8 priority)
6459 {
6460 	struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
6461 	_timer* amsdu_timer = NULL;
6462 
6463 	switch(priority)
6464 	{
6465 		case 1:
6466 		case 2:
6467 			amsdu_timer = &pxmitpriv->amsdu_bk_timer;
6468 			break;
6469 		case 4:
6470 		case 5:
6471 			amsdu_timer = &pxmitpriv->amsdu_vi_timer;
6472 			break;
6473 		case 6:
6474 		case 7:
6475 			amsdu_timer = &pxmitpriv->amsdu_vo_timer;
6476 			break;
6477 		case 0:
6478 		case 3:
6479 		default:
6480 			amsdu_timer = &pxmitpriv->amsdu_be_timer;
6481 			break;
6482 	}
6483 	_cancel_timer_ex(amsdu_timer);
6484 }
6485 #endif /* CONFIG_TX_AMSDU */
6486 
6487 #ifdef DBG_TXBD_DESC_DUMP
6488 static struct rtw_tx_desc_backup tx_backup[HW_QUEUE_ENTRY][TX_BAK_FRMAE_CNT];
6489 static u8 backup_idx[HW_QUEUE_ENTRY];
6490 
rtw_tx_desc_backup(_adapter * padapter,struct xmit_frame * pxmitframe,u8 desc_size,u8 hwq)6491 void rtw_tx_desc_backup(_adapter *padapter, struct xmit_frame *pxmitframe, u8 desc_size, u8 hwq)
6492 {
6493 	u32 tmp32;
6494 	u8 *pxmit_buf;
6495 
6496 	if (rtw_get_hw_init_completed(padapter) == _FALSE)
6497 		return;
6498 
6499 	pxmit_buf = pxmitframe->pxmitbuf->pbuf;
6500 
6501 	_rtw_memcpy(tx_backup[hwq][backup_idx[hwq]].tx_bak_desc, pxmit_buf, desc_size);
6502 	_rtw_memcpy(tx_backup[hwq][backup_idx[hwq]].tx_bak_data_hdr, pxmit_buf+desc_size, TX_BAK_DATA_LEN);
6503 
6504 	tmp32 = rtw_read32(padapter, get_txbd_rw_reg(hwq));
6505 
6506 	tx_backup[hwq][backup_idx[hwq]].tx_bak_rp = (tmp32>>16)&0xfff;
6507 	tx_backup[hwq][backup_idx[hwq]].tx_bak_wp = tmp32&0xfff;
6508 
6509 	tx_backup[hwq][backup_idx[hwq]].tx_desc_size = desc_size;
6510 
6511 	backup_idx[hwq] = (backup_idx[hwq] + 1) % TX_BAK_FRMAE_CNT;
6512 }
6513 
rtw_tx_desc_backup_reset(void)6514 void rtw_tx_desc_backup_reset(void)
6515 {
6516 	int i, j;
6517 
6518 	for (i = 0; i < HW_QUEUE_ENTRY; i++) {
6519 		for (j = 0; j < TX_BAK_FRMAE_CNT; j++)
6520 			_rtw_memset(&tx_backup[i][j], 0, sizeof(struct rtw_tx_desc_backup));
6521 
6522 		backup_idx[i] = 0;
6523 	}
6524 }
6525 
rtw_get_tx_desc_backup(_adapter * padapter,u8 hwq,struct rtw_tx_desc_backup ** pbak)6526 u8 rtw_get_tx_desc_backup(_adapter *padapter, u8 hwq, struct rtw_tx_desc_backup **pbak)
6527 {
6528 	*pbak = &tx_backup[hwq][0];
6529 
6530 	return backup_idx[hwq];
6531 }
6532 #endif
6533 
6534 #ifdef CONFIG_PCI_TX_POLLING
rtw_tx_poll_init(_adapter * padapter)6535 void rtw_tx_poll_init(_adapter *padapter)
6536 {
6537 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6538 	_timer* timer = &pxmitpriv->tx_poll_timer;
6539 
6540 	if (!is_primary_adapter(padapter))
6541 		return;
6542 
6543 	if (timer->function != NULL) {
6544 		RTW_INFO("tx polling timer has been init.\n");
6545 		return;
6546 	}
6547 
6548 	rtw_init_timer(timer, padapter, rtw_tx_poll_timeout_handler, padapter);
6549 	rtw_tx_poll_timer_set(padapter, 1);
6550 	RTW_INFO("Tx poll timer init!\n");
6551 }
6552 
rtw_tx_poll_timeout_handler(void * FunctionContext)6553 void rtw_tx_poll_timeout_handler(void *FunctionContext)
6554 {
6555 	_adapter *adapter = (_adapter *)FunctionContext;
6556 
6557 	rtw_tx_poll_timer_set(adapter, 1);
6558 
6559 	if (adapter->hal_func.tx_poll_handler)
6560 		adapter->hal_func.tx_poll_handler(adapter);
6561 	else
6562 		RTW_WARN("hal ops: tx_poll_handler is NULL\n");
6563 }
6564 
rtw_tx_poll_timer_set(_adapter * padapter,u32 delay)6565 void rtw_tx_poll_timer_set(_adapter *padapter, u32 delay)
6566 {
6567 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6568 	_timer* timer = NULL;
6569 
6570 	timer = &pxmitpriv->tx_poll_timer;
6571 	_set_timer(timer, delay);
6572 }
6573 
rtw_tx_poll_timer_cancel(_adapter * padapter)6574 void rtw_tx_poll_timer_cancel(_adapter *padapter)
6575 {
6576 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6577 	_timer* timer = NULL;
6578 
6579 	if (!is_primary_adapter(padapter))
6580 		return;
6581 
6582 	timer = &pxmitpriv->tx_poll_timer;
6583 	_cancel_timer_ex(timer);
6584 	timer->function = NULL;
6585 	RTW_INFO("Tx poll timer cancel !\n");
6586 }
6587 #endif /* CONFIG_PCI_TX_POLLING */
6588 
rtw_sctx_init(struct submit_ctx * sctx,int timeout_ms)6589 void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms)
6590 {
6591 	sctx->timeout_ms = timeout_ms;
6592 	sctx->submit_time = rtw_get_current_time();
6593 #ifdef PLATFORM_LINUX /* TODO: add condition wating interface for other os */
6594 	init_completion(&sctx->done);
6595 #endif
6596 	sctx->status = RTW_SCTX_SUBMITTED;
6597 }
6598 
rtw_sctx_wait(struct submit_ctx * sctx,const char * msg)6599 int rtw_sctx_wait(struct submit_ctx *sctx, const char *msg)
6600 {
6601 	int ret = _FAIL;
6602 	unsigned long expire;
6603 	int status = 0;
6604 
6605 #ifdef PLATFORM_LINUX
6606 	expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT;
6607 	if (!wait_for_completion_timeout(&sctx->done, expire)) {
6608 		/* timeout, do something?? */
6609 		status = RTW_SCTX_DONE_TIMEOUT;
6610 		RTW_INFO("%s timeout: %s\n", __func__, msg);
6611 	} else
6612 		status = sctx->status;
6613 #endif
6614 
6615 	if (status == RTW_SCTX_DONE_SUCCESS)
6616 		ret = _SUCCESS;
6617 
6618 	return ret;
6619 }
6620 
rtw_sctx_chk_waring_status(int status)6621 bool rtw_sctx_chk_waring_status(int status)
6622 {
6623 	switch (status) {
6624 	case RTW_SCTX_DONE_UNKNOWN:
6625 	case RTW_SCTX_DONE_BUF_ALLOC:
6626 	case RTW_SCTX_DONE_BUF_FREE:
6627 
6628 	case RTW_SCTX_DONE_DRV_STOP:
6629 	case RTW_SCTX_DONE_DEV_REMOVE:
6630 		return _TRUE;
6631 	default:
6632 		return _FALSE;
6633 	}
6634 }
6635 
rtw_sctx_done_err(struct submit_ctx ** sctx,int status)6636 void rtw_sctx_done_err(struct submit_ctx **sctx, int status)
6637 {
6638 	if (*sctx) {
6639 		if (rtw_sctx_chk_waring_status(status))
6640 			RTW_INFO("%s status:%d\n", __func__, status);
6641 		(*sctx)->status = status;
6642 #ifdef PLATFORM_LINUX
6643 		complete(&((*sctx)->done));
6644 #endif
6645 		*sctx = NULL;
6646 	}
6647 }
6648 
rtw_sctx_done(struct submit_ctx ** sctx)6649 void rtw_sctx_done(struct submit_ctx **sctx)
6650 {
6651 	rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS);
6652 }
6653 
6654 #ifdef CONFIG_XMIT_ACK
rtw_ack_tx_wait(struct xmit_priv * pxmitpriv,u32 timeout_ms)6655 int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
6656 {
6657 	struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
6658 
6659 	pack_tx_ops->submit_time = rtw_get_current_time();
6660 	pack_tx_ops->timeout_ms = timeout_ms;
6661 	pack_tx_ops->status = RTW_SCTX_SUBMITTED;
6662 
6663 	return rtw_sctx_wait(pack_tx_ops, __func__);
6664 }
6665 
rtw_ack_tx_done(struct xmit_priv * pxmitpriv,int status)6666 void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)
6667 {
6668 	struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
6669 
6670 	if (pxmitpriv->ack_tx)
6671 		rtw_sctx_done_err(&pack_tx_ops, status);
6672 	else
6673 		RTW_INFO("%s ack_tx not set\n", __func__);
6674 }
6675 #endif /* CONFIG_XMIT_ACK */
6676