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