1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
22 #include <drv_types.h>
24 #if defined(PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
25 #error "Shall be Linux or Windows, but not both!\n"
29 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
30 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
32 static void _init_txservq(struct tx_servq *ptxservq)
35 _rtw_init_listhead(&ptxservq->tx_pending);
36 _rtw_init_queue(&ptxservq->sta_pending);
42 void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
47 _rtw_memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv));
49 _rtw_spinlock_init(&psta_xmitpriv->lock);
51 /* for(i = 0 ; i < MAX_NUMBLKS; i++) */
52 /* _init_txservq(&(psta_xmitpriv->blk_q[i])); */
54 _init_txservq(&psta_xmitpriv->be_q);
55 _init_txservq(&psta_xmitpriv->bk_q);
56 _init_txservq(&psta_xmitpriv->vi_q);
57 _init_txservq(&psta_xmitpriv->vo_q);
58 _rtw_init_listhead(&psta_xmitpriv->legacy_dz);
59 _rtw_init_listhead(&psta_xmitpriv->apsd);
65 s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter)
68 struct xmit_buf *pxmitbuf;
69 struct xmit_frame *pxframe;
74 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
75 /* _rtw_memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); */
77 _rtw_spinlock_init(&pxmitpriv->lock);
78 _rtw_spinlock_init(&pxmitpriv->lock_sctx);
79 _rtw_init_sema(&pxmitpriv->xmit_sema, 0);
80 _rtw_init_sema(&pxmitpriv->terminate_xmitthread_sema, 0);
83 Please insert all the queue initializaiton using _rtw_init_queue below
86 pxmitpriv->adapter = padapter;
88 /* for(i = 0 ; i < MAX_NUMBLKS; i++) */
89 /* _rtw_init_queue(&pxmitpriv->blk_strms[i]); */
91 _rtw_init_queue(&pxmitpriv->be_pending);
92 _rtw_init_queue(&pxmitpriv->bk_pending);
93 _rtw_init_queue(&pxmitpriv->vi_pending);
94 _rtw_init_queue(&pxmitpriv->vo_pending);
95 _rtw_init_queue(&pxmitpriv->bm_pending);
97 /* _rtw_init_queue(&pxmitpriv->legacy_dz_queue); */
98 /* _rtw_init_queue(&pxmitpriv->apsd_queue); */
100 _rtw_init_queue(&pxmitpriv->free_xmit_queue);
103 Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
104 and initialize free_xmit_frame below.
105 Please also apply free_txobj to link_up all the xmit_frames...
108 pxmitpriv->pallocated_frame_buf = rtw_zvmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
110 if (pxmitpriv->pallocated_frame_buf == NULL) {
111 pxmitpriv->pxmit_frame_buf = NULL;
112 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_frame fail!\n"));
116 pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_frame_buf), 4);
117 /* pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - */
118 /* ((SIZE_PTR) (pxmitpriv->pallocated_frame_buf) &3); */
120 pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
122 for (i = 0; i < NR_XMITFRAME; i++) {
123 _rtw_init_listhead(&(pxframe->list));
125 pxframe->padapter = padapter;
126 pxframe->frame_tag = NULL_FRAMETAG;
130 pxframe->buf_addr = NULL;
131 pxframe->pxmitbuf = NULL;
133 rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue));
138 pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
140 pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
144 _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue);
145 _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue);
147 pxmitpriv->pallocated_xmitbuf = rtw_zvmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
149 if (pxmitpriv->pallocated_xmitbuf == NULL) {
150 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_buf fail!\n"));
155 pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmitbuf), 4);
156 /* pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - */
157 /* ((SIZE_PTR) (pxmitpriv->pallocated_xmitbuf) &3); */
159 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
161 for (i = 0; i < NR_XMITBUFF; i++) {
162 _rtw_init_listhead(&pxmitbuf->list);
164 pxmitbuf->priv_data = NULL;
165 pxmitbuf->padapter = padapter;
166 pxmitbuf->buf_tag = XMITBUF_DATA;
168 /* Tx buf allocation may fail sometimes, so sleep and retry. */
169 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
172 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
177 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
178 pxmitbuf->phead = pxmitbuf->pbuf;
179 pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMITBUF_SZ;
181 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
184 pxmitbuf->flags = XMIT_VO_QUEUE;
186 rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue));
195 pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
197 /* init xframe_ext queue, the same count as extbuf */
198 _rtw_init_queue(&pxmitpriv->free_xframe_ext_queue);
200 pxmitpriv->xframe_ext_alloc_addr = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4);
202 if (pxmitpriv->xframe_ext_alloc_addr == NULL) {
203 pxmitpriv->xframe_ext = NULL;
204 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xframe_ext fail!\n"));
208 pxmitpriv->xframe_ext = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->xframe_ext_alloc_addr), 4);
209 pxframe = (struct xmit_frame *)pxmitpriv->xframe_ext;
211 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
212 _rtw_init_listhead(&(pxframe->list));
214 pxframe->padapter = padapter;
215 pxframe->frame_tag = NULL_FRAMETAG;
219 pxframe->buf_addr = NULL;
220 pxframe->pxmitbuf = NULL;
222 pxframe->ext_tag = 1;
224 rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xframe_ext_queue.queue));
228 pxmitpriv->free_xframe_ext_cnt = NR_XMIT_EXTBUFF;
230 /* Init xmit extension buff */
231 _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
233 pxmitpriv->pallocated_xmit_extbuf = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4);
235 if (pxmitpriv->pallocated_xmit_extbuf == NULL) {
236 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_extbuf fail!\n"));
241 pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmit_extbuf), 4);
243 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
245 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
246 _rtw_init_listhead(&pxmitbuf->list);
248 pxmitbuf->priv_data = NULL;
249 pxmitbuf->padapter = padapter;
250 pxmitbuf->buf_tag = XMITBUF_MGNT;
252 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ, _TRUE);
258 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
259 pxmitbuf->phead = pxmitbuf->pbuf;
260 pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMIT_EXTBUF_SZ;
262 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
265 rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue));
266 #ifdef DBG_XMIT_BUF_EXT
273 pxmitpriv->free_xmit_extbuf_cnt = NR_XMIT_EXTBUFF;
275 for (i = 0; i < CMDBUF_MAX; i++) {
276 pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i];
278 _rtw_init_listhead(&pxmitbuf->list);
280 pxmitbuf->priv_data = NULL;
281 pxmitbuf->padapter = padapter;
282 pxmitbuf->buf_tag = XMITBUF_CMD;
284 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ, _TRUE);
290 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
291 pxmitbuf->phead = pxmitbuf->pbuf;
292 pxmitbuf->pend = pxmitbuf->pbuf + MAX_CMDBUF_SZ;
294 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
296 pxmitbuf->alloc_sz = MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ;
300 rtw_alloc_hwxmits(padapter);
301 rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
303 for (i = 0; i < 4; i++)
304 pxmitpriv->wmm_para_seq[i] = i;
306 #ifdef CONFIG_USB_HCI
307 pxmitpriv->txirp_cnt = 1;
309 _rtw_init_sema(&(pxmitpriv->tx_retevt), 0);
311 /* per AC pending irp */
312 pxmitpriv->beq_cnt = 0;
313 pxmitpriv->bkq_cnt = 0;
314 pxmitpriv->viq_cnt = 0;
315 pxmitpriv->voq_cnt = 0;
319 #ifdef CONFIG_XMIT_ACK
320 pxmitpriv->ack_tx = _FALSE;
321 _rtw_mutex_init(&pxmitpriv->ack_tx_mutex);
322 rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0);
326 _init_timer(&(pxmitpriv->amsdu_vo_timer), padapter->pnetdev, rtw_amsdu_vo_timeout_handler, padapter);
327 pxmitpriv->amsdu_vo_timeout = RTW_AMSDU_TIMER_UNSET;
329 _init_timer(&(pxmitpriv->amsdu_vi_timer), padapter->pnetdev, rtw_amsdu_vi_timeout_handler, padapter);
330 pxmitpriv->amsdu_vi_timeout = RTW_AMSDU_TIMER_UNSET;
332 _init_timer(&(pxmitpriv->amsdu_be_timer), padapter->pnetdev, rtw_amsdu_be_timeout_handler, padapter);
333 pxmitpriv->amsdu_be_timeout = RTW_AMSDU_TIMER_UNSET;
335 _init_timer(&(pxmitpriv->amsdu_bk_timer), padapter->pnetdev, rtw_amsdu_bk_timeout_handler, padapter);
336 pxmitpriv->amsdu_bk_timeout = RTW_AMSDU_TIMER_UNSET;
338 pxmitpriv->amsdu_debug_set_timer = 0;
339 pxmitpriv->amsdu_debug_timeout = 0;
340 pxmitpriv->amsdu_debug_coalesce_one = 0;
341 pxmitpriv->amsdu_debug_coalesce_two = 0;
344 rtw_hal_init_xmit_priv(padapter);
352 void rtw_mfree_xmit_priv_lock(struct xmit_priv *pxmitpriv);
353 void rtw_mfree_xmit_priv_lock(struct xmit_priv *pxmitpriv)
355 _rtw_spinlock_free(&pxmitpriv->lock);
356 _rtw_free_sema(&pxmitpriv->xmit_sema);
357 _rtw_free_sema(&pxmitpriv->terminate_xmitthread_sema);
359 _rtw_spinlock_free(&pxmitpriv->be_pending.lock);
360 _rtw_spinlock_free(&pxmitpriv->bk_pending.lock);
361 _rtw_spinlock_free(&pxmitpriv->vi_pending.lock);
362 _rtw_spinlock_free(&pxmitpriv->vo_pending.lock);
363 _rtw_spinlock_free(&pxmitpriv->bm_pending.lock);
365 /* _rtw_spinlock_free(&pxmitpriv->legacy_dz_queue.lock); */
366 /* _rtw_spinlock_free(&pxmitpriv->apsd_queue.lock); */
368 _rtw_spinlock_free(&pxmitpriv->free_xmit_queue.lock);
369 _rtw_spinlock_free(&pxmitpriv->free_xmitbuf_queue.lock);
370 _rtw_spinlock_free(&pxmitpriv->pending_xmitbuf_queue.lock);
374 void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv)
377 _adapter *padapter = pxmitpriv->adapter;
378 struct xmit_frame *pxmitframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
379 struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
383 rtw_hal_free_xmit_priv(padapter);
385 rtw_mfree_xmit_priv_lock(pxmitpriv);
387 if (pxmitpriv->pxmit_frame_buf == NULL)
390 for (i = 0; i < NR_XMITFRAME; i++) {
391 rtw_os_xmit_complete(padapter, pxmitframe);
396 for (i = 0; i < NR_XMITBUFF; i++) {
397 rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
402 if (pxmitpriv->pallocated_frame_buf)
403 rtw_vmfree(pxmitpriv->pallocated_frame_buf, NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
406 if (pxmitpriv->pallocated_xmitbuf)
407 rtw_vmfree(pxmitpriv->pallocated_xmitbuf, NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
409 /* free xframe_ext queue, the same count as extbuf */
410 if ((pxmitframe = (struct xmit_frame *)pxmitpriv->xframe_ext)) {
411 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
412 rtw_os_xmit_complete(padapter, pxmitframe);
416 if (pxmitpriv->xframe_ext_alloc_addr)
417 rtw_vmfree(pxmitpriv->xframe_ext_alloc_addr, NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4);
418 _rtw_spinlock_free(&pxmitpriv->free_xframe_ext_queue.lock);
420 /* free xmit extension buff */
421 _rtw_spinlock_free(&pxmitpriv->free_xmit_extbuf_queue.lock);
423 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
424 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
425 rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
430 if (pxmitpriv->pallocated_xmit_extbuf)
431 rtw_vmfree(pxmitpriv->pallocated_xmit_extbuf, NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4);
433 for (i = 0; i < CMDBUF_MAX; i++) {
434 pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i];
435 if (pxmitbuf != NULL)
436 rtw_os_xmit_resource_free(padapter, pxmitbuf, MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ , _TRUE);
439 rtw_free_hwxmits(padapter);
441 #ifdef CONFIG_XMIT_ACK
442 _rtw_mutex_free(&pxmitpriv->ack_tx_mutex);
451 u8 query_ra_short_GI(struct sta_info *psta)
453 u8 sgi = _FALSE, sgi_20m = _FALSE, sgi_40m = _FALSE, sgi_80m = _FALSE;
455 #ifdef CONFIG_80211N_HT
456 #ifdef CONFIG_80211AC_VHT
457 if (psta->vhtpriv.vht_option)
458 sgi_80m = psta->vhtpriv.sgi_80m;
459 #endif /* CONFIG_80211AC_VHT */
461 sgi_20m = psta->htpriv.sgi_20m;
462 sgi_40m = psta->htpriv.sgi_40m;
466 switch (psta->bw_mode) {
467 case CHANNEL_WIDTH_80:
470 case CHANNEL_WIDTH_40:
473 case CHANNEL_WIDTH_20:
482 static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe)
485 struct pkt_attrib *pattrib = &pxmitframe->attrib;
486 /* struct sta_info *psta = pattrib->psta; */
487 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
488 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
493 psta = pattrib->psta;
497 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
498 psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] );
503 RTW_INFO("%s, psta==NUL\n", __func__);
507 if(!(psta->state &_FW_LINKED))
509 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
514 if (pattrib->nr_frags != 1)
515 sz = padapter->xmitpriv.frag_len;
517 sz = pattrib->last_txcmdsz;
519 /* (1) RTS_Threshold is compared to the MPDU, not MSDU. */
520 /* (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. */
521 /* Other fragments are protected by previous fragment. */
522 /* So we only need to check the length of first fragment. */
523 if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N || padapter->registrypriv.wifi_spec) {
524 if (sz > padapter->registrypriv.rts_thresh)
525 pattrib->vcs_mode = RTS_CTS;
528 pattrib->vcs_mode = RTS_CTS;
529 else if (pattrib->cts2self)
530 pattrib->vcs_mode = CTS_TO_SELF;
532 pattrib->vcs_mode = NONE_VCS;
537 /* check IOT action */
538 if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) {
539 pattrib->vcs_mode = CTS_TO_SELF;
540 pattrib->rts_rate = MGN_24M;
542 } else if (pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS | HT_IOT_ACT_PURE_N_MODE)) {
543 pattrib->vcs_mode = RTS_CTS;
544 pattrib->rts_rate = MGN_24M;
550 if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && (pattrib->ampdu_en == _TRUE) &&
551 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
552 pattrib->vcs_mode = CTS_TO_SELF;
557 /* check ERP protection */
558 if (pattrib->rtsen || pattrib->cts2self) {
560 pattrib->vcs_mode = RTS_CTS;
561 else if (pattrib->cts2self)
562 pattrib->vcs_mode = CTS_TO_SELF;
567 /* check HT op mode */
568 if (pattrib->ht_en) {
569 u8 HTOpMode = pmlmeinfo->HT_protection;
570 if ((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) ||
571 (!pmlmeext->cur_bwmode && HTOpMode == 3)) {
572 pattrib->vcs_mode = RTS_CTS;
578 if (sz > padapter->registrypriv.rts_thresh) {
579 pattrib->vcs_mode = RTS_CTS;
583 /* to do list: check MIMO power save condition. */
585 /* check AMPDU aggregation for TXOP */
586 if ((pattrib->ampdu_en == _TRUE) && (!IS_HARDWARE_TYPE_8812(padapter))) {
587 pattrib->vcs_mode = RTS_CTS;
591 pattrib->vcs_mode = NONE_VCS;
596 /* for debug : force driver control vrtl_carrier_sense. */
597 if (padapter->driver_vcs_en == 1) {
598 /* u8 driver_vcs_en; */ /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */
599 /* u8 driver_vcs_type; */ /* force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1. */
600 pattrib->vcs_mode = padapter->driver_vcs_type;
605 static void update_attrib_phy_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
607 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
609 pattrib->rtsen = psta->rtsen;
610 pattrib->cts2self = psta->cts2self;
614 pattrib->triggered = 0;
615 pattrib->ampdu_spacing = 0;
617 /* qos_en, ht_en, init rate, ,bw, ch_offset, sgi */
618 pattrib->qos_en = psta->qos_option;
620 pattrib->raid = psta->raid;
622 if (mlmeext->cur_bwmode < psta->bw_mode)
623 pattrib->bwmode = mlmeext->cur_bwmode;
625 pattrib->bwmode = psta->bw_mode;
627 pattrib->sgi = query_ra_short_GI(psta);
629 pattrib->ldpc = psta->ldpc;
630 pattrib->stbc = psta->stbc;
632 #ifdef CONFIG_80211N_HT
633 pattrib->ht_en = psta->htpriv.ht_option;
634 pattrib->ch_offset = psta->htpriv.ch_offset;
635 pattrib->ampdu_en = _FALSE;
637 if (padapter->driver_ampdu_spacing != 0xFF) /* driver control AMPDU Density for peer sta's rx */
638 pattrib->ampdu_spacing = padapter->driver_ampdu_spacing;
640 pattrib->ampdu_spacing = psta->htpriv.rx_ampdu_min_spacing;
641 #endif /* CONFIG_80211N_HT */
642 /* if(pattrib->ht_en && psta->htpriv.ampdu_enable) */
644 /* if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) */
645 /* pattrib->ampdu_en = _TRUE; */
649 if (pattrib->direct_link == _TRUE) {
650 psta = pattrib->ptdls_sta;
652 pattrib->raid = psta->raid;
653 #ifdef CONFIG_80211N_HT
654 pattrib->bwmode = psta->bw_mode;
655 pattrib->ht_en = psta->htpriv.ht_option;
656 pattrib->ch_offset = psta->htpriv.ch_offset;
657 pattrib->sgi = query_ra_short_GI(psta);
658 #endif /* CONFIG_80211N_HT */
660 #endif /* CONFIG_TDLS */
662 pattrib->retry_ctrl = _FALSE;
664 #ifdef CONFIG_AUTO_AP_MODE
665 if (psta->isrc && psta->pid > 0)
666 pattrib->pctrl = _TRUE;
671 static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
674 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
675 struct security_priv *psecuritypriv = &padapter->securitypriv;
676 sint bmcast = IS_MCAST(pattrib->ra);
678 _rtw_memset(pattrib->dot118021x_UncstKey.skey, 0, 16);
679 _rtw_memset(pattrib->dot11tkiptxmickey.skey, 0, 16);
680 pattrib->mac_id = psta->mac_id;
682 if (psta->ieee8021x_blocked == _TRUE) {
683 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\n psta->ieee8021x_blocked == _TRUE\n"));
685 pattrib->encrypt = 0;
687 if ((pattrib->ether_type != 0x888e) && (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _FALSE)) {
688 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\npsta->ieee8021x_blocked == _TRUE, pattrib->ether_type(%.4x) != 0x888e\n", pattrib->ether_type));
689 #ifdef DBG_TX_DROP_FRAME
690 RTW_INFO("DBG_TX_DROP_FRAME %s psta->ieee8021x_blocked == _TRUE, pattrib->ether_type(%04x) != 0x888e\n", __FUNCTION__, pattrib->ether_type);
696 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
698 #ifdef CONFIG_WAPI_SUPPORT
699 if (pattrib->ether_type == 0x88B4)
700 pattrib->encrypt = _NO_PRIVACY_;
703 switch (psecuritypriv->dot11AuthAlgrthm) {
704 case dot11AuthAlgrthm_Open:
705 case dot11AuthAlgrthm_Shared:
706 case dot11AuthAlgrthm_Auto:
707 pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
709 case dot11AuthAlgrthm_8021X:
711 pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
713 pattrib->key_idx = 0;
716 pattrib->key_idx = 0;
720 /* For WPS 1.0 WEP, driver should not encrypt EAPOL Packet for WPS handshake. */
721 if (((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) && (pattrib->ether_type == 0x888e))
722 pattrib->encrypt = _NO_PRIVACY_;
727 if (pattrib->direct_link == _TRUE) {
728 if (pattrib->encrypt > 0)
729 pattrib->encrypt = _AES_;
733 switch (pattrib->encrypt) {
737 pattrib->icv_len = 4;
738 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
743 pattrib->icv_len = 4;
745 if (psecuritypriv->busetkipkey == _FAIL) {
746 #ifdef DBG_TX_DROP_FRAME
747 RTW_INFO("DBG_TX_DROP_FRAME %s psecuritypriv->busetkipkey(%d)==_FAIL drop packet\n", __FUNCTION__, psecuritypriv->busetkipkey);
754 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
756 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
759 _rtw_memcpy(pattrib->dot11tkiptxmickey.skey, psta->dot11tkiptxmickey.skey, 16);
766 pattrib->icv_len = 8;
769 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
771 AES_IV(pattrib->iv, psta->dot11txpn, 0);
775 #ifdef CONFIG_WAPI_SUPPORT
777 pattrib->iv_len = 18;
778 pattrib->icv_len = 16;
779 rtw_wapi_get_iv(padapter, pattrib->ra, pattrib->iv);
784 pattrib->icv_len = 0;
788 if (pattrib->encrypt > 0)
789 _rtw_memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16);
791 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
792 ("update_attrib: encrypt=%d securitypriv.sw_encrypt=%d\n",
793 pattrib->encrypt, padapter->securitypriv.sw_encrypt));
795 if (pattrib->encrypt &&
796 ((padapter->securitypriv.sw_encrypt == _TRUE) || (psecuritypriv->hw_decrypted == _FALSE))) {
797 pattrib->bswenc = _TRUE;
798 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
799 ("update_attrib: encrypt=%d securitypriv.hw_decrypted=%d bswenc=_TRUE\n",
800 pattrib->encrypt, padapter->securitypriv.sw_encrypt));
802 pattrib->bswenc = _FALSE;
803 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("update_attrib: bswenc=_FALSE\n"));
806 #if defined(CONFIG_CONCURRENT_MODE)
807 pattrib->bmc_camid = padapter->securitypriv.dot118021x_bmc_cam_id;
810 if (pattrib->encrypt && bmcast && _rtw_camctl_chk_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
811 pattrib->bswenc = _TRUE;
813 #ifdef CONFIG_WAPI_SUPPORT
814 if (pattrib->encrypt == _SMS4_)
815 pattrib->bswenc = _FALSE;
824 u8 qos_acm(u8 acm_mask, u8 priority)
826 u8 change_priority = priority;
831 if (acm_mask & BIT(1))
839 if (acm_mask & BIT(2))
844 if (acm_mask & BIT(3))
848 RTW_INFO("qos_acm(): invalid pattrib->priority: %d!!!\n", priority);
852 return change_priority;
855 static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
857 struct ethhdr etherhdr;
859 s32 UserPriority = 0;
862 _rtw_open_pktfile(ppktfile->pkt, ppktfile);
863 _rtw_pktfile_read(ppktfile, (unsigned char *)ðerhdr, ETH_HLEN);
865 /* get UserPriority from IP hdr */
866 if (pattrib->ether_type == 0x0800) {
867 _rtw_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr));
868 /* UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3; */
869 UserPriority = ip_hdr.tos >> 5;
872 else if (pattrib->ether_type == 0x888e) {
878 pattrib->priority = UserPriority;
879 pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
880 pattrib->subtype = WIFI_QOS_DATA_TYPE;
884 u8 rtw_check_tdls_established(_adapter *padapter, struct pkt_attrib *pattrib)
886 pattrib->ptdls_sta = NULL;
888 pattrib->direct_link = _FALSE;
889 if (padapter->tdlsinfo.link_established == _TRUE) {
890 pattrib->ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
892 if ((pattrib->ptdls_sta != NULL) &&
893 (pattrib->ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) &&
894 (pattrib->ether_type != 0x0806)) {
895 pattrib->direct_link = _TRUE;
896 /* RTW_INFO("send ptk to "MAC_FMT" using direct link\n", MAC_ARG(pattrib->dst)); */
899 if (pattrib->ptdls_sta != NULL &&
900 pattrib->ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
901 pattrib->direct_link = _TRUE;
903 RTW_INFO("send ptk to "MAC_FMT" using direct link\n", MAC_ARG(pattrib->dst));
907 /* ARP frame may be helped by AP*/
908 if (pattrib->ether_type != 0x0806)
909 pattrib->direct_link = _FALSE;
913 return pattrib->direct_link;
916 s32 update_tdls_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
919 struct sta_info *psta = NULL;
920 struct sta_priv *pstapriv = &padapter->stapriv;
921 struct security_priv *psecuritypriv = &padapter->securitypriv;
922 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
923 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
927 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
933 pattrib->mac_id = psta->mac_id;
934 pattrib->psta = psta;
935 pattrib->ack_policy = 0;
936 /* get ether_hdr_len */
937 pattrib->pkt_hdrlen = ETH_HLEN;
939 /* [TDLS] TODO: setup req/rsp should be AC_BK */
940 if (pqospriv->qos_option && psta->qos_option) {
941 pattrib->priority = 4; /* tdls management frame should be AC_VI */
942 pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
943 pattrib->subtype = WIFI_QOS_DATA_TYPE;
945 pattrib->priority = 0;
946 pattrib->hdrlen = WLAN_HDR_A3_LEN;
947 pattrib->subtype = WIFI_DATA_TYPE;
951 if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) {
956 update_attrib_phy_info(padapter, pattrib, psta);
964 #endif /* CONFIG_TDLS */
966 /*get non-qos hw_ssn control register,mapping to REG_HW_SEQ0,1,2,3*/
967 inline u8 rtw_get_hwseq_no(_adapter *padapter)
970 #ifdef CONFIG_CONCURRENT_MODE
971 if (padapter->adapter_type != PRIMARY_ADAPTER)
975 #endif /* CONFIG_CONCURRENT_MODE */
978 static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib)
981 struct pkt_file pktfile;
982 struct sta_info *psta = NULL;
983 struct ethhdr etherhdr;
986 struct sta_priv *pstapriv = &padapter->stapriv;
987 struct security_priv *psecuritypriv = &padapter->securitypriv;
988 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
989 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
990 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
995 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib);
997 _rtw_open_pktfile(pkt, &pktfile);
998 i = _rtw_pktfile_read(&pktfile, (u8 *)ðerhdr, ETH_HLEN);
1000 pattrib->ether_type = ntohs(etherhdr.h_proto);
1003 _rtw_memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN);
1004 _rtw_memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN);
1007 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1008 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
1009 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1010 _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN);
1011 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_adhoc);
1012 } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1014 if (rtw_check_tdls_established(padapter, pattrib) == _TRUE)
1015 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); /* For TDLS direct link Tx, set ra to be same to dst */
1018 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1019 _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN);
1020 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_sta);
1021 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1022 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1023 _rtw_memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
1024 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_ap);
1026 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_unknown);
1028 bmcast = IS_MCAST(pattrib->ra);
1030 psta = rtw_get_bcmc_stainfo(padapter);
1031 if (psta == NULL) { /* if we cannot get psta => drop the pkt */
1032 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sta);
1033 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT "\n", MAC_ARG(pattrib->ra)));
1034 #ifdef DBG_TX_DROP_FRAME
1035 RTW_INFO("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __func__, MAC_ARG(pattrib->ra));
1041 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
1042 if (psta == NULL) { /* if we cannot get psta => drop the pkt */
1043 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_sta);
1044 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT"\n", MAC_ARG(pattrib->ra)));
1045 #ifdef DBG_TX_DROP_FRAME
1046 RTW_INFO("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __func__, MAC_ARG(pattrib->ra));
1050 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE && !(psta->state & _FW_LINKED)) {
1051 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_ap_link);
1057 if (!(psta->state & _FW_LINKED)) {
1058 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_link);
1059 RTW_INFO("%s-"ADPT_FMT" psta("MAC_FMT")->state(0x%x) != _FW_LINKED\n", __func__, ADPT_ARG(padapter), MAC_ARG(psta->hwaddr), psta->state);
1064 pattrib->pktlen = pktfile.pkt_len;
1066 /* TODO: 802.1Q VLAN header */
1069 if (ETH_P_IP == pattrib->ether_type) {
1072 _rtw_pktfile_read(&pktfile, ip, 20);
1074 if (GET_IPV4_IHL(ip) * 4 > 20)
1075 _rtw_pktfile_read(&pktfile, NULL, GET_IPV4_IHL(ip) - 20);
1077 pattrib->icmp_pkt = 0;
1078 pattrib->dhcp_pkt = 0;
1080 if (GET_IPV4_PROTOCOL(ip) == 0x01) { /* ICMP */
1081 pattrib->icmp_pkt = 1;
1082 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_icmp);
1084 } else if (GET_IPV4_PROTOCOL(ip) == 0x11) { /* UDP */
1087 _rtw_pktfile_read(&pktfile, udp, 8);
1089 if ((GET_UDP_SRC(udp) == 68 && GET_UDP_DST(udp) == 67)
1090 || (GET_UDP_SRC(udp) == 67 && GET_UDP_DST(udp) == 68)
1092 /* 67 : UDP BOOTP server, 68 : UDP BOOTP client */
1093 if (pattrib->pktlen > 282) { /* MINIMUM_DHCP_PACKET_SIZE */
1094 pattrib->dhcp_pkt = 1;
1095 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_dhcp);
1097 RTW_INFO("send DHCP packet\n");
1101 } else if (GET_IPV4_PROTOCOL(ip) == 0x06 /* TCP */
1102 && rtw_st_ctl_chk_reg_s_proto(&psta->st_ctl, 0x06) == _TRUE
1106 _rtw_pktfile_read(&pktfile, tcp, 20);
1108 if (rtw_st_ctl_chk_reg_rule(&psta->st_ctl, padapter, IPV4_SRC(ip), TCP_SRC(tcp), IPV4_DST(ip), TCP_DST(tcp)) == _TRUE) {
1109 if (GET_TCP_SYN(tcp) && GET_TCP_ACK(tcp)) {
1110 session_tracker_add_cmd(padapter, psta
1111 , IPV4_SRC(ip), TCP_SRC(tcp)
1112 , IPV4_SRC(ip), TCP_DST(tcp));
1113 if (DBG_SESSION_TRACKER)
1114 RTW_INFO(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" SYN-ACK\n"
1115 , FUNC_ADPT_ARG(padapter)
1116 , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp))
1117 , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp)));
1119 if (GET_TCP_FIN(tcp)) {
1120 session_tracker_del_cmd(padapter, psta
1121 , IPV4_SRC(ip), TCP_SRC(tcp)
1122 , IPV4_SRC(ip), TCP_DST(tcp));
1123 if (DBG_SESSION_TRACKER)
1124 RTW_INFO(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" FIN\n"
1125 , FUNC_ADPT_ARG(padapter)
1126 , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp))
1127 , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp)));
1132 } else if (0x888e == pattrib->ether_type)
1133 RTW_PRINT("send eapol packet\n");
1135 if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
1136 rtw_mi_set_scan_deny(padapter, 3000);
1139 /* If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */
1140 #ifdef CONFIG_WAPI_SUPPORT
1141 if ((pattrib->ether_type == 0x88B4) || (pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
1142 #else /* !CONFIG_WAPI_SUPPORT */
1144 if ((pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
1145 #else /* only ICMP/DHCP packets is as SPECIAL_PACKET, and leave LPS when tx IMCP/DHCP packets. */
1146 /* if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) ) */
1147 if (pattrib->icmp_pkt == 1)
1148 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1);
1149 else if (pattrib->dhcp_pkt == 1)
1153 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_active);
1154 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
1156 #endif /* CONFIG_LPS */
1158 #ifdef CONFIG_BEAMFORMING
1159 update_attrib_txbf_info(padapter, pattrib, psta);
1163 if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) {
1164 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sec);
1169 update_attrib_phy_info(padapter, pattrib, psta);
1171 /* RTW_INFO("%s ==> mac_id(%d)\n",__FUNCTION__,pattrib->mac_id ); */
1173 pattrib->psta = psta;
1178 pattrib->ack_policy = 0;
1179 /* get ether_hdr_len */
1180 pattrib->pkt_hdrlen = ETH_HLEN;/* (pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; */ /* vlan tag */
1182 pattrib->hdrlen = WLAN_HDR_A3_LEN;
1183 pattrib->subtype = WIFI_DATA_TYPE;
1184 pattrib->priority = 0;
1186 if (check_fwstate(pmlmepriv, WIFI_AP_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
1187 if (pattrib->qos_en)
1188 set_qos(&pktfile, pattrib);
1191 if (pattrib->direct_link == _TRUE) {
1192 if (pattrib->qos_en)
1193 set_qos(&pktfile, pattrib);
1197 if (pqospriv->qos_option) {
1198 set_qos(&pktfile, pattrib);
1200 if (pmlmepriv->acm_mask != 0)
1201 pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority);
1206 /* pattrib->priority = 5; */ /* force to used VI queue, for testing */
1207 pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
1208 rtw_set_tx_chksum_offload(pkt, pattrib);
1217 static s32 xmitframe_addmic(_adapter *padapter, struct xmit_frame *pxmitframe)
1219 sint curfragnum, length;
1220 u8 *pframe, *payload, mic[8];
1221 struct mic_data micdata;
1222 /* struct sta_info *stainfo; */
1223 struct qos_priv *pqospriv = &(padapter->mlmepriv.qospriv);
1224 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1225 struct security_priv *psecuritypriv = &padapter->securitypriv;
1226 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1227 u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
1228 u8 hw_hdr_offset = 0;
1229 sint bmcst = IS_MCAST(pattrib->ra);
1234 stainfo = pattrib->psta;
1238 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
1239 stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
1244 RTW_INFO("%s, psta==NUL\n", __func__);
1248 if(!(stainfo->state &_FW_LINKED))
1250 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state);
1257 #ifdef CONFIG_USB_TX_AGGREGATION
1258 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);;
1260 #ifdef CONFIG_TX_EARLY_MODE
1261 hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
1263 hw_hdr_offset = TXDESC_OFFSET;
1267 if (pattrib->encrypt == _TKIP_) { /* if(psecuritypriv->dot11PrivacyAlgrthm==_TKIP_PRIVACY_) */
1268 /* encode mic code */
1269 /* if(stainfo!= NULL) */
1271 u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1273 pframe = pxmitframe->buf_addr + hw_hdr_offset;
1276 if (_rtw_memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16) == _TRUE) {
1277 /* DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); */
1278 /* rtw_msleep_os(10); */
1281 /* start to calculate the mic code */
1282 rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
1284 if (_rtw_memcmp(&pattrib->dot11tkiptxmickey.skey[0], null_key, 16) == _TRUE) {
1285 /* DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); */
1286 /* rtw_msleep_os(10); */
1289 /* start to calculate the mic code */
1290 rtw_secmicsetkey(&micdata, &pattrib->dot11tkiptxmickey.skey[0]);
1293 if (pframe[1] & 1) { /* ToDS==1 */
1294 rtw_secmicappend(&micdata, &pframe[16], 6); /* DA */
1295 if (pframe[1] & 2) /* From Ds==1 */
1296 rtw_secmicappend(&micdata, &pframe[24], 6);
1298 rtw_secmicappend(&micdata, &pframe[10], 6);
1299 } else { /* ToDS==0 */
1300 rtw_secmicappend(&micdata, &pframe[4], 6); /* DA */
1301 if (pframe[1] & 2) /* From Ds==1 */
1302 rtw_secmicappend(&micdata, &pframe[16], 6);
1304 rtw_secmicappend(&micdata, &pframe[10], 6);
1308 /* if(pqospriv->qos_option==1) */
1309 if (pattrib->qos_en)
1310 priority[0] = (u8)pxmitframe->attrib.priority;
1313 rtw_secmicappend(&micdata, &priority[0], 4);
1317 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
1318 payload = (u8 *)RND4((SIZE_PTR)(payload));
1319 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("===curfragnum=%d, pframe= 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n",
1320 curfragnum, *payload, *(payload + 1), *(payload + 2), *(payload + 3), *(payload + 4), *(payload + 5), *(payload + 6), *(payload + 7)));
1322 payload = payload + pattrib->hdrlen + pattrib->iv_len;
1323 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("curfragnum=%d pattrib->hdrlen=%d pattrib->iv_len=%d", curfragnum, pattrib->hdrlen, pattrib->iv_len));
1324 if ((curfragnum + 1) == pattrib->nr_frags) {
1325 length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0);
1326 rtw_secmicappend(&micdata, payload, length);
1327 payload = payload + length;
1329 length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0);
1330 rtw_secmicappend(&micdata, payload, length);
1331 payload = payload + length + pattrib->icv_len;
1332 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("curfragnum=%d length=%d pattrib->icv_len=%d", curfragnum, length, pattrib->icv_len));
1335 rtw_secgetmic(&micdata, &(mic[0]));
1336 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic: before add mic code!!!\n"));
1337 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic: pattrib->last_txcmdsz=%d!!!\n", pattrib->last_txcmdsz));
1338 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic: mic[0]=0x%.2x ,mic[1]=0x%.2x ,mic[2]=0x%.2x ,mic[3]=0x%.2x \n\
1339 mic[4]=0x%.2x ,mic[5]=0x%.2x ,mic[6]=0x%.2x ,mic[7]=0x%.2x !!!!\n",
1340 mic[0], mic[1], mic[2], mic[3], mic[4], mic[5], mic[6], mic[7]));
1341 /* add mic code and add the mic code length in last_txcmdsz */
1343 _rtw_memcpy(payload, &(mic[0]), 8);
1344 pattrib->last_txcmdsz += 8;
1346 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("\n ========last pkt========\n"));
1347 payload = payload - pattrib->last_txcmdsz + 8;
1348 for (curfragnum = 0; curfragnum < pattrib->last_txcmdsz; curfragnum = curfragnum + 8)
1349 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, (" %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x ",
1350 *(payload + curfragnum), *(payload + curfragnum + 1), *(payload + curfragnum + 2), *(payload + curfragnum + 3),
1351 *(payload + curfragnum + 4), *(payload + curfragnum + 5), *(payload + curfragnum + 6), *(payload + curfragnum + 7)));
1355 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: rtw_get_stainfo==NULL!!!\n"));
1365 /*#define DBG_TX_SW_ENCRYPTOR*/
1367 static s32 xmitframe_swencrypt(_adapter *padapter, struct xmit_frame *pxmitframe)
1370 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1371 /* struct security_priv *psecuritypriv=&padapter->securitypriv; */
1375 /* if((psecuritypriv->sw_encrypt)||(pattrib->bswenc)) */
1376 if (pattrib->bswenc) {
1377 #ifdef DBG_TX_SW_ENCRYPTOR
1378 RTW_INFO(ADPT_FMT" - sec_type:%s DO SW encryption\n",
1379 ADPT_ARG(padapter), security_type_str(pattrib->encrypt));
1382 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("### xmitframe_swencrypt\n"));
1383 switch (pattrib->encrypt) {
1386 rtw_wep_encrypt(padapter, (u8 *)pxmitframe);
1389 rtw_tkip_encrypt(padapter, (u8 *)pxmitframe);
1392 rtw_aes_encrypt(padapter, (u8 *)pxmitframe);
1394 #ifdef CONFIG_WAPI_SUPPORT
1396 rtw_sms4_encrypt(padapter, (u8 *)pxmitframe);
1403 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_, ("### xmitframe_hwencrypt\n"));
1410 s32 rtw_make_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib)
1414 struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr;
1415 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1416 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1417 u8 qos_option = _FALSE;
1418 sint res = _SUCCESS;
1419 u16 *fctrl = &pwlanhdr->frame_ctl;
1421 /* struct sta_info *psta; */
1423 /* sint bmcst = IS_MCAST(pattrib->ra); */
1428 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1429 if(pattrib->psta != psta)
1431 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
1437 RTW_INFO("%s, psta==NUL\n", __func__);
1441 if(!(psta->state &_FW_LINKED))
1443 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1448 _rtw_memset(hdr, 0, WLANHDR_OFFSET);
1450 SetFrameSubType(fctrl, pattrib->subtype);
1452 if (pattrib->subtype & WIFI_DATA_TYPE) {
1453 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) {
1455 if (pattrib->direct_link == _TRUE) {
1456 /* TDLS data transfer, ToDS=0, FrDs=0 */
1457 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1458 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1459 _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1461 if (pattrib->qos_en)
1464 #endif /* CONFIG_TDLS */
1466 /* to_ds = 1, fr_ds = 0; */
1467 /* 1.Data transfer to AP */
1468 /* 2.Arp pkt will relayed by AP */
1470 _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1471 _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN);
1472 _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1474 if (pqospriv->qos_option)
1477 } else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)) {
1478 /* to_ds = 0, fr_ds = 1; */
1480 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1481 _rtw_memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN);
1482 _rtw_memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
1484 if (pattrib->qos_en)
1486 } else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1487 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
1488 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1489 _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN);
1490 _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1492 if (pattrib->qos_en)
1495 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("fw_state:%x is not allowed to xmit frame\n", get_fwstate(pmlmepriv)));
1503 if (pattrib->encrypt)
1507 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
1509 if (pattrib->priority)
1510 SetPriority(qc, pattrib->priority);
1512 SetEOSP(qc, pattrib->eosp);
1514 SetAckpolicy(qc, pattrib->ack_policy);
1517 SetAMsdu(qc, pattrib->amsdu);
1520 /* TODO: fill HT Control Field */
1522 /* Update Seq Num will be handled by f/w */
1524 struct sta_info *psta;
1525 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1526 if (pattrib->psta != psta) {
1527 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
1532 RTW_INFO("%s, psta==NUL\n", __func__);
1536 if (!(psta->state & _FW_LINKED)) {
1537 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1543 psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
1544 psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
1545 pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
1547 SetSeqNum(hdr, pattrib->seqnum);
1549 #ifdef CONFIG_80211N_HT
1550 /* check if enable ampdu */
1551 if (pattrib->ht_en && psta->htpriv.ampdu_enable) {
1552 if (psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
1553 pattrib->ampdu_en = _TRUE;
1556 /* re-check if enable ampdu by BA_starting_seqctrl */
1557 if (pattrib->ampdu_en == _TRUE) {
1560 tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
1562 /* check BA_starting_seqctrl */
1563 if (SN_LESS(pattrib->seqnum, tx_seq)) {
1564 /* RTW_INFO("tx ampdu seqnum(%d) < tx_seq(%d)\n", pattrib->seqnum, tx_seq); */
1565 pattrib->ampdu_en = _FALSE;/* AGG BK */
1566 } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) {
1567 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq + 1) & 0xfff;
1569 pattrib->ampdu_en = _TRUE;/* AGG EN */
1571 /* RTW_INFO("tx ampdu over run\n"); */
1572 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum + 1) & 0xfff;
1573 pattrib->ampdu_en = _TRUE;/* AGG EN */
1577 #endif /* CONFIG_80211N_HT */
1592 s32 rtw_txframes_pending(_adapter *padapter)
1594 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1596 return ((_rtw_queue_empty(&pxmitpriv->be_pending) == _FALSE) ||
1597 (_rtw_queue_empty(&pxmitpriv->bk_pending) == _FALSE) ||
1598 (_rtw_queue_empty(&pxmitpriv->vi_pending) == _FALSE) ||
1599 (_rtw_queue_empty(&pxmitpriv->vo_pending) == _FALSE));
1602 s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib)
1604 struct sta_info *psta;
1605 struct tx_servq *ptxservq;
1606 int priority = pattrib->priority;
1610 psta = pattrib->psta;
1614 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
1615 psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
1618 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1619 if (pattrib->psta != psta) {
1620 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
1625 RTW_INFO("%s, psta==NUL\n", __func__);
1629 if (!(psta->state & _FW_LINKED)) {
1630 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1637 ptxservq = &(psta->sta_xmitpriv.bk_q);
1641 ptxservq = &(psta->sta_xmitpriv.vi_q);
1645 ptxservq = &(psta->sta_xmitpriv.vo_q);
1650 ptxservq = &(psta->sta_xmitpriv.be_q);
1655 return ptxservq->qcnt;
1660 int rtw_build_tdls_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
1664 switch (ptxmgmt->action_code) {
1665 case TDLS_SETUP_REQUEST:
1666 rtw_build_tdls_setup_req_ies(padapter, pxmitframe, pframe, ptxmgmt);
1668 case TDLS_SETUP_RESPONSE:
1669 rtw_build_tdls_setup_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt);
1671 case TDLS_SETUP_CONFIRM:
1672 rtw_build_tdls_setup_cfm_ies(padapter, pxmitframe, pframe, ptxmgmt);
1675 rtw_build_tdls_teardown_ies(padapter, pxmitframe, pframe, ptxmgmt);
1677 case TDLS_DISCOVERY_REQUEST:
1678 rtw_build_tdls_dis_req_ies(padapter, pxmitframe, pframe, ptxmgmt);
1680 case TDLS_PEER_TRAFFIC_INDICATION:
1681 rtw_build_tdls_peer_traffic_indication_ies(padapter, pxmitframe, pframe, ptxmgmt);
1683 #ifdef CONFIG_TDLS_CH_SW
1684 case TDLS_CHANNEL_SWITCH_REQUEST:
1685 rtw_build_tdls_ch_switch_req_ies(padapter, pxmitframe, pframe, ptxmgmt);
1687 case TDLS_CHANNEL_SWITCH_RESPONSE:
1688 rtw_build_tdls_ch_switch_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt);
1691 case TDLS_PEER_TRAFFIC_RESPONSE:
1692 rtw_build_tdls_peer_traffic_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt);
1695 case TUNNELED_PROBE_REQ:
1696 rtw_build_tunneled_probe_req_ies(padapter, pxmitframe, pframe);
1698 case TUNNELED_PROBE_RSP:
1699 rtw_build_tunneled_probe_rsp_ies(padapter, pxmitframe, pframe);
1701 #endif /* CONFIG_WFD */
1710 s32 rtw_make_tdls_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt)
1713 struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr;
1714 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1715 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1716 struct sta_priv *pstapriv = &padapter->stapriv;
1717 struct sta_info *psta = NULL, *ptdls_sta = NULL;
1718 u8 tdls_seq = 0, baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1720 sint res = _SUCCESS;
1721 u16 *fctrl = &pwlanhdr->frame_ctl;
1725 _rtw_memset(hdr, 0, WLANHDR_OFFSET);
1727 SetFrameSubType(fctrl, pattrib->subtype);
1729 switch (ptxmgmt->action_code) {
1730 case TDLS_SETUP_REQUEST:
1731 case TDLS_SETUP_RESPONSE:
1732 case TDLS_SETUP_CONFIRM:
1733 case TDLS_PEER_TRAFFIC_INDICATION:
1734 case TDLS_PEER_PSM_REQUEST:
1735 case TUNNELED_PROBE_REQ:
1736 case TUNNELED_PROBE_RSP:
1737 case TDLS_DISCOVERY_REQUEST:
1739 _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1740 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1741 _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1743 case TDLS_CHANNEL_SWITCH_REQUEST:
1744 case TDLS_CHANNEL_SWITCH_RESPONSE:
1745 case TDLS_PEER_PSM_RESPONSE:
1746 case TDLS_PEER_TRAFFIC_RESPONSE:
1747 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1748 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1749 _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1753 if (ptxmgmt->status_code == _RSON_TDLS_TEAR_UN_RSN_) {
1754 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1755 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1756 _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1760 _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1761 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1762 _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1767 if (pattrib->encrypt)
1770 if (ptxmgmt->action_code == TDLS_PEER_TRAFFIC_RESPONSE)
1773 if (pqospriv->qos_option) {
1774 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
1775 if (pattrib->priority)
1776 SetPriority(qc, pattrib->priority);
1777 SetAckpolicy(qc, pattrib->ack_policy);
1780 psta = pattrib->psta;
1782 /* 1. update seq_num per link by sta_info */
1783 /* 2. rewrite encrypt to _AES_, also rewrite iv_len, icv_len */
1784 if (tdls_seq == 1) {
1785 ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
1787 ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
1788 ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
1789 pattrib->seqnum = ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority];
1790 SetSeqNum(hdr, pattrib->seqnum);
1792 if (pattrib->encrypt) {
1793 pattrib->encrypt = _AES_;
1794 pattrib->iv_len = 8;
1795 pattrib->icv_len = 8;
1796 pattrib->bswenc = _FALSE;
1798 pattrib->mac_id = ptdls_sta->mac_id;
1804 psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
1805 psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
1806 pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
1807 SetSeqNum(hdr, pattrib->seqnum);
1818 s32 rtw_xmit_tdls_coalesce(_adapter *padapter, struct xmit_frame *pxmitframe, struct tdls_txmgmt *ptxmgmt)
1822 u8 *pframe, *mem_start;
1824 struct sta_info *psta;
1825 struct sta_priv *pstapriv = &padapter->stapriv;
1826 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1827 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1829 s32 bmcst = IS_MCAST(pattrib->ra);
1835 psta = pattrib->psta;
1838 psta = rtw_get_bcmc_stainfo(padapter);
1840 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1848 if (pxmitframe->buf_addr == NULL) {
1853 pbuf_start = pxmitframe->buf_addr;
1854 mem_start = pbuf_start + TXDESC_OFFSET;
1856 if (rtw_make_tdls_wlanhdr(padapter, mem_start, pattrib, ptxmgmt) == _FAIL) {
1862 pframe += pattrib->hdrlen;
1864 /* adding icv, if necessary... */
1865 if (pattrib->iv_len) {
1867 switch (pattrib->encrypt) {
1870 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1874 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1876 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
1880 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1882 AES_IV(pattrib->iv, psta->dot11txpn, 0);
1887 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
1888 pframe += pattrib->iv_len;
1892 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
1895 /* pattrib->pktlen will be counted in rtw_build_tdls_ies */
1896 pattrib->pktlen = 0;
1898 rtw_build_tdls_ies(padapter, pxmitframe, pframe, ptxmgmt);
1900 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
1901 pframe += pattrib->pktlen;
1902 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
1903 pframe += pattrib->icv_len;
1906 pattrib->nr_frags = 1;
1907 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + llc_sz +
1908 ((pattrib->bswenc) ? pattrib->icv_len : 0) + pattrib->pktlen;
1910 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
1915 xmitframe_swencrypt(padapter, pxmitframe);
1917 update_attrib_vcs_info(padapter, pxmitframe);
1925 #endif /* CONFIG_TDLS */
1928 * Calculate wlan 802.11 packet MAX size from pkt_attrib
1929 * This function doesn't consider fragment case
1931 u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib)
1935 len = pattrib->hdrlen + pattrib->iv_len; /* WLAN Header and IV */
1936 len += SNAP_SIZE + sizeof(u16); /* LLC */
1937 len += pattrib->pktlen;
1938 if (pattrib->encrypt == _TKIP_)
1940 len += ((pattrib->bswenc) ? pattrib->icv_len : 0); /* ICV */
1947 s32 check_amsdu(struct xmit_frame *pxmitframe)
1949 struct pkt_attrib *pattrib;
1955 pattrib = &pxmitframe->attrib;
1957 if (IS_MCAST(pattrib->ra))
1960 if ((pattrib->ether_type == 0x888e) ||
1961 (pattrib->ether_type == 0x0806) ||
1962 (pattrib->ether_type == 0x88b4) ||
1963 (pattrib->dhcp_pkt == 1))
1966 if ((pattrib->encrypt == _WEP40_) ||
1967 (pattrib->encrypt == _WEP104_) ||
1968 (pattrib->encrypt == _TKIP_))
1971 if (!pattrib->qos_en)
1978 s32 rtw_xmitframe_coalesce_amsdu(_adapter *padapter, struct xmit_frame *pxmitframe, struct xmit_frame *pxmitframe_queue)
1981 struct pkt_file pktfile;
1982 struct pkt_attrib *pattrib;
1985 struct pkt_file pktfile_queue;
1986 struct pkt_attrib *pattrib_queue;
1993 u8 *pframe, *mem_start;
2003 if (pxmitframe->buf_addr == NULL) {
2004 RTW_INFO("==> %s buf_addr==NULL\n", __FUNCTION__);
2009 pbuf_start = pxmitframe->buf_addr;
2011 #ifdef CONFIG_USB_TX_AGGREGATION
2012 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
2014 #ifdef CONFIG_TX_EARLY_MODE /* for SDIO && Tx Agg */
2015 hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
2017 hw_hdr_offset = TXDESC_OFFSET;
2021 mem_start = pbuf_start + hw_hdr_offset; //for DMA
2023 pattrib = &pxmitframe->attrib;
2027 if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
2028 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n"));
2029 RTW_INFO("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n");
2038 //SetMFrag(mem_start);
2039 ClearMFrag(mem_start);
2041 pframe += pattrib->hdrlen;
2043 /* adding icv, if necessary... */
2044 if (pattrib->iv_len) {
2045 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len); // queue or new?
2047 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
2048 ("rtw_xmitframe_coalesce: keyid=%d pattrib->iv[3]=%.2x pframe=%.2x %.2x %.2x %.2x\n",
2049 padapter->securitypriv.dot11PrivacyKeyIndex, pattrib->iv[3], *pframe, *(pframe + 1), *(pframe + 2), *(pframe + 3)));
2051 pframe += pattrib->iv_len;
2054 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len;
2056 if(pxmitframe_queue)
2058 pattrib_queue = &pxmitframe_queue->attrib;
2059 pkt_queue = pxmitframe_queue->pkt;
2061 _rtw_open_pktfile(pkt_queue, &pktfile_queue);
2062 _rtw_pktfile_read(&pktfile_queue, NULL, pattrib_queue->pkt_hdrlen);
2064 /* 802.3 MAC Header DA(6) SA(6) Len(2)*/
2066 _rtw_memcpy(pframe, pattrib_queue->dst, ETH_ALEN);
2069 _rtw_memcpy(pframe, pattrib_queue->src, ETH_ALEN);
2072 len = (u16*) pframe;
2075 llc_sz = rtw_put_snap(pframe, pattrib_queue->ether_type);
2078 mem_sz = _rtw_pktfile_read(&pktfile_queue, pframe, pattrib_queue->pktlen);
2081 *len = htons(llc_sz + mem_sz);
2084 padding = 4 - ((ETH_HLEN + llc_sz + mem_sz) & (4-1));
2088 //_rtw_memset(pframe,0xaa, padding);
2091 pattrib->last_txcmdsz += ETH_HLEN + llc_sz + mem_sz + padding ;
2096 pkt = pxmitframe->pkt;
2097 _rtw_open_pktfile(pkt, &pktfile);
2098 _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
2100 /* 802.3 MAC Header DA(6) SA(6) Len(2) */
2102 _rtw_memcpy(pframe, pattrib->dst, ETH_ALEN);
2105 _rtw_memcpy(pframe, pattrib->src, ETH_ALEN);
2108 len = (u16*) pframe;
2111 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
2114 mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
2118 *len = htons(llc_sz + mem_sz);
2120 //the last ampdu has no padding
2123 pattrib->nr_frags = 1;
2125 pattrib->last_txcmdsz += ETH_HLEN + llc_sz + mem_sz + padding +
2126 ((pattrib->bswenc) ? pattrib->icv_len : 0) ;
2128 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2129 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2130 pframe += pattrib->icv_len;
2133 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
2134 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n"));
2135 RTW_INFO("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n");
2140 xmitframe_swencrypt(padapter, pxmitframe);
2142 pattrib->vcs_mode = NONE_VCS;
2153 This sub-routine will perform all the following:
2155 1. remove 802.3 header.
2156 2. create wlan_header, based on the info in pxmitframe
2157 3. append sta's iv/ext-iv
2159 5. move frag chunk from pframe to pxmitframe->mem
2160 6. apply sw-encrypt, if necessary.
2163 s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
2165 struct pkt_file pktfile;
2167 s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
2171 u8 *pframe, *mem_start;
2174 /* struct sta_info *psta; */
2175 /* struct sta_priv *pstapriv = &padapter->stapriv; */
2176 /* struct mlme_priv *pmlmepriv = &padapter->mlmepriv; */
2177 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2179 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2183 s32 bmcst = IS_MCAST(pattrib->ra);
2191 psta = pattrib->psta;
2194 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
2195 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2201 RTW_INFO("%s, psta==NUL\n", __func__);
2206 if(!(psta->state &_FW_LINKED))
2208 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
2212 if (pxmitframe->buf_addr == NULL) {
2213 RTW_INFO("==> %s buf_addr==NULL\n", __FUNCTION__);
2217 pbuf_start = pxmitframe->buf_addr;
2219 #ifdef CONFIG_USB_TX_AGGREGATION
2220 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
2222 #ifdef CONFIG_TX_EARLY_MODE /* for SDIO && Tx Agg */
2223 hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
2225 hw_hdr_offset = TXDESC_OFFSET;
2229 mem_start = pbuf_start + hw_hdr_offset;
2231 if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
2232 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n"));
2233 RTW_INFO("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n");
2238 _rtw_open_pktfile(pkt, &pktfile);
2239 _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
2242 frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
2251 SetMFrag(mem_start);
2253 pframe += pattrib->hdrlen;
2254 mpdu_len -= pattrib->hdrlen;
2256 /* adding icv, if necessary... */
2257 if (pattrib->iv_len) {
2259 /* if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) */
2260 /* psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); */
2262 /* psta = rtw_get_stainfo(pstapriv, pattrib->ra); */
2265 switch (pattrib->encrypt) {
2268 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2272 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2274 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
2278 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2280 AES_IV(pattrib->iv, psta->dot11txpn, 0);
2282 #ifdef CONFIG_WAPI_SUPPORT
2284 rtw_wapi_get_iv(padapter, pattrib->ra, pattrib->iv);
2290 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
2292 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
2293 ("rtw_xmitframe_coalesce: keyid=%d pattrib->iv[3]=%.2x pframe=%.2x %.2x %.2x %.2x\n",
2294 padapter->securitypriv.dot11PrivacyKeyIndex, pattrib->iv[3], *pframe, *(pframe + 1), *(pframe + 2), *(pframe + 3)));
2296 pframe += pattrib->iv_len;
2298 mpdu_len -= pattrib->iv_len;
2302 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
2307 if ((pattrib->icv_len > 0) && (pattrib->bswenc))
2308 mpdu_len -= pattrib->icv_len;
2312 /* don't do fragment to broadcat/multicast packets */
2313 mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
2315 mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len);
2319 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2320 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2321 pframe += pattrib->icv_len;
2326 if (bmcst || (rtw_endofpktfile(&pktfile) == _TRUE)) {
2327 pattrib->nr_frags = frg_inx;
2329 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags == 1) ? llc_sz : 0) +
2330 ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz;
2332 ClearMFrag(mem_start);
2336 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: There're still something in packet!\n", __FUNCTION__));
2338 addr = (SIZE_PTR)(pframe);
2340 mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset;
2341 _rtw_memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
2345 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
2346 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n"));
2347 RTW_INFO("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n");
2352 xmitframe_swencrypt(padapter, pxmitframe);
2354 if (bmcst == _FALSE)
2355 update_attrib_vcs_info(padapter, pxmitframe);
2357 pattrib->vcs_mode = NONE_VCS;
2366 #ifdef CONFIG_IEEE80211W
2367 /* broadcast or multicast management pkt use BIP, unicast management pkt use CCMP encryption */
2368 s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
2370 struct pkt_file pktfile;
2371 s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
2373 u8 *pframe, *mem_start = NULL, *tmp_buf = NULL;
2374 u8 hw_hdr_offset, subtype ;
2375 struct sta_info *psta = NULL;
2376 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2377 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2379 s32 bmcst = IS_MCAST(pattrib->ra);
2382 u8 *MGMT_body = NULL;
2384 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2385 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2386 struct rtw_ieee80211_hdr *pwlanhdr;
2387 u8 MME[_MME_IE_LENGTH_];
2391 mem_start = pframe = (u8 *)(pxmitframe->buf_addr) + TXDESC_OFFSET;
2392 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2395 ori_len = BIP_AAD_SIZE + pattrib->pktlen;
2396 tmp_buf = BIP_AAD = rtw_zmalloc(ori_len);
2397 subtype = GetFrameSubType(pframe); /* bit(7)~bit(2) */
2399 if (BIP_AAD == NULL)
2402 _enter_critical_bh(&padapter->security_key_mutex, &irqL);
2405 /* IGTK key is not install, it may not support 802.11w */
2406 if (padapter->securitypriv.binstallBIPkey != _TRUE) {
2407 RTW_INFO("no instll BIP key\n");
2408 goto xmitframe_coalesce_success;
2410 /* station mode doesn't need TX BIP, just ready the code */
2415 _rtw_memset(MME, 0, _MME_IE_LENGTH_);
2417 /* other types doesn't need the BIP */
2418 if (GetFrameSubType(pframe) != WIFI_DEAUTH && GetFrameSubType(pframe) != WIFI_DISASSOC)
2419 goto xmitframe_coalesce_fail;
2421 MGMT_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
2422 pframe += pattrib->pktlen;
2424 /* octent 0 and 1 is key index ,BIP keyid is 4 or 5, LSB only need octent 0 */
2425 MME[0] = padapter->securitypriv.dot11wBIPKeyid;
2426 /* copy packet number */
2427 _rtw_memcpy(&MME[2], &pmlmeext->mgnt_80211w_IPN, 6);
2428 /* increase the packet number */
2429 pmlmeext->mgnt_80211w_IPN++;
2431 /* add MME IE with MIC all zero, MME string doesn't include element id and length */
2432 pframe = rtw_set_ie(pframe, _MME_IE_ , 16 , MME, &(pattrib->pktlen));
2433 pattrib->last_txcmdsz = pattrib->pktlen;
2434 /* total frame length - header length */
2435 frame_body_len = pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr);
2437 /* conscruct AAD, copy frame control field */
2438 _rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2);
2439 ClearRetry(BIP_AAD);
2440 ClearPwrMgt(BIP_AAD);
2441 ClearMData(BIP_AAD);
2442 /* conscruct AAD, copy address 1 to address 3 */
2443 _rtw_memcpy(BIP_AAD + 2, pwlanhdr->addr1, 18);
2444 /* copy management fram body */
2445 _rtw_memcpy(BIP_AAD + BIP_AAD_SIZE, MGMT_body, frame_body_len);
2447 /* dump total packet include MME with zero MIC */
2450 printk("Total packet: ");
2451 for (i = 0; i < BIP_AAD_SIZE + frame_body_len; i++)
2452 printk(" %02x ", BIP_AAD[i]);
2457 if (omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey
2458 , BIP_AAD, BIP_AAD_SIZE + frame_body_len, mic))
2459 goto xmitframe_coalesce_fail;
2462 /* dump calculated mic result */
2465 printk("Calculated mic result: ");
2466 for (i = 0; i < 16; i++)
2467 printk(" %02x ", mic[i]);
2471 /* copy right BIP mic value, total is 128bits, we use the 0~63 bits */
2472 _rtw_memcpy(pframe - 8, mic, 8);
2473 /*/dump all packet after mic ok
2476 printk("pattrib->pktlen = %d\n", pattrib->pktlen);
2477 for(pp=0;pp< pattrib->pktlen; pp++)
2478 printk(" %02x ", mem_start[pp]);
2481 } else { /* unicast mgmt frame TX */
2482 /* start to encrypt mgmt frame */
2483 if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC ||
2484 subtype == WIFI_REASSOCREQ || subtype == WIFI_ACTION) {
2486 psta = pattrib->psta;
2488 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2492 RTW_INFO("%s, psta==NUL\n", __func__);
2493 goto xmitframe_coalesce_fail;
2496 if (pxmitframe->buf_addr == NULL) {
2497 RTW_INFO("%s, pxmitframe->buf_addr\n", __func__);
2498 goto xmitframe_coalesce_fail;
2501 /* RTW_INFO("%s, action frame category=%d\n", __func__, pframe[WLAN_HDR_A3_LEN]); */
2502 /* according 802.11-2012 standard, these five types are not robust types */
2503 if (subtype == WIFI_ACTION &&
2504 (pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_PUBLIC ||
2505 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_HT ||
2506 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_UNPROTECTED_WNM ||
2507 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_SELF_PROTECTED ||
2508 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_P2P))
2509 goto xmitframe_coalesce_fail;
2510 /* before encrypt dump the management packet content */
2513 printk("Management pkt: ");
2514 for(i=0; i<pattrib->pktlen; i++)
2515 printk(" %02x ", pframe[i]);
2516 printk("=======\n");
2518 if (pattrib->encrypt > 0)
2519 _rtw_memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16);
2521 /* To use wrong key */
2522 if (pattrib->key_type == IEEE80211W_WRONG_KEY) {
2523 RTW_INFO("use wrong key\n");
2524 pattrib->dot118021x_UncstKey.skey[0] = 0xff;
2527 /* bakeup original management packet */
2528 _rtw_memcpy(tmp_buf, pframe, pattrib->pktlen);
2529 /* move to data portion */
2530 pframe += pattrib->hdrlen;
2532 /* 802.11w unicast management packet must be _AES_ */
2533 pattrib->iv_len = 8;
2534 /* it's MIC of AES */
2535 pattrib->icv_len = 8;
2537 switch (pattrib->encrypt) {
2539 /* set AES IV header */
2540 AES_IV(pattrib->iv, psta->dot11wtxpn, 0);
2543 goto xmitframe_coalesce_fail;
2545 /* insert iv header into management frame */
2546 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
2547 pframe += pattrib->iv_len;
2548 /* copy mgmt data portion after CCMP header */
2549 _rtw_memcpy(pframe, tmp_buf + pattrib->hdrlen, pattrib->pktlen - pattrib->hdrlen);
2550 /* move pframe to end of mgmt pkt */
2551 pframe += pattrib->pktlen - pattrib->hdrlen;
2552 /* add 8 bytes CCMP IV header to length */
2553 pattrib->pktlen += pattrib->iv_len;
2555 /* dump management packet include AES IV header */
2558 printk("Management pkt + IV: ");
2559 /* for(i=0; i<pattrib->pktlen; i++) */
2561 printk("@@@@@@@@@@@@@\n");
2565 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2566 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2567 pframe += pattrib->icv_len;
2569 /* add 8 bytes MIC */
2570 pattrib->pktlen += pattrib->icv_len;
2571 /* set final tx command size */
2572 pattrib->last_txcmdsz = pattrib->pktlen;
2574 /* set protected bit must be beofre SW encrypt */
2575 SetPrivacy(mem_start);
2577 /* dump management packet include AES header */
2580 printk("prepare to enc Management pkt + IV: ");
2581 for (i = 0; i < pattrib->pktlen; i++)
2582 printk(" %02x ", mem_start[i]);
2583 printk("@@@@@@@@@@@@@\n");
2586 /* software encrypt */
2587 xmitframe_swencrypt(padapter, pxmitframe);
2591 xmitframe_coalesce_success:
2592 _exit_critical_bh(&padapter->security_key_mutex, &irqL);
2593 rtw_mfree(BIP_AAD, ori_len);
2597 xmitframe_coalesce_fail:
2598 _exit_critical_bh(&padapter->security_key_mutex, &irqL);
2599 rtw_mfree(BIP_AAD, ori_len);
2604 #endif /* CONFIG_IEEE80211W */
2606 /* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
2607 * IEEE LLC/SNAP header contains 8 octets
2608 * First 3 octets comprise the LLC portion
2609 * SNAP portion, 5 octets, is divided into two fields:
2610 * Organizationally Unique Identifier(OUI), 3 octets,
2611 * type, defined by that organization, 2 octets.
2613 s32 rtw_put_snap(u8 *data, u16 h_proto)
2615 struct ieee80211_snap_hdr *snap;
2620 snap = (struct ieee80211_snap_hdr *)data;
2625 if (h_proto == 0x8137 || h_proto == 0x80f3)
2630 snap->oui[0] = oui[0];
2631 snap->oui[1] = oui[1];
2632 snap->oui[2] = oui[2];
2634 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
2638 return SNAP_SIZE + sizeof(u16);
2641 void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len)
2647 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2648 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2652 switch (pxmitpriv->vcs_setting) {
2654 pxmitpriv->vcs = NONE_VCS;
2662 perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
2664 pxmitpriv->vcs = NONE_VCS;
2666 protection = (*(perp + 2)) & BIT(1);
2668 if (pregistrypriv->vcs_type == RTS_CTS)
2669 pxmitpriv->vcs = RTS_CTS;
2671 pxmitpriv->vcs = CTS_TO_SELF;
2673 pxmitpriv->vcs = NONE_VCS;
2684 void rtw_count_tx_stats(PADAPTER padapter, struct xmit_frame *pxmitframe, int sz)
2686 struct sta_info *psta = NULL;
2687 struct stainfo_stats *pstats = NULL;
2688 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2689 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2692 if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
2693 #if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2694 pkt_num = pxmitframe->agg_num;
2696 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pkt_num;
2698 pxmitpriv->tx_pkts += pkt_num;
2700 pxmitpriv->tx_bytes += sz;
2702 psta = pxmitframe->attrib.psta;
2704 pstats = &psta->sta_stats;
2706 pstats->tx_pkts += pkt_num;
2708 pstats->tx_bytes += sz;
2710 if (pxmitframe->attrib.ptdls_sta != NULL) {
2711 pstats = &(pxmitframe->attrib.ptdls_sta->sta_stats);
2712 pstats->tx_pkts += pkt_num;
2713 pstats->tx_bytes += sz;
2715 #endif /* CONFIG_TDLS */
2718 #ifdef CONFIG_CHECK_LEAVE_LPS
2719 /* traffic_check_for_leave_lps(padapter, _TRUE); */
2720 #endif /* CONFIG_LPS */
2725 static struct xmit_buf *__rtw_alloc_cmd_xmitbuf(struct xmit_priv *pxmitpriv,
2726 enum cmdbuf_type buf_type)
2728 struct xmit_buf *pxmitbuf = NULL;
2732 pxmitbuf = &pxmitpriv->pcmd_xmitbuf[buf_type];
2733 if (pxmitbuf != NULL) {
2734 pxmitbuf->priv_data = NULL;
2736 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2738 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
2739 pxmitbuf->agg_num = 0;
2740 pxmitbuf->pg_num = 0;
2742 #ifdef CONFIG_PCI_HCI
2744 #ifdef CONFIG_TRX_BD_ARCH
2745 /*pxmitbuf->buf_desc = NULL;*/
2747 pxmitbuf->desc = NULL;
2751 if (pxmitbuf->sctx) {
2752 RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
2753 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
2756 RTW_INFO("%s fail, no xmitbuf available !!!\n", __func__);
2765 struct xmit_frame *__rtw_alloc_cmdxmitframe(struct xmit_priv *pxmitpriv,
2766 enum cmdbuf_type buf_type)
2768 struct xmit_frame *pcmdframe;
2769 struct xmit_buf *pxmitbuf;
2771 pcmdframe = rtw_alloc_xmitframe(pxmitpriv);
2772 if (pcmdframe == NULL) {
2773 RTW_INFO("%s, alloc xmitframe fail\n", __FUNCTION__);
2777 pxmitbuf = __rtw_alloc_cmd_xmitbuf(pxmitpriv, buf_type);
2778 if (pxmitbuf == NULL) {
2779 RTW_INFO("%s, alloc xmitbuf fail\n", __FUNCTION__);
2780 rtw_free_xmitframe(pxmitpriv, pcmdframe);
2784 pcmdframe->frame_tag = MGNT_FRAMETAG;
2786 pcmdframe->pxmitbuf = pxmitbuf;
2788 pcmdframe->buf_addr = pxmitbuf->pbuf;
2790 pxmitbuf->priv_data = pcmdframe;
2796 struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
2799 struct xmit_buf *pxmitbuf = NULL;
2800 _list *plist, *phead;
2801 _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
2805 _enter_critical(&pfree_queue->lock, &irqL);
2807 if (_rtw_queue_empty(pfree_queue) == _TRUE)
2811 phead = get_list_head(pfree_queue);
2813 plist = get_next(phead);
2815 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
2817 rtw_list_delete(&(pxmitbuf->list));
2820 if (pxmitbuf != NULL) {
2821 pxmitpriv->free_xmit_extbuf_cnt--;
2822 #ifdef DBG_XMIT_BUF_EXT
2823 RTW_INFO("DBG_XMIT_BUF_EXT ALLOC no=%d, free_xmit_extbuf_cnt=%d\n", pxmitbuf->no, pxmitpriv->free_xmit_extbuf_cnt);
2827 pxmitbuf->priv_data = NULL;
2829 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2831 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
2832 pxmitbuf->agg_num = 1;
2834 #ifdef CONFIG_PCI_HCI
2836 #ifdef CONFIG_TRX_BD_ARCH
2837 /*pxmitbuf->buf_desc = NULL;*/
2839 pxmitbuf->desc = NULL;
2843 if (pxmitbuf->sctx) {
2844 RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
2845 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
2850 _exit_critical(&pfree_queue->lock, &irqL);
2857 s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
2860 _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
2864 if (pxmitbuf == NULL)
2867 _enter_critical(&pfree_queue->lock, &irqL);
2869 rtw_list_delete(&pxmitbuf->list);
2871 rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_queue));
2872 pxmitpriv->free_xmit_extbuf_cnt++;
2873 #ifdef DBG_XMIT_BUF_EXT
2874 RTW_INFO("DBG_XMIT_BUF_EXT FREE no=%d, free_xmit_extbuf_cnt=%d\n", pxmitbuf->no , pxmitpriv->free_xmit_extbuf_cnt);
2877 _exit_critical(&pfree_queue->lock, &irqL);
2884 struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
2887 struct xmit_buf *pxmitbuf = NULL;
2888 _list *plist, *phead;
2889 _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
2893 /* RTW_INFO("+rtw_alloc_xmitbuf\n"); */
2895 _enter_critical(&pfree_xmitbuf_queue->lock, &irqL);
2897 if (_rtw_queue_empty(pfree_xmitbuf_queue) == _TRUE)
2901 phead = get_list_head(pfree_xmitbuf_queue);
2903 plist = get_next(phead);
2905 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
2907 rtw_list_delete(&(pxmitbuf->list));
2910 if (pxmitbuf != NULL) {
2911 pxmitpriv->free_xmitbuf_cnt--;
2913 RTW_INFO("DBG_XMIT_BUF ALLOC no=%d, free_xmitbuf_cnt=%d\n", pxmitbuf->no, pxmitpriv->free_xmitbuf_cnt);
2915 /* RTW_INFO("alloc, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); */
2917 pxmitbuf->priv_data = NULL;
2919 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2921 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
2922 pxmitbuf->agg_num = 0;
2923 pxmitbuf->pg_num = 0;
2925 #ifdef CONFIG_PCI_HCI
2927 #ifdef CONFIG_TRX_BD_ARCH
2928 /*pxmitbuf->buf_desc = NULL;*/
2930 pxmitbuf->desc = NULL;
2934 if (pxmitbuf->sctx) {
2935 RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
2936 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
2941 RTW_INFO("DBG_XMIT_BUF rtw_alloc_xmitbuf return NULL\n");
2944 _exit_critical(&pfree_xmitbuf_queue->lock, &irqL);
2951 s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
2954 _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
2958 /* RTW_INFO("+rtw_free_xmitbuf\n"); */
2960 if (pxmitbuf == NULL)
2963 if (pxmitbuf->sctx) {
2964 RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
2965 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
2968 if (pxmitbuf->buf_tag == XMITBUF_CMD) {
2969 } else if (pxmitbuf->buf_tag == XMITBUF_MGNT)
2970 rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf);
2972 _enter_critical(&pfree_xmitbuf_queue->lock, &irqL);
2974 rtw_list_delete(&pxmitbuf->list);
2976 rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
2978 pxmitpriv->free_xmitbuf_cnt++;
2979 /* RTW_INFO("FREE, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); */
2981 RTW_INFO("DBG_XMIT_BUF FREE no=%d, free_xmitbuf_cnt=%d\n", pxmitbuf->no , pxmitpriv->free_xmitbuf_cnt);
2983 _exit_critical(&pfree_xmitbuf_queue->lock, &irqL);
2991 void rtw_init_xmitframe(struct xmit_frame *pxframe)
2993 if (pxframe != NULL) { /* default value setting */
2994 pxframe->buf_addr = NULL;
2995 pxframe->pxmitbuf = NULL;
2997 _rtw_memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
2998 /* pxframe->attrib.psta = NULL; */
3000 pxframe->frame_tag = DATA_FRAMETAG;
3002 #ifdef CONFIG_USB_HCI
3003 pxframe->pkt = NULL;
3004 #ifdef USB_PACKET_OFFSET_SZ
3005 pxframe->pkt_offset = (PACKET_OFFSET_SZ / 8);
3007 pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */
3010 #ifdef CONFIG_USB_TX_AGGREGATION
3011 pxframe->agg_num = 1;
3014 #endif /* #ifdef CONFIG_USB_HCI */
3016 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3017 pxframe->pg_num = 1;
3018 pxframe->agg_num = 1;
3021 #ifdef CONFIG_XMIT_ACK
3022 pxframe->ack_report = 0;
3031 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
3033 If we turn on USE_RXTHREAD, then, no need for critical section.
3034 Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
3036 Must be very very cautious...
3039 struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* (_queue *pfree_xmit_queue) */
3042 Please remember to use all the osdep_service api,
3043 and lock/unlock or _enter/_exit critical to protect
3048 struct xmit_frame *pxframe = NULL;
3049 _list *plist, *phead;
3050 _queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
3054 _enter_critical_bh(&pfree_xmit_queue->lock, &irqL);
3056 if (_rtw_queue_empty(pfree_xmit_queue) == _TRUE) {
3057 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe:%d\n", pxmitpriv->free_xmitframe_cnt));
3060 phead = get_list_head(pfree_xmit_queue);
3062 plist = get_next(phead);
3064 pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3066 rtw_list_delete(&(pxframe->list));
3067 pxmitpriv->free_xmitframe_cnt--;
3068 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt));
3071 _exit_critical_bh(&pfree_xmit_queue->lock, &irqL);
3073 rtw_init_xmitframe(pxframe);
3080 struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv)
3083 struct xmit_frame *pxframe = NULL;
3084 _list *plist, *phead;
3085 _queue *queue = &pxmitpriv->free_xframe_ext_queue;
3089 _enter_critical_bh(&queue->lock, &irqL);
3091 if (_rtw_queue_empty(queue) == _TRUE) {
3092 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe_ext:%d\n", pxmitpriv->free_xframe_ext_cnt));
3095 phead = get_list_head(queue);
3096 plist = get_next(phead);
3097 pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3099 rtw_list_delete(&(pxframe->list));
3100 pxmitpriv->free_xframe_ext_cnt--;
3101 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe_ext():free_xmitframe_cnt=%d\n", pxmitpriv->free_xframe_ext_cnt));
3104 _exit_critical_bh(&queue->lock, &irqL);
3106 rtw_init_xmitframe(pxframe);
3113 struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv)
3115 struct xmit_frame *pxframe = NULL;
3118 alloc_addr = rtw_zmalloc(sizeof(struct xmit_frame) + 4);
3120 if (alloc_addr == NULL)
3123 pxframe = (struct xmit_frame *)N_BYTE_ALIGMENT((SIZE_PTR)(alloc_addr), 4);
3124 pxframe->alloc_addr = alloc_addr;
3126 pxframe->padapter = pxmitpriv->adapter;
3127 pxframe->frame_tag = NULL_FRAMETAG;
3129 pxframe->pkt = NULL;
3131 pxframe->buf_addr = NULL;
3132 pxframe->pxmitbuf = NULL;
3134 rtw_init_xmitframe(pxframe);
3136 RTW_INFO("################## %s ##################\n", __func__);
3142 s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
3145 _queue *queue = NULL;
3146 _adapter *padapter = pxmitpriv->adapter;
3147 _pkt *pndis_pkt = NULL;
3151 if (pxmitframe == NULL) {
3152 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("======rtw_free_xmitframe():pxmitframe==NULL!!!!!!!!!!\n"));
3156 if (pxmitframe->pkt) {
3157 pndis_pkt = pxmitframe->pkt;
3158 pxmitframe->pkt = NULL;
3161 if (pxmitframe->alloc_addr) {
3162 RTW_INFO("################## %s with alloc_addr ##################\n", __func__);
3163 rtw_mfree(pxmitframe->alloc_addr, sizeof(struct xmit_frame) + 4);
3164 goto check_pkt_complete;
3167 if (pxmitframe->ext_tag == 0)
3168 queue = &pxmitpriv->free_xmit_queue;
3169 else if (pxmitframe->ext_tag == 1)
3170 queue = &pxmitpriv->free_xframe_ext_queue;
3174 _enter_critical_bh(&queue->lock, &irqL);
3176 rtw_list_delete(&pxmitframe->list);
3177 rtw_list_insert_tail(&pxmitframe->list, get_list_head(queue));
3178 if (pxmitframe->ext_tag == 0) {
3179 pxmitpriv->free_xmitframe_cnt++;
3180 RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt));
3181 } else if (pxmitframe->ext_tag == 1) {
3182 pxmitpriv->free_xframe_ext_cnt++;
3183 RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xframe_ext_cnt=%d\n", pxmitpriv->free_xframe_ext_cnt));
3187 _exit_critical_bh(&queue->lock, &irqL);
3192 rtw_os_pkt_complete(padapter, pndis_pkt);
3201 void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue)
3204 _list *plist, *phead;
3205 struct xmit_frame *pxmitframe;
3209 _enter_critical_bh(&(pframequeue->lock), &irqL);
3211 phead = get_list_head(pframequeue);
3212 plist = get_next(phead);
3214 while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
3216 pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3218 plist = get_next(plist);
3220 rtw_free_xmitframe(pxmitpriv, pxmitframe);
3223 _exit_critical_bh(&(pframequeue->lock), &irqL);
3228 s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
3230 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue);
3231 if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) {
3232 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
3233 ("rtw_xmitframe_enqueue: drop xmit pkt for classifier fail\n"));
3234 /* pxmitframe->pkt = NULL; */
3241 static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue)
3243 _list *xmitframe_plist, *xmitframe_phead;
3244 struct xmit_frame *pxmitframe = NULL;
3246 xmitframe_phead = get_list_head(pframe_queue);
3247 xmitframe_plist = get_next(xmitframe_phead);
3249 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
3250 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
3252 /* xmitframe_plist = get_next(xmitframe_plist); */
3254 /*#ifdef RTK_DMP_PLATFORM
3255 #ifdef CONFIG_USB_TX_AGGREGATION
3256 if((ptxservq->qcnt>0) && (ptxservq->qcnt<=2))
3260 tasklet_schedule(&pxmitpriv->xmit_tasklet);
3266 rtw_list_delete(&pxmitframe->list);
3270 /* rtw_list_insert_tail(&pxmitframe->list, &phwxmit->pending); */
3272 /* ptxservq->qcnt--; */
3276 /* pxmitframe = NULL; */
3283 static struct xmit_frame *get_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue)
3285 _list *xmitframe_plist, *xmitframe_phead;
3286 struct xmit_frame *pxmitframe = NULL;
3288 xmitframe_phead = get_list_head(pframe_queue);
3289 xmitframe_plist = get_next(xmitframe_phead);
3291 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
3292 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
3299 struct xmit_frame *rtw_get_xframe(struct xmit_priv *pxmitpriv, int *num_frame)
3302 _list *sta_plist, *sta_phead;
3303 struct hw_xmit *phwxmit_i = pxmitpriv->hwxmits;
3304 sint entry = pxmitpriv->hwxmit_entry;
3306 struct hw_xmit *phwxmit;
3307 struct tx_servq *ptxservq = NULL;
3308 _queue *pframe_queue = NULL;
3309 struct xmit_frame *pxmitframe = NULL;
3310 _adapter *padapter = pxmitpriv->adapter;
3311 struct registry_priv *pregpriv = &padapter->registrypriv;
3314 #ifdef CONFIG_USB_HCI
3315 /* int j, tmp, acirp_cnt[4]; */
3327 /*No amsdu when wifi_spec on*/
3328 if (pregpriv->wifi_spec == 1) {
3332 _enter_critical_bh(&pxmitpriv->lock, &irqL0);
3334 for (i = 0; i < entry; i++) {
3335 phwxmit = phwxmit_i + inx[i];
3337 sta_phead = get_list_head(phwxmit->sta_queue);
3338 sta_plist = get_next(sta_phead);
3340 while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) {
3342 ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
3343 pframe_queue = &ptxservq->sta_pending;
3347 *num_frame = ptxservq->qcnt;
3348 pxmitframe = get_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
3351 sta_plist = get_next(sta_plist);
3357 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
3365 struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry)
3368 _list *sta_plist, *sta_phead;
3369 struct hw_xmit *phwxmit;
3370 struct tx_servq *ptxservq = NULL;
3371 _queue *pframe_queue = NULL;
3372 struct xmit_frame *pxmitframe = NULL;
3373 _adapter *padapter = pxmitpriv->adapter;
3374 struct registry_priv *pregpriv = &padapter->registrypriv;
3376 #ifdef CONFIG_USB_HCI
3377 /* int j, tmp, acirp_cnt[4]; */
3387 if (pregpriv->wifi_spec == 1) {
3388 int j, tmp, acirp_cnt[4];
3390 if (flags < XMIT_QUEUE_ENTRY) {
3391 /* priority exchange according to the completed xmitbuf flags. */
3397 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_PCI_HCI)
3398 for (j = 0; j < 4; j++)
3399 inx[j] = pxmitpriv->wmm_para_seq[j];
3403 _enter_critical_bh(&pxmitpriv->lock, &irqL0);
3405 for (i = 0; i < entry; i++) {
3406 phwxmit = phwxmit_i + inx[i];
3408 /* _enter_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
3410 sta_phead = get_list_head(phwxmit->sta_queue);
3411 sta_plist = get_next(sta_phead);
3413 while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) {
3415 ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
3417 pframe_queue = &ptxservq->sta_pending;
3419 pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
3424 /* Remove sta node when there is no pending packets. */
3425 if (_rtw_queue_empty(pframe_queue)) /* must be done after get_next and before break */
3426 rtw_list_delete(&ptxservq->tx_pending);
3428 /* _exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
3433 sta_plist = get_next(sta_plist);
3437 /* _exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
3443 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
3451 struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac)
3453 struct tx_servq *ptxservq = NULL;
3460 ptxservq = &(psta->sta_xmitpriv.bk_q);
3462 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : BK\n"));
3467 ptxservq = &(psta->sta_xmitpriv.vi_q);
3469 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : VI\n"));
3474 ptxservq = &(psta->sta_xmitpriv.vo_q);
3476 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : VO\n"));
3482 ptxservq = &(psta->sta_xmitpriv.be_q);
3484 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : BE\n"));
3494 __inline static struct tx_servq *rtw_get_sta_pending
3495 (_adapter *padapter, _queue **ppstapending, struct sta_info *psta, sint up)
3497 struct tx_servq *ptxservq;
3498 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
3502 #ifdef CONFIG_RTL8711
3504 if (IS_MCAST(psta->hwaddr)) {
3505 ptxservq = &(psta->sta_xmitpriv.be_q); /* we will use be_q to queue bc/mc frames in BCMC_stainfo */
3506 *ppstapending = &padapter->xmitpriv.bm_pending;
3513 ptxservq = &(psta->sta_xmitpriv.bk_q);
3514 *ppstapending = &padapter->xmitpriv.bk_pending;
3515 (phwxmits + 3)->accnt++;
3516 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : BK\n"));
3521 ptxservq = &(psta->sta_xmitpriv.vi_q);
3522 *ppstapending = &padapter->xmitpriv.vi_pending;
3523 (phwxmits + 1)->accnt++;
3524 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : VI\n"));
3529 ptxservq = &(psta->sta_xmitpriv.vo_q);
3530 *ppstapending = &padapter->xmitpriv.vo_pending;
3531 (phwxmits + 0)->accnt++;
3532 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : VO\n"));
3538 ptxservq = &(psta->sta_xmitpriv.be_q);
3539 *ppstapending = &padapter->xmitpriv.be_pending;
3540 (phwxmits + 2)->accnt++;
3541 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : BE\n"));
3555 * Will enqueue pxmitframe to the proper queue,
3556 * and indicate it to xx_pending list.....
3558 s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe)
3562 struct sta_info *psta;
3563 struct tx_servq *ptxservq;
3564 struct pkt_attrib *pattrib = &pxmitframe->attrib;
3565 struct sta_priv *pstapriv = &padapter->stapriv;
3566 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
3567 sint res = _SUCCESS;
3571 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class);
3574 if (pattrib->psta) {
3575 psta = pattrib->psta;
3577 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
3578 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
3582 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
3583 if (pattrib->psta != psta) {
3584 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_sta);
3585 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
3590 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_nosta);
3592 RTW_INFO("rtw_xmit_classifier: psta == NULL\n");
3593 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmit_classifier: psta == NULL\n"));
3597 if (!(psta->state & _FW_LINKED)) {
3598 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_fwlink);
3599 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
3603 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
3605 /* _enter_critical(&pstapending->lock, &irqL0); */
3607 if (rtw_is_list_empty(&ptxservq->tx_pending))
3608 rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
3610 /* _enter_critical(&ptxservq->sta_pending.lock, &irqL1); */
3612 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
3614 phwxmits[ac_index].accnt++;
3616 /* _exit_critical(&ptxservq->sta_pending.lock, &irqL1); */
3618 /* _exit_critical(&pstapending->lock, &irqL0); */
3627 void rtw_alloc_hwxmits(_adapter *padapter)
3629 struct hw_xmit *hwxmits;
3630 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3632 pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
3634 pxmitpriv->hwxmits = NULL;
3636 pxmitpriv->hwxmits = (struct hw_xmit *)rtw_zmalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry);
3638 if (pxmitpriv->hwxmits == NULL) {
3639 RTW_INFO("alloc hwxmits fail!...\n");
3643 hwxmits = pxmitpriv->hwxmits;
3645 if (pxmitpriv->hwxmit_entry == 5) {
3646 /* pxmitpriv->bmc_txqueue.head = 0; */
3647 /* hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; */
3648 hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
3650 /* pxmitpriv->vo_txqueue.head = 0; */
3651 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; */
3652 hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
3654 /* pxmitpriv->vi_txqueue.head = 0; */
3655 /* hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; */
3656 hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
3658 /* pxmitpriv->bk_txqueue.head = 0; */
3659 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
3660 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
3662 /* pxmitpriv->be_txqueue.head = 0; */
3663 /* hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; */
3664 hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
3666 } else if (pxmitpriv->hwxmit_entry == 4) {
3668 /* pxmitpriv->vo_txqueue.head = 0; */
3669 /* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */
3670 hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
3672 /* pxmitpriv->vi_txqueue.head = 0; */
3673 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */
3674 hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
3676 /* pxmitpriv->be_txqueue.head = 0; */
3677 /* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */
3678 hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
3680 /* pxmitpriv->bk_txqueue.head = 0; */
3681 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
3682 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
3691 void rtw_free_hwxmits(_adapter *padapter)
3693 struct hw_xmit *hwxmits;
3694 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3696 hwxmits = pxmitpriv->hwxmits;
3698 rtw_mfree((u8 *)hwxmits, (sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry));
3701 void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry)
3705 for (i = 0; i < entry; i++, phwxmit++) {
3706 /* _rtw_spinlock_init(&phwxmit->xmit_lock); */
3707 /* _rtw_init_listhead(&phwxmit->pending); */
3708 /* phwxmit->txcmdcnt = 0; */
3714 #ifdef CONFIG_BR_EXT
3715 int rtw_br_client_tx(_adapter *padapter, struct sk_buff **pskb)
3717 struct sk_buff *skb = *pskb;
3718 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3720 /* if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) */
3722 void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb);
3723 int res, is_vlan_tag = 0, i, do_nat25 = 1;
3724 unsigned short vlan_hdr = 0;
3725 void *br_port = NULL;
3727 /* mac_clone_handle_frame(priv, skb); */
3729 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3730 br_port = padapter->pnetdev->br_port;
3731 #else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
3733 br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
3735 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
3736 _enter_critical_bh(&padapter->br_ext_lock, &irqL);
3737 if (!(skb->data[0] & 1) &&
3739 memcmp(skb->data + MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
3740 *((unsigned short *)(skb->data + MACADDRLEN * 2)) != __constant_htons(ETH_P_8021Q) &&
3741 *((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP) &&
3742 !memcmp(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN) && padapter->scdb_entry) {
3743 memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
3744 padapter->scdb_entry->ageing_timer = jiffies;
3745 _exit_critical_bh(&padapter->br_ext_lock, &irqL);
3747 /* if (!priv->pmib->ethBrExtInfo.nat25_disable) */
3749 /* if (priv->dev->br_port &&
3750 * !memcmp(skb->data+MACADDRLEN, priv->br_mac, MACADDRLEN)) { */
3752 if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q)) {
3754 vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2));
3755 for (i = 0; i < 6; i++)
3756 *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2));
3759 /* if SA == br_mac && skb== IP => copy SIP to br_ip ?? why */
3760 if (!memcmp(skb->data + MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
3761 (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP)))
3762 memcpy(padapter->br_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4);
3764 if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP)) {
3765 if (memcmp(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN)) {
3766 void *scdb_findEntry(_adapter *priv, unsigned char *macAddr, unsigned char *ipAddr);
3768 padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter,
3769 skb->data + MACADDRLEN, skb->data + WLAN_ETHHDR_LEN + 12);
3770 if (padapter->scdb_entry != NULL) {
3771 memcpy(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN);
3772 memcpy(padapter->scdb_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4);
3773 padapter->scdb_entry->ageing_timer = jiffies;
3777 if (padapter->scdb_entry) {
3778 padapter->scdb_entry->ageing_timer = jiffies;
3781 memset(padapter->scdb_mac, 0, MACADDRLEN);
3782 memset(padapter->scdb_ip, 0, 4);
3786 _exit_critical_bh(&padapter->br_ext_lock, &irqL);
3789 int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method);
3790 if (nat25_db_handle(padapter, skb, NAT25_CHECK) == 0) {
3791 struct sk_buff *newskb;
3795 for (i = 0; i < 6; i++)
3796 *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2));
3797 *((unsigned short *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q);
3798 *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr;
3801 newskb = rtw_skb_copy(skb);
3802 if (newskb == NULL) {
3803 /* priv->ext_stats.tx_drops++; */
3804 DEBUG_ERR("TX DROP: rtw_skb_copy fail!\n");
3805 /* goto stop_proc; */
3810 *pskb = skb = newskb;
3812 vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2));
3813 for (i = 0; i < 6; i++)
3814 *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2));
3819 if (skb_is_nonlinear(skb))
3820 DEBUG_ERR("%s(): skb_is_nonlinear!!\n", __FUNCTION__);
3823 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
3824 res = skb_linearize(skb, GFP_ATOMIC);
3825 #else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) */
3826 res = skb_linearize(skb);
3827 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) */
3829 DEBUG_ERR("TX DROP: skb_linearize fail!\n");
3830 /* goto free_and_stop; */
3834 res = nat25_db_handle(padapter, skb, NAT25_INSERT);
3837 /* priv->ext_stats.tx_drops++; */
3838 DEBUG_ERR("TX DROP: nat25_db_handle fail!\n");
3839 /* goto free_and_stop; */
3843 /* we just print warning message and let it go */
3844 /* DEBUG_WARN("%s()-%d: nat25_db_handle INSERT Warning!\n", __FUNCTION__, __LINE__); */
3845 /* return -1; */ /* return -1 will cause system crash on 2011/08/30! */
3850 memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
3852 dhcp_flag_bcast(padapter, skb);
3856 for (i = 0; i < 6; i++)
3857 *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2));
3858 *((unsigned short *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q);
3859 *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr;
3864 if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q))
3868 if (ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A_VALN(skb->data))
3869 memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
3871 if (ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A(skb->data))
3872 memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
3877 /* check if SA is equal to our MAC */
3878 if (memcmp(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN)) {
3879 /* priv->ext_stats.tx_drops++; */
3880 DEBUG_ERR("TX DROP: untransformed frame SA:%02X%02X%02X%02X%02X%02X!\n",
3881 skb->data[6], skb->data[7], skb->data[8], skb->data[9], skb->data[10], skb->data[11]);
3882 /* goto free_and_stop; */
3888 #endif /* CONFIG_BR_EXT */
3890 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
3893 struct pkt_attrib *pattrib = &pxmitframe->attrib;
3895 switch (pattrib->qsel) {
3898 addr = BE_QUEUE_INX;
3902 addr = BK_QUEUE_INX;
3906 addr = VI_QUEUE_INX;
3910 addr = VO_QUEUE_INX;
3913 addr = BCN_QUEUE_INX;
3915 case 0x11: /* BC/MC in PS (HIQ) */
3916 addr = HIGH_QUEUE_INX;
3919 addr = TXCMD_QUEUE_INX;
3923 addr = MGT_QUEUE_INX;
3932 static void do_queue_select(_adapter *padapter, struct pkt_attrib *pattrib)
3936 qsel = pattrib->priority;
3937 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("### do_queue_select priority=%d ,qsel = %d\n", pattrib->priority , qsel));
3939 #ifdef CONFIG_CONCURRENT_MODE
3940 /* if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
3944 #ifdef CONFIG_MCC_MODE
3945 if (MCC_EN(padapter)) {
3947 if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC)) {
3948 if (padapter->mcc_adapterpriv.role == MCC_ROLE_GO
3949 || padapter->mcc_adapterpriv.role == MCC_ROLE_AP) {
3950 pattrib->qsel = QSLT_VO; /* AP interface VO queue */
3952 pattrib->qsel = QSLT_BE; /* STA interface BE queue */
3956 pattrib->qsel = qsel;
3958 /* Not enable MCC */
3959 pattrib->qsel = qsel;
3960 #else /* !CONFIG_MCC_MODE */
3961 pattrib->qsel = qsel;
3962 #endif /* CONFIG_MCC_MODE */
3966 * The main transmit(tx) entry
3970 * 0 success, hardware will handle this xmit frame(packet)
3973 s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
3978 int dot11_hdr_len = 24;
3980 unsigned char *pdata;
3982 unsigned char src_mac_addr[6];
3983 unsigned char dst_mac_addr[6];
3984 struct rtw_ieee80211_hdr *dot11_hdr;
3985 struct ieee80211_radiotap_header *rtap_hdr;
3986 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3989 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
3991 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
3994 rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
3995 if (unlikely(rtap_hdr->it_version))
3998 rtap_len = ieee80211_get_radiotap_len(skb->data);
3999 if (unlikely(skb->len < rtap_len))
4002 if (rtap_len != 12) {
4003 RTW_INFO("radiotap len (should be 14): %d\n", rtap_len);
4007 /* Skip the ratio tap header */
4008 skb_pull(skb, rtap_len);
4010 dot11_hdr = (struct rtw_ieee80211_hdr *)skb->data;
4011 frame_ctl = le16_to_cpu(dot11_hdr->frame_ctl);
4012 /* Check if the QoS bit is set */
4014 if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
4016 struct xmit_frame *pmgntframe;
4017 struct pkt_attrib *pattrib;
4018 unsigned char *pframe;
4019 struct rtw_ieee80211_hdr *pwlanhdr;
4020 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4021 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4022 u8 *buf = skb->data;
4024 u8 category, action;
4027 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4028 if (pmgntframe == NULL) {
4032 pattrib = &pmgntframe->attrib;
4034 update_monitor_frame_attrib(padapter, pattrib);
4036 pattrib->retry_ctrl = _FALSE;
4038 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4040 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4042 _rtw_memcpy(pframe, (void *)buf, len);
4044 pattrib->pktlen = len;
4046 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4048 if (is_broadcast_mac_addr(pwlanhdr->addr3) || is_broadcast_mac_addr(pwlanhdr->addr1))
4049 pattrib->rate = MGN_24M;
4051 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4052 pattrib->seqnum = pmlmeext->mgnt_seq;
4053 pmlmeext->mgnt_seq++;
4055 pattrib->last_txcmdsz = pattrib->pktlen;
4057 dump_mgntframe(padapter, pmgntframe);
4060 struct xmit_frame *pmgntframe;
4061 struct pkt_attrib *pattrib;
4062 unsigned char *pframe;
4063 struct rtw_ieee80211_hdr *pwlanhdr;
4064 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4065 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4066 u8 *buf = skb->data;
4068 u8 category, action;
4071 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4072 if (pmgntframe == NULL)
4075 pattrib = &pmgntframe->attrib;
4076 update_mgntframe_attrib(padapter, pattrib);
4077 pattrib->retry_ctrl = _FALSE;
4079 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4081 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4083 _rtw_memcpy(pframe, (void *)buf, len);
4085 pattrib->pktlen = len;
4087 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4089 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4090 pattrib->seqnum = pmlmeext->mgnt_seq;
4091 pmlmeext->mgnt_seq++;
4093 pattrib->last_txcmdsz = pattrib->pktlen;
4095 dump_mgntframe(padapter, pmgntframe);
4107 * The main transmit(tx) entry
4111 * 0 success, hardware will handle this xmit frame(packet)
4114 s32 rtw_xmit(_adapter *padapter, _pkt **ppkt)
4116 static u32 start = 0;
4117 static u32 drop_cnt = 0;
4118 #ifdef CONFIG_AP_MODE
4121 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4122 struct xmit_frame *pxmitframe = NULL;
4123 #ifdef CONFIG_BR_EXT
4124 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4125 void *br_port = NULL;
4126 #endif /* CONFIG_BR_EXT */
4130 DBG_COUNTER(padapter->tx_logs.core_tx);
4133 start = rtw_get_current_time();
4135 pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
4137 if (rtw_get_passing_time_ms(start) > 2000) {
4139 RTW_INFO("DBG_TX_DROP_FRAME %s no more pxmitframe, drop_cnt:%u\n", __FUNCTION__, drop_cnt);
4140 start = rtw_get_current_time();
4144 if (pxmitframe == NULL) {
4146 /*RTW_INFO("%s-"ADPT_FMT" no more xmitframe\n", __func__, ADPT_ARG(padapter));*/
4147 DBG_COUNTER(padapter->tx_logs.core_tx_err_pxmitframe);
4151 #ifdef CONFIG_BR_EXT
4153 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
4154 br_port = padapter->pnetdev->br_port;
4155 #else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
4157 br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
4159 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
4161 if (br_port && check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) {
4162 res = rtw_br_client_tx(padapter, ppkt);
4164 rtw_free_xmitframe(pxmitpriv, pxmitframe);
4165 DBG_COUNTER(padapter->tx_logs.core_tx_err_brtx);
4170 #endif /* CONFIG_BR_EXT */
4172 res = update_attrib(padapter, *ppkt, &pxmitframe->attrib);
4174 #ifdef CONFIG_MCC_MODE
4175 /* record data kernel TX to driver to check MCC concurrent TX */
4176 rtw_hal_mcc_calc_tx_bytes_from_kernel(padapter, pxmitframe->attrib.pktlen);
4177 #endif /* CONFIG_MCC_MODE */
4179 #ifdef CONFIG_WAPI_SUPPORT
4180 if (pxmitframe->attrib.ether_type != 0x88B4) {
4181 if (rtw_wapi_drop_for_key_absent(padapter, pxmitframe->attrib.ra)) {
4182 WAPI_TRACE(WAPI_RX, "drop for key absend when tx\n");
4188 /*RTW_INFO("%s-"ADPT_FMT" update attrib fail\n", __func__, ADPT_ARG(padapter));*/
4189 #ifdef DBG_TX_DROP_FRAME
4190 RTW_INFO("DBG_TX_DROP_FRAME %s update attrib fail\n", __FUNCTION__);
4192 rtw_free_xmitframe(pxmitpriv, pxmitframe);
4195 pxmitframe->pkt = *ppkt;
4197 rtw_led_control(padapter, LED_CTL_TX);
4199 do_queue_select(padapter, &pxmitframe->attrib);
4201 #ifdef CONFIG_AP_MODE
4202 _enter_critical_bh(&pxmitpriv->lock, &irqL0);
4203 if (xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE) {
4204 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
4205 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue);
4208 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
4212 if (rtw_hal_xmit(padapter, pxmitframe) == _FALSE)
4219 sint xmitframe_enqueue_for_tdls_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
4224 struct sta_info *ptdls_sta = NULL;
4225 struct sta_priv *pstapriv = &padapter->stapriv;
4226 struct pkt_attrib *pattrib = &pxmitframe->attrib;
4227 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4230 ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
4231 if (ptdls_sta == NULL)
4233 else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
4235 if (pattrib->triggered == 1) {
4240 _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
4242 if (ptdls_sta->state & WIFI_SLEEP_STATE) {
4243 rtw_list_delete(&pxmitframe->list);
4245 /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
4247 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptdls_sta->sleep_q));
4249 ptdls_sta->sleepq_len++;
4250 ptdls_sta->sleepq_ac_len++;
4252 /* indicate 4-AC queue bit in TDLS peer traffic indication */
4253 switch (pattrib->priority) {
4256 ptdls_sta->uapsd_bk |= BIT(1);
4260 ptdls_sta->uapsd_vi |= BIT(1);
4264 ptdls_sta->uapsd_vo |= BIT(1);
4269 ptdls_sta->uapsd_be |= BIT(1);
4273 /* Transmit TDLS PTI via AP */
4274 if (ptdls_sta->sleepq_len == 1)
4275 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ISSUE_PTI);
4280 _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
4286 #endif /* CONFIG_TDLS */
4288 #define RTW_HIQ_FILTER_ALLOW_ALL 0
4289 #define RTW_HIQ_FILTER_ALLOW_SPECIAL 1
4290 #define RTW_HIQ_FILTER_DENY_ALL 2
4292 inline bool xmitframe_hiq_filter(struct xmit_frame *xmitframe)
4294 bool allow = _FALSE;
4295 _adapter *adapter = xmitframe->padapter;
4296 struct registry_priv *registry = &adapter->registrypriv;
4298 if (rtw_get_intf_type(adapter) != RTW_PCIE) {
4300 if (adapter->registrypriv.wifi_spec == 1)
4302 else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_SPECIAL) {
4304 struct pkt_attrib *attrib = &xmitframe->attrib;
4306 if (attrib->ether_type == 0x0806
4307 || attrib->ether_type == 0x888e
4308 #ifdef CONFIG_WAPI_SUPPORT
4309 || attrib->ether_type == 0x88B4
4314 RTW_INFO(FUNC_ADPT_FMT" ether_type:0x%04x%s\n", FUNC_ADPT_ARG(xmitframe->padapter)
4315 , attrib->ether_type, attrib->dhcp_pkt ? " DHCP" : "");
4318 } else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_ALL)
4320 else if (registry->hiq_filter == RTW_HIQ_FILTER_DENY_ALL) {
4327 #if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS)
4329 sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
4333 struct sta_info *psta = NULL;
4334 struct sta_priv *pstapriv = &padapter->stapriv;
4335 struct pkt_attrib *pattrib = &pxmitframe->attrib;
4336 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4337 sint bmcst = IS_MCAST(pattrib->ra);
4338 bool update_tim = _FALSE;
4341 if (padapter->tdlsinfo.link_established == _TRUE)
4342 ret = xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pxmitframe);
4343 #endif /* CONFIG_TDLS */
4345 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _FALSE) {
4346 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_fwstate);
4352 psta = pattrib->psta;
4356 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
4357 psta=rtw_get_stainfo(pstapriv, pattrib->ra);
4360 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
4361 if (pattrib->psta != psta) {
4362 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_sta);
4363 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
4368 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_nosta);
4369 RTW_INFO("%s, psta==NUL\n", __func__);
4373 if (!(psta->state & _FW_LINKED)) {
4374 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_link);
4375 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
4379 if (pattrib->triggered == 1) {
4380 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_trigger);
4381 /* RTW_INFO("directly xmit pspoll_triggered packet\n"); */
4383 /* pattrib->triggered=0; */
4384 if (bmcst && xmitframe_hiq_filter(pxmitframe) == _TRUE)
4385 pattrib->qsel = QSLT_HIGH;/* HIQ */
4392 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
4394 if (pstapriv->sta_dz_bitmap) { /* if anyone sta is in ps mode */
4395 /* pattrib->qsel = QSLT_HIGH; */ /* HIQ */
4397 rtw_list_delete(&pxmitframe->list);
4399 /*_enter_critical_bh(&psta->sleep_q.lock, &irqL);*/
4401 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
4405 if (!(pstapriv->tim_bitmap & BIT(0)))
4408 pstapriv->tim_bitmap |= BIT(0);
4409 pstapriv->sta_dz_bitmap |= BIT(0);
4411 /* RTW_INFO("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
4412 if (update_tim == _TRUE) {
4413 if (is_broadcast_mac_addr(pattrib->ra))
4414 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer BC");
4416 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer MC");
4418 chk_bmc_sleepq_cmd(padapter);
4420 /*_exit_critical_bh(&psta->sleep_q.lock, &irqL);*/
4424 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_mcast);
4428 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
4435 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
4437 if (psta->state & WIFI_SLEEP_STATE) {
4440 if (pstapriv->sta_dz_bitmap & BIT(psta->aid)) {
4441 rtw_list_delete(&pxmitframe->list);
4443 /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
4445 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
4449 switch (pattrib->priority) {
4452 wmmps_ac = psta->uapsd_bk & BIT(0);
4456 wmmps_ac = psta->uapsd_vi & BIT(0);
4460 wmmps_ac = psta->uapsd_vo & BIT(0);
4465 wmmps_ac = psta->uapsd_be & BIT(0);
4470 psta->sleepq_ac_len++;
4472 if (((psta->has_legacy_ac) && (!wmmps_ac)) || ((!psta->has_legacy_ac) && (wmmps_ac))) {
4473 if (!(pstapriv->tim_bitmap & BIT(psta->aid)))
4476 pstapriv->tim_bitmap |= BIT(psta->aid);
4478 /* RTW_INFO("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
4480 if (update_tim == _TRUE) {
4481 /* RTW_INFO("sleepq_len==1, update BCNTIM\n"); */
4482 /* upate BCN for TIM IE */
4483 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer UC");
4487 /* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
4489 /* if(psta->sleepq_len > (NR_XMITFRAME>>3)) */
4491 /* wakeup_sta_to_xmit(padapter, psta); */
4496 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_ucast);
4501 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
4507 static void dequeue_xmitframes_to_sleeping_queue(_adapter *padapter, struct sta_info *psta, _queue *pframequeue)
4510 _list *plist, *phead;
4512 struct tx_servq *ptxservq;
4513 struct pkt_attrib *pattrib;
4514 struct xmit_frame *pxmitframe;
4515 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
4517 phead = get_list_head(pframequeue);
4518 plist = get_next(phead);
4520 while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
4521 pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
4523 plist = get_next(plist);
4525 pattrib = &pxmitframe->attrib;
4527 pattrib->triggered = 0;
4529 ret = xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
4532 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
4535 phwxmits[ac_index].accnt--;
4537 /* RTW_INFO("xmitframe_enqueue_for_sleeping_sta return _FALSE\n"); */
4544 void stop_sta_xmit(_adapter *padapter, struct sta_info *psta)
4547 struct sta_info *psta_bmc;
4548 struct sta_xmit_priv *pstaxmitpriv;
4549 struct sta_priv *pstapriv = &padapter->stapriv;
4550 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4552 pstaxmitpriv = &psta->sta_xmitpriv;
4554 /* for BC/MC Frames */
4555 psta_bmc = rtw_get_bcmc_stainfo(padapter);
4558 _enter_critical_bh(&pxmitpriv->lock, &irqL0);
4560 psta->state |= WIFI_SLEEP_STATE;
4563 if (!(psta->tdls_sta_state & TDLS_LINKED_STATE))
4564 #endif /* CONFIG_TDLS */
4565 pstapriv->sta_dz_bitmap |= BIT(psta->aid);
4569 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
4570 rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));
4573 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
4574 rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));
4577 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
4578 rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
4581 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
4582 rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));
4585 if (!(psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta_bmc != NULL)) {
4586 #endif /* CONFIG_TDLS */
4589 /* for BC/MC Frames */
4590 pstaxmitpriv = &psta_bmc->sta_xmitpriv;
4591 dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending);
4592 rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
4597 #endif /* CONFIG_TDLS */
4598 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
4603 void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta)
4606 u8 update_mask = 0, wmmps_ac = 0;
4607 struct sta_info *psta_bmc;
4608 _list *xmitframe_plist, *xmitframe_phead;
4609 struct xmit_frame *pxmitframe = NULL;
4610 struct sta_priv *pstapriv = &padapter->stapriv;
4611 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4613 psta_bmc = rtw_get_bcmc_stainfo(padapter);
4616 /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
4617 _enter_critical_bh(&pxmitpriv->lock, &irqL);
4619 xmitframe_phead = get_list_head(&psta->sleep_q);
4620 xmitframe_plist = get_next(xmitframe_phead);
4622 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
4623 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4625 xmitframe_plist = get_next(xmitframe_plist);
4627 rtw_list_delete(&pxmitframe->list);
4629 switch (pxmitframe->attrib.priority) {
4632 wmmps_ac = psta->uapsd_bk & BIT(1);
4636 wmmps_ac = psta->uapsd_vi & BIT(1);
4640 wmmps_ac = psta->uapsd_vo & BIT(1);
4645 wmmps_ac = psta->uapsd_be & BIT(1);
4650 if (psta->sleepq_len > 0)
4651 pxmitframe->attrib.mdata = 1;
4653 pxmitframe->attrib.mdata = 0;
4656 psta->sleepq_ac_len--;
4657 if (psta->sleepq_ac_len > 0) {
4658 pxmitframe->attrib.mdata = 1;
4659 pxmitframe->attrib.eosp = 0;
4661 pxmitframe->attrib.mdata = 0;
4662 pxmitframe->attrib.eosp = 1;
4666 pxmitframe->attrib.triggered = 1;
4669 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
4670 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
4672 rtw_os_xmit_complete(padapter, pxmitframe);
4674 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
4676 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
4681 if (psta->sleepq_len == 0) {
4683 if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
4684 if (psta->state & WIFI_SLEEP_STATE)
4685 psta->state ^= WIFI_SLEEP_STATE;
4687 _exit_critical_bh(&pxmitpriv->lock, &irqL);
4690 #endif /* CONFIG_TDLS */
4692 if (pstapriv->tim_bitmap & BIT(psta->aid)) {
4693 /* RTW_INFO("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); */
4694 /* upate BCN for TIM IE */
4695 /* update_BCNTIM(padapter); */
4696 update_mask = BIT(0);
4699 pstapriv->tim_bitmap &= ~BIT(psta->aid);
4701 if (psta->state & WIFI_SLEEP_STATE)
4702 psta->state ^= WIFI_SLEEP_STATE;
4704 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
4705 RTW_INFO("%s alive check\n", __func__);
4706 psta->expire_to = pstapriv->expire_to;
4707 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
4710 pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
4713 /* for BC/MC Frames */
4717 if ((pstapriv->sta_dz_bitmap & 0xfffe) == 0x0) { /* no any sta in ps mode */
4718 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
4719 xmitframe_plist = get_next(xmitframe_phead);
4721 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
4722 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4724 xmitframe_plist = get_next(xmitframe_plist);
4726 rtw_list_delete(&pxmitframe->list);
4728 psta_bmc->sleepq_len--;
4729 if (psta_bmc->sleepq_len > 0)
4730 pxmitframe->attrib.mdata = 1;
4732 pxmitframe->attrib.mdata = 0;
4735 pxmitframe->attrib.triggered = 1;
4737 _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
4738 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
4740 rtw_os_xmit_complete(padapter, pxmitframe);
4742 _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
4745 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
4749 if (psta_bmc->sleepq_len == 0) {
4750 if (pstapriv->tim_bitmap & BIT(0)) {
4751 /* RTW_INFO("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); */
4752 /* upate BCN for TIM IE */
4753 /* update_BCNTIM(padapter); */
4754 update_mask |= BIT(1);
4756 pstapriv->tim_bitmap &= ~BIT(0);
4757 pstapriv->sta_dz_bitmap &= ~BIT(0);
4764 /* _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); */
4765 _exit_critical_bh(&pxmitpriv->lock, &irqL);
4768 /* update_BCNTIM(padapter); */
4769 if ((update_mask & (BIT(0) | BIT(1))) == (BIT(0) | BIT(1)))
4770 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear UC&BMC");
4771 else if ((update_mask & BIT(1)) == BIT(1))
4772 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear BMC");
4774 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear UC");
4779 void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta)
4783 _list *xmitframe_plist, *xmitframe_phead;
4784 struct xmit_frame *pxmitframe = NULL;
4785 struct sta_priv *pstapriv = &padapter->stapriv;
4786 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4789 /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
4790 _enter_critical_bh(&pxmitpriv->lock, &irqL);
4792 xmitframe_phead = get_list_head(&psta->sleep_q);
4793 xmitframe_plist = get_next(xmitframe_phead);
4795 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
4796 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4798 xmitframe_plist = get_next(xmitframe_plist);
4800 switch (pxmitframe->attrib.priority) {
4803 wmmps_ac = psta->uapsd_bk & BIT(1);
4807 wmmps_ac = psta->uapsd_vi & BIT(1);
4811 wmmps_ac = psta->uapsd_vo & BIT(1);
4816 wmmps_ac = psta->uapsd_be & BIT(1);
4823 rtw_list_delete(&pxmitframe->list);
4826 psta->sleepq_ac_len--;
4828 if (psta->sleepq_ac_len > 0) {
4829 pxmitframe->attrib.mdata = 1;
4830 pxmitframe->attrib.eosp = 0;
4832 pxmitframe->attrib.mdata = 0;
4833 pxmitframe->attrib.eosp = 1;
4836 pxmitframe->attrib.triggered = 1;
4837 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
4839 if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) {
4841 if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
4842 /* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
4845 #endif /* CONFIG_TDLS */
4846 pstapriv->tim_bitmap &= ~BIT(psta->aid);
4848 /* RTW_INFO("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); */
4849 /* upate BCN for TIM IE */
4850 /* update_BCNTIM(padapter); */
4851 update_beacon(padapter, _TIM_IE_, NULL, _TRUE);
4852 /* update_mask = BIT(0); */
4858 /* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
4859 _exit_critical_bh(&pxmitpriv->lock, &irqL);
4864 #endif /* defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) */
4866 #ifdef CONFIG_XMIT_THREAD_MODE
4867 void enqueue_pending_xmitbuf(
4868 struct xmit_priv *pxmitpriv,
4869 struct xmit_buf *pxmitbuf)
4873 _adapter *pri_adapter = pxmitpriv->adapter;
4875 pqueue = &pxmitpriv->pending_xmitbuf_queue;
4877 _enter_critical_bh(&pqueue->lock, &irql);
4878 rtw_list_delete(&pxmitbuf->list);
4879 rtw_list_insert_tail(&pxmitbuf->list, get_list_head(pqueue));
4880 _exit_critical_bh(&pqueue->lock, &irql);
4882 #if defined(CONFIG_SDIO_HCI) && defined(CONFIG_CONCURRENT_MODE)
4883 pri_adapter = GET_PRIMARY_ADAPTER(pri_adapter);
4884 #endif /*SDIO_HCI + CONCURRENT*/
4885 _rtw_up_sema(&(pri_adapter->xmitpriv.xmit_sema));
4888 void enqueue_pending_xmitbuf_to_head(
4889 struct xmit_priv *pxmitpriv,
4890 struct xmit_buf *pxmitbuf)
4893 _queue *pqueue = &pxmitpriv->pending_xmitbuf_queue;
4895 _enter_critical_bh(&pqueue->lock, &irql);
4896 rtw_list_delete(&pxmitbuf->list);
4897 rtw_list_insert_head(&pxmitbuf->list, get_list_head(pqueue));
4898 _exit_critical_bh(&pqueue->lock, &irql);
4901 struct xmit_buf *dequeue_pending_xmitbuf(
4902 struct xmit_priv *pxmitpriv)
4905 struct xmit_buf *pxmitbuf;
4910 pqueue = &pxmitpriv->pending_xmitbuf_queue;
4912 _enter_critical_bh(&pqueue->lock, &irql);
4914 if (_rtw_queue_empty(pqueue) == _FALSE) {
4915 _list *plist, *phead;
4917 phead = get_list_head(pqueue);
4918 plist = get_next(phead);
4919 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
4920 rtw_list_delete(&pxmitbuf->list);
4923 _exit_critical_bh(&pqueue->lock, &irql);
4928 struct xmit_buf *dequeue_pending_xmitbuf_under_survey(
4929 struct xmit_priv *pxmitpriv)
4932 struct xmit_buf *pxmitbuf;
4933 #ifdef CONFIG_USB_HCI
4934 struct xmit_frame *pxmitframe;
4940 pqueue = &pxmitpriv->pending_xmitbuf_queue;
4942 _enter_critical_bh(&pqueue->lock, &irql);
4944 if (_rtw_queue_empty(pqueue) == _FALSE) {
4945 _list *plist, *phead;
4948 phead = get_list_head(pqueue);
4951 plist = get_next(plist);
4955 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
4957 #ifdef CONFIG_USB_HCI
4958 pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
4960 type = GetFrameSubType(pxmitbuf->pbuf + TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
4962 RTW_INFO("%s, !!!ERROR!!! For USB, TODO ITEM\n", __FUNCTION__);
4964 type = GetFrameSubType(pxmitbuf->pbuf + TXDESC_OFFSET);
4967 if ((type == WIFI_PROBEREQ) ||
4968 (type == WIFI_DATA_NULL) ||
4969 (type == WIFI_QOS_DATA_NULL)) {
4970 rtw_list_delete(&pxmitbuf->list);
4977 _exit_critical_bh(&pqueue->lock, &irql);
4982 sint check_pending_xmitbuf(
4983 struct xmit_priv *pxmitpriv)
4989 pqueue = &pxmitpriv->pending_xmitbuf_queue;
4991 _enter_critical_bh(&pqueue->lock, &irql);
4993 if (_rtw_queue_empty(pqueue) == _FALSE)
4996 _exit_critical_bh(&pqueue->lock, &irql);
5001 thread_return rtw_xmit_thread(thread_context context)
5008 padapter = (PADAPTER)context;
5010 thread_enter("RTW_XMIT_THREAD");
5013 err = rtw_hal_xmit_thread_handler(padapter);
5014 flush_signals_thread();
5015 } while (_SUCCESS == err);
5017 _rtw_up_sema(&padapter->xmitpriv.terminate_xmitthread_sema);
5023 bool rtw_xmit_ac_blocked(_adapter *adapter)
5025 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5027 struct mlme_ext_priv *mlmeext;
5028 struct mlme_ext_info *mlmeextinfo;
5029 bool blocked = _FALSE;
5032 for (i = 0; i < dvobj->iface_nums; i++) {
5033 iface = dvobj->padapters[i];
5034 mlmeext = &iface->mlmeextpriv;
5036 /* check scan state */
5037 if (mlmeext_scan_state(mlmeext) != SCAN_DISABLE
5038 && mlmeext_scan_state(mlmeext) != SCAN_BACK_OP
5044 if (mlmeext_scan_state(mlmeext) == SCAN_BACK_OP
5045 && !mlmeext_chk_scan_backop_flags(mlmeext, SS_BACKOP_TX_RESUME)
5052 #ifdef CONFIG_MCC_MODE
5053 if (MCC_EN(adapter)) {
5054 if (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC)) {
5055 if (MCC_STOP(adapter)) {
5061 #endif /* CONFIG_MCC_MODE */
5068 void rtw_amsdu_vo_timeout_handler(void *FunctionContext)
5070 _adapter *adapter = (_adapter *)FunctionContext;
5072 adapter->xmitpriv.amsdu_vo_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5074 tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5076 void rtw_amsdu_vi_timeout_handler(void *FunctionContext)
5078 _adapter *adapter = (_adapter *)FunctionContext;
5080 adapter->xmitpriv.amsdu_vi_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5082 tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5084 void rtw_amsdu_be_timeout_handler(void *FunctionContext)
5086 _adapter *adapter = (_adapter *)FunctionContext;
5088 adapter->xmitpriv.amsdu_be_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5090 if (printk_ratelimit())
5091 RTW_INFO("%s Timeout!\n",__FUNCTION__);
5093 tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5095 void rtw_amsdu_bk_timeout_handler(void *FunctionContext)
5097 _adapter *adapter = (_adapter *)FunctionContext;
5099 adapter->xmitpriv.amsdu_bk_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5101 tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5104 u8 rtw_amsdu_get_timer_status(_adapter *padapter, u8 priority)
5106 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5108 u8 status = RTW_AMSDU_TIMER_UNSET;
5114 status = pxmitpriv->amsdu_bk_timeout;
5118 status = pxmitpriv->amsdu_vi_timeout;
5122 status = pxmitpriv->amsdu_vo_timeout;
5127 status = pxmitpriv->amsdu_be_timeout;
5132 void rtw_amsdu_set_timer_status(_adapter *padapter, u8 priority, u8 status)
5134 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5140 pxmitpriv->amsdu_bk_timeout = status;
5144 pxmitpriv->amsdu_vi_timeout = status;
5148 pxmitpriv->amsdu_vo_timeout = status;
5153 pxmitpriv->amsdu_be_timeout = status;
5157 void rtw_amsdu_set_timer(_adapter *padapter, u8 priority)
5159 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5161 _timer* amsdu_timer = NULL;
5167 amsdu_timer = &pxmitpriv->amsdu_bk_timer;
5171 amsdu_timer = &pxmitpriv->amsdu_vi_timer;
5175 amsdu_timer = &pxmitpriv->amsdu_vo_timer;
5180 amsdu_timer = &pxmitpriv->amsdu_be_timer;
5183 _set_timer(amsdu_timer, 1);
5185 void rtw_amsdu_cancel_timer(_adapter *padapter, u8 priority)
5187 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5188 _timer* amsdu_timer = NULL;
5195 amsdu_timer = &pxmitpriv->amsdu_bk_timer;
5199 amsdu_timer = &pxmitpriv->amsdu_vi_timer;
5203 amsdu_timer = &pxmitpriv->amsdu_vo_timer;
5208 amsdu_timer = &pxmitpriv->amsdu_be_timer;
5211 _cancel_timer(amsdu_timer, &cancel);
5215 void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms)
5217 sctx->timeout_ms = timeout_ms;
5218 sctx->submit_time = rtw_get_current_time();
5219 #ifdef PLATFORM_LINUX /* TODO: add condition wating interface for other os */
5220 init_completion(&sctx->done);
5222 sctx->status = RTW_SCTX_SUBMITTED;
5225 int rtw_sctx_wait(struct submit_ctx *sctx, const char *msg)
5228 unsigned long expire;
5231 #ifdef PLATFORM_LINUX
5232 expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT;
5233 if (!wait_for_completion_timeout(&sctx->done, expire)) {
5234 /* timeout, do something?? */
5235 status = RTW_SCTX_DONE_TIMEOUT;
5236 RTW_INFO("%s timeout: %s\n", __func__, msg);
5238 status = sctx->status;
5241 if (status == RTW_SCTX_DONE_SUCCESS)
5247 bool rtw_sctx_chk_waring_status(int status)
5250 case RTW_SCTX_DONE_UNKNOWN:
5251 case RTW_SCTX_DONE_BUF_ALLOC:
5252 case RTW_SCTX_DONE_BUF_FREE:
5254 case RTW_SCTX_DONE_DRV_STOP:
5255 case RTW_SCTX_DONE_DEV_REMOVE:
5262 void rtw_sctx_done_err(struct submit_ctx **sctx, int status)
5265 if (rtw_sctx_chk_waring_status(status))
5266 RTW_INFO("%s status:%d\n", __func__, status);
5267 (*sctx)->status = status;
5268 #ifdef PLATFORM_LINUX
5269 complete(&((*sctx)->done));
5275 void rtw_sctx_done(struct submit_ctx **sctx)
5277 rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS);
5280 #ifdef CONFIG_XMIT_ACK
5282 #ifdef CONFIG_XMIT_ACK_POLLING
5283 s32 c2h_evt_hdl(_adapter *adapter, u8 *c2h_evt, c2h_id_filter filter);
5286 * rtw_ack_tx_polling -
5287 * @pxmitpriv: xmit_priv to address ack_tx_ops
5288 * @timeout_ms: timeout msec
5290 * Init ack_tx_ops and then do c2h_evt_hdl() and polling ack_tx_ops repeatedly
5291 * till tx report or timeout
5292 * Returns: _SUCCESS if TX report ok, _FAIL for others
5294 int rtw_ack_tx_polling(struct xmit_priv *pxmitpriv, u32 timeout_ms)
5297 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
5298 _adapter *adapter = container_of(pxmitpriv, _adapter, xmitpriv);
5300 pack_tx_ops->submit_time = rtw_get_current_time();
5301 pack_tx_ops->timeout_ms = timeout_ms;
5302 pack_tx_ops->status = RTW_SCTX_SUBMITTED;
5305 c2h_evt_hdl(adapter, NULL, rtw_hal_c2h_id_filter_ccx(adapter));
5306 if (pack_tx_ops->status != RTW_SCTX_SUBMITTED)
5309 if (rtw_is_drv_stopped(adapter)) {
5310 pack_tx_ops->status = RTW_SCTX_DONE_DRV_STOP;
5313 if (rtw_is_surprise_removed(adapter)) {
5314 pack_tx_ops->status = RTW_SCTX_DONE_DEV_REMOVE;
5319 } while (rtw_get_passing_time_ms(pack_tx_ops->submit_time) < timeout_ms);
5321 if (pack_tx_ops->status == RTW_SCTX_SUBMITTED) {
5322 pack_tx_ops->status = RTW_SCTX_DONE_TIMEOUT;
5323 RTW_INFO("%s timeout\n", __func__);
5326 if (pack_tx_ops->status == RTW_SCTX_DONE_SUCCESS)
5333 int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
5335 #ifdef CONFIG_XMIT_ACK_POLLING
5336 return rtw_ack_tx_polling(pxmitpriv, timeout_ms);
5338 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
5340 pack_tx_ops->submit_time = rtw_get_current_time();
5341 pack_tx_ops->timeout_ms = timeout_ms;
5342 pack_tx_ops->status = RTW_SCTX_SUBMITTED;
5344 return rtw_sctx_wait(pack_tx_ops, __func__);
5348 void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)
5350 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
5352 if (pxmitpriv->ack_tx)
5353 rtw_sctx_done_err(&pack_tx_ops, status);
5355 RTW_INFO("%s ack_tx not set\n", __func__);
5357 #endif /* CONFIG_XMIT_ACK */