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 ******************************************************************************/
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <rtw_byteorder.h>
27 #include <osdep_intf.h>
31 #if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
32 #error "Shall be Linux or Windows, but not both!\n"
35 #ifdef PLATFORM_WINDOWS
44 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
45 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
47 static void _init_txservq(struct tx_servq *ptxservq)
50 _rtw_init_listhead(&ptxservq->tx_pending);
51 _rtw_init_queue(&ptxservq->sta_pending);
57 void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
62 _rtw_memset((unsigned char *)psta_xmitpriv, 0, sizeof (struct sta_xmit_priv));
64 _rtw_spinlock_init(&psta_xmitpriv->lock);
66 //for(i = 0 ; i < MAX_NUMBLKS; i++)
67 // _init_txservq(&(psta_xmitpriv->blk_q[i]));
69 _init_txservq(&psta_xmitpriv->be_q);
70 _init_txservq(&psta_xmitpriv->bk_q);
71 _init_txservq(&psta_xmitpriv->vi_q);
72 _init_txservq(&psta_xmitpriv->vo_q);
73 _rtw_init_listhead(&psta_xmitpriv->legacy_dz);
74 _rtw_init_listhead(&psta_xmitpriv->apsd);
80 s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter)
83 struct xmit_buf *pxmitbuf;
84 struct xmit_frame *pxframe;
86 u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
87 u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
89 #if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_RTL8723A)
90 if (padapter->registrypriv.mp_mode) {
91 max_xmit_extbuf_size = 6000;
98 // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
99 //_rtw_memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
101 _rtw_spinlock_init(&pxmitpriv->lock);
102 _rtw_spinlock_init(&pxmitpriv->lock_sctx);
103 _rtw_init_sema(&pxmitpriv->xmit_sema, 0);
104 _rtw_init_sema(&pxmitpriv->terminate_xmitthread_sema, 0);
107 Please insert all the queue initializaiton using _rtw_init_queue below
110 pxmitpriv->adapter = padapter;
112 //for(i = 0 ; i < MAX_NUMBLKS; i++)
113 // _rtw_init_queue(&pxmitpriv->blk_strms[i]);
115 _rtw_init_queue(&pxmitpriv->be_pending);
116 _rtw_init_queue(&pxmitpriv->bk_pending);
117 _rtw_init_queue(&pxmitpriv->vi_pending);
118 _rtw_init_queue(&pxmitpriv->vo_pending);
119 _rtw_init_queue(&pxmitpriv->bm_pending);
121 //_rtw_init_queue(&pxmitpriv->legacy_dz_queue);
122 //_rtw_init_queue(&pxmitpriv->apsd_queue);
124 _rtw_init_queue(&pxmitpriv->free_xmit_queue);
127 Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
128 and initialize free_xmit_frame below.
129 Please also apply free_txobj to link_up all the xmit_frames...
132 pxmitpriv->pallocated_frame_buf = rtw_zvmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
134 if (pxmitpriv->pallocated_frame_buf == NULL){
135 pxmitpriv->pxmit_frame_buf =NULL;
136 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_frame fail!\n"));
140 pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_frame_buf), 4);
141 //pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 -
142 // ((SIZE_PTR) (pxmitpriv->pallocated_frame_buf) &3);
144 pxframe = (struct xmit_frame*) pxmitpriv->pxmit_frame_buf;
146 for (i = 0; i < NR_XMITFRAME; i++)
148 _rtw_init_listhead(&(pxframe->list));
150 pxframe->padapter = padapter;
151 pxframe->frame_tag = NULL_FRAMETAG;
155 pxframe->buf_addr = NULL;
156 pxframe->pxmitbuf = NULL;
158 rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue));
163 pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
165 pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
169 _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue);
170 _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue);
172 pxmitpriv->pallocated_xmitbuf = rtw_zvmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
174 if (pxmitpriv->pallocated_xmitbuf == NULL){
175 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_buf fail!\n"));
180 pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmitbuf), 4);
181 //pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
182 // ((SIZE_PTR) (pxmitpriv->pallocated_xmitbuf) &3);
184 pxmitbuf = (struct xmit_buf*)pxmitpriv->pxmitbuf;
186 for (i = 0; i < NR_XMITBUFF; i++)
188 _rtw_init_listhead(&pxmitbuf->list);
190 pxmitbuf->priv_data = NULL;
191 pxmitbuf->padapter = padapter;
192 pxmitbuf->ext_tag = _FALSE;
195 pxmitbuf->pallocated_buf = rtw_zmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ);
196 if (pxmitbuf->pallocated_buf == NULL)
202 pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ);
203 //pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -((SIZE_PTR) (pxmitbuf->pallocated_buf) &(XMITBUF_ALIGN_SZ-1));
205 /* Tx buf allocation may fail sometimes, so sleep and retry. */
206 if((res=rtw_os_xmit_resource_alloc(padapter, pxmitbuf,(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ))) == _FAIL) {
208 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf,(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
214 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
215 pxmitbuf->phead = pxmitbuf->pbuf;
216 pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMITBUF_SZ;
218 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
221 pxmitbuf->flags = XMIT_VO_QUEUE;
223 rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue));
232 pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
234 /* init xframe_ext queue, the same count as extbuf */
235 _rtw_init_queue(&pxmitpriv->free_xframe_ext_queue);
237 pxmitpriv->xframe_ext_alloc_addr = rtw_zvmalloc(num_xmit_extbuf * sizeof(struct xmit_frame) + 4);
239 if (pxmitpriv->xframe_ext_alloc_addr == NULL){
240 pxmitpriv->xframe_ext = NULL;
241 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xframe_ext fail!\n"));
245 pxmitpriv->xframe_ext = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->xframe_ext_alloc_addr), 4);
246 pxframe = (struct xmit_frame*)pxmitpriv->xframe_ext;
248 for (i = 0; i < num_xmit_extbuf; i++) {
249 _rtw_init_listhead(&(pxframe->list));
251 pxframe->padapter = padapter;
252 pxframe->frame_tag = NULL_FRAMETAG;
256 pxframe->buf_addr = NULL;
257 pxframe->pxmitbuf = NULL;
259 pxframe->ext_tag = 1;
261 rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xframe_ext_queue.queue));
265 pxmitpriv->free_xframe_ext_cnt = num_xmit_extbuf;
267 // Init xmit extension buff
268 _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
270 pxmitpriv->pallocated_xmit_extbuf = rtw_zvmalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4);
272 if (pxmitpriv->pallocated_xmit_extbuf == NULL){
273 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_extbuf fail!\n"));
278 pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmit_extbuf), 4);
280 pxmitbuf = (struct xmit_buf*)pxmitpriv->pxmit_extbuf;
282 for (i = 0; i < num_xmit_extbuf; i++)
284 _rtw_init_listhead(&pxmitbuf->list);
286 pxmitbuf->priv_data = NULL;
287 pxmitbuf->padapter = padapter;
288 pxmitbuf->ext_tag = _TRUE;
291 pxmitbuf->pallocated_buf = rtw_zmalloc(max_xmit_extbuf_size);
292 if (pxmitbuf->pallocated_buf == NULL)
298 pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), 4);
301 if((res=rtw_os_xmit_resource_alloc(padapter, pxmitbuf,max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)) == _FAIL) {
306 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
307 pxmitbuf->phead = pxmitbuf->pbuf;
308 pxmitbuf->pend = pxmitbuf->pbuf + max_xmit_extbuf_size;
310 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
313 rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue));
314 #ifdef DBG_XMIT_BUF_EXT
321 pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
323 rtw_alloc_hwxmits(padapter);
324 rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
326 for (i = 0; i < 4; i ++)
328 pxmitpriv->wmm_para_seq[i] = i;
331 #ifdef CONFIG_USB_HCI
332 pxmitpriv->txirp_cnt=1;
334 _rtw_init_sema(&(pxmitpriv->tx_retevt), 0);
337 pxmitpriv->beq_cnt = 0;
338 pxmitpriv->bkq_cnt = 0;
339 pxmitpriv->viq_cnt = 0;
340 pxmitpriv->voq_cnt = 0;
344 #ifdef CONFIG_XMIT_ACK
345 pxmitpriv->ack_tx = _FALSE;
346 _rtw_mutex_init(&pxmitpriv->ack_tx_mutex);
347 rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0);
350 rtw_hal_init_xmit_priv(padapter);
359 void rtw_mfree_xmit_priv_lock (struct xmit_priv *pxmitpriv);
360 void rtw_mfree_xmit_priv_lock (struct xmit_priv *pxmitpriv)
362 _rtw_spinlock_free(&pxmitpriv->lock);
363 _rtw_free_sema(&pxmitpriv->xmit_sema);
364 _rtw_free_sema(&pxmitpriv->terminate_xmitthread_sema);
366 _rtw_spinlock_free(&pxmitpriv->be_pending.lock);
367 _rtw_spinlock_free(&pxmitpriv->bk_pending.lock);
368 _rtw_spinlock_free(&pxmitpriv->vi_pending.lock);
369 _rtw_spinlock_free(&pxmitpriv->vo_pending.lock);
370 _rtw_spinlock_free(&pxmitpriv->bm_pending.lock);
372 //_rtw_spinlock_free(&pxmitpriv->legacy_dz_queue.lock);
373 //_rtw_spinlock_free(&pxmitpriv->apsd_queue.lock);
375 _rtw_spinlock_free(&pxmitpriv->free_xmit_queue.lock);
376 _rtw_spinlock_free(&pxmitpriv->free_xmitbuf_queue.lock);
377 _rtw_spinlock_free(&pxmitpriv->pending_xmitbuf_queue.lock);
381 void _rtw_free_xmit_priv (struct xmit_priv *pxmitpriv)
384 _adapter *padapter = pxmitpriv->adapter;
385 struct xmit_frame *pxmitframe = (struct xmit_frame*) pxmitpriv->pxmit_frame_buf;
386 struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
387 u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
388 u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
390 #if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_RTL8723A)
391 if (padapter->registrypriv.mp_mode) {
392 max_xmit_extbuf_size = 6000;
399 rtw_hal_free_xmit_priv(padapter);
401 rtw_mfree_xmit_priv_lock(pxmitpriv);
403 if(pxmitpriv->pxmit_frame_buf==NULL)
406 for(i=0; i<NR_XMITFRAME; i++)
408 rtw_os_xmit_complete(padapter, pxmitframe);
413 for(i=0; i<NR_XMITBUFF; i++)
415 rtw_os_xmit_resource_free(padapter, pxmitbuf,(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
417 //if(pxmitbuf->pallocated_buf)
418 // rtw_mfree(pxmitbuf->pallocated_buf, MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ);
423 if(pxmitpriv->pallocated_frame_buf) {
424 rtw_vmfree(pxmitpriv->pallocated_frame_buf, NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
428 if(pxmitpriv->pallocated_xmitbuf) {
429 rtw_vmfree(pxmitpriv->pallocated_xmitbuf, NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
432 /* free xframe_ext queue, the same count as extbuf */
433 if ((pxmitframe = (struct xmit_frame*)pxmitpriv->xframe_ext)) {
434 for (i=0; i<num_xmit_extbuf; i++) {
435 rtw_os_xmit_complete(padapter, pxmitframe);
439 if (pxmitpriv->xframe_ext_alloc_addr)
440 rtw_vmfree(pxmitpriv->xframe_ext_alloc_addr, num_xmit_extbuf * sizeof(struct xmit_frame) + 4);
441 _rtw_spinlock_free(&pxmitpriv->free_xframe_ext_queue.lock);
443 // free xmit extension buff
444 _rtw_spinlock_free(&pxmitpriv->free_xmit_extbuf_queue.lock);
446 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
447 for(i=0; i<num_xmit_extbuf; i++)
449 rtw_os_xmit_resource_free(padapter, pxmitbuf,(max_xmit_extbuf_size + XMITBUF_ALIGN_SZ));
451 //if(pxmitbuf->pallocated_buf)
452 // rtw_mfree(pxmitbuf->pallocated_buf, max_xmit_extbuf_size);
457 if(pxmitpriv->pallocated_xmit_extbuf) {
458 rtw_vmfree(pxmitpriv->pallocated_xmit_extbuf, num_xmit_extbuf * sizeof(struct xmit_buf) + 4);
461 rtw_free_hwxmits(padapter);
463 #ifdef CONFIG_XMIT_ACK
464 _rtw_mutex_free(&pxmitpriv->ack_tx_mutex);
473 static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe)
476 struct pkt_attrib *pattrib = &pxmitframe->attrib;
477 struct sta_info *psta = pattrib->psta;
478 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
479 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
483 psta = pattrib->psta;
487 DBG_871X("%s, call rtw_get_stainfo()\n", __func__);
488 psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] );
493 DBG_871X("%s, psta==NUL\n", __func__);
497 if(!(psta->state &_FW_LINKED))
499 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
503 if (pattrib->nr_frags != 1)
505 sz = padapter->xmitpriv.frag_len;
509 sz = pattrib->last_txcmdsz;
512 // (1) RTS_Threshold is compared to the MPDU, not MSDU.
513 // (2) If there are more than one frag in this MSDU, only the first frag uses protection frame.
514 // Other fragments are protected by previous fragment.
515 // So we only need to check the length of first fragment.
516 if(pmlmeext->cur_wireless_mode < WIRELESS_11_24N || padapter->registrypriv.wifi_spec)
518 if(sz > padapter->registrypriv.rts_thresh)
520 pattrib->vcs_mode = RTS_CTS;
525 pattrib->vcs_mode = RTS_CTS;
526 else if(psta->cts2self)
527 pattrib->vcs_mode = CTS_TO_SELF;
529 pattrib->vcs_mode = NONE_VCS;
538 if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
540 pattrib->vcs_mode = CTS_TO_SELF;
541 pattrib->rts_rate = MGN_24M;
544 else if(pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE))
546 pattrib->vcs_mode = RTS_CTS;
547 pattrib->rts_rate = MGN_24M;
553 if((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && (pattrib->ampdu_en==_TRUE) &&
554 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_ ))
556 pattrib->vcs_mode = CTS_TO_SELF;
561 //check ERP protection
562 if(psta->rtsen || psta->cts2self)
565 pattrib->vcs_mode = RTS_CTS;
566 else if(psta->cts2self)
567 pattrib->vcs_mode = CTS_TO_SELF;
575 u8 HTOpMode = pmlmeinfo->HT_protection;
576 if((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) ||
577 (!pmlmeext->cur_bwmode && HTOpMode == 3) )
579 pattrib->vcs_mode = RTS_CTS;
585 if(sz > padapter->registrypriv.rts_thresh)
587 pattrib->vcs_mode = RTS_CTS;
591 //to do list: check MIMO power save condition.
593 //check AMPDU aggregation for TXOP
594 if(pattrib->ampdu_en==_TRUE)
596 pattrib->vcs_mode = RTS_CTS;
600 pattrib->vcs_mode = NONE_VCS;
606 static void update_attrib_phy_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
608 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
611 pattrib->vcs_mode = RTS_CTS;
612 else if(psta->cts2self)
613 pattrib->vcs_mode = CTS_TO_SELF;
615 pattrib->vcs_mode = NONE_VCS;*/
619 pattrib->triggered=0;
621 //qos_en, ht_en, init rate, ,bw, ch_offset, sgi
622 pattrib->qos_en = psta->qos_option;
624 pattrib->raid = psta->raid;
625 #ifdef CONFIG_80211N_HT
626 pattrib->ht_en = psta->htpriv.ht_option;
627 if (mlmeext->cur_bwmode < psta->htpriv.bwmode)
628 pattrib->bwmode = mlmeext->cur_bwmode;
630 pattrib->bwmode = psta->htpriv.bwmode;
631 pattrib->ch_offset = psta->htpriv.ch_offset;
632 pattrib->sgi= psta->htpriv.sgi;
633 pattrib->ampdu_en = _FALSE;
634 #endif //CONFIG_80211N_HT
635 //if(pattrib->ht_en && psta->htpriv.ampdu_enable)
637 // if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
638 // pattrib->ampdu_en = _TRUE;
642 pattrib->retry_ctrl = _FALSE;
646 u8 qos_acm(u8 acm_mask, u8 priority)
648 u8 change_priority = priority;
654 if(acm_mask & BIT(1))
662 if(acm_mask & BIT(2))
667 if(acm_mask & BIT(3))
671 DBG_871X("qos_acm(): invalid pattrib->priority: %d!!!\n", priority);
675 return change_priority;
678 static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
680 struct ethhdr etherhdr;
682 s32 UserPriority = 0;
685 _rtw_open_pktfile(ppktfile->pkt, ppktfile);
686 _rtw_pktfile_read(ppktfile, (unsigned char*)ðerhdr, ETH_HLEN);
688 // get UserPriority from IP hdr
689 if (pattrib->ether_type == 0x0800) {
690 _rtw_pktfile_read(ppktfile, (u8*)&ip_hdr, sizeof(ip_hdr));
691 // UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3;
692 UserPriority = ip_hdr.tos >> 5;
693 } else if (pattrib->ether_type == 0x888e) {
694 // "When priority processing of data frames is supported,
695 // a STA's SME should send EAPOL-Key frames at the highest priority."
699 pattrib->priority = UserPriority;
700 pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
701 pattrib->subtype = WIFI_QOS_DATA_TYPE;
704 static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib)
707 struct pkt_file pktfile;
708 struct sta_info *psta = NULL;
709 struct ethhdr etherhdr;
712 struct sta_priv *pstapriv = &padapter->stapriv;
713 struct security_priv *psecuritypriv = &padapter->securitypriv;
714 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
715 struct qos_priv *pqospriv= &pmlmepriv->qospriv;
720 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib);
722 _rtw_open_pktfile(pkt, &pktfile);
723 i = _rtw_pktfile_read(&pktfile, (u8*)ðerhdr, ETH_HLEN);
725 pattrib->ether_type = ntohs(etherhdr.h_proto);
728 _rtw_memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN);
729 _rtw_memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN);
733 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
734 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
735 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
736 _rtw_memcpy(pattrib->ta, myid(&padapter->eeprompriv), ETH_ALEN);
737 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_adhoc);
739 else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
740 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
741 _rtw_memcpy(pattrib->ta, myid(&padapter->eeprompriv), ETH_ALEN);
742 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_sta);
744 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
745 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
746 _rtw_memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
747 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_ap);
750 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_unknown);
752 pattrib->pktlen = pktfile.pkt_len;
754 if (ETH_P_IP == pattrib->ether_type)
756 // The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time
757 // to prevent DHCP protocol fail
759 _rtw_pktfile_read(&pktfile, &tmp[0], 24);
760 pattrib->dhcp_pkt = 0;
761 if (pktfile.pkt_len > 282) {//MINIMUM_DHCP_PACKET_SIZE) {
762 if (ETH_P_IP == pattrib->ether_type) {// IP header
763 if (((tmp[21] == 68) && (tmp[23] == 67)) ||
764 ((tmp[21] == 67) && (tmp[23] == 68))) {
765 // 68 : UDP BOOTP client
766 // 67 : UDP BOOTP server
767 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("======================update_attrib: get DHCP Packet \n"));
768 // Use low rate to send DHCP packet.
769 //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
771 // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m
772 // tcb_desc->bTxDisableRateFallBack = false;
775 // pTcb->DataRate = Adapter->MgntInfo.LowestBasicRate;
776 //RTPRINT(FDM, WA_IOT, ("DHCP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate));
777 pattrib->dhcp_pkt = 1;
778 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_dhcp);
782 } else if (0x888e == pattrib->ether_type) {
783 DBG_871X_LEVEL(_drv_always_, "send eapol packet\n");
786 if ( (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) )
788 rtw_set_scan_deny(padapter, 3000);
792 // If EAPOL , ARP , OR DHCP packet, driver must be in active mode.
793 #ifdef CONFIG_WAPI_SUPPORT
794 if ( (pattrib->ether_type == 0x88B4) || (pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) )
796 if ( (pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) )
799 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_active);
800 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
804 bmcast = IS_MCAST(pattrib->ra);
808 psta = rtw_get_bcmc_stainfo(padapter);
810 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
811 if (psta == NULL) { // if we cannot get psta => drrp the pkt
812 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_sta);
813 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT"\n", MAC_ARG(pattrib->ra)));
814 #ifdef DBG_TX_DROP_FRAME
815 DBG_871X("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __FUNCTION__, MAC_ARG(pattrib->ra));
820 else if((check_fwstate(pmlmepriv, WIFI_AP_STATE)==_TRUE)&&(!(psta->state & _FW_LINKED)))
822 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_ap_link);
830 pattrib->mac_id = psta->mac_id;
831 //DBG_8192C("%s ==> mac_id(%d)\n",__FUNCTION__,pattrib->mac_id );
832 pattrib->psta = psta;
836 // if we cannot get psta => drop the pkt
837 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sta);
838 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT "\n", MAC_ARG(pattrib->ra)));
839 #ifdef DBG_TX_DROP_FRAME
840 DBG_871X("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __FUNCTION__, MAC_ARG(pattrib->ra));
846 pattrib->ack_policy = 0;
848 pattrib->pkt_hdrlen = ETH_HLEN;//(pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; //vlan tag
850 pattrib->hdrlen = WLAN_HDR_A3_LEN;
851 pattrib->subtype = WIFI_DATA_TYPE;
852 pattrib->priority = 0;
854 if (check_fwstate(pmlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
857 set_qos(&pktfile, pattrib);
861 if(pqospriv->qos_option)
863 set_qos(&pktfile, pattrib);
865 if(pmlmepriv->acm_mask != 0)
867 pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority);
872 //pattrib->priority = 5; //force to used VI queue, for testing
874 if (psta->ieee8021x_blocked == _TRUE)
876 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\n psta->ieee8021x_blocked == _TRUE \n"));
878 pattrib->encrypt = 0;
880 if((pattrib->ether_type != 0x888e) && (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _FALSE))
882 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\npsta->ieee8021x_blocked == _TRUE, pattrib->ether_type(%.4x) != 0x888e\n",pattrib->ether_type));
883 #ifdef DBG_TX_DROP_FRAME
884 DBG_871X("DBG_TX_DROP_FRAME %s psta->ieee8021x_blocked == _TRUE, pattrib->ether_type(%04x) != 0x888e\n", __FUNCTION__,pattrib->ether_type);
892 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
894 #ifdef CONFIG_WAPI_SUPPORT
895 if(pattrib->ether_type == 0x88B4)
896 pattrib->encrypt=_NO_PRIVACY_;
899 switch(psecuritypriv->dot11AuthAlgrthm)
901 case dot11AuthAlgrthm_Open:
902 case dot11AuthAlgrthm_Shared:
903 case dot11AuthAlgrthm_Auto:
904 pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
906 case dot11AuthAlgrthm_8021X:
908 pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
910 pattrib->key_idx = 0;
913 pattrib->key_idx = 0;
920 switch (pattrib->encrypt)
925 pattrib->icv_len = 4;
930 pattrib->icv_len = 4;
932 if(padapter->securitypriv.busetkipkey==_FAIL)
934 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\npadapter->securitypriv.busetkipkey(%d)==_FAIL drop packet\n", padapter->securitypriv.busetkipkey));
935 #ifdef DBG_TX_DROP_FRAME
936 DBG_871X("DBG_TX_DROP_FRAME %s padapter->securitypriv.busetkipkey(%d)==_FAIL drop packet\n", __FUNCTION__, padapter->securitypriv.busetkipkey);
944 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("pattrib->encrypt=%d (_AES_)\n",pattrib->encrypt));
946 pattrib->icv_len = 8;
949 #ifdef CONFIG_WAPI_SUPPORT
951 pattrib->iv_len = 18;
952 pattrib->icv_len = 16;
958 pattrib->icv_len = 0;
962 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
963 ("update_attrib: encrypt=%d securitypriv.sw_encrypt=%d\n",
964 pattrib->encrypt, padapter->securitypriv.sw_encrypt));
966 if (pattrib->encrypt &&
967 ((padapter->securitypriv.sw_encrypt == _TRUE) || (psecuritypriv->hw_decrypted == _FALSE)))
969 pattrib->bswenc = _TRUE;
970 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,
971 ("update_attrib: encrypt=%d securitypriv.hw_decrypted=%d bswenc=_TRUE\n",
972 pattrib->encrypt, padapter->securitypriv.sw_encrypt));
974 pattrib->bswenc = _FALSE;
975 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("update_attrib: bswenc=_FALSE\n"));
978 #if defined(CONFIG_CONCURRENT_MODE) && !defined(DYNAMIC_CAMID_ALLOC)
979 if((pattrib->encrypt && bmcast) || (pattrib->encrypt ==_WEP40_) || (pattrib->encrypt ==_WEP104_))
981 pattrib->bswenc = _TRUE;//force using sw enc.
985 #ifdef CONFIG_WAPI_SUPPORT
986 if(pattrib->encrypt == _SMS4_)
987 pattrib->bswenc = _FALSE;
990 rtw_set_tx_chksum_offload(pkt, pattrib);
992 update_attrib_phy_info(padapter, pattrib, psta);
1001 static s32 xmitframe_addmic(_adapter *padapter, struct xmit_frame *pxmitframe){
1002 sint curfragnum,length;
1003 u8 *pframe, *payload,mic[8];
1004 struct mic_data micdata;
1005 struct sta_info *stainfo;
1006 struct qos_priv *pqospriv= &(padapter->mlmepriv.qospriv);
1007 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1008 struct security_priv *psecuritypriv=&padapter->securitypriv;
1009 struct xmit_priv *pxmitpriv=&padapter->xmitpriv;
1010 u8 priority[4]={0x0,0x0,0x0,0x0};
1011 u8 hw_hdr_offset = 0;
1012 sint bmcst = IS_MCAST(pattrib->ra);
1016 stainfo = pattrib->psta;
1020 DBG_871X("%s, call rtw_get_stainfo()\n", __func__);
1021 stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
1026 DBG_871X("%s, psta==NUL\n", __func__);
1030 if(!(stainfo->state &_FW_LINKED))
1032 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state);
1038 #ifdef CONFIG_USB_TX_AGGREGATION
1039 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);;
1041 #ifdef CONFIG_TX_EARLY_MODE
1042 hw_hdr_offset = TXDESC_OFFSET+ EARLY_MODE_INFO_SIZE;
1044 hw_hdr_offset = TXDESC_OFFSET;
1048 if(pattrib->encrypt ==_TKIP_)//if(psecuritypriv->dot11PrivacyAlgrthm==_TKIP_PRIVACY_)
1052 u8 null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
1054 pframe = pxmitframe->buf_addr + hw_hdr_offset;
1058 if(_rtw_memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16)==_TRUE){
1059 //DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n");
1060 //rtw_msleep_os(10);
1063 //start to calculate the mic code
1064 rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
1068 if(_rtw_memcmp(&stainfo->dot11tkiptxmickey.skey[0],null_key, 16)==_TRUE){
1069 //DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n");
1070 //rtw_msleep_os(10);
1073 //start to calculate the mic code
1074 rtw_secmicsetkey(&micdata, &stainfo->dot11tkiptxmickey.skey[0]);
1077 if(pframe[1]&1){ //ToDS==1
1078 rtw_secmicappend(&micdata, &pframe[16], 6); //DA
1079 if(pframe[1]&2) //From Ds==1
1080 rtw_secmicappend(&micdata, &pframe[24], 6);
1082 rtw_secmicappend(&micdata, &pframe[10], 6);
1085 rtw_secmicappend(&micdata, &pframe[4], 6); //DA
1086 if(pframe[1]&2) //From Ds==1
1087 rtw_secmicappend(&micdata, &pframe[16], 6);
1089 rtw_secmicappend(&micdata, &pframe[10], 6);
1093 //if(pqospriv->qos_option==1)
1095 priority[0]=(u8)pxmitframe->attrib.priority;
1098 rtw_secmicappend(&micdata, &priority[0], 4);
1102 for(curfragnum=0;curfragnum<pattrib->nr_frags;curfragnum++){
1103 payload=(u8 *)RND4((SIZE_PTR)(payload));
1104 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",
1105 curfragnum,*payload, *(payload+1),*(payload+2),*(payload+3),*(payload+4),*(payload+5),*(payload+6),*(payload+7)));
1107 payload=payload+pattrib->hdrlen+pattrib->iv_len;
1108 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("curfragnum=%d pattrib->hdrlen=%d pattrib->iv_len=%d",curfragnum,pattrib->hdrlen,pattrib->iv_len));
1109 if((curfragnum+1)==pattrib->nr_frags){
1110 length=pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-( (pattrib->bswenc) ? pattrib->icv_len : 0);
1111 rtw_secmicappend(&micdata, payload,length);
1112 payload=payload+length;
1115 length=pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-( (pattrib->bswenc) ? pattrib->icv_len : 0);
1116 rtw_secmicappend(&micdata, payload, length);
1117 payload=payload+length+pattrib->icv_len;
1118 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("curfragnum=%d length=%d pattrib->icv_len=%d",curfragnum,length,pattrib->icv_len));
1121 rtw_secgetmic(&micdata,&(mic[0]));
1122 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: before add mic code!!!\n"));
1123 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: pattrib->last_txcmdsz=%d!!!\n",pattrib->last_txcmdsz));
1124 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\
1125 mic[4]=0x%.2x ,mic[5]=0x%.2x ,mic[6]=0x%.2x ,mic[7]=0x%.2x !!!!\n",
1126 mic[0],mic[1],mic[2],mic[3],mic[4],mic[5],mic[6],mic[7]));
1127 //add mic code and add the mic code length in last_txcmdsz
1129 _rtw_memcpy(payload, &(mic[0]),8);
1130 pattrib->last_txcmdsz+=8;
1132 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("\n ========last pkt========\n"));
1133 payload=payload-pattrib->last_txcmdsz+8;
1134 for(curfragnum=0;curfragnum<pattrib->last_txcmdsz;curfragnum=curfragnum+8)
1135 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,(" %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x ",
1136 *(payload+curfragnum), *(payload+curfragnum+1), *(payload+curfragnum+2),*(payload+curfragnum+3),
1137 *(payload+curfragnum+4),*(payload+curfragnum+5),*(payload+curfragnum+6),*(payload+curfragnum+7)));
1140 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: rtw_get_stainfo==NULL!!!\n"));
1149 static s32 xmitframe_swencrypt(_adapter *padapter, struct xmit_frame *pxmitframe){
1151 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1152 //struct security_priv *psecuritypriv=&padapter->securitypriv;
1156 //if((psecuritypriv->sw_encrypt)||(pattrib->bswenc))
1159 //DBG_871X("start xmitframe_swencrypt\n");
1160 RT_TRACE(_module_rtl871x_xmit_c_,_drv_alert_,("### xmitframe_swencrypt\n"));
1161 switch(pattrib->encrypt){
1164 rtw_wep_encrypt(padapter, (u8 *)pxmitframe);
1167 rtw_tkip_encrypt(padapter, (u8 *)pxmitframe);
1170 rtw_aes_encrypt(padapter, (u8 * )pxmitframe);
1172 #ifdef CONFIG_WAPI_SUPPORT
1174 rtw_sms4_encrypt(padapter, (u8 * )pxmitframe);
1181 RT_TRACE(_module_rtl871x_xmit_c_,_drv_notice_,("### xmitframe_hwencrypt\n"));
1189 s32 rtw_make_wlanhdr (_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib)
1193 struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr;
1194 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1195 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1196 u8 qos_option = _FALSE;
1198 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1199 struct sta_priv *pstapriv = &padapter->stapriv;
1200 struct sta_info *ptdls_sta=NULL, *psta_backup=NULL;
1202 #endif //CONFIG_TDLS
1204 sint res = _SUCCESS;
1205 u16 *fctrl = &pwlanhdr->frame_ctl;
1207 struct sta_info *psta;
1209 sint bmcst = IS_MCAST(pattrib->ra);
1213 if (pattrib->psta) {
1214 psta = pattrib->psta;
1216 DBG_871X("%s, call rtw_get_stainfo()\n", __func__);
1218 psta = rtw_get_bcmc_stainfo(padapter);
1220 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1226 DBG_871X("%s, psta==NUL\n", __func__);
1230 if(!(psta->state &_FW_LINKED))
1232 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1236 _rtw_memset(hdr, 0, WLANHDR_OFFSET);
1238 SetFrameSubType(fctrl, pattrib->subtype);
1240 if (pattrib->subtype & WIFI_DATA_TYPE)
1242 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) {
1244 if((ptdlsinfo->setup_state == TDLS_LINKED_STATE)){
1245 ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
1246 if((ptdls_sta!=NULL)&&(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)&&(pattrib->ether_type!=0x0806)){
1247 //TDLS data transfer, ToDS=0, FrDs=0
1248 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1249 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1250 _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1253 // 1.Data transfer to AP
1254 // 2.Arp pkt will relayed by AP
1256 _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1257 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1258 _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1261 #endif //CONFIG_TDLS
1263 //to_ds = 1, fr_ds = 0;
1264 //Data transfer to AP
1266 _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1267 _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN);
1268 _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1271 if (pqospriv->qos_option)
1275 else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) ) {
1276 //to_ds = 0, fr_ds = 1;
1278 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1279 _rtw_memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN);
1280 _rtw_memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
1282 if(psta->qos_option)
1285 else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1286 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
1287 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1288 _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN);
1289 _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1291 if(psta->qos_option)
1295 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("fw_state:%x is not allowed to xmit frame\n", get_fwstate(pmlmepriv)));
1303 if (pattrib->encrypt)
1308 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
1310 if (pattrib->priority)
1311 SetPriority(qc, pattrib->priority);
1313 SetEOSP(qc, pattrib->eosp);
1315 SetAckpolicy(qc, pattrib->ack_policy);
1318 //TODO: fill HT Control Field
1320 //Update Seq Num will be handled by f/w
1329 #endif //CONFIG_TDLS
1331 psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
1332 psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
1334 pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
1336 SetSeqNum(hdr, pattrib->seqnum);
1338 #ifdef CONFIG_80211N_HT
1339 //check if enable ampdu
1340 if(pattrib->ht_en && psta->htpriv.ampdu_enable)
1342 if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
1343 pattrib->ampdu_en = _TRUE;
1346 //re-check if enable ampdu by BA_starting_seqctrl
1347 if(pattrib->ampdu_en == _TRUE)
1351 tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
1353 //check BA_starting_seqctrl
1354 if(SN_LESS(pattrib->seqnum, tx_seq))
1356 //DBG_871X("tx ampdu seqnum(%d) < tx_seq(%d)\n", pattrib->seqnum, tx_seq);
1357 pattrib->ampdu_en = _FALSE;//AGG BK
1359 else if(SN_EQUAL(pattrib->seqnum, tx_seq))
1361 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff;
1363 pattrib->ampdu_en = _TRUE;//AGG EN
1367 //DBG_871X("tx ampdu over run\n");
1368 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff;
1369 pattrib->ampdu_en = _TRUE;//AGG EN
1373 #endif //CONFIG_80211N_HT
1377 if (pattrib->encrypt){
1378 pattrib->encrypt= _AES_;
1383 //qos_en, ht_en, init rate, ,bw, ch_offset, sgi
1384 //pattrib->qos_en = ptdls_sta->qos_option;
1386 pattrib->raid = ptdls_sta->raid;
1387 #ifdef CONFIG_80211N_HT
1388 pattrib->bwmode = ptdls_sta->htpriv.bwmode;
1389 pattrib->ht_en = ptdls_sta->htpriv.ht_option;
1390 pattrib->ch_offset = ptdls_sta->htpriv.ch_offset;
1391 pattrib->sgi= ptdls_sta->htpriv.sgi;
1392 #endif //CONFIG_80211N_HT
1393 pattrib->mac_id = ptdls_sta->mac_id;
1397 #endif //CONFIG_TDLS
1415 s32 rtw_txframes_pending(_adapter *padapter)
1417 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1419 return ((_rtw_queue_empty(&pxmitpriv->be_pending) == _FALSE) ||
1420 (_rtw_queue_empty(&pxmitpriv->bk_pending) == _FALSE) ||
1421 (_rtw_queue_empty(&pxmitpriv->vi_pending) == _FALSE) ||
1422 (_rtw_queue_empty(&pxmitpriv->vo_pending) == _FALSE));
1425 s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib)
1427 struct sta_info *psta;
1428 struct tx_servq *ptxservq;
1429 int priority = pattrib->priority;
1433 psta = pattrib->psta;
1437 DBG_871X("%s, call rtw_get_stainfo()\n", __func__);
1438 psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
1443 DBG_871X("%s, psta==NUL\n", __func__);
1447 if(!(psta->state &_FW_LINKED))
1449 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1457 ptxservq = &(psta->sta_xmitpriv.bk_q);
1461 ptxservq = &(psta->sta_xmitpriv.vi_q);
1465 ptxservq = &(psta->sta_xmitpriv.vo_q);
1470 ptxservq = &(psta->sta_xmitpriv.be_q);
1475 return ptxservq->qcnt;
1480 int rtw_build_tdls_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, u8 action)
1485 case TDLS_SETUP_REQUEST:
1486 rtw_build_tdls_setup_req_ies(padapter, pxmitframe, pframe);
1488 case TDLS_SETUP_RESPONSE:
1489 rtw_build_tdls_setup_rsp_ies(padapter, pxmitframe, pframe);
1491 case TDLS_SETUP_CONFIRM:
1492 rtw_build_tdls_setup_cfm_ies(padapter, pxmitframe, pframe);
1495 rtw_build_tdls_teardown_ies(padapter, pxmitframe, pframe);
1497 case TDLS_DISCOVERY_REQUEST:
1498 rtw_build_tdls_dis_req_ies(padapter, pxmitframe, pframe);
1500 case TDLS_PEER_TRAFFIC_INDICATION:
1501 rtw_build_tdls_peer_traffic_indication_ies(padapter, pxmitframe, pframe);
1503 case TDLS_CHANNEL_SWITCH_REQUEST:
1504 rtw_build_tdls_ch_switch_req_ies(padapter, pxmitframe, pframe);
1506 case TDLS_CHANNEL_SWITCH_RESPONSE:
1507 rtw_build_tdls_ch_switch_rsp_ies(padapter, pxmitframe, pframe);
1510 case TUNNELED_PROBE_REQ:
1511 rtw_build_tunneled_probe_req_ies(padapter, pxmitframe, pframe);
1513 case TUNNELED_PROBE_RSP:
1514 rtw_build_tunneled_probe_rsp_ies(padapter, pxmitframe, pframe);
1525 s32 rtw_make_tdls_wlanhdr (_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib, u8 action)
1528 struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr;
1529 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1530 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1531 struct sta_priv *pstapriv = &padapter->stapriv;
1532 struct sta_info *psta=NULL, *ptdls_sta=NULL;
1533 u8 tdls_seq=0, baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1535 sint res = _SUCCESS;
1536 u16 *fctrl = &pwlanhdr->frame_ctl;
1540 _rtw_memset(hdr, 0, WLANHDR_OFFSET);
1542 SetFrameSubType(fctrl, pattrib->subtype);
1545 case TDLS_SETUP_REQUEST:
1546 case TDLS_SETUP_RESPONSE:
1547 case TDLS_SETUP_CONFIRM:
1548 case TDLS_TEARDOWN: //directly to peer STA or via AP
1549 case TDLS_PEER_TRAFFIC_INDICATION:
1550 case TDLS_PEER_PSM_REQUEST: //directly to peer STA or via AP
1551 case TUNNELED_PROBE_REQ:
1552 case TUNNELED_PROBE_RSP:
1554 _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1555 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1556 _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1558 case TDLS_CHANNEL_SWITCH_REQUEST:
1559 case TDLS_CHANNEL_SWITCH_RESPONSE:
1560 case TDLS_PEER_PSM_RESPONSE:
1561 case TDLS_PEER_TRAFFIC_RESPONSE:
1562 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1563 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1564 _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1567 case TDLS_DISCOVERY_REQUEST: //unicast: directly to peer sta, Bcast: via AP
1568 if(_rtw_memcmp(pattrib->dst, baddr, ETH_ALEN) )
1571 _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1572 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1573 _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1577 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1578 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1579 _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1585 if (pattrib->encrypt)
1588 if (pqospriv->qos_option)
1590 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
1591 if (pattrib->priority)
1592 SetPriority(qc, pattrib->priority);
1593 SetAckpolicy(qc, pattrib->ack_policy);
1596 psta = pattrib->psta;
1598 // 1. update seq_num per link by sta_info
1599 // 2. rewrite encrypt to _AES_, also rewrite iv_len, icv_len
1601 ptdls_sta=rtw_get_stainfo(pstapriv, pattrib->dst);
1603 ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
1604 ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
1605 pattrib->seqnum = ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority];
1606 SetSeqNum(hdr, pattrib->seqnum);
1608 if (pattrib->encrypt){
1609 pattrib->encrypt= _AES_;
1618 psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
1619 psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
1620 pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
1621 SetSeqNum(hdr, pattrib->seqnum);
1632 s32 rtw_xmit_tdls_coalesce(_adapter * padapter, struct xmit_frame * pxmitframe, u8 action)
1636 u8 *pframe, *mem_start;
1638 struct sta_info *psta;
1639 struct sta_priv *pstapriv = &padapter->stapriv;
1640 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1641 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1643 s32 bmcst = IS_MCAST(pattrib->ra);
1648 if (pattrib->psta) {
1649 psta = pattrib->psta;
1652 psta = rtw_get_bcmc_stainfo(padapter);
1654 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1661 if (pxmitframe->buf_addr == NULL)
1664 pbuf_start = pxmitframe->buf_addr;
1665 mem_start = pbuf_start + TXDESC_OFFSET;
1667 if (rtw_make_tdls_wlanhdr(padapter, mem_start, pattrib, action) == _FAIL) {
1673 pframe += pattrib->hdrlen;
1675 //adding icv, if necessary...
1676 if (pattrib->iv_len)
1680 switch(pattrib->encrypt)
1684 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1688 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1690 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
1694 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1696 AES_IV(pattrib->iv, psta->dot11txpn, 0);
1701 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
1702 pframe += pattrib->iv_len;
1706 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
1709 //pattrib->pktlen will be counted in rtw_build_tdls_ies
1710 pattrib->pktlen = 0;
1712 rtw_build_tdls_ies(padapter, pxmitframe, pframe, action);
1714 if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) {
1715 pframe += pattrib->pktlen;
1716 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
1717 pframe += pattrib->icv_len;
1720 pattrib->nr_frags = 1;
1721 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + llc_sz +
1722 ((pattrib->bswenc) ? pattrib->icv_len : 0) + pattrib->pktlen;
1724 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL)
1729 xmitframe_swencrypt(padapter, pxmitframe);
1731 update_attrib_vcs_info(padapter, pxmitframe);
1739 #endif //CONFIG_TDLS
1742 * Calculate wlan 802.11 packet MAX size from pkt_attrib
1743 * This function doesn't consider fragment case
1745 u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib)
1749 len = pattrib->hdrlen + pattrib->iv_len; // WLAN Header and IV
1750 len += SNAP_SIZE + sizeof(u16); // LLC
1751 len += pattrib->pktlen;
1752 if (pattrib->encrypt == _TKIP_) len += 8; // MIC
1753 len += ((pattrib->bswenc) ? pattrib->icv_len : 0); // ICV
1760 This sub-routine will perform all the following:
1762 1. remove 802.3 header.
1763 2. create wlan_header, based on the info in pxmitframe
1764 3. append sta's iv/ext-iv
1766 5. move frag chunk from pframe to pxmitframe->mem
1767 6. apply sw-encrypt, if necessary.
1770 s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
1772 struct pkt_file pktfile;
1774 s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
1778 u8 *pframe, *mem_start;
1781 struct sta_info *psta;
1782 //struct sta_priv *pstapriv = &padapter->stapriv;
1783 //struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1784 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1786 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1790 s32 bmcst = IS_MCAST(pattrib->ra);
1797 psta = pattrib->psta;
1800 DBG_871X("%s, call rtw_get_stainfo()\n", __func__);
1801 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1807 DBG_871X("%s, psta==NUL\n", __func__);
1812 if(!(psta->state &_FW_LINKED))
1814 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1818 if (pxmitframe->buf_addr == NULL){
1819 DBG_8192C("==> %s buf_addr==NULL \n",__FUNCTION__);
1823 pbuf_start = pxmitframe->buf_addr;
1825 #ifdef CONFIG_USB_TX_AGGREGATION
1826 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
1828 #ifdef CONFIG_TX_EARLY_MODE //for SDIO && Tx Agg
1829 hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
1831 hw_hdr_offset = TXDESC_OFFSET;
1835 mem_start = pbuf_start + hw_hdr_offset;
1837 if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
1838 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n"));
1839 DBG_8192C("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n");
1844 _rtw_open_pktfile(pkt, &pktfile);
1845 _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
1848 frg_len = pxmitpriv->frag_len - 4;//2346-4 = 2342
1858 SetMFrag(mem_start);
1860 pframe += pattrib->hdrlen;
1861 mpdu_len -= pattrib->hdrlen;
1863 //adding icv, if necessary...
1864 if (pattrib->iv_len)
1866 //if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
1867 // psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
1869 // psta = rtw_get_stainfo(pstapriv, pattrib->ra);
1873 switch(pattrib->encrypt)
1877 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1881 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1883 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
1887 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1889 AES_IV(pattrib->iv, psta->dot11txpn, 0);
1891 #ifdef CONFIG_WAPI_SUPPORT
1893 rtw_wapi_get_iv(padapter,pattrib->ra,pattrib->iv);
1899 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
1901 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
1902 ("rtw_xmitframe_coalesce: keyid=%d pattrib->iv[3]=%.2x pframe=%.2x %.2x %.2x %.2x\n",
1903 padapter->securitypriv.dot11PrivacyKeyIndex, pattrib->iv[3], *pframe, *(pframe+1), *(pframe+2), *(pframe+3)));
1905 pframe += pattrib->iv_len;
1907 mpdu_len -= pattrib->iv_len;
1911 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
1916 if ((pattrib->icv_len >0) && (pattrib->bswenc)) {
1917 mpdu_len -= pattrib->icv_len;
1922 // don't do fragment to broadcat/multicast packets
1923 mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
1925 mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len);
1930 if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) {
1931 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
1932 pframe += pattrib->icv_len;
1937 if (bmcst || (rtw_endofpktfile(&pktfile) == _TRUE))
1939 pattrib->nr_frags = frg_inx;
1941 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags==1)? llc_sz:0) +
1942 ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz;
1944 ClearMFrag(mem_start);
1948 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: There're still something in packet!\n", __FUNCTION__));
1951 addr = (SIZE_PTR)(pframe);
1953 mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset;
1954 _rtw_memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
1958 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL)
1960 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n"));
1961 DBG_8192C("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n");
1966 xmitframe_swencrypt(padapter, pxmitframe);
1969 update_attrib_vcs_info(padapter, pxmitframe);
1971 pattrib->vcs_mode = NONE_VCS;
1980 #ifdef CONFIG_IEEE80211W
1981 //broadcast or multicast management pkt use BIP, unicast management pkt use CCMP encryption
1982 s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
1984 struct pkt_file pktfile;
1985 s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
1987 u8 *pframe, *mem_start = NULL, *tmp_buf=NULL;
1988 u8 hw_hdr_offset, subtype ;
1989 struct sta_info *psta = NULL;
1990 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1991 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1993 s32 bmcst = IS_MCAST(pattrib->ra);
1998 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1999 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2000 struct rtw_ieee80211_hdr *pwlanhdr;
2001 u8 MME[_MME_IE_LENGTH_];
2005 mem_start = pframe = (u8 *)(pxmitframe->buf_addr) + TXDESC_OFFSET;
2006 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2010 ori_len = BIP_AAD_SIZE+pattrib->pktlen;
2011 tmp_buf = BIP_AAD = rtw_zmalloc(ori_len);
2012 subtype = GetFrameSubType(pframe); //bit(7)~bit(2)
2017 _enter_critical_bh(&padapter->security_key_mutex, &irqL);
2019 //only support station mode
2020 if(!check_fwstate(pmlmepriv, WIFI_STATION_STATE) || !check_fwstate(pmlmepriv, _FW_LINKED))
2021 goto xmitframe_coalesce_success;
2023 //IGTK key is not install, it may not support 802.11w
2024 if(padapter->securitypriv.binstallBIPkey != _TRUE)
2026 DBG_871X("no instll BIP key\n");
2027 goto xmitframe_coalesce_success;
2029 //station mode doesn't need TX BIP, just ready the code
2035 _rtw_memset(MME, 0, 18);
2037 //other types doesn't need the BIP
2038 if(GetFrameSubType(pframe) != WIFI_DEAUTH && GetFrameSubType(pframe) != WIFI_DISASSOC)
2039 goto xmitframe_coalesce_fail;
2041 MGMT_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
2042 pframe += pattrib->pktlen;
2044 //octent 0 and 1 is key index ,BIP keyid is 4 or 5, LSB only need octent 0
2045 MME[0]=padapter->securitypriv.dot11wBIPKeyid;
2046 //copy packet number
2047 _rtw_memcpy(&MME[2], &pmlmeext->mgnt_80211w_IPN, 6);
2048 //increase the packet number
2049 pmlmeext->mgnt_80211w_IPN++;
2051 //add MME IE with MIC all zero, MME string doesn't include element id and length
2052 pframe = rtw_set_ie(pframe, _MME_IE_ , 16 , MME, &(pattrib->pktlen));
2053 pattrib->last_txcmdsz = pattrib->pktlen;
2054 // total frame length - header length
2055 frame_body_len = pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr);
2057 //conscruct AAD, copy frame control field
2058 _rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2);
2059 ClearRetry(BIP_AAD);
2060 ClearPwrMgt(BIP_AAD);
2061 ClearMData(BIP_AAD);
2062 //conscruct AAD, copy address 1 to address 3
2063 _rtw_memcpy(BIP_AAD+2, pwlanhdr->addr1, 18);
2064 //copy management fram body
2065 _rtw_memcpy(BIP_AAD+BIP_AAD_SIZE, MGMT_body, frame_body_len);
2066 /*//dump total packet include MME with zero MIC
2069 printk("Total packet: ");
2070 for(i=0; i < BIP_AAD_SIZE+frame_body_len; i++)
2071 printk(" %02x ", BIP_AAD[i]);
2075 if(omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey
2076 , BIP_AAD, BIP_AAD_SIZE+frame_body_len, mic))
2077 goto xmitframe_coalesce_fail;
2079 /*//dump calculated mic result
2082 printk("Calculated mic result: ");
2084 printk(" %02x ", mic[i]);
2087 //copy right BIP mic value, total is 128bits, we use the 0~63 bits
2088 _rtw_memcpy(pframe-8, mic, 8);
2089 /*/dump all packet after mic ok
2092 printk("pattrib->pktlen = %d \n", pattrib->pktlen);
2093 for(pp=0;pp< pattrib->pktlen; pp++)
2094 printk(" %02x ", mem_start[pp]);
2098 else //unicast mgmt frame TX
2100 //start to encrypt mgmt frame
2101 if(subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC ||
2102 subtype == WIFI_REASSOCREQ || subtype == WIFI_ACTION)
2105 psta = pattrib->psta;
2108 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2114 DBG_871X("%s, psta==NUL\n", __func__);
2115 goto xmitframe_coalesce_fail;
2118 if(!(psta->state & _FW_LINKED) || pxmitframe->buf_addr==NULL)
2120 DBG_871X("%s, not _FW_LINKED or addr null\n", __func__);
2121 goto xmitframe_coalesce_fail;
2124 //DBG_871X("%s, action frame category=%d \n", __func__, pframe[WLAN_HDR_A3_LEN]);
2125 //according 802.11-2012 standard, these five types are not robust types
2126 if(subtype == WIFI_ACTION &&
2127 (pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_PUBLIC ||
2128 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_HT ||
2129 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_UNPROTECTED_WNM ||
2130 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_SELF_PROTECTED ||
2131 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_P2P))
2132 goto xmitframe_coalesce_fail;
2133 /*//before encrypt dump the management packet content
2136 printk("Management pkt: ");
2137 for(i=0; i<pattrib->pktlen; i++)
2138 printk(" %02x ", pframe[i]);
2139 printk("=======\n");
2142 //bakeup original management packet
2143 _rtw_memcpy(tmp_buf, pframe, pattrib->pktlen);
2144 //move to data portion
2145 pframe += pattrib->hdrlen;
2147 //802.11w unicast management packet must be _AES_
2148 pattrib->iv_len = 8;
2150 pattrib->icv_len = 8;
2152 switch(pattrib->encrypt)
2156 AES_IV(pattrib->iv, psta->dot11wtxpn, 0);
2159 goto xmitframe_coalesce_fail;
2161 //insert iv header into management frame
2162 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
2163 pframe += pattrib->iv_len;
2164 //copy mgmt data portion after CCMP header
2165 _rtw_memcpy(pframe, tmp_buf+pattrib->hdrlen, pattrib->pktlen-pattrib->hdrlen);
2166 //move pframe to end of mgmt pkt
2167 pframe += pattrib->pktlen-pattrib->hdrlen;
2168 //add 8 bytes CCMP IV header to length
2169 pattrib->pktlen += pattrib->iv_len;
2170 /*//dump management packet include AES IV header
2173 printk("Management pkt + IV: ");
2174 //for(i=0; i<pattrib->pktlen; i++)
2175 //printk(" %02x ", mem_start[i]);
2176 printk("@@@@@@@@@@@@@\n");
2179 if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) {
2180 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2181 pframe += pattrib->icv_len;
2184 pattrib->pktlen += pattrib->icv_len;
2185 //set final tx command size
2186 pattrib->last_txcmdsz = pattrib->pktlen;
2188 //set protected bit must be beofre SW encrypt
2189 SetPrivacy(mem_start);
2190 /*//dump management packet include AES header
2193 printk("prepare to enc Management pkt + IV: ");
2194 for(i=0; i<pattrib->pktlen; i++)
2195 printk(" %02x ", mem_start[i]);
2196 printk("@@@@@@@@@@@@@\n");
2199 xmitframe_swencrypt(padapter, pxmitframe);
2203 xmitframe_coalesce_success:
2204 _exit_critical_bh(&padapter->security_key_mutex, &irqL);
2205 rtw_mfree(BIP_AAD, ori_len);
2209 xmitframe_coalesce_fail:
2210 _exit_critical_bh(&padapter->security_key_mutex, &irqL);
2211 rtw_mfree(BIP_AAD, ori_len);
2216 #endif //CONFIG_IEEE80211W
2218 /* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
2219 * IEEE LLC/SNAP header contains 8 octets
2220 * First 3 octets comprise the LLC portion
2221 * SNAP portion, 5 octets, is divided into two fields:
2222 * Organizationally Unique Identifier(OUI), 3 octets,
2223 * type, defined by that organization, 2 octets.
2225 s32 rtw_put_snap(u8 *data, u16 h_proto)
2227 struct ieee80211_snap_hdr *snap;
2232 snap = (struct ieee80211_snap_hdr *)data;
2237 if (h_proto == 0x8137 || h_proto == 0x80f3)
2242 snap->oui[0] = oui[0];
2243 snap->oui[1] = oui[1];
2244 snap->oui[2] = oui[2];
2246 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
2250 return SNAP_SIZE + sizeof(u16);
2253 void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len)
2259 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2260 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2264 switch(pxmitpriv->vcs_setting)
2267 pxmitpriv->vcs = NONE_VCS;
2275 perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
2278 pxmitpriv->vcs = NONE_VCS;
2282 protection = (*(perp + 2)) & BIT(1);
2285 if(pregistrypriv->vcs_type == RTS_CTS)
2286 pxmitpriv->vcs = RTS_CTS;
2288 pxmitpriv->vcs = CTS_TO_SELF;
2291 pxmitpriv->vcs = NONE_VCS;
2302 void rtw_count_tx_stats(PADAPTER padapter, struct xmit_frame *pxmitframe, int sz)
2304 struct sta_info *psta = NULL;
2305 struct stainfo_stats *pstats = NULL;
2306 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2307 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2309 if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
2311 pxmitpriv->tx_bytes += sz;
2312 #if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2313 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pxmitframe->agg_num;
2315 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod++;
2318 psta = pxmitframe->attrib.psta;
2321 pstats = &psta->sta_stats;
2322 #if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2323 pstats->tx_pkts += pxmitframe->agg_num;
2327 pstats->tx_bytes += sz;
2332 struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
2335 struct xmit_buf *pxmitbuf = NULL;
2336 _list *plist, *phead;
2337 _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
2341 _enter_critical(&pfree_queue->lock, &irqL);
2343 if(_rtw_queue_empty(pfree_queue) == _TRUE) {
2347 phead = get_list_head(pfree_queue);
2349 plist = get_next(phead);
2351 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
2353 rtw_list_delete(&(pxmitbuf->list));
2356 if (pxmitbuf != NULL)
2358 pxmitpriv->free_xmit_extbuf_cnt--;
2359 #ifdef DBG_XMIT_BUF_EXT
2360 DBG_871X("DBG_XMIT_BUF_EXT ALLOC no=%d, free_xmit_extbuf_cnt=%d\n",pxmitbuf->no, pxmitpriv->free_xmit_extbuf_cnt);
2364 pxmitbuf->priv_data = NULL;
2365 //pxmitbuf->ext_tag = _TRUE;
2367 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2369 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
2371 #ifdef CONFIG_PCI_HCI
2375 if (pxmitbuf->sctx) {
2376 DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__);
2377 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
2382 _exit_critical(&pfree_queue->lock, &irqL);
2389 s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
2392 _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
2401 _enter_critical(&pfree_queue->lock, &irqL);
2403 rtw_list_delete(&pxmitbuf->list);
2405 rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_queue));
2406 pxmitpriv->free_xmit_extbuf_cnt++;
2407 #ifdef DBG_XMIT_BUF_EXT
2408 DBG_871X("DBG_XMIT_BUF_EXT FREE no=%d, free_xmit_extbuf_cnt=%d\n",pxmitbuf->no ,pxmitpriv->free_xmit_extbuf_cnt);
2411 _exit_critical(&pfree_queue->lock, &irqL);
2418 struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
2421 struct xmit_buf *pxmitbuf = NULL;
2422 _list *plist, *phead;
2423 _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
2427 //DBG_871X("+rtw_alloc_xmitbuf\n");
2429 _enter_critical(&pfree_xmitbuf_queue->lock, &irqL);
2431 if(_rtw_queue_empty(pfree_xmitbuf_queue) == _TRUE) {
2435 phead = get_list_head(pfree_xmitbuf_queue);
2437 plist = get_next(phead);
2439 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
2441 rtw_list_delete(&(pxmitbuf->list));
2444 if (pxmitbuf != NULL)
2446 pxmitpriv->free_xmitbuf_cnt--;
2448 DBG_871X("DBG_XMIT_BUF ALLOC no=%d, free_xmitbuf_cnt=%d\n",pxmitbuf->no, pxmitpriv->free_xmitbuf_cnt);
2450 //DBG_871X("alloc, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt);
2452 pxmitbuf->priv_data = NULL;
2453 //pxmitbuf->ext_tag = _FALSE;
2454 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2456 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
2457 pxmitbuf->agg_num = 0;
2458 pxmitbuf->pg_num = 0;
2460 #ifdef CONFIG_PCI_HCI
2464 if (pxmitbuf->sctx) {
2465 DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__);
2466 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
2472 DBG_871X("DBG_XMIT_BUF rtw_alloc_xmitbuf return NULL\n");
2476 _exit_critical(&pfree_xmitbuf_queue->lock, &irqL);
2483 s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
2486 _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
2490 //DBG_871X("+rtw_free_xmitbuf\n");
2497 if (pxmitbuf->sctx) {
2498 DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__);
2499 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
2502 if(pxmitbuf->ext_tag)
2504 rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf);
2508 _enter_critical(&pfree_xmitbuf_queue->lock, &irqL);
2510 rtw_list_delete(&pxmitbuf->list);
2512 rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
2514 pxmitpriv->free_xmitbuf_cnt++;
2515 //DBG_871X("FREE, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt);
2517 DBG_871X("DBG_XMIT_BUF FREE no=%d, free_xmitbuf_cnt=%d\n",pxmitbuf->no ,pxmitpriv->free_xmitbuf_cnt);
2519 _exit_critical(&pfree_xmitbuf_queue->lock, &irqL);
2527 void rtw_init_xmitframe(struct xmit_frame *pxframe)
2529 if (pxframe != NULL)//default value setting
2531 pxframe->buf_addr = NULL;
2532 pxframe->pxmitbuf = NULL;
2534 _rtw_memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
2535 //pxframe->attrib.psta = NULL;
2537 pxframe->frame_tag = DATA_FRAMETAG;
2539 #ifdef CONFIG_USB_HCI
2540 pxframe->pkt = NULL;
2541 #ifdef USB_PACKET_OFFSET_SZ
2542 pxframe->pkt_offset = (PACKET_OFFSET_SZ/8);
2544 pxframe->pkt_offset = 1;//default use pkt_offset to fill tx desc
2547 #ifdef CONFIG_USB_TX_AGGREGATION
2548 pxframe->agg_num = 1;
2551 #endif //#ifdef CONFIG_USB_HCI
2553 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2554 pxframe->pg_num = 1;
2555 pxframe->agg_num = 1;
2558 #ifdef CONFIG_XMIT_ACK
2559 pxframe->ack_report = 0;
2568 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
2570 If we turn on USE_RXTHREAD, then, no need for critical section.
2571 Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
2573 Must be very very cautious...
2576 struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)//(_queue *pfree_xmit_queue)
2579 Please remember to use all the osdep_service api,
2580 and lock/unlock or _enter/_exit critical to protect
2585 struct xmit_frame *pxframe = NULL;
2586 _list *plist, *phead;
2587 _queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
2588 #ifdef PLATFORM_LINUX
2589 _adapter *padapter = pxmitpriv->adapter;
2590 #endif //PLATFORM_LINUX
2594 _enter_critical_bh(&pfree_xmit_queue->lock, &irqL);
2596 if (_rtw_queue_empty(pfree_xmit_queue) == _TRUE) {
2597 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_alloc_xmitframe:%d\n", pxmitpriv->free_xmitframe_cnt));
2600 phead = get_list_head(pfree_xmit_queue);
2602 plist = get_next(phead);
2604 pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
2606 rtw_list_delete(&(pxframe->list));
2607 pxmitpriv->free_xmitframe_cnt--;
2608 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt));
2611 _exit_critical_bh(&pfree_xmit_queue->lock, &irqL);
2613 rtw_init_xmitframe(pxframe);
2620 struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv)
2623 struct xmit_frame *pxframe = NULL;
2624 _list *plist, *phead;
2625 _queue *queue = &pxmitpriv->free_xframe_ext_queue;
2629 _enter_critical_bh(&queue->lock, &irqL);
2631 if (_rtw_queue_empty(queue) == _TRUE) {
2632 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_alloc_xmitframe_ext:%d\n", pxmitpriv->free_xframe_ext_cnt));
2635 phead = get_list_head(queue);
2636 plist = get_next(phead);
2637 pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
2639 rtw_list_delete(&(pxframe->list));
2640 pxmitpriv->free_xframe_ext_cnt--;
2641 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe_ext():free_xmitframe_cnt=%d\n", pxmitpriv->free_xframe_ext_cnt));
2644 _exit_critical_bh(&queue->lock, &irqL);
2646 rtw_init_xmitframe(pxframe);
2653 struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv)
2655 struct xmit_frame *pxframe = NULL;
2658 alloc_addr = rtw_zmalloc(sizeof(struct xmit_frame) + 4);
2660 if (alloc_addr == NULL)
2663 pxframe = (struct xmit_frame *)N_BYTE_ALIGMENT((SIZE_PTR)(alloc_addr), 4);
2664 pxframe->alloc_addr = alloc_addr;
2666 pxframe->padapter = pxmitpriv->adapter;
2667 pxframe->frame_tag = NULL_FRAMETAG;
2669 pxframe->pkt = NULL;
2671 pxframe->buf_addr = NULL;
2672 pxframe->pxmitbuf = NULL;
2674 rtw_init_xmitframe(pxframe);
2676 DBG_871X("################## %s ##################\n", __func__);
2682 s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
2686 _adapter *padapter = pxmitpriv->adapter;
2687 _pkt *pndis_pkt = NULL;
2691 if (pxmitframe == NULL) {
2692 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("======rtw_free_xmitframe():pxmitframe==NULL!!!!!!!!!!\n"));
2696 if (pxmitframe->pkt){
2697 pndis_pkt = pxmitframe->pkt;
2698 pxmitframe->pkt = NULL;
2701 if (pxmitframe->alloc_addr) {
2702 DBG_871X("################## %s with alloc_addr ##################\n", __func__);
2703 rtw_mfree(pxmitframe->alloc_addr, sizeof(struct xmit_frame) + 4);
2704 goto check_pkt_complete;
2707 if (pxmitframe->ext_tag == 0)
2708 queue = &pxmitpriv->free_xmit_queue;
2709 else if(pxmitframe->ext_tag == 1)
2710 queue = &pxmitpriv->free_xframe_ext_queue;
2714 _enter_critical_bh(&queue->lock, &irqL);
2716 rtw_list_delete(&pxmitframe->list);
2717 rtw_list_insert_tail(&pxmitframe->list, get_list_head(queue));
2718 if (pxmitframe->ext_tag == 0) {
2719 pxmitpriv->free_xmitframe_cnt++;
2720 RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt));
2721 } else if(pxmitframe->ext_tag == 1) {
2722 pxmitpriv->free_xframe_ext_cnt++;
2723 RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xframe_ext_cnt=%d\n", pxmitpriv->free_xframe_ext_cnt));
2727 _exit_critical_bh(&queue->lock, &irqL);
2732 rtw_os_pkt_complete(padapter, pndis_pkt);
2741 void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue)
2744 _list *plist, *phead;
2745 struct xmit_frame *pxmitframe;
2749 _enter_critical_bh(&(pframequeue->lock), &irqL);
2751 phead = get_list_head(pframequeue);
2752 plist = get_next(phead);
2754 while (rtw_end_of_queue_search(phead, plist) == _FALSE)
2757 pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
2759 plist = get_next(plist);
2761 rtw_free_xmitframe(pxmitpriv,pxmitframe);
2764 _exit_critical_bh(&(pframequeue->lock), &irqL);
2769 s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
2771 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue);
2772 if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL)
2774 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
2775 ("rtw_xmitframe_enqueue: drop xmit pkt for classifier fail\n"));
2776 // pxmitframe->pkt = NULL;
2783 static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue)
2785 _list *xmitframe_plist, *xmitframe_phead;
2786 struct xmit_frame *pxmitframe=NULL;
2788 xmitframe_phead = get_list_head(pframe_queue);
2789 xmitframe_plist = get_next(xmitframe_phead);
2791 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
2793 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
2795 xmitframe_plist = get_next(xmitframe_plist);
2797 /*#ifdef RTK_DMP_PLATFORM
2798 #ifdef CONFIG_USB_TX_AGGREGATION
2799 if((ptxservq->qcnt>0) && (ptxservq->qcnt<=2))
2803 tasklet_schedule(&pxmitpriv->xmit_tasklet);
2809 rtw_list_delete(&pxmitframe->list);
2813 //rtw_list_insert_tail(&pxmitframe->list, &phwxmit->pending);
2826 struct xmit_frame* rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry)
2829 _list *sta_plist, *sta_phead;
2830 struct hw_xmit *phwxmit;
2831 struct tx_servq *ptxservq = NULL;
2832 _queue *pframe_queue = NULL;
2833 struct xmit_frame *pxmitframe = NULL;
2834 _adapter *padapter = pxmitpriv->adapter;
2835 struct registry_priv *pregpriv = &padapter->registrypriv;
2837 #ifdef CONFIG_USB_HCI
2838 // int j, tmp, acirp_cnt[4];
2843 inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
2845 if(pregpriv->wifi_spec==1)
2847 int j, tmp, acirp_cnt[4];
2849 if(flags<XMIT_QUEUE_ENTRY)
2851 //priority exchange according to the completed xmitbuf flags.
2857 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
2859 inx[j] = pxmitpriv->wmm_para_seq[j];
2863 _enter_critical_bh(&pxmitpriv->lock, &irqL0);
2865 for(i = 0; i < entry; i++)
2867 phwxmit = phwxmit_i + inx[i];
2869 //_enter_critical_ex(&phwxmit->sta_queue->lock, &irqL0);
2871 sta_phead = get_list_head(phwxmit->sta_queue);
2872 sta_plist = get_next(sta_phead);
2874 while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE)
2877 ptxservq= LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
2879 pframe_queue = &ptxservq->sta_pending;
2881 pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
2887 //Remove sta node when there is no pending packets.
2888 if(_rtw_queue_empty(pframe_queue)) //must be done after get_next and before break
2889 rtw_list_delete(&ptxservq->tx_pending);
2891 //_exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0);
2896 sta_plist = get_next(sta_plist);
2900 //_exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0);
2906 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
2914 struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac)
2916 struct tx_servq *ptxservq=NULL;
2924 ptxservq = &(psta->sta_xmitpriv.bk_q);
2926 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BK \n"));
2931 ptxservq = &(psta->sta_xmitpriv.vi_q);
2933 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VI\n"));
2938 ptxservq = &(psta->sta_xmitpriv.vo_q);
2940 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VO \n"));
2946 ptxservq = &(psta->sta_xmitpriv.be_q);
2948 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BE \n"));
2958 __inline static struct tx_servq *rtw_get_sta_pending
2959 (_adapter *padapter, _queue **ppstapending, struct sta_info *psta, sint up)
2961 struct tx_servq *ptxservq;
2962 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
2966 #ifdef CONFIG_RTL8711
2968 if(IS_MCAST(psta->hwaddr))
2970 ptxservq = &(psta->sta_xmitpriv.be_q); // we will use be_q to queue bc/mc frames in BCMC_stainfo
2971 *ppstapending = &padapter->xmitpriv.bm_pending;
2980 ptxservq = &(psta->sta_xmitpriv.bk_q);
2981 *ppstapending = &padapter->xmitpriv.bk_pending;
2982 (phwxmits+3)->accnt++;
2983 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BK \n"));
2988 ptxservq = &(psta->sta_xmitpriv.vi_q);
2989 *ppstapending = &padapter->xmitpriv.vi_pending;
2990 (phwxmits+1)->accnt++;
2991 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VI\n"));
2996 ptxservq = &(psta->sta_xmitpriv.vo_q);
2997 *ppstapending = &padapter->xmitpriv.vo_pending;
2998 (phwxmits+0)->accnt++;
2999 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VO \n"));
3005 ptxservq = &(psta->sta_xmitpriv.be_q);
3006 *ppstapending = &padapter->xmitpriv.be_pending;
3007 (phwxmits+2)->accnt++;
3008 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BE \n"));
3022 * Will enqueue pxmitframe to the proper queue,
3023 * and indicate it to xx_pending list.....
3025 s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe)
3029 struct sta_info *psta;
3030 struct tx_servq *ptxservq;
3031 struct pkt_attrib *pattrib = &pxmitframe->attrib;
3032 struct sta_priv *pstapriv = &padapter->stapriv;
3033 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
3034 sint res = _SUCCESS;
3038 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class);
3039 if (pattrib->psta) {
3040 psta = pattrib->psta;
3042 DBG_871X("%s, call rtw_get_stainfo()\n", __func__);
3043 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
3047 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_nosta);
3049 DBG_8192C("rtw_xmit_classifier: psta == NULL\n");
3050 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("rtw_xmit_classifier: psta == NULL\n"));
3054 if(!(psta->state &_FW_LINKED))
3056 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_fwlink);
3057 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
3061 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
3063 //_enter_critical(&pstapending->lock, &irqL0);
3065 if (rtw_is_list_empty(&ptxservq->tx_pending)) {
3066 rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
3069 //_enter_critical(&ptxservq->sta_pending.lock, &irqL1);
3071 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
3073 phwxmits[ac_index].accnt++;
3075 //_exit_critical(&ptxservq->sta_pending.lock, &irqL1);
3077 //_exit_critical(&pstapending->lock, &irqL0);
3086 void rtw_alloc_hwxmits(_adapter *padapter)
3088 struct hw_xmit *hwxmits;
3089 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3091 pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
3093 pxmitpriv->hwxmits = (struct hw_xmit *)rtw_zmalloc(sizeof (struct hw_xmit) * pxmitpriv->hwxmit_entry);
3095 hwxmits = pxmitpriv->hwxmits;
3097 if(pxmitpriv->hwxmit_entry == 5)
3099 //pxmitpriv->bmc_txqueue.head = 0;
3100 //hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue;
3101 hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
3103 //pxmitpriv->vo_txqueue.head = 0;
3104 //hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue;
3105 hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
3107 //pxmitpriv->vi_txqueue.head = 0;
3108 //hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue;
3109 hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
3111 //pxmitpriv->bk_txqueue.head = 0;
3112 //hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
3113 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
3115 //pxmitpriv->be_txqueue.head = 0;
3116 //hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue;
3117 hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
3120 else if(pxmitpriv->hwxmit_entry == 4)
3123 //pxmitpriv->vo_txqueue.head = 0;
3124 //hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue;
3125 hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
3127 //pxmitpriv->vi_txqueue.head = 0;
3128 //hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue;
3129 hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
3131 //pxmitpriv->be_txqueue.head = 0;
3132 //hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue;
3133 hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
3135 //pxmitpriv->bk_txqueue.head = 0;
3136 //hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
3137 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
3148 void rtw_free_hwxmits(_adapter *padapter)
3150 struct hw_xmit *hwxmits;
3151 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3153 hwxmits = pxmitpriv->hwxmits;
3155 rtw_mfree((u8 *)hwxmits, (sizeof (struct hw_xmit) * pxmitpriv->hwxmit_entry));
3158 void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry)
3162 for(i = 0; i < entry; i++, phwxmit++)
3164 //_rtw_spinlock_init(&phwxmit->xmit_lock);
3165 //_rtw_init_listhead(&phwxmit->pending);
3166 //phwxmit->txcmdcnt = 0;
3172 #ifdef CONFIG_BR_EXT
3173 int rtw_br_client_tx(_adapter *padapter, struct sk_buff **pskb)
3175 struct sk_buff *skb = *pskb;
3176 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3178 //if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE)
3180 void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb);
3181 int res, is_vlan_tag=0, i, do_nat25=1;
3182 unsigned short vlan_hdr=0;
3183 void *br_port = NULL;
3185 //mac_clone_handle_frame(priv, skb);
3187 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3188 br_port = padapter->pnetdev->br_port;
3189 #else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3191 br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
3193 #endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3194 _enter_critical_bh(&padapter->br_ext_lock, &irqL);
3195 if ( !(skb->data[0] & 1) &&
3197 memcmp(skb->data+MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
3198 *((unsigned short *)(skb->data+MACADDRLEN*2)) != __constant_htons(ETH_P_8021Q) &&
3199 *((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP) &&
3200 !memcmp(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN) && padapter->scdb_entry) {
3201 memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
3202 padapter->scdb_entry->ageing_timer = jiffies;
3203 _exit_critical_bh(&padapter->br_ext_lock, &irqL);
3206 //if (!priv->pmib->ethBrExtInfo.nat25_disable)
3208 // if (priv->dev->br_port &&
3209 // !memcmp(skb->data+MACADDRLEN, priv->br_mac, MACADDRLEN)) {
3211 if (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_8021Q)) {
3213 vlan_hdr = *((unsigned short *)(skb->data+MACADDRLEN*2+2));
3215 *((unsigned short *)(skb->data+MACADDRLEN*2+2-i*2)) = *((unsigned short *)(skb->data+MACADDRLEN*2-2-i*2));
3218 //if SA == br_mac && skb== IP => copy SIP to br_ip ?? why
3219 if (!memcmp(skb->data+MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
3220 (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP)))
3221 memcpy(padapter->br_ip, skb->data+WLAN_ETHHDR_LEN+12, 4);
3223 if (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP)) {
3224 if (memcmp(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN)) {
3225 void *scdb_findEntry(_adapter *priv, unsigned char *macAddr, unsigned char *ipAddr);
3227 if ((padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter,
3228 skb->data+MACADDRLEN, skb->data+WLAN_ETHHDR_LEN+12)) != NULL) {
3229 memcpy(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN);
3230 memcpy(padapter->scdb_ip, skb->data+WLAN_ETHHDR_LEN+12, 4);
3231 padapter->scdb_entry->ageing_timer = jiffies;
3236 if (padapter->scdb_entry) {
3237 padapter->scdb_entry->ageing_timer = jiffies;
3241 memset(padapter->scdb_mac, 0, MACADDRLEN);
3242 memset(padapter->scdb_ip, 0, 4);
3246 _exit_critical_bh(&padapter->br_ext_lock, &irqL);
3250 int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method);
3251 if (nat25_db_handle(padapter, skb, NAT25_CHECK) == 0) {
3252 struct sk_buff *newskb;
3257 *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2));
3258 *((unsigned short *)(skb->data+MACADDRLEN*2)) = __constant_htons(ETH_P_8021Q);
3259 *((unsigned short *)(skb->data+MACADDRLEN*2+2)) = vlan_hdr;
3262 newskb = rtw_skb_copy(skb);
3263 if (newskb == NULL) {
3264 //priv->ext_stats.tx_drops++;
3265 DEBUG_ERR("TX DROP: rtw_skb_copy fail!\n");
3271 *pskb = skb = newskb;
3273 vlan_hdr = *((unsigned short *)(skb->data+MACADDRLEN*2+2));
3275 *((unsigned short *)(skb->data+MACADDRLEN*2+2-i*2)) = *((unsigned short *)(skb->data+MACADDRLEN*2-2-i*2));
3280 if (skb_is_nonlinear(skb))
3281 DEBUG_ERR("%s(): skb_is_nonlinear!!\n", __FUNCTION__);
3284 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
3285 res = skb_linearize(skb, GFP_ATOMIC);
3286 #else // (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
3287 res = skb_linearize(skb);
3288 #endif // (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
3290 DEBUG_ERR("TX DROP: skb_linearize fail!\n");
3291 //goto free_and_stop;
3295 res = nat25_db_handle(padapter, skb, NAT25_INSERT);
3298 //priv->ext_stats.tx_drops++;
3299 DEBUG_ERR("TX DROP: nat25_db_handle fail!\n");
3300 //goto free_and_stop;
3304 // we just print warning message and let it go
3305 //DEBUG_WARN("%s()-%d: nat25_db_handle INSERT Warning!\n", __FUNCTION__, __LINE__);
3306 //return -1; // return -1 will cause system crash on 2011/08/30!
3311 memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
3313 dhcp_flag_bcast(padapter, skb);
3318 *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2));
3319 *((unsigned short *)(skb->data+MACADDRLEN*2)) = __constant_htons(ETH_P_8021Q);
3320 *((unsigned short *)(skb->data+MACADDRLEN*2+2)) = vlan_hdr;
3325 if (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_8021Q)) {
3330 if(ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A_VALN(skb->data)){
3331 memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
3335 if(ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A(skb->data)){
3336 memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
3342 // check if SA is equal to our MAC
3343 if (memcmp(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN)) {
3344 //priv->ext_stats.tx_drops++;
3345 DEBUG_ERR("TX DROP: untransformed frame SA:%02X%02X%02X%02X%02X%02X!\n",
3346 skb->data[6],skb->data[7],skb->data[8],skb->data[9],skb->data[10],skb->data[11]);
3347 //goto free_and_stop;
3353 #endif // CONFIG_BR_EXT
3355 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
3358 struct pkt_attrib *pattrib = &pxmitframe->attrib;
3360 switch(pattrib->qsel)
3364 addr = BE_QUEUE_INX;
3368 addr = BK_QUEUE_INX;
3372 addr = VI_QUEUE_INX;
3376 addr = VO_QUEUE_INX;
3379 addr = BCN_QUEUE_INX;
3381 case 0x11://BC/MC in PS (HIQ)
3382 addr = HIGH_QUEUE_INX;
3386 addr = MGT_QUEUE_INX;
3395 static void do_queue_select(_adapter *padapter, struct pkt_attrib *pattrib)
3399 qsel = pattrib->priority;
3400 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("### do_queue_select priority=%d ,qsel = %d\n",pattrib->priority ,qsel));
3402 #ifdef CONFIG_CONCURRENT_MODE
3403 // if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
3407 pattrib->qsel = qsel;
3411 * The main transmit(tx) entry
3415 * 0 success, hardware will handle this xmit frame(packet)
3418 s32 rtw_xmit(_adapter *padapter, _pkt **ppkt)
3420 static u32 start = 0;
3421 static u32 drop_cnt = 0;
3422 #ifdef CONFIG_AP_MODE
3425 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3426 struct xmit_frame *pxmitframe = NULL;
3427 #ifdef CONFIG_BR_EXT
3428 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3429 void *br_port = NULL;
3430 #endif // CONFIG_BR_EXT
3434 DBG_COUNTER(padapter->tx_logs.core_tx);
3437 start = rtw_get_current_time();
3439 pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
3441 if (rtw_get_passing_time_ms(start) > 2000) {
3443 DBG_871X("DBG_TX_DROP_FRAME %s no more pxmitframe, drop_cnt:%u\n", __FUNCTION__, drop_cnt);
3444 start = rtw_get_current_time();
3448 if (pxmitframe == NULL) {
3450 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: no more pxmitframe\n"));
3451 DBG_COUNTER(padapter->tx_logs.core_tx_err_pxmitframe);
3455 #ifdef CONFIG_BR_EXT
3457 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3458 br_port = padapter->pnetdev->br_port;
3459 #else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3461 br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
3463 #endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3465 if( br_port && check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE)
3467 res = rtw_br_client_tx(padapter, ppkt);
3470 rtw_free_xmitframe(pxmitpriv, pxmitframe);
3471 DBG_COUNTER(padapter->tx_logs.core_tx_err_brtx);
3476 #endif // CONFIG_BR_EXT
3478 res = update_attrib(padapter, *ppkt, &pxmitframe->attrib);
3480 #ifdef CONFIG_WAPI_SUPPORT
3481 if(pxmitframe->attrib.ether_type != 0x88B4)
3483 if(rtw_wapi_drop_for_key_absent(padapter, pxmitframe->attrib.ra))
3485 WAPI_TRACE(WAPI_RX,"drop for key absend when tx \n");
3491 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: update attrib fail\n"));
3492 #ifdef DBG_TX_DROP_FRAME
3493 DBG_871X("DBG_TX_DROP_FRAME %s update attrib fail\n", __FUNCTION__);
3495 rtw_free_xmitframe(pxmitpriv, pxmitframe);
3498 pxmitframe->pkt = *ppkt;
3500 rtw_led_control(padapter, LED_CTL_TX);
3502 do_queue_select(padapter, &pxmitframe->attrib);
3504 #ifdef CONFIG_AP_MODE
3505 _enter_critical_bh(&pxmitpriv->lock, &irqL0);
3506 if(xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE)
3508 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
3509 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue);
3512 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
3515 if (rtw_hal_xmit(padapter, pxmitframe) == _FALSE)
3522 sint xmitframe_enqueue_for_tdls_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
3527 struct sta_info *ptdls_sta=NULL;
3528 struct sta_priv *pstapriv = &padapter->stapriv;
3529 struct pkt_attrib *pattrib = &pxmitframe->attrib;
3530 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3533 ptdls_sta=rtw_get_stainfo(pstapriv, pattrib->dst);
3534 if(ptdls_sta==NULL){
3536 }else if(ptdls_sta->tdls_sta_state&TDLS_LINKED_STATE){
3538 if(pattrib->triggered==1)
3544 _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
3546 if(ptdls_sta->state&WIFI_SLEEP_STATE)
3548 rtw_list_delete(&pxmitframe->list);
3550 //_enter_critical_bh(&psta->sleep_q.lock, &irqL);
3552 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptdls_sta->sleep_q));
3554 ptdls_sta->sleepq_len++;
3555 ptdls_sta->sleepq_ac_len++;
3557 //indicate 4-AC queue bit in TDLS peer traffic indication
3558 switch(pattrib->priority)
3562 ptdls_sta->uapsd_bk = ptdls_sta->uapsd_bk | BIT(1);
3566 ptdls_sta->uapsd_vi = ptdls_sta->uapsd_vi | BIT(1);
3570 ptdls_sta->uapsd_vo = ptdls_sta->uapsd_vo | BIT(1);
3575 ptdls_sta->uapsd_be = ptdls_sta->uapsd_be | BIT(1);
3579 if(ptdls_sta->sleepq_len==1)
3581 //transmit TDLS PTI via AP
3582 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_SD_PTI);
3588 _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
3594 #endif //CONFIG_TDLS
3596 #define RTW_HIQ_FILTER_ALLOW_ALL 0
3597 #define RTW_HIQ_FILTER_ALLOW_SPECIAL 1
3598 #define RTW_HIQ_FILTER_DENY_ALL 2
3600 inline bool xmitframe_hiq_filter(struct xmit_frame *xmitframe)
3602 bool allow = _FALSE;
3603 _adapter *adapter = xmitframe->padapter;
3604 struct registry_priv *registry = &adapter->registrypriv;
3606 if (adapter->interface_type != RTW_PCIE) {
3608 if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_SPECIAL) {
3610 struct pkt_attrib *attrib = &xmitframe->attrib;
3612 if (attrib->ether_type == 0x0806
3613 || attrib->ether_type == 0x888e
3614 #ifdef CONFIG_WAPI_SUPPORT
3615 || attrib->ether_type == 0x88B4
3620 DBG_871X(FUNC_ADPT_FMT" ether_type:0x%04x%s\n", FUNC_ADPT_ARG(xmitframe->padapter)
3621 , attrib->ether_type, attrib->dhcp_pkt?" DHCP":"");
3625 else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_ALL) {
3628 else if (registry->hiq_filter == RTW_HIQ_FILTER_DENY_ALL) {
3637 #if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS)
3639 sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
3643 struct sta_info *psta=NULL;
3644 struct sta_priv *pstapriv = &padapter->stapriv;
3645 struct pkt_attrib *pattrib = &pxmitframe->attrib;
3646 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3647 sint bmcst = IS_MCAST(pattrib->ra);
3648 bool update_tim = _FALSE;
3650 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
3652 if( ptdlsinfo->setup_state == TDLS_LINKED_STATE )
3654 ret = xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pxmitframe);
3657 #endif //CONFIG_TDLS
3659 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _FALSE)
3661 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_fwstate);
3667 psta = pattrib->psta;
3671 DBG_871X("%s, call rtw_get_stainfo()\n", __func__);
3672 psta=rtw_get_stainfo(pstapriv, pattrib->ra);
3677 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_nosta);
3678 DBG_871X("%s, psta==NUL\n", __func__);
3682 if(!(psta->state &_FW_LINKED))
3684 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_link);
3685 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
3689 if(pattrib->triggered==1)
3691 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_trigger);
3692 //DBG_871X("directly xmit pspoll_triggered packet\n");
3694 //pattrib->triggered=0;
3695 if (bmcst && xmitframe_hiq_filter(pxmitframe) == _TRUE)
3696 pattrib->qsel = 0x11;//HIQ
3704 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
3706 if(pstapriv->sta_dz_bitmap)//if anyone sta is in ps mode
3708 //pattrib->qsel = 0x11;//HIQ
3710 rtw_list_delete(&pxmitframe->list);
3712 //_enter_critical_bh(&psta->sleep_q.lock, &irqL);
3714 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
3718 if (!(pstapriv->tim_bitmap & BIT(0)))
3721 pstapriv->tim_bitmap |= BIT(0);//
3722 pstapriv->sta_dz_bitmap |= BIT(0);
3724 //DBG_871X("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap);
3726 if (update_tim == _TRUE) {
3727 if (is_broadcast_mac_addr(pattrib->ra))
3728 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer BC");
3730 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer MC");
3732 chk_bmc_sleepq_cmd(padapter);
3735 //_exit_critical_bh(&psta->sleep_q.lock, &irqL);
3739 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_mcast);
3743 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
3750 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
3752 if(psta->state&WIFI_SLEEP_STATE)
3756 if(pstapriv->sta_dz_bitmap&BIT(psta->aid))
3758 rtw_list_delete(&pxmitframe->list);
3760 //_enter_critical_bh(&psta->sleep_q.lock, &irqL);
3762 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
3766 switch(pattrib->priority)
3770 wmmps_ac = psta->uapsd_bk&BIT(0);
3774 wmmps_ac = psta->uapsd_vi&BIT(0);
3778 wmmps_ac = psta->uapsd_vo&BIT(0);
3783 wmmps_ac = psta->uapsd_be&BIT(0);
3788 psta->sleepq_ac_len++;
3790 if(((psta->has_legacy_ac) && (!wmmps_ac)) ||((!psta->has_legacy_ac)&&(wmmps_ac)))
3792 if (!(pstapriv->tim_bitmap & BIT(psta->aid)))
3795 pstapriv->tim_bitmap |= BIT(psta->aid);
3797 //DBG_871X("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap);
3799 if(update_tim == _TRUE)
3801 //DBG_871X("sleepq_len==1, update BCNTIM\n");
3802 //upate BCN for TIM IE
3803 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer UC");
3807 //_exit_critical_bh(&psta->sleep_q.lock, &irqL);
3809 //if(psta->sleepq_len > (NR_XMITFRAME>>3))
3811 // wakeup_sta_to_xmit(padapter, psta);
3816 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_ucast);
3821 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
3827 static void dequeue_xmitframes_to_sleeping_queue(_adapter *padapter, struct sta_info *psta, _queue *pframequeue)
3830 _list *plist, *phead;
3832 struct tx_servq *ptxservq;
3833 struct pkt_attrib *pattrib;
3834 struct xmit_frame *pxmitframe;
3835 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
3837 phead = get_list_head(pframequeue);
3838 plist = get_next(phead);
3840 while (rtw_end_of_queue_search(phead, plist) == _FALSE)
3842 pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3844 plist = get_next(plist);
3846 pattrib = &pxmitframe->attrib;
3848 pattrib->triggered = 0;
3850 ret = xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
3854 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
3857 phwxmits[ac_index].accnt--;
3861 //DBG_871X("xmitframe_enqueue_for_sleeping_sta return _FALSE\n");
3868 void stop_sta_xmit(_adapter *padapter, struct sta_info *psta)
3871 struct sta_info *psta_bmc;
3872 struct sta_xmit_priv *pstaxmitpriv;
3873 struct sta_priv *pstapriv = &padapter->stapriv;
3874 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3876 pstaxmitpriv = &psta->sta_xmitpriv;
3879 psta_bmc = rtw_get_bcmc_stainfo(padapter);
3882 _enter_critical_bh(&pxmitpriv->lock, &irqL0);
3884 psta->state |= WIFI_SLEEP_STATE;
3887 if( !(psta->tdls_sta_state & TDLS_LINKED_STATE) )
3888 #endif //CONFIG_TDLS
3889 pstapriv->sta_dz_bitmap |= BIT(psta->aid);
3893 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
3894 rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));
3897 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
3898 rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));
3901 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
3902 rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
3905 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
3906 rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));
3909 if( !(psta->tdls_sta_state & TDLS_LINKED_STATE) )
3911 if( psta_bmc != NULL )
3913 #endif //CONFIG_TDLS
3917 pstaxmitpriv = &psta_bmc->sta_xmitpriv;
3918 dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending);
3919 rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
3925 #endif //CONFIG_TDLS
3926 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
3931 void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta)
3934 u8 update_mask=0, wmmps_ac=0;
3935 struct sta_info *psta_bmc;
3936 _list *xmitframe_plist, *xmitframe_phead;
3937 struct xmit_frame *pxmitframe=NULL;
3938 struct sta_priv *pstapriv = &padapter->stapriv;
3939 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3941 psta_bmc = rtw_get_bcmc_stainfo(padapter);
3944 //_enter_critical_bh(&psta->sleep_q.lock, &irqL);
3945 _enter_critical_bh(&pxmitpriv->lock, &irqL);
3947 xmitframe_phead = get_list_head(&psta->sleep_q);
3948 xmitframe_plist = get_next(xmitframe_phead);
3950 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
3952 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
3954 xmitframe_plist = get_next(xmitframe_plist);
3956 rtw_list_delete(&pxmitframe->list);
3958 switch(pxmitframe->attrib.priority)
3962 wmmps_ac = psta->uapsd_bk&BIT(1);
3966 wmmps_ac = psta->uapsd_vi&BIT(1);
3970 wmmps_ac = psta->uapsd_vo&BIT(1);
3975 wmmps_ac = psta->uapsd_be&BIT(1);
3980 if(psta->sleepq_len>0)
3981 pxmitframe->attrib.mdata = 1;
3983 pxmitframe->attrib.mdata = 0;
3987 psta->sleepq_ac_len--;
3988 if(psta->sleepq_ac_len>0)
3990 pxmitframe->attrib.mdata = 1;
3991 pxmitframe->attrib.eosp = 0;
3995 pxmitframe->attrib.mdata = 0;
3996 pxmitframe->attrib.eosp = 1;
4000 pxmitframe->attrib.triggered = 1;
4003 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
4004 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
4006 rtw_os_xmit_complete(padapter, pxmitframe);
4008 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
4010 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
4014 if(psta->sleepq_len==0)
4017 if( psta->tdls_sta_state & TDLS_LINKED_STATE )
4019 if(psta->state&WIFI_SLEEP_STATE)
4020 psta->state ^= WIFI_SLEEP_STATE;
4024 #endif //CONFIG_TDLS
4026 if (pstapriv->tim_bitmap & BIT(psta->aid)) {
4027 //DBG_871X("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap);
4028 //upate BCN for TIM IE
4029 //update_BCNTIM(padapter);
4030 update_mask = BIT(0);
4033 pstapriv->tim_bitmap &= ~BIT(psta->aid);
4035 if(psta->state&WIFI_SLEEP_STATE)
4036 psta->state ^= WIFI_SLEEP_STATE;
4038 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
4040 psta->expire_to = pstapriv->expire_to;
4041 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
4044 pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
4051 if((pstapriv->sta_dz_bitmap&0xfffe) == 0x0)//no any sta in ps mode
4053 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
4054 xmitframe_plist = get_next(xmitframe_phead);
4056 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
4058 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4060 xmitframe_plist = get_next(xmitframe_plist);
4062 rtw_list_delete(&pxmitframe->list);
4064 psta_bmc->sleepq_len--;
4065 if(psta_bmc->sleepq_len>0)
4066 pxmitframe->attrib.mdata = 1;
4068 pxmitframe->attrib.mdata = 0;
4071 pxmitframe->attrib.triggered = 1;
4073 _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
4074 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
4076 rtw_os_xmit_complete(padapter, pxmitframe);
4078 _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
4081 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
4085 if(psta_bmc->sleepq_len==0)
4087 if (pstapriv->tim_bitmap & BIT(0)) {
4088 //DBG_871X("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap);
4089 //upate BCN for TIM IE
4090 //update_BCNTIM(padapter);
4091 update_mask |= BIT(1);
4094 pstapriv->tim_bitmap &= ~BIT(0);
4095 pstapriv->sta_dz_bitmap &= ~BIT(0);
4101 //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
4102 _exit_critical_bh(&pxmitpriv->lock, &irqL);
4106 //update_BCNTIM(padapter);
4107 if ((update_mask & (BIT(0)|BIT(1))) == (BIT(0)|BIT(1)))
4108 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear UC&BMC");
4109 else if ((update_mask & BIT(1)) == BIT(1))
4110 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear BMC");
4112 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear UC");
4117 void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta)
4121 _list *xmitframe_plist, *xmitframe_phead;
4122 struct xmit_frame *pxmitframe=NULL;
4123 struct sta_priv *pstapriv = &padapter->stapriv;
4124 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4127 //_enter_critical_bh(&psta->sleep_q.lock, &irqL);
4128 _enter_critical_bh(&pxmitpriv->lock, &irqL);
4130 xmitframe_phead = get_list_head(&psta->sleep_q);
4131 xmitframe_plist = get_next(xmitframe_phead);
4133 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
4135 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4137 xmitframe_plist = get_next(xmitframe_plist);
4139 switch(pxmitframe->attrib.priority)
4143 wmmps_ac = psta->uapsd_bk&BIT(1);
4147 wmmps_ac = psta->uapsd_vi&BIT(1);
4151 wmmps_ac = psta->uapsd_vo&BIT(1);
4156 wmmps_ac = psta->uapsd_be&BIT(1);
4163 rtw_list_delete(&pxmitframe->list);
4166 psta->sleepq_ac_len--;
4168 if(psta->sleepq_ac_len>0)
4170 pxmitframe->attrib.mdata = 1;
4171 pxmitframe->attrib.eosp = 0;
4175 pxmitframe->attrib.mdata = 0;
4176 pxmitframe->attrib.eosp = 1;
4179 pxmitframe->attrib.triggered = 1;
4182 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
4184 rtw_os_xmit_complete(padapter, pxmitframe);
4187 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
4189 if((psta->sleepq_ac_len==0) && (!psta->has_legacy_ac) && (wmmps_ac))
4192 if(psta->tdls_sta_state & TDLS_LINKED_STATE )
4194 //_exit_critical_bh(&psta->sleep_q.lock, &irqL);
4195 _exit_critical_bh(&pxmitpriv->lock, &irqL);
4198 #endif //CONFIG_TDLS
4199 pstapriv->tim_bitmap &= ~BIT(psta->aid);
4201 //DBG_871X("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap);
4202 //upate BCN for TIM IE
4203 //update_BCNTIM(padapter);
4204 update_beacon(padapter, _TIM_IE_, NULL, _TRUE);
4205 //update_mask = BIT(0);
4210 //_exit_critical_bh(&psta->sleep_q.lock, &irqL);
4211 _exit_critical_bh(&pxmitpriv->lock, &irqL);
4217 #ifdef CONFIG_XMIT_THREAD_MODE
4218 void enqueue_pending_xmitbuf(
4219 struct xmit_priv *pxmitpriv,
4220 struct xmit_buf *pxmitbuf)
4224 _adapter *pri_adapter = pxmitpriv->adapter;
4226 pqueue = &pxmitpriv->pending_xmitbuf_queue;
4228 _enter_critical_bh(&pqueue->lock, &irql);
4229 rtw_list_delete(&pxmitbuf->list);
4230 rtw_list_insert_tail(&pxmitbuf->list, get_list_head(pqueue));
4231 _exit_critical_bh(&pqueue->lock, &irql);
4235 #if defined(CONFIG_SDIO_HCI) && defined(CONFIG_CONCURRENT_MODE)
4236 if (pri_adapter->adapter_type > PRIMARY_ADAPTER)
4237 pri_adapter = pri_adapter->pbuddy_adapter;
4238 #endif //SDIO_HCI + CONCURRENT
4239 _rtw_up_sema(&(pri_adapter->xmitpriv.xmit_sema));
4243 void enqueue_pending_xmitbuf_to_head(
4244 struct xmit_priv *pxmitpriv,
4245 struct xmit_buf *pxmitbuf)
4249 _adapter *pri_adapter = pxmitpriv->adapter;
4251 pqueue = &pxmitpriv->pending_xmitbuf_queue;
4253 _enter_critical_bh(&pqueue->lock, &irql);
4254 rtw_list_delete(&pxmitbuf->list);
4255 rtw_list_insert_head(&pxmitbuf->list, get_list_head(pqueue));
4256 _exit_critical_bh(&pqueue->lock, &irql);
4259 struct xmit_buf* dequeue_pending_xmitbuf(
4260 struct xmit_priv *pxmitpriv)
4263 struct xmit_buf *pxmitbuf;
4268 pqueue = &pxmitpriv->pending_xmitbuf_queue;
4270 _enter_critical_bh(&pqueue->lock, &irql);
4272 if (_rtw_queue_empty(pqueue) == _FALSE)
4274 _list *plist, *phead;
4276 phead = get_list_head(pqueue);
4277 plist = get_next(phead);
4278 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
4279 rtw_list_delete(&pxmitbuf->list);
4282 _exit_critical_bh(&pqueue->lock, &irql);
4287 struct xmit_buf* dequeue_pending_xmitbuf_under_survey(
4288 struct xmit_priv *pxmitpriv)
4291 struct xmit_buf *pxmitbuf;
4292 #ifdef CONFIG_USB_HCI
4293 struct xmit_frame *pxmitframe;
4299 pqueue = &pxmitpriv->pending_xmitbuf_queue;
4301 _enter_critical_bh(&pqueue->lock, &irql);
4303 if (_rtw_queue_empty(pqueue) == _FALSE)
4305 _list *plist, *phead;
4308 phead = get_list_head(pqueue);
4311 plist = get_next(plist);
4312 if (plist == phead) break;
4314 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
4316 #ifdef CONFIG_USB_HCI
4317 pxmitframe = (struct xmit_frame*)pxmitbuf->priv_data;
4320 type = GetFrameSubType(pxmitbuf->pbuf + TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
4324 DBG_871X("%s, !!!ERROR!!! For USB, TODO ITEM \n", __FUNCTION__);
4327 type = GetFrameSubType(pxmitbuf->pbuf + TXDESC_OFFSET);
4330 if ((type == WIFI_PROBEREQ) ||
4331 (type == WIFI_DATA_NULL) ||
4332 (type == WIFI_QOS_DATA_NULL))
4334 rtw_list_delete(&pxmitbuf->list);
4341 _exit_critical_bh(&pqueue->lock, &irql);
4346 sint check_pending_xmitbuf(
4347 struct xmit_priv *pxmitpriv)
4353 pqueue = &pxmitpriv->pending_xmitbuf_queue;
4355 _enter_critical_bh(&pqueue->lock, &irql);
4357 if(_rtw_queue_empty(pqueue) == _FALSE)
4360 _exit_critical_bh(&pqueue->lock, &irql);
4365 thread_return rtw_xmit_thread(thread_context context)
4372 padapter = (PADAPTER)context;
4374 thread_enter("RTW_XMIT_THREAD");
4377 err = rtw_hal_xmit_thread_handler(padapter);
4378 flush_signals_thread();
4379 } while (_SUCCESS == err);
4381 _rtw_up_sema(&padapter->xmitpriv.terminate_xmitthread_sema);
4387 void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms)
4389 sctx->timeout_ms = timeout_ms;
4390 sctx->submit_time= rtw_get_current_time();
4391 #ifdef PLATFORM_LINUX /* TODO: add condition wating interface for other os */
4392 init_completion(&sctx->done);
4394 sctx->status = RTW_SCTX_SUBMITTED;
4397 int rtw_sctx_wait(struct submit_ctx *sctx)
4400 unsigned long expire;
4403 #ifdef PLATFORM_LINUX
4404 expire= sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT;
4405 if (!wait_for_completion_timeout(&sctx->done, expire)) {
4406 /* timeout, do something?? */
4407 status = RTW_SCTX_DONE_TIMEOUT;
4408 DBG_871X("%s timeout\n", __func__);
4410 status = sctx->status;
4414 if (status == RTW_SCTX_DONE_SUCCESS) {
4421 bool rtw_sctx_chk_waring_status(int status)
4424 case RTW_SCTX_DONE_UNKNOWN:
4425 case RTW_SCTX_DONE_BUF_ALLOC:
4426 case RTW_SCTX_DONE_BUF_FREE:
4428 case RTW_SCTX_DONE_DRV_STOP:
4429 case RTW_SCTX_DONE_DEV_REMOVE:
4436 void rtw_sctx_done_err(struct submit_ctx **sctx, int status)
4439 if (rtw_sctx_chk_waring_status(status))
4440 DBG_871X("%s status:%d\n", __func__, status);
4441 (*sctx)->status = status;
4442 #ifdef PLATFORM_LINUX
4443 complete(&((*sctx)->done));
4449 void rtw_sctx_done(struct submit_ctx **sctx)
4451 rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS);
4454 #ifdef CONFIG_XMIT_ACK
4456 #ifdef CONFIG_XMIT_ACK_POLLING
4457 s32 c2h_evt_hdl(_adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter);
4460 * rtw_ack_tx_polling -
4461 * @pxmitpriv: xmit_priv to address ack_tx_ops
4462 * @timeout_ms: timeout msec
4464 * Init ack_tx_ops and then do c2h_evt_hdl() and polling ack_tx_ops repeatedly
4465 * till tx report or timeout
4466 * Returns: _SUCCESS if TX report ok, _FAIL for others
4468 int rtw_ack_tx_polling(struct xmit_priv *pxmitpriv, u32 timeout_ms)
4471 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
4472 _adapter *adapter = container_of(pxmitpriv, _adapter, xmitpriv);
4474 pack_tx_ops->submit_time = rtw_get_current_time();
4475 pack_tx_ops->timeout_ms = timeout_ms;
4476 pack_tx_ops->status = RTW_SCTX_SUBMITTED;
4479 c2h_evt_hdl(adapter, NULL, rtw_hal_c2h_id_filter_ccx(adapter));
4480 if (pack_tx_ops->status != RTW_SCTX_SUBMITTED)
4483 if (adapter->bDriverStopped) {
4484 pack_tx_ops->status = RTW_SCTX_DONE_DRV_STOP;
4487 if (adapter->bSurpriseRemoved) {
4488 pack_tx_ops->status = RTW_SCTX_DONE_DEV_REMOVE;
4493 } while (rtw_get_passing_time_ms(pack_tx_ops->submit_time) < timeout_ms);
4495 if (pack_tx_ops->status == RTW_SCTX_SUBMITTED) {
4496 pack_tx_ops->status = RTW_SCTX_DONE_TIMEOUT;
4497 DBG_871X("%s timeout\n", __func__);
4500 if (pack_tx_ops->status == RTW_SCTX_DONE_SUCCESS)
4507 #ifdef CONFIG_DETECT_C2H_BY_POLLING
4508 s32 c2h_evt_hdl(_adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter);
4511 int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
4513 #ifdef CONFIG_DETECT_C2H_BY_POLLING
4514 _adapter *adapter = container_of(pxmitpriv, _adapter, xmitpriv);
4515 c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter);
4516 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
4521 pack_tx_ops->submit_time = rtw_get_current_time();
4522 pack_tx_ops->timeout_ms = timeout_ms;
4523 pack_tx_ops->status = RTW_SCTX_SUBMITTED;
4527 //check_c2hcmd = rtw_read8(adapter, 0x1AF);
4528 //check_ccx = rtw_read8(adapter, 0x1A0);
4529 rtw_hal_get_hwreg(adapter, HW_VAR_C2HEVT_CLEAR, (u8 *)(&check_c2hcmd));
4530 rtw_hal_get_hwreg(adapter, HW_VAR_C2HEVT_MSG_NORMAL, (u8 *)(&check_ccx));
4533 if (check_c2hcmd != 0)
4535 if (check_c2hcmd != 0xFF)
4537 c2h_evt_clear(adapter);
4539 else if (ccx_id_filter(check_ccx & 0x0F) == _TRUE)
4541 c2h_evt_hdl(adapter, NULL, ccx_id_filter);
4542 if (pack_tx_ops->status != RTW_SCTX_SUBMITTED)
4545 if (adapter->bDriverStopped) {
4546 pack_tx_ops->status = RTW_SCTX_DONE_DRV_STOP;
4549 if (adapter->bSurpriseRemoved) {
4550 pack_tx_ops->status = RTW_SCTX_DONE_DEV_REMOVE;
4555 } while (rtw_get_passing_time_ms(pack_tx_ops->submit_time) < timeout_ms);
4557 if (pack_tx_ops->status == RTW_SCTX_SUBMITTED) {
4558 pack_tx_ops->status = RTW_SCTX_DONE_TIMEOUT;
4559 DBG_871X("%s timeout\n", __func__);
4562 if (pack_tx_ops->status == RTW_SCTX_DONE_SUCCESS)
4567 #ifdef CONFIG_XMIT_ACK_POLLING
4568 return rtw_ack_tx_polling(pxmitpriv, timeout_ms);
4570 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
4572 pack_tx_ops->submit_time = rtw_get_current_time();
4573 pack_tx_ops->timeout_ms = timeout_ms;
4574 pack_tx_ops->status = RTW_SCTX_SUBMITTED;
4576 return rtw_sctx_wait(pack_tx_ops);
4581 void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)
4583 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
4585 if (pxmitpriv->ack_tx) {
4586 rtw_sctx_done_err(&pack_tx_ops, status);
4588 DBG_871X("%s ack_tx not set\n", __func__);
4591 #endif //CONFIG_XMIT_ACK