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