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>
26 #include <osdep_intf.h>
31 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
32 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
34 static void _init_txservq(struct tx_servq *ptxservq)
37 INIT_LIST_HEAD(&ptxservq->tx_pending);
38 _rtw_init_queue(&ptxservq->sta_pending);
43 void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
48 memset((unsigned char *)psta_xmitpriv, 0, sizeof (struct sta_xmit_priv));
50 spin_lock_init(&psta_xmitpriv->lock);
52 /* for(i = 0 ; i < MAX_NUMBLKS; i++) */
53 /* _init_txservq(&(psta_xmitpriv->blk_q[i])); */
55 _init_txservq(&psta_xmitpriv->be_q);
56 _init_txservq(&psta_xmitpriv->bk_q);
57 _init_txservq(&psta_xmitpriv->vi_q);
58 _init_txservq(&psta_xmitpriv->vo_q);
59 INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
60 INIT_LIST_HEAD(&psta_xmitpriv->apsd);
65 s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter)
68 struct xmit_buf *pxmitbuf;
69 struct xmit_frame *pxframe;
71 u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
72 u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
76 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
77 /* memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); */
79 spin_lock_init(&pxmitpriv->lock);
80 spin_lock_init(&pxmitpriv->lock_sctx);
81 sema_init(&pxmitpriv->xmit_sema, 0);
82 sema_init(&pxmitpriv->terminate_xmitthread_sema, 0);
85 Please insert all the queue initializaiton using _rtw_init_queue below
88 pxmitpriv->adapter = padapter;
90 _rtw_init_queue(&pxmitpriv->be_pending);
91 _rtw_init_queue(&pxmitpriv->bk_pending);
92 _rtw_init_queue(&pxmitpriv->vi_pending);
93 _rtw_init_queue(&pxmitpriv->vo_pending);
94 _rtw_init_queue(&pxmitpriv->bm_pending);
96 _rtw_init_queue(&pxmitpriv->free_xmit_queue);
99 Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
100 and initialize free_xmit_frame below.
101 Please also apply free_txobj to link_up all the xmit_frames...
104 pxmitpriv->pallocated_frame_buf = rtw_zvmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
106 if (pxmitpriv->pallocated_frame_buf == NULL){
107 pxmitpriv->pxmit_frame_buf =NULL;
108 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_frame fail!\n"));
112 pxmitpriv->pxmit_frame_buf = PTR_ALIGN(pxmitpriv->pallocated_frame_buf, 4);
114 pxframe = (struct xmit_frame*) pxmitpriv->pxmit_frame_buf;
116 for (i = 0; i < NR_XMITFRAME; i++)
118 INIT_LIST_HEAD(&(pxframe->list));
120 pxframe->padapter = padapter;
121 pxframe->frame_tag = NULL_FRAMETAG;
125 pxframe->buf_addr = NULL;
126 pxframe->pxmitbuf = NULL;
128 list_add_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue));
133 pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
135 pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
138 _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue);
139 _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue);
141 pxmitpriv->pallocated_xmitbuf = rtw_zvmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
143 if (pxmitpriv->pallocated_xmitbuf == NULL){
144 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_buf fail!\n"));
149 pxmitpriv->pxmitbuf = PTR_ALIGN(pxmitpriv->pallocated_xmitbuf, 4);
151 pxmitbuf = (struct xmit_buf*)pxmitpriv->pxmitbuf;
153 for (i = 0; i < NR_XMITBUFF; i++)
155 INIT_LIST_HEAD(&pxmitbuf->list);
157 pxmitbuf->priv_data = NULL;
158 pxmitbuf->padapter = padapter;
159 pxmitbuf->ext_tag = _FALSE;
161 /* Tx buf allocation may fail sometimes, so sleep and retry. */
162 if((res=rtw_os_xmit_resource_alloc(padapter, pxmitbuf,(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ))) == _FAIL) {
164 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf,(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
170 pxmitbuf->flags = XMIT_VO_QUEUE;
172 list_add_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue));
181 pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
183 /* init xframe_ext queue, the same count as extbuf */
184 _rtw_init_queue(&pxmitpriv->free_xframe_ext_queue);
186 pxmitpriv->xframe_ext_alloc_addr = rtw_zvmalloc(num_xmit_extbuf * sizeof(struct xmit_frame) + 4);
188 if (pxmitpriv->xframe_ext_alloc_addr == NULL){
189 pxmitpriv->xframe_ext = NULL;
190 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xframe_ext fail!\n"));
194 pxmitpriv->xframe_ext = PTR_ALIGN(pxmitpriv->xframe_ext_alloc_addr, 4);
195 pxframe = (struct xmit_frame*)pxmitpriv->xframe_ext;
197 for (i = 0; i < num_xmit_extbuf; i++) {
198 INIT_LIST_HEAD(&(pxframe->list));
200 pxframe->padapter = padapter;
201 pxframe->frame_tag = NULL_FRAMETAG;
205 pxframe->buf_addr = NULL;
206 pxframe->pxmitbuf = NULL;
208 pxframe->ext_tag = 1;
210 list_add_tail(&(pxframe->list), &(pxmitpriv->free_xframe_ext_queue.queue));
214 pxmitpriv->free_xframe_ext_cnt = num_xmit_extbuf;
216 /* Init xmit extension buff */
217 _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
219 pxmitpriv->pallocated_xmit_extbuf = rtw_zvmalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4);
221 if (pxmitpriv->pallocated_xmit_extbuf == NULL){
222 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_extbuf fail!\n"));
227 pxmitpriv->pxmit_extbuf = PTR_ALIGN(pxmitpriv->pallocated_xmit_extbuf, 4);
229 pxmitbuf = (struct xmit_buf*)pxmitpriv->pxmit_extbuf;
231 for (i = 0; i < num_xmit_extbuf; i++)
233 INIT_LIST_HEAD(&pxmitbuf->list);
235 pxmitbuf->priv_data = NULL;
236 pxmitbuf->padapter = padapter;
237 pxmitbuf->ext_tag = _TRUE;
240 pxmitbuf->pallocated_buf = rtw_zmalloc(max_xmit_extbuf_size);
241 if (pxmitbuf->pallocated_buf == NULL)
247 pxmitbuf->pbuf = PTR_ALIGN(pxmitbuf->pallocated_buf, 4);
250 if((res=rtw_os_xmit_resource_alloc(padapter, pxmitbuf,max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)) == _FAIL) {
255 list_add_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue));
256 #ifdef DBG_XMIT_BUF_EXT
263 pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
265 rtw_alloc_hwxmits(padapter);
266 rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
268 for (i = 0; i < 4; i ++)
269 pxmitpriv->wmm_para_seq[i] = i;
271 pxmitpriv->txirp_cnt=1;
273 sema_init(&(pxmitpriv->tx_retevt), 0);
275 /* per AC pending irp */
276 pxmitpriv->beq_cnt = 0;
277 pxmitpriv->bkq_cnt = 0;
278 pxmitpriv->viq_cnt = 0;
279 pxmitpriv->voq_cnt = 0;
281 #ifdef CONFIG_XMIT_ACK
282 pxmitpriv->ack_tx = _FALSE;
283 mutex_init(&pxmitpriv->ack_tx_mutex);
284 rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0);
287 rtw_hal_init_xmit_priv(padapter);
296 void _rtw_free_xmit_priv (struct xmit_priv *pxmitpriv)
299 _adapter *padapter = pxmitpriv->adapter;
300 struct xmit_frame *pxmitframe = (struct xmit_frame*) pxmitpriv->pxmit_frame_buf;
301 struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
302 u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
303 u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
307 rtw_hal_free_xmit_priv(padapter);
309 if(pxmitpriv->pxmit_frame_buf==NULL)
312 for(i=0; i<NR_XMITFRAME; i++)
314 rtw_os_xmit_complete(padapter, pxmitframe);
319 for(i=0; i<NR_XMITBUFF; i++)
321 rtw_os_xmit_resource_free(padapter, pxmitbuf,(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
323 /* if(pxmitbuf->pallocated_buf) */
324 /* rtw_mfree(pxmitbuf->pallocated_buf, MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ); */
329 if(pxmitpriv->pallocated_frame_buf) {
330 rtw_vmfree(pxmitpriv->pallocated_frame_buf, NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
333 if(pxmitpriv->pallocated_xmitbuf) {
334 rtw_vmfree(pxmitpriv->pallocated_xmitbuf, NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
337 /* free xframe_ext queue, the same count as extbuf */
338 if ((pxmitframe = (struct xmit_frame*)pxmitpriv->xframe_ext)) {
339 for (i=0; i<num_xmit_extbuf; i++) {
340 rtw_os_xmit_complete(padapter, pxmitframe);
344 if (pxmitpriv->xframe_ext_alloc_addr)
345 rtw_vmfree(pxmitpriv->xframe_ext_alloc_addr, num_xmit_extbuf * sizeof(struct xmit_frame) + 4);
347 /* free xmit extension buff */
348 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
349 for(i=0; i<num_xmit_extbuf; i++)
351 rtw_os_xmit_resource_free(padapter, pxmitbuf,(max_xmit_extbuf_size + XMITBUF_ALIGN_SZ));
353 /* if(pxmitbuf->pallocated_buf) */
354 /* rtw_mfree(pxmitbuf->pallocated_buf, max_xmit_extbuf_size); */
359 if(pxmitpriv->pallocated_xmit_extbuf) {
360 rtw_vmfree(pxmitpriv->pallocated_xmit_extbuf, num_xmit_extbuf * sizeof(struct xmit_buf) + 4);
363 rtw_free_hwxmits(padapter);
365 #ifdef CONFIG_XMIT_ACK
366 mutex_destroy(&pxmitpriv->ack_tx_mutex);
374 static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe)
377 struct pkt_attrib *pattrib = &pxmitframe->attrib;
378 struct sta_info *psta = pattrib->psta;
379 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
380 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
384 psta = pattrib->psta;
388 DBG_8723A("%s, call rtw_get_stainfo()\n", __func__);
389 psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] );
394 DBG_8723A("%s, psta==NUL\n", __func__);
398 if(!(psta->state &_FW_LINKED))
400 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
404 if (pattrib->nr_frags != 1)
406 sz = padapter->xmitpriv.frag_len;
410 sz = pattrib->last_txcmdsz;
413 /* (1) RTS_Threshold is compared to the MPDU, not MSDU. */
414 /* (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. */
415 /* Other fragments are protected by previous fragment. */
416 /* So we only need to check the length of first fragment. */
417 if(pmlmeext->cur_wireless_mode < WIRELESS_11_24N || padapter->registrypriv.wifi_spec) {
418 if(sz > padapter->registrypriv.rts_thresh) {
419 pattrib->vcs_mode = RTS_CTS;
422 pattrib->vcs_mode = RTS_CTS;
423 else if(psta->cts2self)
424 pattrib->vcs_mode = CTS_TO_SELF;
426 pattrib->vcs_mode = NONE_VCS;
431 if((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && (pattrib->ampdu_en==_TRUE) &&
432 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_ ))
434 pattrib->vcs_mode = CTS_TO_SELF;
438 /* check ERP protection */
439 if(psta->rtsen || psta->cts2self)
442 pattrib->vcs_mode = RTS_CTS;
443 else if(psta->cts2self)
444 pattrib->vcs_mode = CTS_TO_SELF;
449 /* check HT op mode */
452 u8 HTOpMode = pmlmeinfo->HT_protection;
453 if((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) ||
454 (!pmlmeext->cur_bwmode && HTOpMode == 3) )
456 pattrib->vcs_mode = RTS_CTS;
462 if(sz > padapter->registrypriv.rts_thresh)
464 pattrib->vcs_mode = RTS_CTS;
468 /* to do list: check MIMO power save condition. */
470 /* check AMPDU aggregation for TXOP */
471 if(pattrib->ampdu_en==_TRUE)
473 pattrib->vcs_mode = RTS_CTS;
477 pattrib->vcs_mode = NONE_VCS;
483 static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *psta)
486 pattrib->vcs_mode = RTS_CTS;
487 else if(psta->cts2self)
488 pattrib->vcs_mode = CTS_TO_SELF;
490 pattrib->vcs_mode = NONE_VCS;*/
494 pattrib->triggered=0;
496 /* qos_en, ht_en, init rate, ,bw, ch_offset, sgi */
497 pattrib->qos_en = psta->qos_option;
499 pattrib->raid = psta->raid;
500 #ifdef CONFIG_80211N_HT
501 pattrib->ht_en = psta->htpriv.ht_option;
502 pattrib->bwmode = psta->htpriv.bwmode;
503 pattrib->ch_offset = psta->htpriv.ch_offset;
504 pattrib->sgi= psta->htpriv.sgi;
505 pattrib->ampdu_en = _FALSE;
506 #endif /* CONFIG_80211N_HT */
507 /* if(pattrib->ht_en && psta->htpriv.ampdu_enable) */
509 /* if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) */
510 /* pattrib->ampdu_en = _TRUE; */
513 pattrib->retry_ctrl = _FALSE;
516 u8 qos_acm(u8 acm_mask, u8 priority)
518 u8 change_priority = priority;
524 if(acm_mask & BIT(1))
532 if(acm_mask & BIT(2))
537 if(acm_mask & BIT(3))
541 DBG_8723A("qos_acm(): invalid pattrib->priority: %d!!!\n", priority);
545 return change_priority;
548 static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
550 struct ethhdr etherhdr;
552 s32 UserPriority = 0;
554 _rtw_open_pktfile(ppktfile->pkt, ppktfile);
555 _rtw_pktfile_read(ppktfile, (unsigned char*)ðerhdr, ETH_HLEN);
557 /* get UserPriority from IP hdr */
558 if (pattrib->ether_type == 0x0800) {
559 _rtw_pktfile_read(ppktfile, (u8*)&ip_hdr, sizeof(ip_hdr));
560 /* UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3; */
561 UserPriority = ip_hdr.tos >> 5;
562 } else if (pattrib->ether_type == 0x888e) {
563 /* "When priority processing of data frames is supported, */
564 /* a STA's SME should send EAPOL-Key frames at the highest priority." */
568 pattrib->priority = UserPriority;
569 pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
570 pattrib->subtype = WIFI_QOS_DATA_TYPE;
573 static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib)
576 struct pkt_file pktfile;
577 struct sta_info *psta = NULL;
578 struct ethhdr etherhdr;
581 struct sta_priv *pstapriv = &padapter->stapriv;
582 struct security_priv *psecuritypriv = &padapter->securitypriv;
583 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
584 struct qos_priv *pqospriv= &pmlmepriv->qospriv;
589 _rtw_open_pktfile(pkt, &pktfile);
590 i = _rtw_pktfile_read(&pktfile, (u8*)ðerhdr, ETH_HLEN);
592 pattrib->ether_type = ntohs(etherhdr.h_proto);
594 memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN);
595 memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN);
599 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
600 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
601 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
602 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
604 else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
605 memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
606 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
608 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
609 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
610 memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
613 pattrib->pktlen = pktfile.pkt_len;
615 if (ETH_P_IP == pattrib->ether_type)
617 /* The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time */
618 /* to prevent DHCP protocol fail */
620 _rtw_pktfile_read(&pktfile, &tmp[0], 24);
621 pattrib->dhcp_pkt = 0;
622 if (pktfile.pkt_len > 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */
623 if (ETH_P_IP == pattrib->ether_type) {/* IP header */
624 if (((tmp[21] == 68) && (tmp[23] == 67)) ||
625 ((tmp[21] == 67) && (tmp[23] == 68))) {
626 /* 68 : UDP BOOTP client */
627 /* 67 : UDP BOOTP server */
628 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("======================update_attrib: get DHCP Packet \n"));
629 pattrib->dhcp_pkt = 1;
633 } else if (0x888e == pattrib->ether_type) {
634 DBG_8723A_LEVEL(_drv_always_, "send eapol packet\n");
637 if ( (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) )
639 rtw_set_scan_deny(padapter, 3000);
643 /* If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */
644 if ( (pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) )
646 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
650 bmcast = IS_MCAST(pattrib->ra);
654 psta = rtw_get_bcmc_stainfo(padapter);
656 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
657 if (psta == NULL) { /* if we cannot get psta => drrp the pkt */
658 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT"\n", MAC_ARG(pattrib->ra)));
659 #ifdef DBG_TX_DROP_FRAME
660 DBG_8723A("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __FUNCTION__, MAC_ARG(pattrib->ra));
665 else if((check_fwstate(pmlmepriv, WIFI_AP_STATE)==_TRUE)&&(!(psta->state & _FW_LINKED)))
674 pattrib->mac_id = psta->mac_id;
675 /* DBG_8723A("%s ==> mac_id(%d)\n",__FUNCTION__,pattrib->mac_id ); */
676 pattrib->psta = psta;
680 /* if we cannot get psta => drop the pkt */
681 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT "\n", MAC_ARG(pattrib->ra)));
682 #ifdef DBG_TX_DROP_FRAME
683 DBG_8723A("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __FUNCTION__, MAC_ARG(pattrib->ra));
689 pattrib->ack_policy = 0;
690 /* get ether_hdr_len */
691 pattrib->pkt_hdrlen = ETH_HLEN;/* pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; vlan tag */
693 pattrib->hdrlen = WLAN_HDR_A3_LEN;
694 pattrib->subtype = WIFI_DATA_TYPE;
695 pattrib->priority = 0;
697 if (check_fwstate(pmlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
700 set_qos(&pktfile, pattrib);
704 if(pqospriv->qos_option)
706 set_qos(&pktfile, pattrib);
708 if(pmlmepriv->acm_mask != 0)
710 pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority);
715 if (psta->ieee8021x_blocked == _TRUE) {
716 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\n psta->ieee8021x_blocked == _TRUE \n"));
718 pattrib->encrypt = 0;
720 if((pattrib->ether_type != 0x888e) && (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _FALSE)) {
721 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\npsta->ieee8021x_blocked == _TRUE, pattrib->ether_type(%.4x) != 0x888e\n",pattrib->ether_type));
722 #ifdef DBG_TX_DROP_FRAME
723 DBG_8723A("DBG_TX_DROP_FRAME %s psta->ieee8021x_blocked == _TRUE, pattrib->ether_type(%04x) != 0x888e\n", __FUNCTION__,pattrib->ether_type);
729 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
731 switch(psecuritypriv->dot11AuthAlgrthm)
733 case dot11AuthAlgrthm_Open:
734 case dot11AuthAlgrthm_Shared:
735 case dot11AuthAlgrthm_Auto:
736 pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
738 case dot11AuthAlgrthm_8021X:
740 pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
742 pattrib->key_idx = 0;
745 pattrib->key_idx = 0;
751 switch (pattrib->encrypt)
756 pattrib->icv_len = 4;
761 pattrib->icv_len = 4;
763 if(padapter->securitypriv.busetkipkey==_FAIL)
765 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\npadapter->securitypriv.busetkipkey(%d)==_FAIL drop packet\n", padapter->securitypriv.busetkipkey));
766 #ifdef DBG_TX_DROP_FRAME
767 DBG_8723A("DBG_TX_DROP_FRAME %s padapter->securitypriv.busetkipkey(%d)==_FAIL drop packet\n", __FUNCTION__, padapter->securitypriv.busetkipkey);
775 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("pattrib->encrypt=%d (_AES_)\n",pattrib->encrypt));
777 pattrib->icv_len = 8;
782 pattrib->icv_len = 0;
786 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
787 ("update_attrib: encrypt=%d securitypriv.sw_encrypt=%d\n",
788 pattrib->encrypt, padapter->securitypriv.sw_encrypt));
790 if (pattrib->encrypt &&
791 ((padapter->securitypriv.sw_encrypt == _TRUE) || (psecuritypriv->hw_decrypted == _FALSE)))
793 pattrib->bswenc = _TRUE;
794 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,
795 ("update_attrib: encrypt=%d securitypriv.hw_decrypted=%d bswenc=_TRUE\n",
796 pattrib->encrypt, padapter->securitypriv.sw_encrypt));
798 pattrib->bswenc = _FALSE;
799 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("update_attrib: bswenc=_FALSE\n"));
802 #ifdef CONFIG_CONCURRENT_MODE
803 if((pattrib->encrypt && bmcast) || (pattrib->encrypt ==_WEP40_) || (pattrib->encrypt ==_WEP104_))
805 pattrib->bswenc = _TRUE;/* force using sw enc. */
809 rtw_set_tx_chksum_offload(pkt, pattrib);
811 update_attrib_phy_info(pattrib, psta);
820 static s32 xmitframe_addmic(_adapter *padapter, struct xmit_frame *pxmitframe){
821 int curfragnum,length;
822 u8 *pframe, *payload,mic[8];
823 struct mic_data micdata;
824 struct sta_info *stainfo;
825 struct qos_priv *pqospriv= &(padapter->mlmepriv.qospriv);
826 struct pkt_attrib *pattrib = &pxmitframe->attrib;
827 struct security_priv *psecuritypriv=&padapter->securitypriv;
828 struct xmit_priv *pxmitpriv=&padapter->xmitpriv;
829 u8 priority[4]={0x0,0x0,0x0,0x0};
830 u8 hw_hdr_offset = 0;
831 int bmcst = IS_MCAST(pattrib->ra);
835 stainfo = pattrib->psta;
839 DBG_8723A("%s, call rtw_get_stainfo()\n", __func__);
840 stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
845 DBG_8723A("%s, psta==NUL\n", __func__);
849 if(!(stainfo->state &_FW_LINKED))
851 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state);
857 #ifdef CONFIG_USB_TX_AGGREGATION
858 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);;
860 #ifdef CONFIG_TX_EARLY_MODE
861 hw_hdr_offset = TXDESC_OFFSET+ EARLY_MODE_INFO_SIZE;
863 hw_hdr_offset = TXDESC_OFFSET;
867 if(pattrib->encrypt ==_TKIP_)/* if(psecuritypriv->dot11PrivacyAlgrthm==_TKIP_PRIVACY_) */
869 /* encode mic code */
871 u8 null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
873 pframe = pxmitframe->buf_addr + hw_hdr_offset;
877 if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16)){
878 /* DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); */
882 /* start to calculate the mic code */
883 rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
887 if(!memcmp(&stainfo->dot11tkiptxmickey.skey[0],null_key, 16)){
888 /* DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); */
892 /* start to calculate the mic code */
893 rtw_secmicsetkey(&micdata, &stainfo->dot11tkiptxmickey.skey[0]);
896 if(pframe[1]&1){ /* ToDS==1 */
897 rtw_secmicappend(&micdata, &pframe[16], 6); /* DA */
898 if(pframe[1]&2) /* From Ds==1 */
899 rtw_secmicappend(&micdata, &pframe[24], 6);
901 rtw_secmicappend(&micdata, &pframe[10], 6);
904 rtw_secmicappend(&micdata, &pframe[4], 6); /* DA */
905 if(pframe[1]&2) /* From Ds==1 */
906 rtw_secmicappend(&micdata, &pframe[16], 6);
908 rtw_secmicappend(&micdata, &pframe[10], 6);
912 /* if(pqospriv->qos_option==1) */
914 priority[0]=(u8)pxmitframe->attrib.priority;
916 rtw_secmicappend(&micdata, &priority[0], 4);
920 for(curfragnum=0;curfragnum<pattrib->nr_frags;curfragnum++){
921 payload=(u8 *)RND4((unsigned long)(payload));
922 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",
923 curfragnum,*payload, *(payload+1),*(payload+2),*(payload+3),*(payload+4),*(payload+5),*(payload+6),*(payload+7)));
925 payload=payload+pattrib->hdrlen+pattrib->iv_len;
926 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("curfragnum=%d pattrib->hdrlen=%d pattrib->iv_len=%d",curfragnum,pattrib->hdrlen,pattrib->iv_len));
927 if((curfragnum+1)==pattrib->nr_frags){
928 length=pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-( (pattrib->bswenc) ? pattrib->icv_len : 0);
929 rtw_secmicappend(&micdata, payload,length);
930 payload=payload+length;
933 length=pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-( (pattrib->bswenc) ? pattrib->icv_len : 0);
934 rtw_secmicappend(&micdata, payload, length);
935 payload=payload+length+pattrib->icv_len;
936 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("curfragnum=%d length=%d pattrib->icv_len=%d",curfragnum,length,pattrib->icv_len));
939 rtw_secgetmic(&micdata,&(mic[0]));
940 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: before add mic code!!!\n"));
941 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: pattrib->last_txcmdsz=%d!!!\n",pattrib->last_txcmdsz));
942 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\
943 mic[4]=0x%.2x ,mic[5]=0x%.2x ,mic[6]=0x%.2x ,mic[7]=0x%.2x !!!!\n",
944 mic[0],mic[1],mic[2],mic[3],mic[4],mic[5],mic[6],mic[7]));
945 /* add mic code and add the mic code length in last_txcmdsz */
947 memcpy(payload, &(mic[0]),8);
948 pattrib->last_txcmdsz+=8;
950 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("\n ========last pkt========\n"));
951 payload=payload-pattrib->last_txcmdsz+8;
952 for(curfragnum=0;curfragnum<pattrib->last_txcmdsz;curfragnum=curfragnum+8)
953 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,(" %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x ",
954 *(payload+curfragnum), *(payload+curfragnum+1), *(payload+curfragnum+2),*(payload+curfragnum+3),
955 *(payload+curfragnum+4),*(payload+curfragnum+5),*(payload+curfragnum+6),*(payload+curfragnum+7)));
958 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: rtw_get_stainfo==NULL!!!\n"));
967 static s32 xmitframe_swencrypt(_adapter *padapter, struct xmit_frame *pxmitframe){
969 struct pkt_attrib *pattrib = &pxmitframe->attrib;
970 /* struct security_priv *psecuritypriv=&padapter->securitypriv; */
974 /* if((psecuritypriv->sw_encrypt)||(pattrib->bswenc)) */
977 /* DBG_8723A("start xmitframe_swencrypt\n"); */
978 RT_TRACE(_module_rtl871x_xmit_c_,_drv_alert_,("### xmitframe_swencrypt\n"));
979 switch(pattrib->encrypt){
982 rtw_wep_encrypt(padapter, (u8 *)pxmitframe);
985 rtw_tkip_encrypt(padapter, (u8 *)pxmitframe);
988 rtw_aes_encrypt(padapter, (u8 * )pxmitframe);
995 RT_TRACE(_module_rtl871x_xmit_c_,_drv_notice_,("### xmitframe_hwencrypt\n"));
1003 s32 rtw_make_wlanhdr (_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib)
1007 struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr;
1008 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1009 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1010 u8 qos_option = _FALSE;
1012 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1013 struct sta_priv *pstapriv = &padapter->stapriv;
1014 struct sta_info *ptdls_sta=NULL, *psta_backup=NULL;
1016 #endif /* CONFIG_TDLS */
1019 u16 *fctrl = &pwlanhdr->frame_ctl;
1021 struct sta_info *psta;
1023 int bmcst = IS_MCAST(pattrib->ra);
1027 if (pattrib->psta) {
1028 psta = pattrib->psta;
1030 DBG_8723A("%s, call rtw_get_stainfo()\n", __func__);
1032 psta = rtw_get_bcmc_stainfo(padapter);
1034 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1040 DBG_8723A("%s, psta==NUL\n", __func__);
1044 if(!(psta->state &_FW_LINKED))
1046 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1050 memset(hdr, 0, WLANHDR_OFFSET);
1052 SetFrameSubType(fctrl, pattrib->subtype);
1054 if (pattrib->subtype & WIFI_DATA_TYPE)
1056 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) {
1057 /* to_ds = 1, fr_ds = 0; */
1059 if((ptdlsinfo->setup_state == TDLS_LINKED_STATE)){
1060 ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
1061 if((ptdls_sta!=NULL)&&(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)&&(pattrib->ether_type!=0x0806)){
1062 /* TDLS data transfer, ToDS=0, FrDs=0 */
1063 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1064 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1065 memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1068 /* 1.Data transfer to AP */
1069 /* 2.Arp pkt will relayed by AP */
1071 memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1072 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1073 memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1076 #endif /* CONFIG_TDLS */
1078 /* Data transfer to AP */
1080 memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1081 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1082 memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1085 if (pqospriv->qos_option)
1089 else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) ) {
1090 /* to_ds = 0, fr_ds = 1; */
1092 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1093 memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN);
1094 memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
1096 if(psta->qos_option)
1099 else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1100 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
1101 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1102 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1103 memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1105 if(psta->qos_option)
1109 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("fw_state:%x is not allowed to xmit frame\n", get_fwstate(pmlmepriv)));
1117 if (pattrib->encrypt)
1122 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
1124 if (pattrib->priority)
1125 SetPriority(qc, pattrib->priority);
1127 SetEOSP(qc, pattrib->eosp);
1129 SetAckpolicy(qc, pattrib->ack_policy);
1132 /* TODO: fill HT Control Field */
1134 /* Update Seq Num will be handled by f/w */
1143 #endif /* CONFIG_TDLS */
1145 psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
1146 psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
1148 pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
1150 SetSeqNum(hdr, pattrib->seqnum);
1152 #ifdef CONFIG_80211N_HT
1153 /* check if enable ampdu */
1154 if(pattrib->ht_en && psta->htpriv.ampdu_enable)
1156 if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
1157 pattrib->ampdu_en = _TRUE;
1160 /* re-check if enable ampdu by BA_starting_seqctrl */
1161 if(pattrib->ampdu_en == _TRUE)
1165 tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
1167 /* check BA_starting_seqctrl */
1168 if(SN_LESS(pattrib->seqnum, tx_seq))
1170 /* DBG_8723A("tx ampdu seqnum(%d) < tx_seq(%d)\n", pattrib->seqnum, tx_seq); */
1171 pattrib->ampdu_en = _FALSE;/* AGG BK */
1173 else if(SN_EQUAL(pattrib->seqnum, tx_seq))
1175 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff;
1177 pattrib->ampdu_en = _TRUE;/* AGG EN */
1181 /* DBG_8723A("tx ampdu over run\n"); */
1182 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff;
1183 pattrib->ampdu_en = _TRUE;/* AGG EN */
1187 #endif /* CONFIG_80211N_HT */
1191 if (pattrib->encrypt){
1192 pattrib->encrypt= _AES_;
1197 /* qos_en, ht_en, init rate, ,bw, ch_offset, sgi */
1198 /* pattrib->qos_en = ptdls_sta->qos_option; */
1200 pattrib->raid = ptdls_sta->raid;
1201 #ifdef CONFIG_80211N_HT
1202 pattrib->bwmode = ptdls_sta->htpriv.bwmode;
1203 pattrib->ht_en = ptdls_sta->htpriv.ht_option;
1204 pattrib->ch_offset = ptdls_sta->htpriv.ch_offset;
1205 pattrib->sgi= ptdls_sta->htpriv.sgi;
1206 #endif /* CONFIG_80211N_HT */
1207 pattrib->mac_id = ptdls_sta->mac_id;
1211 #endif /* CONFIG_TDLS */
1229 s32 rtw_txframes_pending(_adapter *padapter)
1231 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1233 return ((_rtw_queue_empty(&pxmitpriv->be_pending) == _FALSE) ||
1234 (_rtw_queue_empty(&pxmitpriv->bk_pending) == _FALSE) ||
1235 (_rtw_queue_empty(&pxmitpriv->vi_pending) == _FALSE) ||
1236 (_rtw_queue_empty(&pxmitpriv->vo_pending) == _FALSE));
1239 s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib)
1241 struct sta_info *psta;
1242 struct tx_servq *ptxservq;
1243 int priority = pattrib->priority;
1247 psta = pattrib->psta;
1251 DBG_8723A("%s, call rtw_get_stainfo()\n", __func__);
1252 psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
1257 DBG_8723A("%s, psta==NUL\n", __func__);
1261 if(!(psta->state &_FW_LINKED))
1263 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1271 ptxservq = &(psta->sta_xmitpriv.bk_q);
1275 ptxservq = &(psta->sta_xmitpriv.vi_q);
1279 ptxservq = &(psta->sta_xmitpriv.vo_q);
1284 ptxservq = &(psta->sta_xmitpriv.be_q);
1289 return ptxservq->qcnt;
1294 int rtw_build_tdls_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, u8 action)
1299 case TDLS_SETUP_REQUEST:
1300 rtw_build_tdls_setup_req_ies(padapter, pxmitframe, pframe);
1302 case TDLS_SETUP_RESPONSE:
1303 rtw_build_tdls_setup_rsp_ies(padapter, pxmitframe, pframe);
1305 case TDLS_SETUP_CONFIRM:
1306 rtw_build_tdls_setup_cfm_ies(padapter, pxmitframe, pframe);
1309 rtw_build_tdls_teardown_ies(padapter, pxmitframe, pframe);
1311 case TDLS_DISCOVERY_REQUEST:
1312 rtw_build_tdls_dis_req_ies(padapter, pxmitframe, pframe);
1314 case TDLS_PEER_TRAFFIC_INDICATION:
1315 rtw_build_tdls_peer_traffic_indication_ies(padapter, pxmitframe, pframe);
1317 case TDLS_CHANNEL_SWITCH_REQUEST:
1318 rtw_build_tdls_ch_switch_req_ies(padapter, pxmitframe, pframe);
1320 case TDLS_CHANNEL_SWITCH_RESPONSE:
1321 rtw_build_tdls_ch_switch_rsp_ies(padapter, pxmitframe, pframe);
1324 case TUNNELED_PROBE_REQ:
1325 rtw_build_tunneled_probe_req_ies(padapter, pxmitframe, pframe);
1327 case TUNNELED_PROBE_RSP:
1328 rtw_build_tunneled_probe_rsp_ies(padapter, pxmitframe, pframe);
1330 #endif /* CONFIG_WFD */
1339 s32 rtw_make_tdls_wlanhdr (_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib, u8 action)
1342 struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr;
1343 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1344 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1345 struct sta_priv *pstapriv = &padapter->stapriv;
1346 struct sta_info *psta=NULL, *ptdls_sta=NULL;
1347 u8 tdls_seq=0, baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1350 u16 *fctrl = &pwlanhdr->frame_ctl;
1354 memset(hdr, 0, WLANHDR_OFFSET);
1356 SetFrameSubType(fctrl, pattrib->subtype);
1359 case TDLS_SETUP_REQUEST:
1360 case TDLS_SETUP_RESPONSE:
1361 case TDLS_SETUP_CONFIRM:
1362 case TDLS_TEARDOWN: /* directly to peer STA or via AP */
1363 case TDLS_PEER_TRAFFIC_INDICATION:
1364 case TDLS_PEER_PSM_REQUEST: /* directly to peer STA or via AP */
1365 case TUNNELED_PROBE_REQ:
1366 case TUNNELED_PROBE_RSP:
1368 memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1369 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1370 memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1372 case TDLS_CHANNEL_SWITCH_REQUEST:
1373 case TDLS_CHANNEL_SWITCH_RESPONSE:
1374 case TDLS_PEER_PSM_RESPONSE:
1375 case TDLS_PEER_TRAFFIC_RESPONSE:
1376 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1377 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1378 memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1381 case TDLS_DISCOVERY_REQUEST: /* unicast: directly to peer sta, Bcast: via AP */
1382 if (!memcmp(pattrib->dst, baddr, ETH_ALEN))
1385 memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1386 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1387 memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1389 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1390 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1391 memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1397 if (pattrib->encrypt)
1400 if (pqospriv->qos_option)
1402 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
1403 if (pattrib->priority)
1404 SetPriority(qc, pattrib->priority);
1405 SetAckpolicy(qc, pattrib->ack_policy);
1408 psta = pattrib->psta;
1410 /* 1. update seq_num per link by sta_info */
1411 /* 2. rewrite encrypt to _AES_, also rewrite iv_len, icv_len */
1413 ptdls_sta=rtw_get_stainfo(pstapriv, pattrib->dst);
1415 ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
1416 ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
1417 pattrib->seqnum = ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority];
1418 SetSeqNum(hdr, pattrib->seqnum);
1420 if (pattrib->encrypt){
1421 pattrib->encrypt= _AES_;
1430 psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
1431 psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
1432 pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
1433 SetSeqNum(hdr, pattrib->seqnum);
1443 s32 rtw_xmit_tdls_coalesce(_adapter * padapter, struct xmit_frame * pxmitframe, u8 action)
1447 u8 *pframe, *mem_start;
1449 struct sta_info *psta;
1450 struct sta_priv *pstapriv = &padapter->stapriv;
1451 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1452 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1454 s32 bmcst = IS_MCAST(pattrib->ra);
1459 if (pattrib->psta) {
1460 psta = pattrib->psta;
1463 psta = rtw_get_bcmc_stainfo(padapter);
1465 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1472 if (pxmitframe->buf_addr == NULL)
1475 pbuf_start = pxmitframe->buf_addr;
1476 mem_start = pbuf_start + TXDESC_OFFSET;
1478 if (rtw_make_tdls_wlanhdr(padapter, mem_start, pattrib, action) == _FAIL) {
1484 pframe += pattrib->hdrlen;
1486 /* adding icv, if necessary... */
1487 if (pattrib->iv_len)
1491 switch(pattrib->encrypt)
1495 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1499 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1501 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
1505 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1507 AES_IV(pattrib->iv, psta->dot11txpn, 0);
1512 memcpy(pframe, pattrib->iv, pattrib->iv_len);
1513 pframe += pattrib->iv_len;
1517 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
1520 /* pattrib->pktlen will be counted in rtw_build_tdls_ies */
1521 pattrib->pktlen = 0;
1523 rtw_build_tdls_ies(padapter, pxmitframe, pframe, action);
1525 if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) {
1526 pframe += pattrib->pktlen;
1527 memcpy(pframe, pattrib->icv, pattrib->icv_len);
1528 pframe += pattrib->icv_len;
1531 pattrib->nr_frags = 1;
1532 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + llc_sz +
1533 ((pattrib->bswenc) ? pattrib->icv_len : 0) + pattrib->pktlen;
1535 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL)
1540 xmitframe_swencrypt(padapter, pxmitframe);
1542 update_attrib_vcs_info(padapter, pxmitframe);
1550 #endif /* CONFIG_TDLS */
1553 * Calculate wlan 802.11 packet MAX size from pkt_attrib
1554 * This function doesn't consider fragment case
1556 u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib)
1560 len = pattrib->hdrlen + pattrib->iv_len; /* WLAN Header and IV */
1561 len += SNAP_SIZE + sizeof(u16); /* LLC */
1562 len += pattrib->pktlen;
1563 if (pattrib->encrypt == _TKIP_) len += 8; /* MIC */
1564 len += ((pattrib->bswenc) ? pattrib->icv_len : 0); /* ICV */
1571 This sub-routine will perform all the following:
1573 1. remove 802.3 header.
1574 2. create wlan_header, based on the info in pxmitframe
1575 3. append sta's iv/ext-iv
1577 5. move frag chunk from pframe to pxmitframe->mem
1578 6. apply sw-encrypt, if necessary.
1581 s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
1583 struct pkt_file pktfile;
1585 s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
1589 u8 *pframe, *mem_start;
1592 struct sta_info *psta;
1593 /* struct sta_priv *pstapriv = &padapter->stapriv; */
1594 /* struct mlme_priv *pmlmepriv = &padapter->mlmepriv; */
1595 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1597 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1601 s32 bmcst = IS_MCAST(pattrib->ra);
1608 psta = pattrib->psta;
1611 DBG_8723A("%s, call rtw_get_stainfo()\n", __func__);
1612 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1618 DBG_8723A("%s, psta==NUL\n", __func__);
1622 if(!(psta->state &_FW_LINKED))
1624 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1628 if (pxmitframe->buf_addr == NULL){
1629 DBG_8723A("==> %s buf_addr==NULL \n",__FUNCTION__);
1633 pbuf_start = pxmitframe->buf_addr;
1635 #ifdef CONFIG_USB_TX_AGGREGATION
1636 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
1638 #ifdef CONFIG_TX_EARLY_MODE /* for SDIO && Tx Agg */
1639 hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
1641 hw_hdr_offset = TXDESC_OFFSET;
1645 mem_start = pbuf_start + hw_hdr_offset;
1647 if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
1648 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n"));
1649 DBG_8723A("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n");
1654 _rtw_open_pktfile(pkt, &pktfile);
1655 _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
1658 frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
1668 SetMFrag(mem_start);
1670 pframe += pattrib->hdrlen;
1671 mpdu_len -= pattrib->hdrlen;
1673 /* adding icv, if necessary... */
1674 if (pattrib->iv_len)
1676 /* if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) */
1677 /* psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); */
1679 /* psta = rtw_get_stainfo(pstapriv, pattrib->ra); */
1683 switch(pattrib->encrypt)
1687 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1691 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1693 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
1697 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1699 AES_IV(pattrib->iv, psta->dot11txpn, 0);
1704 memcpy(pframe, pattrib->iv, pattrib->iv_len);
1706 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
1707 ("rtw_xmitframe_coalesce: keyid=%d pattrib->iv[3]=%.2x pframe=%.2x %.2x %.2x %.2x\n",
1708 padapter->securitypriv.dot11PrivacyKeyIndex, pattrib->iv[3], *pframe, *(pframe+1), *(pframe+2), *(pframe+3)));
1710 pframe += pattrib->iv_len;
1712 mpdu_len -= pattrib->iv_len;
1716 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
1721 if ((pattrib->icv_len >0) && (pattrib->bswenc)) {
1722 mpdu_len -= pattrib->icv_len;
1726 /* don't do fragment to broadcat/multicast packets */
1727 mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
1729 mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len);
1734 if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) {
1735 memcpy(pframe, pattrib->icv, pattrib->icv_len);
1736 pframe += pattrib->icv_len;
1741 if (bmcst || (rtw_endofpktfile(&pktfile) == _TRUE))
1743 pattrib->nr_frags = frg_inx;
1745 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags==1)? llc_sz:0) +
1746 ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz;
1748 ClearMFrag(mem_start);
1752 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: There're still something in packet!\n", __FUNCTION__));
1755 addr = (unsigned long)pframe;
1757 mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset;
1758 memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
1762 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL)
1764 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n"));
1765 DBG_8723A("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n");
1770 xmitframe_swencrypt(padapter, pxmitframe);
1773 update_attrib_vcs_info(padapter, pxmitframe);
1775 pattrib->vcs_mode = NONE_VCS;
1784 /* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
1785 * IEEE LLC/SNAP header contains 8 octets
1786 * First 3 octets comprise the LLC portion
1787 * SNAP portion, 5 octets, is divided into two fields:
1788 * Organizationally Unique Identifier(OUI), 3 octets,
1789 * type, defined by that organization, 2 octets.
1791 s32 rtw_put_snap(u8 *data, u16 h_proto)
1793 struct ieee80211_snap_hdr *snap;
1798 snap = (struct ieee80211_snap_hdr *)data;
1803 if (h_proto == 0x8137 || h_proto == 0x80f3)
1808 snap->oui[0] = oui[0];
1809 snap->oui[1] = oui[1];
1810 snap->oui[2] = oui[2];
1812 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
1816 return SNAP_SIZE + sizeof(u16);
1819 void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len)
1825 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1826 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1830 switch(pxmitpriv->vcs_setting)
1833 pxmitpriv->vcs = NONE_VCS;
1841 perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
1844 pxmitpriv->vcs = NONE_VCS;
1848 protection = (*(perp + 2)) & BIT(1);
1851 if(pregistrypriv->vcs_type == RTS_CTS)
1852 pxmitpriv->vcs = RTS_CTS;
1854 pxmitpriv->vcs = CTS_TO_SELF;
1857 pxmitpriv->vcs = NONE_VCS;
1867 void rtw_count_tx_stats(PADAPTER padapter, struct xmit_frame *pxmitframe, int sz)
1869 struct sta_info *psta = NULL;
1870 struct stainfo_stats *pstats = NULL;
1871 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1872 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1874 if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
1876 pxmitpriv->tx_bytes += sz;
1877 #if defined(CONFIG_USB_TX_AGGREGATION)
1878 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pxmitframe->agg_num;
1880 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod++;
1883 psta = pxmitframe->attrib.psta;
1886 pstats = &psta->sta_stats;
1887 #if defined(CONFIG_USB_TX_AGGREGATION)
1888 pstats->tx_pkts += pxmitframe->agg_num;
1892 pstats->tx_bytes += sz;
1897 struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
1900 struct xmit_buf *pxmitbuf = NULL;
1901 struct list_head *plist, *phead;
1902 _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1906 spin_lock_irqsave(&pfree_queue->lock, irqL);
1908 if(_rtw_queue_empty(pfree_queue) == _TRUE) {
1912 phead = get_list_head(pfree_queue);
1914 plist = phead->next;
1916 pxmitbuf = container_of(plist, struct xmit_buf, list);
1918 list_del_init(&(pxmitbuf->list));
1921 if (pxmitbuf != NULL)
1923 pxmitpriv->free_xmit_extbuf_cnt--;
1924 #ifdef DBG_XMIT_BUF_EXT
1925 DBG_8723A("DBG_XMIT_BUF_EXT ALLOC no=%d, free_xmit_extbuf_cnt=%d\n",pxmitbuf->no, pxmitpriv->free_xmit_extbuf_cnt);
1928 pxmitbuf->priv_data = NULL;
1929 /* pxmitbuf->ext_tag = _TRUE; */
1931 if (pxmitbuf->sctx) {
1932 DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__);
1933 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1938 spin_unlock_irqrestore(&pfree_queue->lock, irqL);
1945 s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
1948 _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1957 spin_lock_irqsave(&pfree_queue->lock, irqL);
1959 list_del_init(&pxmitbuf->list);
1961 list_add_tail(&(pxmitbuf->list), get_list_head(pfree_queue));
1962 pxmitpriv->free_xmit_extbuf_cnt++;
1963 #ifdef DBG_XMIT_BUF_EXT
1964 DBG_8723A("DBG_XMIT_BUF_EXT FREE no=%d, free_xmit_extbuf_cnt=%d\n",pxmitbuf->no ,pxmitpriv->free_xmit_extbuf_cnt);
1967 spin_unlock_irqrestore(&pfree_queue->lock, irqL);
1974 struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
1977 struct xmit_buf *pxmitbuf = NULL;
1978 struct list_head *plist, *phead;
1979 _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
1983 /* DBG_8723A("+rtw_alloc_xmitbuf\n"); */
1985 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
1987 if(_rtw_queue_empty(pfree_xmitbuf_queue) == _TRUE) {
1991 phead = get_list_head(pfree_xmitbuf_queue);
1993 plist = phead->next;
1995 pxmitbuf = container_of(plist, struct xmit_buf, list);
1997 list_del_init(&(pxmitbuf->list));
2000 if (pxmitbuf != NULL)
2002 pxmitpriv->free_xmitbuf_cnt--;
2004 DBG_8723A("DBG_XMIT_BUF ALLOC no=%d, free_xmitbuf_cnt=%d\n",pxmitbuf->no, pxmitpriv->free_xmitbuf_cnt);
2006 /* DBG_8723A("alloc, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); */
2008 pxmitbuf->priv_data = NULL;
2009 if (pxmitbuf->sctx) {
2010 DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__);
2011 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
2017 DBG_8723A("DBG_XMIT_BUF rtw_alloc_xmitbuf return NULL\n");
2021 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
2028 s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
2031 _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
2035 /* DBG_8723A("+rtw_free_xmitbuf\n"); */
2042 if (pxmitbuf->sctx) {
2043 DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__);
2044 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
2047 if(pxmitbuf->ext_tag)
2049 rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf);
2053 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
2055 list_del_init(&pxmitbuf->list);
2057 list_add_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
2059 pxmitpriv->free_xmitbuf_cnt++;
2060 /* DBG_8723A("FREE, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); */
2062 DBG_8723A("DBG_XMIT_BUF FREE no=%d, free_xmitbuf_cnt=%d\n",pxmitbuf->no ,pxmitpriv->free_xmitbuf_cnt);
2064 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
2072 void rtw_init_xmitframe(struct xmit_frame *pxframe)
2074 if (pxframe != NULL)/* default value setting */
2076 pxframe->buf_addr = NULL;
2077 pxframe->pxmitbuf = NULL;
2079 memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
2080 /* pxframe->attrib.psta = NULL; */
2082 pxframe->frame_tag = DATA_FRAMETAG;
2084 pxframe->pkt = NULL;
2085 pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */
2087 #ifdef CONFIG_USB_TX_AGGREGATION
2088 pxframe->agg_num = 1;
2091 #ifdef CONFIG_XMIT_ACK
2092 pxframe->ack_report = 0;
2100 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
2102 If we turn on USE_RXTHREAD, then, no need for critical section.
2103 Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
2105 Must be very very cautious...
2108 struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* _queue *pfree_xmit_queue) */
2111 Please remember to use all the osdep_service api,
2112 and lock/unlock or _enter/_exit critical to protect
2116 struct xmit_frame *pxframe = NULL;
2117 struct list_head *plist, *phead;
2118 _queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
2119 _adapter *padapter = pxmitpriv->adapter;
2123 spin_lock_bh(&pfree_xmit_queue->lock);
2125 if (_rtw_queue_empty(pfree_xmit_queue) == _TRUE) {
2126 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_alloc_xmitframe:%d\n", pxmitpriv->free_xmitframe_cnt));
2129 phead = get_list_head(pfree_xmit_queue);
2131 plist = phead->next;
2133 pxframe = container_of(plist, struct xmit_frame, list);
2135 list_del_init(&(pxframe->list));
2136 pxmitpriv->free_xmitframe_cnt--;
2137 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt));
2140 spin_unlock_bh(&pfree_xmit_queue->lock);
2142 rtw_init_xmitframe(pxframe);
2149 struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv)
2151 struct xmit_frame *pxframe = NULL;
2152 struct list_head *plist, *phead;
2153 _queue *queue = &pxmitpriv->free_xframe_ext_queue;
2157 spin_lock_bh(&queue->lock);
2159 if (_rtw_queue_empty(queue) == _TRUE) {
2160 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_alloc_xmitframe_ext:%d\n", pxmitpriv->free_xframe_ext_cnt));
2163 phead = get_list_head(queue);
2164 plist = phead->next;
2165 pxframe = container_of(plist, struct xmit_frame, list);
2167 list_del_init(&(pxframe->list));
2168 pxmitpriv->free_xframe_ext_cnt--;
2169 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe_ext():free_xmitframe_cnt=%d\n", pxmitpriv->free_xframe_ext_cnt));
2172 spin_unlock_bh(&queue->lock);
2174 rtw_init_xmitframe(pxframe);
2181 struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv)
2183 struct xmit_frame *pxframe = NULL;
2186 alloc_addr = rtw_zmalloc(sizeof(struct xmit_frame) + 4);
2188 if (alloc_addr == NULL)
2191 pxframe = (struct xmit_frame *)PTR_ALIGN(alloc_addr, 4);
2192 pxframe->alloc_addr = alloc_addr;
2194 pxframe->padapter = pxmitpriv->adapter;
2195 pxframe->frame_tag = NULL_FRAMETAG;
2197 pxframe->pkt = NULL;
2199 pxframe->buf_addr = NULL;
2200 pxframe->pxmitbuf = NULL;
2202 rtw_init_xmitframe(pxframe);
2204 DBG_8723A("################## %s ##################\n", __func__);
2210 s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
2212 _queue *queue = NULL;
2213 _adapter *padapter = pxmitpriv->adapter;
2214 _pkt *pndis_pkt = NULL;
2218 if (pxmitframe == NULL) {
2219 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("======rtw_free_xmitframe():pxmitframe==NULL!!!!!!!!!!\n"));
2223 if (pxmitframe->pkt){
2224 pndis_pkt = pxmitframe->pkt;
2225 pxmitframe->pkt = NULL;
2228 if (pxmitframe->alloc_addr) {
2229 DBG_8723A("################## %s with alloc_addr ##################\n", __func__);
2230 rtw_mfree(pxmitframe->alloc_addr, sizeof(struct xmit_frame) + 4);
2231 goto check_pkt_complete;
2234 if (pxmitframe->ext_tag == 0)
2235 queue = &pxmitpriv->free_xmit_queue;
2236 else if(pxmitframe->ext_tag == 1)
2237 queue = &pxmitpriv->free_xframe_ext_queue;
2240 goto check_pkt_complete;
2241 spin_lock_bh(&queue->lock);
2243 list_del_init(&pxmitframe->list);
2244 list_add_tail(&pxmitframe->list, get_list_head(queue));
2245 if (pxmitframe->ext_tag == 0) {
2246 pxmitpriv->free_xmitframe_cnt++;
2247 RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt));
2248 } else if(pxmitframe->ext_tag == 1) {
2249 pxmitpriv->free_xframe_ext_cnt++;
2250 RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xframe_ext_cnt=%d\n", pxmitpriv->free_xframe_ext_cnt));
2253 spin_unlock_bh(&queue->lock);
2258 rtw_os_pkt_complete(padapter, pndis_pkt);
2267 void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue)
2269 struct list_head *plist, *phead;
2270 struct xmit_frame *pxmitframe;
2274 spin_lock_bh(&(pframequeue->lock));
2276 phead = get_list_head(pframequeue);
2277 plist = phead->next;
2279 while (rtw_end_of_queue_search(phead, plist) == _FALSE)
2282 pxmitframe = container_of(plist, struct xmit_frame, list);
2284 plist = plist->next;
2286 rtw_free_xmitframe(pxmitpriv,pxmitframe);
2289 spin_unlock_bh(&(pframequeue->lock));
2294 s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
2296 if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL)
2298 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
2299 ("rtw_xmitframe_enqueue: drop xmit pkt for classifier fail\n"));
2300 /* pxmitframe->pkt = NULL; */
2307 static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue)
2309 struct list_head *xmitframe_plist, *xmitframe_phead;
2310 struct xmit_frame *pxmitframe=NULL;
2312 xmitframe_phead = get_list_head(pframe_queue);
2313 xmitframe_plist = xmitframe_phead->next;
2315 if ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
2316 pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
2317 xmitframe_plist = xmitframe_plist->next;
2318 list_del_init(&pxmitframe->list);
2324 struct xmit_frame* rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, int entry)
2326 struct list_head *sta_plist, *sta_phead;
2327 struct hw_xmit *phwxmit;
2328 struct tx_servq *ptxservq = NULL;
2329 _queue *pframe_queue = NULL;
2330 struct xmit_frame *pxmitframe = NULL;
2331 _adapter *padapter = pxmitpriv->adapter;
2332 struct registry_priv *pregpriv = &padapter->registrypriv;
2337 inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
2339 if(pregpriv->wifi_spec==1) {
2340 int j, tmp, acirp_cnt[4];
2342 inx[j] = pxmitpriv->wmm_para_seq[j];
2345 spin_lock_bh(&pxmitpriv->lock);
2347 for(i = 0; i < entry; i++) {
2348 phwxmit = phwxmit_i + inx[i];
2350 sta_phead = get_list_head(phwxmit->sta_queue);
2351 sta_plist = sta_phead->next;
2353 while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE)
2356 ptxservq= container_of(sta_plist, struct tx_servq, tx_pending);
2358 pframe_queue = &ptxservq->sta_pending;
2360 pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
2366 /* Remove sta node when there is no pending packets. */
2367 if(_rtw_queue_empty(pframe_queue)) /* must be done after get_next and before break */
2368 list_del_init(&ptxservq->tx_pending);
2370 /* _exit_critical_ex(&phwxmit->sta_queue->lock); */
2375 sta_plist = sta_plist->next;
2379 /* _exit_critical_ex(&phwxmit->sta_queue->lock); */
2385 spin_unlock_bh(&pxmitpriv->lock);
2393 struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, int up, u8 *ac)
2395 struct tx_servq *ptxservq=NULL;
2403 ptxservq = &(psta->sta_xmitpriv.bk_q);
2405 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BK \n"));
2410 ptxservq = &(psta->sta_xmitpriv.vi_q);
2412 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VI\n"));
2417 ptxservq = &(psta->sta_xmitpriv.vo_q);
2419 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VO \n"));
2425 ptxservq = &(psta->sta_xmitpriv.be_q);
2427 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BE \n"));
2437 __inline static struct tx_servq *rtw_get_sta_pending
2438 (_adapter *padapter, _queue **ppstapending, struct sta_info *psta, int up)
2440 struct tx_servq *ptxservq;
2441 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
2445 #ifdef CONFIG_RTL8711
2447 if(IS_MCAST(psta->hwaddr))
2449 ptxservq = &(psta->sta_xmitpriv.be_q); /* we will use be_q to queue bc/mc frames in BCMC_stainfo */
2450 *ppstapending = &padapter->xmitpriv.bm_pending;
2459 ptxservq = &(psta->sta_xmitpriv.bk_q);
2460 *ppstapending = &padapter->xmitpriv.bk_pending;
2461 (phwxmits+3)->accnt++;
2462 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BK \n"));
2467 ptxservq = &(psta->sta_xmitpriv.vi_q);
2468 *ppstapending = &padapter->xmitpriv.vi_pending;
2469 (phwxmits+1)->accnt++;
2470 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VI\n"));
2475 ptxservq = &(psta->sta_xmitpriv.vo_q);
2476 *ppstapending = &padapter->xmitpriv.vo_pending;
2477 (phwxmits+0)->accnt++;
2478 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VO \n"));
2484 ptxservq = &(psta->sta_xmitpriv.be_q);
2485 *ppstapending = &padapter->xmitpriv.be_pending;
2486 (phwxmits+2)->accnt++;
2487 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BE \n"));
2501 * Will enqueue pxmitframe to the proper queue,
2502 * and indicate it to xx_pending list.....
2504 s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe)
2506 /* unsigned long irqL0; */
2508 struct sta_info *psta;
2509 struct tx_servq *ptxservq;
2510 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2511 struct sta_priv *pstapriv = &padapter->stapriv;
2512 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
2517 if (pattrib->psta) {
2518 psta = pattrib->psta;
2520 DBG_8723A("%s, call rtw_get_stainfo()\n", __func__);
2521 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
2526 DBG_8723A("rtw_xmit_classifier: psta == NULL\n");
2527 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("rtw_xmit_classifier: psta == NULL\n"));
2531 if(!(psta->state &_FW_LINKED))
2533 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
2537 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
2539 /* spin_lock_irqsave(&pstapending->lock, irqL0); */
2541 if (list_empty(&ptxservq->tx_pending)) {
2542 list_add_tail(&ptxservq->tx_pending,
2543 get_list_head(phwxmits[ac_index].sta_queue));
2546 /* spin_lock_irqsave(&ptxservq->sta_pending.lock, irqL1); */
2548 list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
2550 phwxmits[ac_index].accnt++;
2552 /* spin_unlock_irqrestore(&ptxservq->sta_pending.lock, irqL1); */
2554 /* spin_unlock_irqrestore(&pstapending->lock, irqL0); */
2563 void rtw_alloc_hwxmits(_adapter *padapter)
2565 struct hw_xmit *hwxmits;
2566 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2568 pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
2570 pxmitpriv->hwxmits = (struct hw_xmit *)rtw_zmalloc(sizeof (struct hw_xmit) * pxmitpriv->hwxmit_entry);
2572 hwxmits = pxmitpriv->hwxmits;
2574 if(pxmitpriv->hwxmit_entry == 5)
2576 /* pxmitpriv->bmc_txqueue.head = 0; */
2577 /* hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; */
2578 hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
2580 /* pxmitpriv->vo_txqueue.head = 0; */
2581 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; */
2582 hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
2584 /* pxmitpriv->vi_txqueue.head = 0; */
2585 /* hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; */
2586 hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
2588 /* pxmitpriv->bk_txqueue.head = 0; */
2589 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
2590 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
2592 /* pxmitpriv->be_txqueue.head = 0; */
2593 /* hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; */
2594 hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
2597 else if(pxmitpriv->hwxmit_entry == 4)
2600 /* pxmitpriv->vo_txqueue.head = 0; */
2601 /* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */
2602 hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
2604 /* pxmitpriv->vi_txqueue.head = 0; */
2605 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */
2606 hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
2608 /* pxmitpriv->be_txqueue.head = 0; */
2609 /* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */
2610 hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
2612 /* pxmitpriv->bk_txqueue.head = 0; */
2613 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
2614 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
2622 void rtw_free_hwxmits(_adapter *padapter)
2624 struct hw_xmit *hwxmits;
2625 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2627 hwxmits = pxmitpriv->hwxmits;
2629 rtw_mfree((u8 *)hwxmits, (sizeof (struct hw_xmit) * pxmitpriv->hwxmit_entry));
2632 void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry)
2636 for(i = 0; i < entry; i++, phwxmit++)
2638 /* spin_lock_init(&phwxmit->xmit_lock); */
2639 /* INIT_LIST_HEAD(&phwxmit->pending); */
2640 /* phwxmit->txcmdcnt = 0; */
2646 #ifdef CONFIG_BR_EXT
2647 int rtw_br_client_tx(_adapter *padapter, struct sk_buff **pskb)
2649 struct sk_buff *skb = *pskb;
2650 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2651 /* if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) */
2653 void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb);
2654 int res, is_vlan_tag=0, i, do_nat25=1;
2655 unsigned short vlan_hdr=0;
2656 void *br_port = NULL;
2658 /* mac_clone_handle_frame(priv, skb); */
2660 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
2661 br_port = padapter->pnetdev->br_port;
2662 #else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
2664 br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
2666 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
2667 spin_lock_bh(&padapter->br_ext_lock);
2668 if (!(skb->data[0] & 1) && br_port &&
2669 memcmp(skb->data+MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
2670 *((unsigned short *)(skb->data+MACADDRLEN*2)) != __constant_htons(ETH_P_8021Q) &&
2671 *((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP) &&
2672 !memcmp(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN) && padapter->scdb_entry) {
2673 memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
2674 padapter->scdb_entry->ageing_timer = jiffies;
2675 spin_unlock_bh(&padapter->br_ext_lock);
2677 /* if (!priv->pmib->ethBrExtInfo.nat25_disable) */
2679 /* if (priv->dev->br_port && */
2680 /* !memcmp(skb->data+MACADDRLEN, priv->br_mac, MACADDRLEN)) { */
2682 if (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_8021Q)) {
2684 vlan_hdr = *((unsigned short *)(skb->data+MACADDRLEN*2+2));
2686 *((unsigned short *)(skb->data+MACADDRLEN*2+2-i*2)) = *((unsigned short *)(skb->data+MACADDRLEN*2-2-i*2));
2689 /* if SA == br_mac && skb== IP => copy SIP to br_ip ?? why */
2690 if (!memcmp(skb->data+MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
2691 (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP)))
2692 memcpy(padapter->br_ip, skb->data+WLAN_ETHHDR_LEN+12, 4);
2694 if (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP)) {
2695 if (memcmp(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN)) {
2696 void *scdb_findEntry(_adapter *priv, unsigned char *macAddr, unsigned char *ipAddr);
2698 if ((padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter,
2699 skb->data+MACADDRLEN, skb->data+WLAN_ETHHDR_LEN+12)) != NULL) {
2700 memcpy(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN);
2701 memcpy(padapter->scdb_ip, skb->data+WLAN_ETHHDR_LEN+12, 4);
2702 padapter->scdb_entry->ageing_timer = jiffies;
2707 if (padapter->scdb_entry) {
2708 padapter->scdb_entry->ageing_timer = jiffies;
2712 memset(padapter->scdb_mac, 0, MACADDRLEN);
2713 memset(padapter->scdb_ip, 0, 4);
2717 spin_unlock_bh(&padapter->br_ext_lock);
2721 int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method);
2722 if (nat25_db_handle(padapter, skb, NAT25_CHECK) == 0) {
2723 struct sk_buff *newskb;
2728 *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2));
2729 *((unsigned short *)(skb->data+MACADDRLEN*2)) = __constant_htons(ETH_P_8021Q);
2730 *((unsigned short *)(skb->data+MACADDRLEN*2+2)) = vlan_hdr;
2733 newskb = skb_copy(skb, GFP_ATOMIC);
2734 if (newskb == NULL) {
2735 /* priv->ext_stats.tx_drops++; */
2736 DEBUG_ERR("TX DROP: skb_copy fail!\n");
2737 /* goto stop_proc; */
2740 dev_kfree_skb_any(skb);
2742 *pskb = skb = newskb;
2744 vlan_hdr = *((unsigned short *)(skb->data+MACADDRLEN*2+2));
2746 *((unsigned short *)(skb->data+MACADDRLEN*2+2-i*2)) = *((unsigned short *)(skb->data+MACADDRLEN*2-2-i*2));
2751 if (skb_is_nonlinear(skb))
2752 DEBUG_ERR("%s(): skb_is_nonlinear!!\n", __FUNCTION__);
2754 res = skb_linearize(skb);
2756 DEBUG_ERR("TX DROP: skb_linearize fail!\n");
2757 /* goto free_and_stop; */
2761 res = nat25_db_handle(padapter, skb, NAT25_INSERT);
2764 /* priv->ext_stats.tx_drops++; */
2765 DEBUG_ERR("TX DROP: nat25_db_handle fail!\n");
2766 /* goto free_and_stop; */
2774 memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
2776 dhcp_flag_bcast(padapter, skb);
2781 *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2));
2782 *((unsigned short *)(skb->data+MACADDRLEN*2)) = __constant_htons(ETH_P_8021Q);
2783 *((unsigned short *)(skb->data+MACADDRLEN*2+2)) = vlan_hdr;
2787 /* check if SA is equal to our MAC */
2788 if (memcmp(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN)) {
2789 /* priv->ext_stats.tx_drops++; */
2790 DEBUG_ERR("TX DROP: untransformed frame SA:%02X%02X%02X%02X%02X%02X!\n",
2791 skb->data[6],skb->data[7],skb->data[8],skb->data[9],skb->data[10],skb->data[11]);
2792 /* goto free_and_stop; */
2798 #endif /* CONFIG_BR_EXT */
2800 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
2803 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2805 switch(pattrib->qsel)
2809 addr = BE_QUEUE_INX;
2813 addr = BK_QUEUE_INX;
2817 addr = VI_QUEUE_INX;
2821 addr = VO_QUEUE_INX;
2824 addr = BCN_QUEUE_INX;
2826 case 0x11:/* BC/MC in PS (HIQ) */
2827 addr = HIGH_QUEUE_INX;
2831 addr = MGT_QUEUE_INX;
2839 static void do_queue_select(_adapter *padapter, struct pkt_attrib *pattrib)
2843 qsel = pattrib->priority;
2844 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("### do_queue_select priority=%d ,qsel = %d\n",pattrib->priority ,qsel));
2846 pattrib->qsel = qsel;
2850 * The main transmit(tx) entry
2854 * 0 success, hardware will handle this xmit frame(packet)
2857 s32 rtw_xmit(_adapter *padapter, _pkt **ppkt)
2859 static u32 start = 0;
2860 static u32 drop_cnt = 0;
2861 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2862 struct xmit_frame *pxmitframe = NULL;
2863 #ifdef CONFIG_BR_EXT
2864 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2865 void *br_port = NULL;
2866 #endif /* CONFIG_BR_EXT */
2871 start = rtw_get_current_time();
2873 pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
2875 if (rtw_get_passing_time_ms(start) > 2000) {
2877 DBG_8723A("DBG_TX_DROP_FRAME %s no more pxmitframe, drop_cnt:%u\n", __FUNCTION__, drop_cnt);
2878 start = rtw_get_current_time();
2882 if (pxmitframe == NULL) {
2884 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: no more pxmitframe\n"));
2888 #ifdef CONFIG_BR_EXT
2890 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
2891 br_port = padapter->pnetdev->br_port;
2892 #else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
2894 br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
2896 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
2898 if( br_port && check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE)
2900 res = rtw_br_client_tx(padapter, ppkt);
2903 rtw_free_xmitframe(pxmitpriv, pxmitframe);
2908 #endif /* CONFIG_BR_EXT */
2910 res = update_attrib(padapter, *ppkt, &pxmitframe->attrib);
2913 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: update attrib fail\n"));
2914 #ifdef DBG_TX_DROP_FRAME
2915 DBG_8723A("DBG_TX_DROP_FRAME %s update attrib fail\n", __FUNCTION__);
2917 rtw_free_xmitframe(pxmitpriv, pxmitframe);
2920 pxmitframe->pkt = *ppkt;
2922 rtw_led_control(padapter, LED_CTL_TX);
2924 do_queue_select(padapter, &pxmitframe->attrib);
2926 #ifdef CONFIG_AP_MODE
2927 spin_lock_bh(&pxmitpriv->lock);
2928 if(xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE)
2930 spin_unlock_bh(&pxmitpriv->lock);
2933 spin_unlock_bh(&pxmitpriv->lock);
2936 if (rtw_hal_xmit(padapter, pxmitframe) == _FALSE)
2943 int xmitframe_enqueue_for_tdls_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
2947 struct sta_info *ptdls_sta=NULL;
2948 struct sta_priv *pstapriv = &padapter->stapriv;
2949 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2950 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2953 ptdls_sta=rtw_get_stainfo(pstapriv, pattrib->dst);
2954 if(ptdls_sta==NULL){
2956 }else if(ptdls_sta->tdls_sta_state&TDLS_LINKED_STATE){
2958 if(pattrib->triggered==1)
2964 spin_lock_bh(&ptdls_sta->sleep_q.lock);
2966 if(ptdls_sta->state&WIFI_SLEEP_STATE)
2968 list_del_init(&pxmitframe->list);
2970 /* spin_lock_bh(&psta->sleep_q.lock); */
2972 list_add_tail(&pxmitframe->list, get_list_head(&ptdls_sta->sleep_q));
2974 ptdls_sta->sleepq_len++;
2975 ptdls_sta->sleepq_ac_len++;
2977 /* indicate 4-AC queue bit in TDLS peer traffic indication */
2978 switch(pattrib->priority)
2982 ptdls_sta->uapsd_bk = ptdls_sta->uapsd_bk | BIT(1);
2986 ptdls_sta->uapsd_vi = ptdls_sta->uapsd_vi | BIT(1);
2990 ptdls_sta->uapsd_vo = ptdls_sta->uapsd_vo | BIT(1);
2995 ptdls_sta->uapsd_be = ptdls_sta->uapsd_be | BIT(1);
2999 if(ptdls_sta->sleepq_len==1)
3001 /* transmit TDLS PTI via AP */
3002 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_SD_PTI);
3008 spin_unlock_bh(&ptdls_sta->sleep_q.lock);
3013 #endif /* CONFIG_TDLS */
3015 #if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS)
3017 int xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
3020 struct sta_info *psta=NULL;
3021 struct sta_priv *pstapriv = &padapter->stapriv;
3022 struct pkt_attrib *pattrib = &pxmitframe->attrib;
3023 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3024 int bmcst = IS_MCAST(pattrib->ra);
3026 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
3028 if( ptdlsinfo->setup_state == TDLS_LINKED_STATE )
3030 ret = xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pxmitframe);
3033 #endif /* CONFIG_TDLS */
3035 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _FALSE)
3040 psta = pattrib->psta;
3044 DBG_8723A("%s, call rtw_get_stainfo()\n", __func__);
3045 psta=rtw_get_stainfo(pstapriv, pattrib->ra);
3050 DBG_8723A("%s, psta==NUL\n", __func__);
3054 if(!(psta->state &_FW_LINKED))
3056 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
3060 if(pattrib->triggered==1)
3062 /* DBG_8723A("directly xmit pspoll_triggered packet\n"); */
3064 /* pattrib->triggered=0; */
3067 pattrib->qsel = 0x11;/* HIQ */
3074 spin_lock_bh(&psta->sleep_q.lock);
3076 if(pstapriv->sta_dz_bitmap)/* if anyone sta is in ps mode */
3078 list_del_init(&pxmitframe->list);
3080 /* spin_lock_bh(&psta->sleep_q.lock); */
3082 list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
3086 pstapriv->tim_bitmap |= BIT(0);/* */
3087 pstapriv->sta_dz_bitmap |= BIT(0);
3089 /* DBG_8723A("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
3091 update_beacon(padapter, _TIM_IE_, NULL, _FALSE);/* tx bc/mc packets after upate bcn */
3093 /* spin_unlock_bh(&psta->sleep_q.lock); */
3099 spin_unlock_bh(&psta->sleep_q.lock);
3105 spin_lock_bh(&psta->sleep_q.lock);
3107 if(psta->state&WIFI_SLEEP_STATE)
3111 if(pstapriv->sta_dz_bitmap&BIT(psta->aid))
3113 list_del_init(&pxmitframe->list);
3115 /* spin_lock_bh(&psta->sleep_q.lock); */
3117 list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
3121 switch(pattrib->priority)
3125 wmmps_ac = psta->uapsd_bk&BIT(0);
3129 wmmps_ac = psta->uapsd_vi&BIT(0);
3133 wmmps_ac = psta->uapsd_vo&BIT(0);
3138 wmmps_ac = psta->uapsd_be&BIT(0);
3143 psta->sleepq_ac_len++;
3145 if(((psta->has_legacy_ac) && (!wmmps_ac)) ||((!psta->has_legacy_ac)&&(wmmps_ac)))
3147 pstapriv->tim_bitmap |= BIT(psta->aid);
3149 /* DBG_8723A("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
3151 if(psta->sleepq_len==1)
3153 /* DBG_8723A("sleepq_len==1, update BCNTIM\n"); */
3154 /* upate BCN for TIM IE */
3155 update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
3159 /* spin_unlock_bh(&psta->sleep_q.lock); */
3161 /* if(psta->sleepq_len > (NR_XMITFRAME>>3)) */
3163 /* wakeup_sta_to_xmit(padapter, psta); */
3172 spin_unlock_bh(&psta->sleep_q.lock);
3177 static void dequeue_xmitframes_to_sleeping_queue(_adapter *padapter, struct sta_info *psta, _queue *pframequeue)
3180 struct list_head *plist, *phead;
3182 struct tx_servq *ptxservq;
3183 struct pkt_attrib *pattrib;
3184 struct xmit_frame *pxmitframe;
3185 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
3187 phead = get_list_head(pframequeue);
3188 plist = phead->next;
3190 while (rtw_end_of_queue_search(phead, plist) == _FALSE)
3192 pxmitframe = container_of(plist, struct xmit_frame, list);
3194 plist = plist->next;
3196 ret = xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
3200 pattrib = &pxmitframe->attrib;
3202 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
3205 phwxmits[ac_index].accnt--;
3209 /* DBG_8723A("xmitframe_enqueue_for_sleeping_sta return _FALSE\n"); */
3215 void stop_sta_xmit(_adapter *padapter, struct sta_info *psta)
3217 struct sta_info *psta_bmc;
3218 struct sta_xmit_priv *pstaxmitpriv;
3219 struct sta_priv *pstapriv = &padapter->stapriv;
3220 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3222 pstaxmitpriv = &psta->sta_xmitpriv;
3224 /* for BC/MC Frames */
3225 psta_bmc = rtw_get_bcmc_stainfo(padapter);
3227 spin_lock_bh(&pxmitpriv->lock);
3229 psta->state |= WIFI_SLEEP_STATE;
3232 if( !(psta->tdls_sta_state & TDLS_LINKED_STATE) )
3233 #endif /* CONFIG_TDLS */
3234 pstapriv->sta_dz_bitmap |= BIT(psta->aid);
3236 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
3237 list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
3239 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
3240 list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
3242 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
3243 list_del_init(&(pstaxmitpriv->be_q.tx_pending));
3245 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
3246 list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
3249 if( !(psta->tdls_sta_state & TDLS_LINKED_STATE) )
3251 if( psta_bmc != NULL )
3253 #endif /* CONFIG_TDLS */
3255 /* for BC/MC Frames */
3256 pstaxmitpriv = &psta_bmc->sta_xmitpriv;
3257 dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending);
3258 list_del_init(&(pstaxmitpriv->be_q.tx_pending));
3263 #endif /* CONFIG_TDLS */
3264 spin_unlock_bh(&pxmitpriv->lock);
3267 void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta)
3269 u8 update_mask=0, wmmps_ac=0;
3270 struct sta_info *psta_bmc;
3271 struct list_head *xmitframe_plist, *xmitframe_phead;
3272 struct xmit_frame *pxmitframe=NULL;
3273 struct sta_priv *pstapriv = &padapter->stapriv;
3274 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3276 /* spin_lock_bh(&psta->sleep_q.lock); */
3277 spin_lock_bh(&pxmitpriv->lock);
3279 xmitframe_phead = get_list_head(&psta->sleep_q);
3280 xmitframe_plist = xmitframe_phead->next;
3282 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
3284 pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
3286 xmitframe_plist = xmitframe_plist->next;
3288 list_del_init(&pxmitframe->list);
3290 switch(pxmitframe->attrib.priority)
3294 wmmps_ac = psta->uapsd_bk&BIT(1);
3298 wmmps_ac = psta->uapsd_vi&BIT(1);
3302 wmmps_ac = psta->uapsd_vo&BIT(1);
3307 wmmps_ac = psta->uapsd_be&BIT(1);
3312 if(psta->sleepq_len>0)
3313 pxmitframe->attrib.mdata = 1;
3315 pxmitframe->attrib.mdata = 0;
3319 psta->sleepq_ac_len--;
3320 if(psta->sleepq_ac_len>0)
3322 pxmitframe->attrib.mdata = 1;
3323 pxmitframe->attrib.eosp = 0;
3327 pxmitframe->attrib.mdata = 0;
3328 pxmitframe->attrib.eosp = 1;
3332 pxmitframe->attrib.triggered = 1;
3335 spin_unlock_bh(&psta->sleep_q.lock);
3336 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
3338 rtw_os_xmit_complete(padapter, pxmitframe);
3340 spin_lock_bh(&psta->sleep_q.lock);
3342 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
3346 if(psta->sleepq_len==0)
3349 if( psta->tdls_sta_state & TDLS_LINKED_STATE )
3351 if(psta->state&WIFI_SLEEP_STATE)
3352 psta->state ^= WIFI_SLEEP_STATE;
3354 /* spin_unlock_bh(&psta->sleep_q.lock); */
3355 spin_unlock_bh(&pxmitpriv->lock);
3358 #endif /* CONFIG_TDLS */
3359 pstapriv->tim_bitmap &= ~BIT(psta->aid);
3361 /* DBG_8723A("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); */
3362 /* upate BCN for TIM IE */
3363 /* update_BCNTIM(padapter); */
3364 update_mask = BIT(0);
3366 if(psta->state&WIFI_SLEEP_STATE)
3367 psta->state ^= WIFI_SLEEP_STATE;
3369 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
3371 psta->expire_to = pstapriv->expire_to;
3372 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
3375 pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
3378 /* spin_unlock_bh(&psta->sleep_q.lock); */
3379 spin_unlock_bh(&pxmitpriv->lock);
3381 /* for BC/MC Frames */
3382 psta_bmc = rtw_get_bcmc_stainfo(padapter);
3386 if((pstapriv->sta_dz_bitmap&0xfffe) == 0x0)/* no any sta in ps mode */
3388 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
3389 spin_lock_bh(&pxmitpriv->lock);
3391 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
3392 xmitframe_plist = xmitframe_phead->next;
3394 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
3396 pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
3398 xmitframe_plist = xmitframe_plist->next;
3400 list_del_init(&pxmitframe->list);
3402 psta_bmc->sleepq_len--;
3403 if(psta_bmc->sleepq_len>0)
3404 pxmitframe->attrib.mdata = 1;
3406 pxmitframe->attrib.mdata = 0;
3408 pxmitframe->attrib.triggered = 1;
3410 spin_unlock_bh(&psta_bmc->sleep_q.lock);
3411 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
3413 rtw_os_xmit_complete(padapter, pxmitframe);
3415 spin_lock_bh(&psta_bmc->sleep_q.lock);
3418 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
3422 if(psta_bmc->sleepq_len==0)
3424 pstapriv->tim_bitmap &= ~BIT(0);
3425 pstapriv->sta_dz_bitmap &= ~BIT(0);
3427 /* DBG_8723A("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); */
3428 /* upate BCN for TIM IE */
3429 /* update_BCNTIM(padapter); */
3430 update_mask |= BIT(1);
3433 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
3434 spin_unlock_bh(&pxmitpriv->lock);
3440 /* update_BCNTIM(padapter); */
3441 /* printk("%s => call update_beacon\n",__FUNCTION__); */
3442 update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
3446 void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta)
3449 struct list_head *xmitframe_plist, *xmitframe_phead;
3450 struct xmit_frame *pxmitframe=NULL;
3451 struct sta_priv *pstapriv = &padapter->stapriv;
3452 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3454 /* spin_lock_bh(&psta->sleep_q.lock); */
3455 spin_lock_bh(&pxmitpriv->lock);
3457 xmitframe_phead = get_list_head(&psta->sleep_q);
3458 xmitframe_plist = xmitframe_phead->next;
3460 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
3462 pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
3464 xmitframe_plist = xmitframe_plist->next;
3466 switch(pxmitframe->attrib.priority)
3470 wmmps_ac = psta->uapsd_bk&BIT(1);
3474 wmmps_ac = psta->uapsd_vi&BIT(1);
3478 wmmps_ac = psta->uapsd_vo&BIT(1);
3483 wmmps_ac = psta->uapsd_be&BIT(1);
3490 list_del_init(&pxmitframe->list);
3493 psta->sleepq_ac_len--;
3495 if(psta->sleepq_ac_len>0)
3497 pxmitframe->attrib.mdata = 1;
3498 pxmitframe->attrib.eosp = 0;
3502 pxmitframe->attrib.mdata = 0;
3503 pxmitframe->attrib.eosp = 1;
3506 pxmitframe->attrib.triggered = 1;
3509 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
3511 rtw_os_xmit_complete(padapter, pxmitframe);
3514 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
3516 if((psta->sleepq_ac_len==0) && (!psta->has_legacy_ac) && (wmmps_ac))
3519 if(psta->tdls_sta_state & TDLS_LINKED_STATE )
3521 /* spin_unlock_bh(&psta->sleep_q.lock); */
3522 spin_unlock_bh(&pxmitpriv->lock);
3525 #endif /* CONFIG_TDLS */
3526 pstapriv->tim_bitmap &= ~BIT(psta->aid);
3528 /* DBG_8723A("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); */
3529 /* upate BCN for TIM IE */
3530 /* update_BCNTIM(padapter); */
3531 update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
3532 /* update_mask = BIT(0); */
3537 /* spin_unlock_bh(&psta->sleep_q.lock); */
3538 spin_unlock_bh(&pxmitpriv->lock);
3543 #ifdef CONFIG_XMIT_THREAD_MODE
3544 void enqueue_pending_xmitbuf(
3545 struct xmit_priv *pxmitpriv,
3546 struct xmit_buf *pxmitbuf)
3549 _adapter *pri_adapter = pxmitpriv->adapter;
3551 pqueue = &pxmitpriv->pending_xmitbuf_queue;
3553 spin_lock_bh(&pqueue->lock, &irql);
3554 list_del_init(&pxmitbuf->list);
3555 list_add_tail(&pxmitbuf->list, get_list_head(pqueue));
3556 spin_unlock_bh(&pqueue->lock, &irql);
3558 up(&(pri_adapter->xmitpriv.xmit_sema));
3561 struct xmit_buf* dequeue_pending_xmitbuf(
3562 struct xmit_priv *pxmitpriv)
3564 struct xmit_buf *pxmitbuf;
3568 pqueue = &pxmitpriv->pending_xmitbuf_queue;
3570 spin_lock_bh(&pqueue->lock, &irql);
3572 if (_rtw_queue_empty(pqueue) == _FALSE)
3574 struct list_head *plist, *phead;
3576 phead = get_list_head(pqueue);
3577 plist = phead->next;
3578 pxmitbuf = container_of(plist, struct xmit_buf, list);
3579 list_del_init(&pxmitbuf->list);
3582 spin_unlock_bh(&pqueue->lock, &irql);
3587 struct xmit_buf* dequeue_pending_xmitbuf_under_survey(
3588 struct xmit_priv *pxmitpriv)
3590 struct xmit_buf *pxmitbuf;
3591 struct xmit_frame *pxmitframe;
3595 pqueue = &pxmitpriv->pending_xmitbuf_queue;
3597 spin_lock_bh(&pqueue->lock, &irql);
3599 if (_rtw_queue_empty(pqueue) == _FALSE)
3601 struct list_head *plist, *phead;
3604 phead = get_list_head(pqueue);
3607 plist = plist->next;
3611 pxmitbuf = container_of(plist, struct xmit_buf, list);
3613 pxmitframe = (struct xmit_frame*)pxmitbuf->priv_data;
3616 type = GetFrameSubType(pxmitbuf->pbuf + TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
3620 DBG_8723A("%s, !!!ERROR!!! For USB, TODO ITEM \n", __FUNCTION__);
3623 if ((type == WIFI_PROBEREQ) ||
3624 (type == WIFI_DATA_NULL) ||
3625 (type == WIFI_QOS_DATA_NULL))
3627 list_del_init(&pxmitbuf->list);
3634 spin_unlock_bh(&pqueue->lock, &irql);
3639 int check_pending_xmitbuf(
3640 struct xmit_priv *pxmitpriv)
3644 pqueue = &pxmitpriv->pending_xmitbuf_queue;
3646 if(_rtw_queue_empty(pqueue) == _FALSE)
3652 thread_return rtw_xmit_thread(thread_context context)
3658 padapter = (PADAPTER)context;
3660 thread_enter("RTW_XMIT_THREAD");
3663 err = rtw_hal_xmit_thread_handler(padapter);
3664 flush_signals_thread();
3665 } while (_SUCCESS == err);
3667 up(&padapter->xmitpriv.terminate_xmitthread_sema);
3673 void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms)
3675 sctx->timeout_ms = timeout_ms;
3676 sctx->submit_time= rtw_get_current_time();
3677 init_completion(&sctx->done);
3678 sctx->status = RTW_SCTX_SUBMITTED;
3681 int rtw_sctx_wait(struct submit_ctx *sctx)
3684 unsigned long expire;
3687 expire= sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT;
3688 if (!wait_for_completion_timeout(&sctx->done, expire)) {
3689 /* timeout, do something?? */
3690 status = RTW_SCTX_DONE_TIMEOUT;
3691 DBG_8723A("%s timeout\n", __func__);
3693 status = sctx->status;
3696 if (status == RTW_SCTX_DONE_SUCCESS) {
3703 bool rtw_sctx_chk_waring_status(int status)
3706 case RTW_SCTX_DONE_UNKNOWN:
3707 case RTW_SCTX_DONE_BUF_ALLOC:
3708 case RTW_SCTX_DONE_BUF_FREE:
3710 case RTW_SCTX_DONE_DRV_STOP:
3711 case RTW_SCTX_DONE_DEV_REMOVE:
3718 void rtw_sctx_done_err(struct submit_ctx **sctx, int status)
3721 if (rtw_sctx_chk_waring_status(status))
3722 DBG_8723A("%s status:%d\n", __func__, status);
3723 (*sctx)->status = status;
3724 complete(&((*sctx)->done));
3729 void rtw_sctx_done(struct submit_ctx **sctx)
3731 rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS);
3734 #ifdef CONFIG_XMIT_ACK
3736 #ifdef CONFIG_XMIT_ACK_POLLING
3739 * rtw_ack_tx_polling -
3740 * @pxmitpriv: xmit_priv to address ack_tx_ops
3741 * @timeout_ms: timeout msec
3743 * Init ack_tx_ops and then do c2h_evt_hdl() and polling ack_tx_ops repeatedly
3744 * till tx report or timeout
3745 * Returns: _SUCCESS if TX report ok, _FAIL for others
3747 int rtw_ack_tx_polling(struct xmit_priv *pxmitpriv, u32 timeout_ms)
3750 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
3751 _adapter *adapter = container_of(pxmitpriv, _adapter, xmitpriv);
3753 pack_tx_ops->submit_time = rtw_get_current_time();
3754 pack_tx_ops->timeout_ms = timeout_ms;
3755 pack_tx_ops->status = RTW_SCTX_SUBMITTED;
3758 c2h_evt_hdl(adapter, NULL, rtw_hal_c2h_id_filter_ccx(adapter));
3759 if (pack_tx_ops->status != RTW_SCTX_SUBMITTED)
3762 if (adapter->bDriverStopped) {
3763 pack_tx_ops->status = RTW_SCTX_DONE_DRV_STOP;
3766 if (adapter->bSurpriseRemoved) {
3767 pack_tx_ops->status = RTW_SCTX_DONE_DEV_REMOVE;
3772 } while (rtw_get_passing_time_ms(pack_tx_ops->submit_time) < timeout_ms);
3774 if (pack_tx_ops->status == RTW_SCTX_SUBMITTED) {
3775 pack_tx_ops->status = RTW_SCTX_DONE_TIMEOUT;
3776 DBG_8723A("%s timeout\n", __func__);
3779 if (pack_tx_ops->status == RTW_SCTX_DONE_SUCCESS)
3786 int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
3788 #ifdef CONFIG_XMIT_ACK_POLLING
3789 return rtw_ack_tx_polling(pxmitpriv, timeout_ms);
3791 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
3793 pack_tx_ops->submit_time = rtw_get_current_time();
3794 pack_tx_ops->timeout_ms = timeout_ms;
3795 pack_tx_ops->status = RTW_SCTX_SUBMITTED;
3797 return rtw_sctx_wait(pack_tx_ops);
3801 void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)
3803 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
3805 if (pxmitpriv->ack_tx) {
3806 rtw_sctx_done_err(&pack_tx_ops, status);
3808 DBG_8723A("%s ack_tx not set\n", __func__);
3811 #endif /* CONFIG_XMIT_ACK */