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 ******************************************************************************/
17 #include <osdep_service.h>
18 #include <drv_types.h>
20 #include <osdep_intf.h>
23 #include <rtl8723a_xmit.h>
25 static void _init_txservq(struct tx_servq
*ptxservq
)
28 INIT_LIST_HEAD(&ptxservq
->tx_pending
);
29 _rtw_init_queue23a(&ptxservq
->sta_pending
);
34 void _rtw_init_sta_xmit_priv23a(struct sta_xmit_priv
*psta_xmitpriv
)
37 spin_lock_init(&psta_xmitpriv
->lock
);
39 /* for (i = 0 ; i < MAX_NUMBLKS; i++) */
40 /* _init_txservq(&psta_xmitpriv->blk_q[i]); */
42 _init_txservq(&psta_xmitpriv
->be_q
);
43 _init_txservq(&psta_xmitpriv
->bk_q
);
44 _init_txservq(&psta_xmitpriv
->vi_q
);
45 _init_txservq(&psta_xmitpriv
->vo_q
);
46 INIT_LIST_HEAD(&psta_xmitpriv
->legacy_dz
);
47 INIT_LIST_HEAD(&psta_xmitpriv
->apsd
);
51 int _rtw_init_xmit_priv23a(struct xmit_priv
*pxmitpriv
,
52 struct rtw_adapter
*padapter
)
55 struct xmit_buf
*pxmitbuf
;
56 struct xmit_frame
*pxframe
;
58 u32 max_xmit_extbuf_size
= MAX_XMIT_EXTBUF_SZ
;
59 u32 num_xmit_extbuf
= NR_XMIT_EXTBUFF
;
61 spin_lock_init(&pxmitpriv
->lock
);
62 spin_lock_init(&pxmitpriv
->lock_sctx
);
63 sema_init(&pxmitpriv
->xmit_sema
, 0);
64 sema_init(&pxmitpriv
->terminate_xmitthread_sema
, 0);
66 pxmitpriv
->adapter
= padapter
;
68 _rtw_init_queue23a(&pxmitpriv
->be_pending
);
69 _rtw_init_queue23a(&pxmitpriv
->bk_pending
);
70 _rtw_init_queue23a(&pxmitpriv
->vi_pending
);
71 _rtw_init_queue23a(&pxmitpriv
->vo_pending
);
72 _rtw_init_queue23a(&pxmitpriv
->bm_pending
);
74 _rtw_init_queue23a(&pxmitpriv
->free_xmit_queue
);
76 for (i
= 0; i
< NR_XMITFRAME
; i
++) {
77 pxframe
= kzalloc(sizeof(struct xmit_frame
), GFP_KERNEL
);
80 INIT_LIST_HEAD(&pxframe
->list
);
82 pxframe
->padapter
= padapter
;
83 pxframe
->frame_tag
= NULL_FRAMETAG
;
85 list_add_tail(&pxframe
->list
,
86 &pxmitpriv
->free_xmit_queue
.queue
);
89 pxmitpriv
->free_xmitframe_cnt
= i
;
91 pxmitpriv
->frag_len
= MAX_FRAG_THRESHOLD
;
94 _rtw_init_queue23a(&pxmitpriv
->free_xmitbuf_queue
);
95 INIT_LIST_HEAD(&pxmitpriv
->xmitbuf_list
);
96 _rtw_init_queue23a(&pxmitpriv
->pending_xmitbuf_queue
);
98 for (i
= 0; i
< NR_XMITBUFF
; i
++) {
99 pxmitbuf
= kzalloc(sizeof(struct xmit_buf
), GFP_KERNEL
);
102 INIT_LIST_HEAD(&pxmitbuf
->list
);
103 INIT_LIST_HEAD(&pxmitbuf
->list2
);
105 pxmitbuf
->padapter
= padapter
;
107 /* Tx buf allocation may fail sometimes, so sleep and retry. */
108 res
= rtw_os_xmit_resource_alloc23a(padapter
, pxmitbuf
,
109 (MAX_XMITBUF_SZ
+ XMITBUF_ALIGN_SZ
));
114 list_add_tail(&pxmitbuf
->list
,
115 &pxmitpriv
->free_xmitbuf_queue
.queue
);
116 list_add_tail(&pxmitbuf
->list2
,
117 &pxmitpriv
->xmitbuf_list
);
120 pxmitpriv
->free_xmitbuf_cnt
= NR_XMITBUFF
;
122 /* init xframe_ext queue, the same count as extbuf */
123 _rtw_init_queue23a(&pxmitpriv
->free_xframe_ext_queue
);
125 for (i
= 0; i
< num_xmit_extbuf
; i
++) {
126 pxframe
= kzalloc(sizeof(struct xmit_frame
), GFP_KERNEL
);
129 INIT_LIST_HEAD(&pxframe
->list
);
131 pxframe
->padapter
= padapter
;
132 pxframe
->frame_tag
= NULL_FRAMETAG
;
136 pxframe
->buf_addr
= NULL
;
137 pxframe
->pxmitbuf
= NULL
;
139 pxframe
->ext_tag
= 1;
141 list_add_tail(&pxframe
->list
,
142 &pxmitpriv
->free_xframe_ext_queue
.queue
);
144 pxmitpriv
->free_xframe_ext_cnt
= i
;
146 /* Init xmit extension buff */
147 _rtw_init_queue23a(&pxmitpriv
->free_xmit_extbuf_queue
);
148 INIT_LIST_HEAD(&pxmitpriv
->xmitextbuf_list
);
150 for (i
= 0; i
< num_xmit_extbuf
; i
++) {
151 pxmitbuf
= kzalloc(sizeof(struct xmit_buf
), GFP_KERNEL
);
154 INIT_LIST_HEAD(&pxmitbuf
->list
);
155 INIT_LIST_HEAD(&pxmitbuf
->list2
);
157 pxmitbuf
->padapter
= padapter
;
159 /* Tx buf allocation may fail sometimes, so sleep and retry. */
160 res
= rtw_os_xmit_resource_alloc23a(padapter
, pxmitbuf
,
161 max_xmit_extbuf_size
+ XMITBUF_ALIGN_SZ
);
166 list_add_tail(&pxmitbuf
->list
,
167 &pxmitpriv
->free_xmit_extbuf_queue
.queue
);
168 list_add_tail(&pxmitbuf
->list2
,
169 &pxmitpriv
->xmitextbuf_list
);
172 pxmitpriv
->free_xmit_extbuf_cnt
= num_xmit_extbuf
;
174 rtw_alloc_hwxmits23a(padapter
);
175 rtw_init_hwxmits23a(pxmitpriv
->hwxmits
, pxmitpriv
->hwxmit_entry
);
177 for (i
= 0; i
< 4; i
++)
178 pxmitpriv
->wmm_para_seq
[i
] = i
;
180 sema_init(&pxmitpriv
->tx_retevt
, 0);
182 pxmitpriv
->ack_tx
= false;
183 mutex_init(&pxmitpriv
->ack_tx_mutex
);
184 rtw_sctx_init23a(&pxmitpriv
->ack_tx_ops
, 0);
185 tasklet_init(&padapter
->xmitpriv
.xmit_tasklet
,
186 (void(*)(unsigned long))rtl8723au_xmit_tasklet
,
187 (unsigned long)padapter
);
196 void _rtw_free_xmit_priv23a(struct xmit_priv
*pxmitpriv
)
198 struct rtw_adapter
*padapter
= pxmitpriv
->adapter
;
199 struct xmit_frame
*pxframe
, *ptmp
;
200 struct xmit_buf
*pxmitbuf
, *ptmp2
;
202 list_for_each_entry_safe(pxframe
, ptmp
,
203 &pxmitpriv
->free_xmit_queue
.queue
, list
) {
204 list_del_init(&pxframe
->list
);
205 rtw_os_xmit_complete23a(padapter
, pxframe
);
209 list_for_each_entry_safe(pxmitbuf
, ptmp2
,
210 &pxmitpriv
->xmitbuf_list
, list2
) {
211 list_del_init(&pxmitbuf
->list2
);
212 rtw_os_xmit_resource_free23a(padapter
, pxmitbuf
);
216 /* free xframe_ext queue, the same count as extbuf */
217 list_for_each_entry_safe(pxframe
, ptmp
,
218 &pxmitpriv
->free_xframe_ext_queue
.queue
,
220 list_del_init(&pxframe
->list
);
221 rtw_os_xmit_complete23a(padapter
, pxframe
);
225 /* free xmit extension buff */
226 list_for_each_entry_safe(pxmitbuf
, ptmp2
,
227 &pxmitpriv
->xmitextbuf_list
, list2
) {
228 list_del_init(&pxmitbuf
->list2
);
229 rtw_os_xmit_resource_free23a(padapter
, pxmitbuf
);
233 rtw_free_hwxmits23a(padapter
);
234 mutex_destroy(&pxmitpriv
->ack_tx_mutex
);
237 static void update_attrib_vcs_info(struct rtw_adapter
*padapter
, struct xmit_frame
*pxmitframe
)
240 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
241 struct sta_info
*psta
= pattrib
->psta
;
242 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
243 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
246 psta
= pattrib
->psta
;
248 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__
);
249 psta
= rtw_get_stainfo23a(&padapter
->stapriv
, &pattrib
->ra
[0]);
253 DBG_8723A("%s, psta == NUL\n", __func__
);
257 if (!(psta
->state
&_FW_LINKED
)) {
258 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__
, psta
->state
);
262 if (pattrib
->nr_frags
!= 1)
263 sz
= padapter
->xmitpriv
.frag_len
;
265 sz
= pattrib
->last_txcmdsz
;
267 /* (1) RTS_Threshold is compared to the MPDU, not MSDU. */
268 /* (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. */
269 /* Other fragments are protected by previous fragment. */
270 /* So we only need to check the length of first fragment. */
271 if (pmlmeext
->cur_wireless_mode
< WIRELESS_11_24N
|| padapter
->registrypriv
.wifi_spec
) {
272 if (sz
> padapter
->registrypriv
.rts_thresh
) {
273 pattrib
->vcs_mode
= RTS_CTS
;
276 pattrib
->vcs_mode
= RTS_CTS
;
277 else if (psta
->cts2self
)
278 pattrib
->vcs_mode
= CTS_TO_SELF
;
280 pattrib
->vcs_mode
= NONE_VCS
;
285 if (pmlmeinfo
->assoc_AP_vendor
== HT_IOT_PEER_ATHEROS
&&
287 padapter
->securitypriv
.dot11PrivacyAlgrthm
==
288 WLAN_CIPHER_SUITE_CCMP
) {
289 pattrib
->vcs_mode
= CTS_TO_SELF
;
293 /* check ERP protection */
294 if (psta
->rtsen
|| psta
->cts2self
) {
296 pattrib
->vcs_mode
= RTS_CTS
;
297 else if (psta
->cts2self
)
298 pattrib
->vcs_mode
= CTS_TO_SELF
;
303 /* check HT op mode */
304 if (pattrib
->ht_en
) {
305 u8 HTOpMode
= pmlmeinfo
->HT_protection
;
307 if ((pmlmeext
->cur_bwmode
&& (HTOpMode
== 2 || HTOpMode
== 3)) ||
308 (!pmlmeext
->cur_bwmode
&& HTOpMode
== 3)) {
309 pattrib
->vcs_mode
= RTS_CTS
;
315 if (sz
> padapter
->registrypriv
.rts_thresh
) {
316 pattrib
->vcs_mode
= RTS_CTS
;
320 /* to do list: check MIMO power save condition. */
322 /* check AMPDU aggregation for TXOP */
323 if (pattrib
->ampdu_en
) {
324 pattrib
->vcs_mode
= RTS_CTS
;
328 pattrib
->vcs_mode
= NONE_VCS
;
334 static void update_attrib_phy_info(struct pkt_attrib
*pattrib
, struct sta_info
*psta
)
337 pattrib->vcs_mode = RTS_CTS;
338 else if (psta->cts2self)
339 pattrib->vcs_mode = CTS_TO_SELF;
341 pattrib->vcs_mode = NONE_VCS;*/
345 pattrib
->triggered
= 0;
347 /* qos_en, ht_en, init rate, , bw, ch_offset, sgi */
348 pattrib
->qos_en
= psta
->qos_option
;
350 pattrib
->raid
= psta
->raid
;
351 pattrib
->ht_en
= psta
->htpriv
.ht_option
;
352 pattrib
->bwmode
= psta
->htpriv
.bwmode
;
353 pattrib
->ch_offset
= psta
->htpriv
.ch_offset
;
354 pattrib
->sgi
= psta
->htpriv
.sgi
;
355 pattrib
->ampdu_en
= false;
357 pattrib
->retry_ctrl
= false;
360 u8
qos_acm23a(u8 acm_mask
, u8 priority
)
362 u8 change_priority
= priority
;
367 if (acm_mask
& BIT(1))
375 if (acm_mask
& BIT(2))
380 if (acm_mask
& BIT(3))
384 DBG_8723A("qos_acm23a(): invalid pattrib->priority: %d!!!\n",
390 return change_priority
;
393 static void set_qos(struct sk_buff
*skb
, struct pkt_attrib
*pattrib
)
395 u8
*pframe
= skb
->data
;
396 struct iphdr
*ip_hdr
;
399 /* get UserPriority from IP hdr */
400 if (pattrib
->ether_type
== ETH_P_IP
) {
401 ip_hdr
= (struct iphdr
*)(pframe
+ ETH_HLEN
);
402 UserPriority
= ip_hdr
->tos
>> 5;
403 } else if (pattrib
->ether_type
== ETH_P_PAE
) {
404 /* "When priority processing of data frames is supported, */
405 /* a STA's SME should send EAPOL-Key frames at the highest
410 pattrib
->priority
= UserPriority
;
411 pattrib
->hdrlen
= sizeof(struct ieee80211_qos_hdr
);
412 pattrib
->type
= IEEE80211_FTYPE_DATA
| IEEE80211_STYPE_QOS_DATA
;
415 static int update_attrib(struct rtw_adapter
*padapter
,
416 struct sk_buff
*skb
, struct pkt_attrib
*pattrib
)
418 struct sta_info
*psta
= NULL
;
420 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
421 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
422 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
424 struct ethhdr
*ehdr
= (struct ethhdr
*) skb
->data
;
426 pattrib
->ether_type
= ntohs(ehdr
->h_proto
);
428 ether_addr_copy(pattrib
->dst
, ehdr
->h_dest
);
429 ether_addr_copy(pattrib
->src
, ehdr
->h_source
);
433 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) ||
434 check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) {
435 ether_addr_copy(pattrib
->ra
, pattrib
->dst
);
436 ether_addr_copy(pattrib
->ta
, pattrib
->src
);
437 } else if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) {
438 ether_addr_copy(pattrib
->ra
, get_bssid(pmlmepriv
));
439 ether_addr_copy(pattrib
->ta
, pattrib
->src
);
440 } else if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
441 ether_addr_copy(pattrib
->ra
, pattrib
->dst
);
442 ether_addr_copy(pattrib
->ta
, get_bssid(pmlmepriv
));
445 pattrib
->pktlen
= skb
->len
- ETH_HLEN
;
447 if (pattrib
->ether_type
== ETH_P_IP
) {
448 /* The following is for DHCP and ARP packet, we use cck1M
449 to tx these packets and let LPS awake some time */
450 /* to prevent DHCP protocol fail */
451 pattrib
->dhcp_pkt
= 0;
452 /* MINIMUM_DHCP_PACKET_SIZE) { */
453 if (pattrib
->pktlen
> 282 + 24) {
454 if (pattrib
->ether_type
== ETH_P_IP
) {/* IP header */
455 u8
*pframe
= skb
->data
;
459 if ((pframe
[21] == 68 && pframe
[23] == 67) ||
460 (pframe
[21] == 67 && pframe
[23] == 68)) {
461 /* 68 : UDP BOOTP client */
462 /* 67 : UDP BOOTP server */
463 RT_TRACE(_module_rtl871x_xmit_c_
,
465 "======================update_attrib: get DHCP Packet\n");
466 pattrib
->dhcp_pkt
= 1;
470 } else if (pattrib
->ether_type
== ETH_P_PAE
) {
471 DBG_8723A_LEVEL(_drv_always_
, "send eapol packet\n");
474 if ((pattrib
->ether_type
== ETH_P_PAE
) || (pattrib
->dhcp_pkt
== 1)) {
475 rtw_set_scan_deny(padapter
, 3000);
478 /* If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */
479 if ((pattrib
->ether_type
== ETH_P_ARP
) ||
480 (pattrib
->ether_type
== ETH_P_PAE
) || (pattrib
->dhcp_pkt
== 1)) {
481 rtw_lps_ctrl_wk_cmd23a(padapter
, LPS_CTRL_SPECIAL_PACKET
, 1);
484 bmcast
= is_multicast_ether_addr(pattrib
->ra
);
488 psta
= rtw_get_bcmc_stainfo23a(padapter
);
490 psta
= rtw_get_stainfo23a(pstapriv
, pattrib
->ra
);
491 if (psta
== NULL
) { /* if we cannot get psta => drrp the pkt */
492 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_alert_
,
493 "update_attrib => get sta_info fail, ra:%pM\n",
497 } else if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) &&
498 (!(psta
->state
& _FW_LINKED
))) {
505 pattrib
->mac_id
= psta
->mac_id
;
506 /* DBG_8723A("%s ==> mac_id(%d)\n", __func__, pattrib->mac_id); */
507 pattrib
->psta
= psta
;
509 /* if we cannot get psta => drop the pkt */
510 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_alert_
,
511 "update_attrib => get sta_info fail, ra:%pM\n",
517 pattrib
->ack_policy
= 0;
518 /* get ether_hdr_len */
520 /* pattrib->ether_type == 0x8100) ? (14 + 4): 14; vlan tag */
521 pattrib
->pkt_hdrlen
= ETH_HLEN
;
523 pattrib
->hdrlen
= sizeof(struct ieee80211_hdr_3addr
);
524 pattrib
->type
= IEEE80211_FTYPE_DATA
;
525 pattrib
->priority
= 0;
527 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
| WIFI_ADHOC_STATE
|
528 WIFI_ADHOC_MASTER_STATE
)) {
529 if (psta
->qos_option
)
530 set_qos(skb
, pattrib
);
532 if (pmlmepriv
->qos_option
) {
533 set_qos(skb
, pattrib
);
535 if (pmlmepriv
->acm_mask
!= 0) {
536 pattrib
->priority
= qos_acm23a(pmlmepriv
->acm_mask
,
542 if (psta
->ieee8021x_blocked
== true) {
543 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
544 "psta->ieee8021x_blocked == true\n");
546 pattrib
->encrypt
= 0;
548 if ((pattrib
->ether_type
!= ETH_P_PAE
) &&
549 !check_fwstate(pmlmepriv
, WIFI_MP_STATE
)) {
550 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
551 "psta->ieee8021x_blocked == true, pattrib->ether_type(%.4x) != 0x888e\n",
552 pattrib
->ether_type
);
557 GET_ENCRY_ALGO(psecuritypriv
, psta
, pattrib
->encrypt
, bmcast
);
559 switch (psecuritypriv
->dot11AuthAlgrthm
) {
560 case dot11AuthAlgrthm_Open
:
561 case dot11AuthAlgrthm_Shared
:
562 case dot11AuthAlgrthm_Auto
:
564 (u8
)psecuritypriv
->dot11PrivacyKeyIndex
;
566 case dot11AuthAlgrthm_8021X
:
569 (u8
)psecuritypriv
->dot118021XGrpKeyid
;
571 pattrib
->key_idx
= 0;
574 pattrib
->key_idx
= 0;
580 switch (pattrib
->encrypt
) {
581 case WLAN_CIPHER_SUITE_WEP40
:
582 case WLAN_CIPHER_SUITE_WEP104
:
583 pattrib
->iv_len
= IEEE80211_WEP_IV_LEN
;
584 pattrib
->icv_len
= IEEE80211_WEP_ICV_LEN
;
587 case WLAN_CIPHER_SUITE_TKIP
:
588 pattrib
->iv_len
= IEEE80211_TKIP_IV_LEN
;
589 pattrib
->icv_len
= IEEE80211_TKIP_ICV_LEN
;
591 if (!padapter
->securitypriv
.busetkipkey
) {
592 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
593 "padapter->securitypriv.busetkipkey(%d) == false drop packet\n",
594 padapter
->securitypriv
.busetkipkey
);
600 case WLAN_CIPHER_SUITE_CCMP
:
601 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
602 "pattrib->encrypt =%d (WLAN_CIPHER_SUITE_CCMP)\n",
604 pattrib
->iv_len
= IEEE80211_CCMP_HDR_LEN
;
605 pattrib
->icv_len
= IEEE80211_CCMP_MIC_LEN
;
610 pattrib
->icv_len
= 0;
614 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
615 "update_attrib: encrypt =%d\n", pattrib
->encrypt
);
617 if (pattrib
->encrypt
&& !psecuritypriv
->hw_decrypted
) {
618 pattrib
->bswenc
= true;
619 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
620 "update_attrib: encrypt =%d bswenc = true\n",
623 pattrib
->bswenc
= false;
624 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
625 "update_attrib: bswenc = false\n");
627 update_attrib_phy_info(pattrib
, psta
);
634 static int xmitframe_addmic(struct rtw_adapter
*padapter
,
635 struct xmit_frame
*pxmitframe
) {
636 struct mic_data micdata
;
637 struct sta_info
*stainfo
;
638 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
639 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
640 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
641 int curfragnum
, length
;
642 u8
*pframe
, *payload
, mic
[8];
643 u8 priority
[4]= {0x0, 0x0, 0x0, 0x0};
644 u8 hw_hdr_offset
= 0;
645 int bmcst
= is_multicast_ether_addr(pattrib
->ra
);
648 stainfo
= pattrib
->psta
;
650 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__
);
651 stainfo
= rtw_get_stainfo23a(&padapter
->stapriv
, &pattrib
->ra
[0]);
655 DBG_8723A("%s, psta == NUL\n", __func__
);
659 if (!(stainfo
->state
&_FW_LINKED
)) {
660 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
661 __func__
, stainfo
->state
);
665 hw_hdr_offset
= TXDESC_OFFSET
;
667 if (pattrib
->encrypt
== WLAN_CIPHER_SUITE_TKIP
) {
668 /* encode mic code */
670 u8 null_key
[16]={0x0, 0x0, 0x0, 0x0,
675 pframe
= pxmitframe
->buf_addr
+ hw_hdr_offset
;
678 if (!memcmp(psecuritypriv
->dot118021XGrptxmickey
[psecuritypriv
->dot118021XGrpKeyid
].skey
, null_key
, 16)) {
681 /* start to calculate the mic code */
682 rtw_secmicsetkey23a(&micdata
, psecuritypriv
->dot118021XGrptxmickey
[psecuritypriv
->dot118021XGrpKeyid
].skey
);
684 if (!memcmp(&stainfo
->dot11tkiptxmickey
.skey
[0],
688 /* start to calculate the mic code */
689 rtw_secmicsetkey23a(&micdata
, &stainfo
->dot11tkiptxmickey
.skey
[0]);
692 if (pframe
[1] & 1) { /* ToDS == 1 */
694 rtw_secmicappend23a(&micdata
, &pframe
[16], 6);
695 if (pframe
[1] & 2) /* From Ds == 1 */
696 rtw_secmicappend23a(&micdata
,
699 rtw_secmicappend23a(&micdata
,
701 } else { /* ToDS == 0 */
703 rtw_secmicappend23a(&micdata
, &pframe
[4], 6);
704 if (pframe
[1] & 2) /* From Ds == 1 */
705 rtw_secmicappend23a(&micdata
,
708 rtw_secmicappend23a(&micdata
,
712 /* if (pmlmepriv->qos_option == 1) */
714 priority
[0] = (u8
)pxmitframe
->attrib
.priority
;
716 rtw_secmicappend23a(&micdata
, &priority
[0], 4);
720 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
;
722 payload
= PTR_ALIGN(payload
, 4);
723 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
724 "=== curfragnum =%d, pframe = 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n",
725 curfragnum
, *payload
, *(payload
+ 1),
726 *(payload
+ 2), *(payload
+ 3),
727 *(payload
+ 4), *(payload
+ 5),
728 *(payload
+ 6), *(payload
+ 7));
730 payload
= payload
+ pattrib
->hdrlen
+
732 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
733 "curfragnum =%d pattrib->hdrlen =%d pattrib->iv_len =%d\n",
735 pattrib
->hdrlen
, pattrib
->iv_len
);
736 if ((curfragnum
+ 1) == pattrib
->nr_frags
) {
737 length
= pattrib
->last_txcmdsz
-
741 pattrib
->icv_len
: 0);
742 rtw_secmicappend23a(&micdata
, payload
,
744 payload
= payload
+ length
;
746 length
= pxmitpriv
->frag_len
-
750 pattrib
->icv_len
: 0);
751 rtw_secmicappend23a(&micdata
, payload
,
753 payload
= payload
+ length
+
755 RT_TRACE(_module_rtl871x_xmit_c_
,
757 "curfragnum =%d length =%d pattrib->icv_len =%d\n",
762 rtw_secgetmic23a(&micdata
, &mic
[0]);
763 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
764 "xmitframe_addmic: before add mic code!!\n");
765 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
766 "xmitframe_addmic: pattrib->last_txcmdsz =%d!!!\n",
767 pattrib
->last_txcmdsz
);
768 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
769 "xmitframe_addmic: mic[0]= 0x%.2x , mic[1]=0x%.2x , mic[2]= 0x%.2x , mic[3]= 0x%.2x\nmic[4]= 0x%.2x , mic[5]= 0x%.2x , mic[6]= 0x%.2x , mic[7]= 0x%.2x !!!!\n",
770 mic
[0], mic
[1], mic
[2], mic
[3],
771 mic
[4], mic
[5], mic
[6], mic
[7]);
772 /* add mic code and add the mic code length
775 memcpy(payload
, &mic
[0], 8);
776 pattrib
->last_txcmdsz
+= 8;
778 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
779 "======== last pkt ========\n");
780 payload
= payload
- pattrib
->last_txcmdsz
+ 8;
781 for (curfragnum
= 0; curfragnum
< pattrib
->last_txcmdsz
;
782 curfragnum
= curfragnum
+ 8) {
783 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
784 "%.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x\n",
785 *(payload
+ curfragnum
),
786 *(payload
+ curfragnum
+ 1),
787 *(payload
+ curfragnum
+ 2),
788 *(payload
+ curfragnum
+ 3),
789 *(payload
+ curfragnum
+ 4),
790 *(payload
+ curfragnum
+ 5),
791 *(payload
+ curfragnum
+ 6),
792 *(payload
+ curfragnum
+ 7));
795 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
796 "xmitframe_addmic: rtw_get_stainfo23a ==NULL!!!\n");
803 static int xmitframe_swencrypt(struct rtw_adapter
*padapter
,
804 struct xmit_frame
*pxmitframe
)
806 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
808 /* if ((psecuritypriv->sw_encrypt)||(pattrib->bswenc)) */
809 if (pattrib
->bswenc
) {
810 /* DBG_8723A("start xmitframe_swencrypt\n"); */
811 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_alert_
,
812 "### xmitframe_swencrypt\n");
813 switch (pattrib
->encrypt
) {
814 case WLAN_CIPHER_SUITE_WEP40
:
815 case WLAN_CIPHER_SUITE_WEP104
:
816 rtw_wep_encrypt23a(padapter
, pxmitframe
);
818 case WLAN_CIPHER_SUITE_TKIP
:
819 rtw_tkip_encrypt23a(padapter
, pxmitframe
);
821 case WLAN_CIPHER_SUITE_CCMP
:
822 rtw_aes_encrypt23a(padapter
, pxmitframe
);
829 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_notice_
,
830 "### xmitframe_hwencrypt\n");
836 static int rtw_make_wlanhdr(struct rtw_adapter
*padapter
, u8
*hdr
,
837 struct pkt_attrib
*pattrib
)
839 struct ieee80211_hdr
*pwlanhdr
= (struct ieee80211_hdr
*)hdr
;
840 struct ieee80211_qos_hdr
*qoshdr
;
841 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
842 u8 qos_option
= false;
845 struct sta_info
*psta
;
847 int bmcst
= is_multicast_ether_addr(pattrib
->ra
);
850 psta
= pattrib
->psta
;
852 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__
);
854 psta
= rtw_get_bcmc_stainfo23a(padapter
);
856 psta
= rtw_get_stainfo23a(&padapter
->stapriv
, pattrib
->ra
);
861 DBG_8723A("%s, psta == NUL\n", __func__
);
865 if (!(psta
->state
&_FW_LINKED
)) {
866 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__
, psta
->state
);
870 memset(hdr
, 0, WLANHDR_OFFSET
);
872 pwlanhdr
->frame_control
= cpu_to_le16(pattrib
->type
);
874 if (pattrib
->type
& IEEE80211_FTYPE_DATA
) {
875 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) {
876 /* to_ds = 1, fr_ds = 0; */
877 /* Data transfer to AP */
878 pwlanhdr
->frame_control
|=
879 cpu_to_le16(IEEE80211_FCTL_TODS
);
880 ether_addr_copy(pwlanhdr
->addr1
, get_bssid(pmlmepriv
));
881 ether_addr_copy(pwlanhdr
->addr2
, pattrib
->src
);
882 ether_addr_copy(pwlanhdr
->addr3
, pattrib
->dst
);
884 if (pmlmepriv
->qos_option
)
887 } else if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
888 /* to_ds = 0, fr_ds = 1; */
889 pwlanhdr
->frame_control
|=
890 cpu_to_le16(IEEE80211_FCTL_FROMDS
);
891 ether_addr_copy(pwlanhdr
->addr1
, pattrib
->dst
);
892 ether_addr_copy(pwlanhdr
->addr2
, get_bssid(pmlmepriv
));
893 ether_addr_copy(pwlanhdr
->addr3
, pattrib
->src
);
895 if (psta
->qos_option
)
897 } else if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) ||
898 check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) {
899 ether_addr_copy(pwlanhdr
->addr1
, pattrib
->dst
);
900 ether_addr_copy(pwlanhdr
->addr2
, pattrib
->src
);
901 ether_addr_copy(pwlanhdr
->addr3
, get_bssid(pmlmepriv
));
903 if (psta
->qos_option
)
907 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
908 "fw_state:%x is not allowed to xmit frame\n",
909 get_fwstate(pmlmepriv
));
914 pwlanhdr
->frame_control
|=
915 cpu_to_le16(IEEE80211_FCTL_MOREDATA
);
916 if (pattrib
->encrypt
)
917 pwlanhdr
->frame_control
|=
918 cpu_to_le16(IEEE80211_FCTL_PROTECTED
);
920 qoshdr
= (struct ieee80211_qos_hdr
*)hdr
;
922 qoshdr
->qos_ctrl
= cpu_to_le16(
923 pattrib
->priority
& IEEE80211_QOS_CTL_TID_MASK
);
925 qoshdr
->qos_ctrl
|= cpu_to_le16(
926 (pattrib
->ack_policy
<< 5) &
927 IEEE80211_QOS_CTL_ACK_POLICY_MASK
);
931 cpu_to_le16(IEEE80211_QOS_CTL_EOSP
);
933 /* TODO: fill HT Control Field */
935 /* Update Seq Num will be handled by f/w */
937 psta
->sta_xmitpriv
.txseq_tid
[pattrib
->priority
]++;
938 psta
->sta_xmitpriv
.txseq_tid
[pattrib
->priority
] &= 0xFFF;
939 pattrib
->seqnum
= psta
->sta_xmitpriv
.txseq_tid
[pattrib
->priority
];
940 /* We dont need to worry about frag bits here */
941 pwlanhdr
->seq_ctrl
= cpu_to_le16(IEEE80211_SN_TO_SEQ(
943 /* check if enable ampdu */
944 if (pattrib
->ht_en
&& psta
->htpriv
.ampdu_enable
) {
945 if (pattrib
->priority
>= 16)
946 printk(KERN_WARNING
"%s: Invalid "
947 "pattrib->priority %i\n",
948 __func__
, pattrib
->priority
);
949 if (psta
->htpriv
.agg_enable_bitmap
&
950 BIT(pattrib
->priority
))
951 pattrib
->ampdu_en
= true;
953 /* re-check if enable ampdu by BA_starting_seqctrl */
954 if (pattrib
->ampdu_en
) {
957 tx_seq
= psta
->BA_starting_seqctrl
[pattrib
->priority
& 0x0f];
959 /* check BA_starting_seqctrl */
960 if (SN_LESS(pattrib
->seqnum
, tx_seq
)) {
961 /* DBG_8723A("tx ampdu seqnum(%d) < tx_seq(%d)\n", pattrib->seqnum, tx_seq); */
962 pattrib
->ampdu_en
= false;/* AGG BK */
963 } else if (SN_EQUAL(pattrib
->seqnum
, tx_seq
)) {
964 psta
->BA_starting_seqctrl
[pattrib
->priority
& 0x0f] = (tx_seq
+1)&0xfff;
965 pattrib
->ampdu_en
= true;/* AGG EN */
967 /* DBG_8723A("tx ampdu over run\n"); */
968 psta
->BA_starting_seqctrl
[pattrib
->priority
& 0x0f] = (pattrib
->seqnum
+1)&0xfff;
969 pattrib
->ampdu_en
= true;/* AGG EN */
978 s32
rtw_txframes_pending23a(struct rtw_adapter
*padapter
)
980 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
982 return (!list_empty(&pxmitpriv
->be_pending
.queue
)) ||
983 (!list_empty(&pxmitpriv
->bk_pending
.queue
)) ||
984 (!list_empty(&pxmitpriv
->vi_pending
.queue
)) ||
985 (!list_empty(&pxmitpriv
->vo_pending
.queue
));
988 s32
rtw_txframes_sta_ac_pending23a(struct rtw_adapter
*padapter
,
989 struct pkt_attrib
*pattrib
)
991 struct sta_info
*psta
;
992 struct tx_servq
*ptxservq
;
993 int priority
= pattrib
->priority
;
996 psta
= pattrib
->psta
;
998 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__
);
999 psta
= rtw_get_stainfo23a(&padapter
->stapriv
, &pattrib
->ra
[0]);
1002 DBG_8723A("%s, psta == NUL\n", __func__
);
1005 if (!(psta
->state
&_FW_LINKED
)) {
1006 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__
,
1013 ptxservq
= &psta
->sta_xmitpriv
.bk_q
;
1017 ptxservq
= &psta
->sta_xmitpriv
.vi_q
;
1021 ptxservq
= &psta
->sta_xmitpriv
.vo_q
;
1026 ptxservq
= &psta
->sta_xmitpriv
.be_q
;
1029 return ptxservq
->qcnt
;
1032 /* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
1033 * IEEE LLC/SNAP header contains 8 octets
1034 * First 3 octets comprise the LLC portion
1035 * SNAP portion, 5 octets, is divided into two fields:
1036 * Organizationally Unique Identifier(OUI), 3 octets,
1037 * type, defined by that organization, 2 octets.
1039 static int rtw_put_snap(u8
*data
, u16 h_proto
)
1041 if (h_proto
== ETH_P_IPX
|| h_proto
== ETH_P_AARP
)
1042 ether_addr_copy(data
, bridge_tunnel_header
);
1044 ether_addr_copy(data
, rfc1042_header
);
1047 put_unaligned_be16(h_proto
, data
);
1048 return ETH_ALEN
+ sizeof(u16
);
1053 This sub-routine will perform all the following:
1055 1. remove 802.3 header.
1056 2. create wlan_header, based on the info in pxmitframe
1057 3. append sta's iv/ext-iv
1059 5. move frag chunk from pframe to pxmitframe->mem
1060 6. apply sw-encrypt, if necessary.
1063 int rtw_xmitframe_coalesce23a(struct rtw_adapter
*padapter
, struct sk_buff
*skb
,
1064 struct xmit_frame
*pxmitframe
)
1066 struct sta_info
*psta
;
1067 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1068 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
1069 struct ieee80211_hdr
*hdr
;
1070 s32 frg_inx
, frg_len
, mpdu_len
, llc_sz
, mem_sz
;
1071 u8
*pframe
, *mem_start
;
1074 u8
*pdata
= skb
->data
;
1075 int data_len
= skb
->len
;
1076 s32 bmcst
= is_multicast_ether_addr(pattrib
->ra
);
1080 psta
= pattrib
->psta
;
1082 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__
);
1083 psta
= rtw_get_stainfo23a(&padapter
->stapriv
, pattrib
->ra
);
1087 DBG_8723A("%s, psta == NUL\n", __func__
);
1091 if (!(psta
->state
&_FW_LINKED
)) {
1092 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
1093 __func__
, psta
->state
);
1097 if (!pxmitframe
->buf_addr
) {
1098 DBG_8723A("==> %s buf_addr == NULL\n", __func__
);
1102 pbuf_start
= pxmitframe
->buf_addr
;
1104 hw_hdr_offset
= TXDESC_OFFSET
;
1106 mem_start
= pbuf_start
+ hw_hdr_offset
;
1108 if (rtw_make_wlanhdr(padapter
, mem_start
, pattrib
) == _FAIL
) {
1109 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
1110 "%s: rtw_make_wlanhdr fail; drop pkt\n", __func__
);
1115 pdata
+= pattrib
->pkt_hdrlen
;
1116 data_len
-= pattrib
->pkt_hdrlen
;
1119 frg_len
= pxmitpriv
->frag_len
- 4;/* 2346-4 = 2342 */
1127 hdr
= (struct ieee80211_hdr
*)mem_start
;
1129 pframe
+= pattrib
->hdrlen
;
1130 mpdu_len
-= pattrib
->hdrlen
;
1132 /* adding icv, if necessary... */
1133 if (pattrib
->iv_len
) {
1135 switch (pattrib
->encrypt
) {
1136 case WLAN_CIPHER_SUITE_WEP40
:
1137 case WLAN_CIPHER_SUITE_WEP104
:
1138 WEP_IV(pattrib
->iv
, psta
->dot11txpn
,
1141 case WLAN_CIPHER_SUITE_TKIP
:
1143 TKIP_IV(pattrib
->iv
,
1147 TKIP_IV(pattrib
->iv
,
1148 psta
->dot11txpn
, 0);
1150 case WLAN_CIPHER_SUITE_CCMP
:
1157 psta
->dot11txpn
, 0);
1162 memcpy(pframe
, pattrib
->iv
, pattrib
->iv_len
);
1164 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_notice_
,
1165 "rtw_xmiaframe_coalesce23a: keyid =%d pattrib->iv[3]=%.2x pframe =%.2x %.2x %.2x %.2x\n",
1166 padapter
->securitypriv
.dot11PrivacyKeyIndex
,
1167 pattrib
->iv
[3], *pframe
, *(pframe
+1),
1168 *(pframe
+2), *(pframe
+3));
1169 pframe
+= pattrib
->iv_len
;
1170 mpdu_len
-= pattrib
->iv_len
;
1173 llc_sz
= rtw_put_snap(pframe
, pattrib
->ether_type
);
1178 if (pattrib
->icv_len
> 0 && pattrib
->bswenc
)
1179 mpdu_len
-= pattrib
->icv_len
;
1182 /* don't do fragment to broadcast/multicast packets */
1183 mem_sz
= min_t(s32
, data_len
, pattrib
->pktlen
);
1185 mem_sz
= min_t(s32
, data_len
, mpdu_len
);
1187 memcpy(pframe
, pdata
, mem_sz
);
1193 if ((pattrib
->icv_len
>0) && (pattrib
->bswenc
)) {
1194 memcpy(pframe
, pattrib
->icv
, pattrib
->icv_len
);
1195 pframe
+= pattrib
->icv_len
;
1200 if (bmcst
|| data_len
<= 0) {
1201 pattrib
->nr_frags
= frg_inx
;
1203 pattrib
->last_txcmdsz
= pattrib
->hdrlen
+
1205 ((pattrib
->nr_frags
== 1) ?
1207 ((pattrib
->bswenc
) ?
1208 pattrib
->icv_len
: 0) + mem_sz
;
1209 hdr
->frame_control
&=
1210 ~cpu_to_le16(IEEE80211_FCTL_MOREFRAGS
);
1214 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
1215 "%s: There're still something in packet!\n",
1218 hdr
->frame_control
|= cpu_to_le16(IEEE80211_FCTL_MOREFRAGS
);
1220 mem_start
= PTR_ALIGN(pframe
, 4) + hw_hdr_offset
;
1221 memcpy(mem_start
, pbuf_start
+ hw_hdr_offset
, pattrib
->hdrlen
);
1224 if (xmitframe_addmic(padapter
, pxmitframe
) == _FAIL
) {
1225 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
1226 "xmitframe_addmic(padapter, pxmitframe) == _FAIL\n");
1227 DBG_8723A("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n");
1232 xmitframe_swencrypt(padapter
, pxmitframe
);
1235 update_attrib_vcs_info(padapter
, pxmitframe
);
1237 pattrib
->vcs_mode
= NONE_VCS
;
1243 void rtw_update_protection23a(struct rtw_adapter
*padapter
, u8
*ie
, uint ie_len
)
1245 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1246 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
1250 switch (pregistrypriv
->vrtl_carrier_sense
) {
1252 pxmitpriv
->vcs
= NONE_VCS
;
1258 p
= cfg80211_find_ie(WLAN_EID_ERP_INFO
, ie
, ie_len
);
1260 pxmitpriv
->vcs
= NONE_VCS
;
1262 protection
= (*(p
+ 2)) & BIT(1);
1264 if (pregistrypriv
->vcs_type
== RTS_CTS
)
1265 pxmitpriv
->vcs
= RTS_CTS
;
1267 pxmitpriv
->vcs
= CTS_TO_SELF
;
1269 pxmitpriv
->vcs
= NONE_VCS
;
1276 void rtw_count_tx_stats23a(struct rtw_adapter
*padapter
, struct xmit_frame
*pxmitframe
, int sz
)
1278 struct sta_info
*psta
= NULL
;
1279 struct stainfo_stats
*pstats
= NULL
;
1280 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1281 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1283 if (pxmitframe
->frame_tag
== DATA_FRAMETAG
) {
1284 pxmitpriv
->tx_bytes
+= sz
;
1285 pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
++;
1287 psta
= pxmitframe
->attrib
.psta
;
1289 pstats
= &psta
->sta_stats
;
1291 pstats
->tx_bytes
+= sz
;
1296 struct xmit_buf
*rtw_alloc_xmitbuf23a_ext(struct xmit_priv
*pxmitpriv
)
1299 struct xmit_buf
*pxmitbuf
= NULL
;
1300 struct list_head
*phead
;
1301 struct rtw_queue
*pfree_queue
= &pxmitpriv
->free_xmit_extbuf_queue
;
1303 spin_lock_irqsave(&pfree_queue
->lock
, irqL
);
1305 phead
= get_list_head(pfree_queue
);
1307 if (!list_empty(phead
)) {
1308 pxmitbuf
= list_first_entry(phead
, struct xmit_buf
, list
);
1310 list_del_init(&pxmitbuf
->list
);
1312 pxmitpriv
->free_xmit_extbuf_cnt
--;
1313 pxmitbuf
->priv_data
= NULL
;
1314 pxmitbuf
->ext_tag
= true;
1316 if (pxmitbuf
->sctx
) {
1317 DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__
);
1318 rtw23a_sctx_done_err(&pxmitbuf
->sctx
, RTW_SCTX_DONE_BUF_ALLOC
);
1322 spin_unlock_irqrestore(&pfree_queue
->lock
, irqL
);
1327 int rtw_free_xmitbuf_ext23a(struct xmit_priv
*pxmitpriv
,
1328 struct xmit_buf
*pxmitbuf
)
1331 struct rtw_queue
*pfree_queue
= &pxmitpriv
->free_xmit_extbuf_queue
;
1333 if (pxmitbuf
== NULL
)
1336 spin_lock_irqsave(&pfree_queue
->lock
, irqL
);
1338 list_del_init(&pxmitbuf
->list
);
1340 list_add_tail(&pxmitbuf
->list
, get_list_head(pfree_queue
));
1341 pxmitpriv
->free_xmit_extbuf_cnt
++;
1343 spin_unlock_irqrestore(&pfree_queue
->lock
, irqL
);
1348 struct xmit_buf
*rtw_alloc_xmitbuf23a(struct xmit_priv
*pxmitpriv
)
1351 struct xmit_buf
*pxmitbuf
= NULL
;
1352 struct list_head
*phead
;
1353 struct rtw_queue
*pfree_xmitbuf_queue
= &pxmitpriv
->free_xmitbuf_queue
;
1355 /* DBG_8723A("+rtw_alloc_xmitbuf23a\n"); */
1357 spin_lock_irqsave(&pfree_xmitbuf_queue
->lock
, irqL
);
1359 phead
= get_list_head(pfree_xmitbuf_queue
);
1361 if (!list_empty(phead
)) {
1362 pxmitbuf
= list_first_entry(phead
, struct xmit_buf
, list
);
1364 list_del_init(&pxmitbuf
->list
);
1366 pxmitpriv
->free_xmitbuf_cnt
--;
1367 pxmitbuf
->priv_data
= NULL
;
1368 pxmitbuf
->ext_tag
= false;
1369 pxmitbuf
->flags
= XMIT_VO_QUEUE
;
1371 if (pxmitbuf
->sctx
) {
1372 DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__
);
1373 rtw23a_sctx_done_err(&pxmitbuf
->sctx
, RTW_SCTX_DONE_BUF_ALLOC
);
1377 spin_unlock_irqrestore(&pfree_xmitbuf_queue
->lock
, irqL
);
1382 int rtw_free_xmitbuf23a(struct xmit_priv
*pxmitpriv
, struct xmit_buf
*pxmitbuf
)
1385 struct rtw_queue
*pfree_xmitbuf_queue
= &pxmitpriv
->free_xmitbuf_queue
;
1387 /* DBG_8723A("+rtw_free_xmitbuf23a\n"); */
1389 if (pxmitbuf
== NULL
)
1392 if (pxmitbuf
->sctx
) {
1393 DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__
);
1394 rtw23a_sctx_done_err(&pxmitbuf
->sctx
, RTW_SCTX_DONE_BUF_FREE
);
1397 if (pxmitbuf
->ext_tag
) {
1398 rtw_free_xmitbuf_ext23a(pxmitpriv
, pxmitbuf
);
1400 spin_lock_irqsave(&pfree_xmitbuf_queue
->lock
, irqL
);
1402 list_del_init(&pxmitbuf
->list
);
1404 list_add_tail(&pxmitbuf
->list
,
1405 get_list_head(pfree_xmitbuf_queue
));
1407 pxmitpriv
->free_xmitbuf_cnt
++;
1408 spin_unlock_irqrestore(&pfree_xmitbuf_queue
->lock
, irqL
);
1414 static void rtw_init_xmitframe(struct xmit_frame
*pxframe
)
1416 if (pxframe
!= NULL
) {
1417 /* default value setting */
1418 pxframe
->buf_addr
= NULL
;
1419 pxframe
->pxmitbuf
= NULL
;
1421 memset(&pxframe
->attrib
, 0, sizeof(struct pkt_attrib
));
1422 /* pxframe->attrib.psta = NULL; */
1424 pxframe
->frame_tag
= DATA_FRAMETAG
;
1426 pxframe
->pkt
= NULL
;
1427 pxframe
->pkt_offset
= 1;/* default use pkt_offset to fill tx desc */
1429 pxframe
->ack_report
= 0;
1436 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
1438 If we turn on USE_RXTHREAD, then, no need for critical section.
1439 Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
1441 Must be very very cautious...
1444 static struct xmit_frame
*rtw_alloc_xmitframe(struct xmit_priv
*pxmitpriv
)
1446 struct xmit_frame
*pxframe
;
1447 struct rtw_queue
*pfree_xmit_queue
= &pxmitpriv
->free_xmit_queue
;
1449 spin_lock_bh(&pfree_xmit_queue
->lock
);
1451 pxframe
= list_first_entry_or_null(&pfree_xmit_queue
->queue
,
1452 struct xmit_frame
, list
);
1454 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
1455 "rtw_alloc_xmitframe:%d\n",
1456 pxmitpriv
->free_xmitframe_cnt
);
1458 list_del_init(&pxframe
->list
);
1459 pxmitpriv
->free_xmitframe_cnt
--;
1460 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
1461 "rtw_alloc_xmitframe():free_xmitframe_cnt =%d\n",
1462 pxmitpriv
->free_xmitframe_cnt
);
1465 spin_unlock_bh(&pfree_xmit_queue
->lock
);
1467 rtw_init_xmitframe(pxframe
);
1472 struct xmit_frame
*rtw_alloc_xmitframe23a_ext(struct xmit_priv
*pxmitpriv
)
1474 struct xmit_frame
*pxframe
;
1475 struct rtw_queue
*queue
= &pxmitpriv
->free_xframe_ext_queue
;
1477 spin_lock_bh(&queue
->lock
);
1479 pxframe
= list_first_entry_or_null(&queue
->queue
,
1480 struct xmit_frame
, list
);
1482 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
1483 "rtw_alloc_xmitframe23a_ext:%d\n",
1484 pxmitpriv
->free_xframe_ext_cnt
);
1486 list_del_init(&pxframe
->list
);
1487 pxmitpriv
->free_xframe_ext_cnt
--;
1488 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
1489 "rtw_alloc_xmitframe23a_ext():free_xmitframe_cnt =%d\n",
1490 pxmitpriv
->free_xframe_ext_cnt
);
1493 spin_unlock_bh(&queue
->lock
);
1495 rtw_init_xmitframe(pxframe
);
1500 s32
rtw_free_xmitframe23a(struct xmit_priv
*pxmitpriv
, struct xmit_frame
*pxmitframe
)
1502 struct rtw_queue
*queue
= NULL
;
1503 struct rtw_adapter
*padapter
= pxmitpriv
->adapter
;
1504 struct sk_buff
*pndis_pkt
= NULL
;
1506 if (pxmitframe
== NULL
) {
1507 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
1508 "====== rtw_free_xmitframe23a():pxmitframe == NULL!!!!!!!!!!\n");
1512 if (pxmitframe
->pkt
) {
1513 pndis_pkt
= pxmitframe
->pkt
;
1514 pxmitframe
->pkt
= NULL
;
1517 if (pxmitframe
->ext_tag
== 0)
1518 queue
= &pxmitpriv
->free_xmit_queue
;
1519 else if (pxmitframe
->ext_tag
== 1)
1520 queue
= &pxmitpriv
->free_xframe_ext_queue
;
1523 goto check_pkt_complete
;
1524 spin_lock_bh(&queue
->lock
);
1526 list_del_init(&pxmitframe
->list
);
1527 list_add_tail(&pxmitframe
->list
, get_list_head(queue
));
1528 if (pxmitframe
->ext_tag
== 0) {
1529 pxmitpriv
->free_xmitframe_cnt
++;
1530 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_debug_
,
1531 "rtw_free_xmitframe23a():free_xmitframe_cnt =%d\n",
1532 pxmitpriv
->free_xmitframe_cnt
);
1533 } else if (pxmitframe
->ext_tag
== 1) {
1534 pxmitpriv
->free_xframe_ext_cnt
++;
1535 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_debug_
,
1536 "rtw_free_xmitframe23a():free_xframe_ext_cnt =%d\n",
1537 pxmitpriv
->free_xframe_ext_cnt
);
1540 spin_unlock_bh(&queue
->lock
);
1545 rtw_os_pkt_complete23a(padapter
, pndis_pkt
);
1552 void rtw_free_xmitframe_queue23a(struct xmit_priv
*pxmitpriv
,
1553 struct rtw_queue
*pframequeue
)
1555 struct list_head
*phead
;
1556 struct xmit_frame
*pxmitframe
, *ptmp
;
1558 spin_lock_bh(&pframequeue
->lock
);
1559 phead
= get_list_head(pframequeue
);
1560 list_for_each_entry_safe(pxmitframe
, ptmp
, phead
, list
)
1561 rtw_free_xmitframe23a(pxmitpriv
, pxmitframe
);
1562 spin_unlock_bh(&pframequeue
->lock
);
1566 int rtw_xmitframe_enqueue23a(struct rtw_adapter
*padapter
,
1567 struct xmit_frame
*pxmitframe
)
1569 if (rtw_xmit23a_classifier(padapter
, pxmitframe
) == _FAIL
) {
1570 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
1571 "rtw_xmitframe_enqueue23a: drop xmit pkt for classifier fail\n");
1578 static struct xmit_frame
*
1579 dequeue_one_xmitframe(struct xmit_priv
*pxmitpriv
, struct hw_xmit
*phwxmit
,
1580 struct tx_servq
*ptxservq
, struct rtw_queue
*pframe_queue
)
1582 struct list_head
*phead
;
1583 struct xmit_frame
*pxmitframe
= NULL
;
1585 phead
= get_list_head(pframe_queue
);
1587 if (!list_empty(phead
)) {
1588 pxmitframe
= list_first_entry(phead
, struct xmit_frame
, list
);
1589 list_del_init(&pxmitframe
->list
);
1596 rtw_dequeue_xframe23a(struct xmit_priv
*pxmitpriv
, struct hw_xmit
*phwxmit_i
,
1599 struct list_head
*sta_phead
;
1600 struct hw_xmit
*phwxmit
;
1601 struct tx_servq
*ptxservq
= NULL
, *ptmp
;
1602 struct rtw_queue
*pframe_queue
= NULL
;
1603 struct xmit_frame
*pxmitframe
= NULL
;
1604 struct rtw_adapter
*padapter
= pxmitpriv
->adapter
;
1605 struct registry_priv
*pregpriv
= &padapter
->registrypriv
;
1612 if (pregpriv
->wifi_spec
== 1) {
1615 for (j
= 0; j
< 4; j
++)
1616 inx
[j
] = pxmitpriv
->wmm_para_seq
[j
];
1619 spin_lock_bh(&pxmitpriv
->lock
);
1621 for (i
= 0; i
< entry
; i
++) {
1622 phwxmit
= phwxmit_i
+ inx
[i
];
1624 sta_phead
= get_list_head(phwxmit
->sta_queue
);
1625 list_for_each_entry_safe(ptxservq
, ptmp
, sta_phead
,
1627 pframe_queue
= &ptxservq
->sta_pending
;
1629 pxmitframe
= dequeue_one_xmitframe(pxmitpriv
, phwxmit
, ptxservq
, pframe_queue
);
1634 /* Remove sta node when there is no pending packets. */
1635 /* must be done after get_next and
1637 if (list_empty(&pframe_queue
->queue
))
1638 list_del_init(&ptxservq
->tx_pending
);
1644 spin_unlock_bh(&pxmitpriv
->lock
);
1648 struct tx_servq
*rtw_get_sta_pending23a(struct rtw_adapter
*padapter
, struct sta_info
*psta
, int up
, u8
*ac
)
1650 struct tx_servq
*ptxservq
= NULL
;
1655 ptxservq
= &psta
->sta_xmitpriv
.bk_q
;
1657 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
1658 "rtw_get_sta_pending23a : BK\n");
1662 ptxservq
= &psta
->sta_xmitpriv
.vi_q
;
1664 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
1665 "rtw_get_sta_pending23a : VI\n");
1669 ptxservq
= &psta
->sta_xmitpriv
.vo_q
;
1671 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
1672 "rtw_get_sta_pending23a : VO\n");
1677 ptxservq
= &psta
->sta_xmitpriv
.be_q
;
1679 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_info_
,
1680 "rtw_get_sta_pending23a : BE\n");
1687 * Will enqueue pxmitframe to the proper queue,
1688 * and indicate it to xx_pending list.....
1690 int rtw_xmit23a_classifier(struct rtw_adapter
*padapter
,
1691 struct xmit_frame
*pxmitframe
)
1693 struct sta_info
*psta
;
1694 struct tx_servq
*ptxservq
;
1695 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
1696 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1697 struct hw_xmit
*phwxmits
= padapter
->xmitpriv
.hwxmits
;
1701 if (pattrib
->psta
) {
1702 psta
= pattrib
->psta
;
1704 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__
);
1705 psta
= rtw_get_stainfo23a(pstapriv
, pattrib
->ra
);
1709 DBG_8723A("rtw_xmit23a_classifier: psta == NULL\n");
1710 RT_TRACE(_module_rtl871x_xmit_c_
, _drv_err_
,
1711 "rtw_xmit23a_classifier: psta == NULL\n");
1714 if (!(psta
->state
& _FW_LINKED
)) {
1715 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__
,
1719 ptxservq
= rtw_get_sta_pending23a(padapter
, psta
, pattrib
->priority
,
1722 if (list_empty(&ptxservq
->tx_pending
)) {
1723 list_add_tail(&ptxservq
->tx_pending
,
1724 get_list_head(phwxmits
[ac_index
].sta_queue
));
1727 list_add_tail(&pxmitframe
->list
, get_list_head(&ptxservq
->sta_pending
));
1729 phwxmits
[ac_index
].accnt
++;
1734 void rtw_alloc_hwxmits23a(struct rtw_adapter
*padapter
)
1736 struct hw_xmit
*hwxmits
;
1737 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1740 pxmitpriv
->hwxmit_entry
= HWXMIT_ENTRY
;
1742 size
= sizeof(struct hw_xmit
) * (pxmitpriv
->hwxmit_entry
+ 1);
1743 pxmitpriv
->hwxmits
= kzalloc(size
, GFP_KERNEL
);
1745 hwxmits
= pxmitpriv
->hwxmits
;
1747 if (pxmitpriv
->hwxmit_entry
== 5) {
1748 /* pxmitpriv->bmc_txqueue.head = 0; */
1749 /* hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; */
1750 hwxmits
[0] .sta_queue
= &pxmitpriv
->bm_pending
;
1752 /* pxmitpriv->vo_txqueue.head = 0; */
1753 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; */
1754 hwxmits
[1] .sta_queue
= &pxmitpriv
->vo_pending
;
1756 /* pxmitpriv->vi_txqueue.head = 0; */
1757 /* hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; */
1758 hwxmits
[2] .sta_queue
= &pxmitpriv
->vi_pending
;
1760 /* pxmitpriv->bk_txqueue.head = 0; */
1761 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
1762 hwxmits
[3] .sta_queue
= &pxmitpriv
->bk_pending
;
1764 /* pxmitpriv->be_txqueue.head = 0; */
1765 /* hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; */
1766 hwxmits
[4] .sta_queue
= &pxmitpriv
->be_pending
;
1768 } else if (pxmitpriv
->hwxmit_entry
== 4) {
1770 /* pxmitpriv->vo_txqueue.head = 0; */
1771 /* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */
1772 hwxmits
[0] .sta_queue
= &pxmitpriv
->vo_pending
;
1774 /* pxmitpriv->vi_txqueue.head = 0; */
1775 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */
1776 hwxmits
[1] .sta_queue
= &pxmitpriv
->vi_pending
;
1778 /* pxmitpriv->be_txqueue.head = 0; */
1779 /* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */
1780 hwxmits
[2] .sta_queue
= &pxmitpriv
->be_pending
;
1782 /* pxmitpriv->bk_txqueue.head = 0; */
1783 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
1784 hwxmits
[3] .sta_queue
= &pxmitpriv
->bk_pending
;
1790 void rtw_free_hwxmits23a(struct rtw_adapter
*padapter
)
1792 struct hw_xmit
*hwxmits
;
1793 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1795 hwxmits
= pxmitpriv
->hwxmits
;
1799 void rtw_init_hwxmits23a(struct hw_xmit
*phwxmit
, int entry
)
1803 for (i
= 0; i
< entry
; i
++, phwxmit
++)
1807 u32
rtw_get_ff_hwaddr23a(struct xmit_frame
*pxmitframe
)
1810 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
1812 switch (pattrib
->qsel
) {
1815 addr
= BE_QUEUE_INX
;
1819 addr
= BK_QUEUE_INX
;
1823 addr
= VI_QUEUE_INX
;
1827 addr
= VO_QUEUE_INX
;
1830 addr
= BCN_QUEUE_INX
;
1832 case 0x11:/* BC/MC in PS (HIQ) */
1833 addr
= HIGH_QUEUE_INX
;
1837 addr
= MGT_QUEUE_INX
;
1845 * The main transmit(tx) entry
1849 * 0 success, hardware will handle this xmit frame(packet)
1852 int rtw_xmit23a(struct rtw_adapter
*padapter
, struct sk_buff
*skb
)
1854 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1855 struct xmit_frame
*pxmitframe
= NULL
;
1858 pxmitframe
= rtw_alloc_xmitframe(pxmitpriv
);
1860 if (pxmitframe
== NULL
) {
1861 RT_TRACE(_module_xmit_osdep_c_
, _drv_err_
,
1862 "rtw_xmit23a: no more pxmitframe\n");
1866 res
= update_attrib(padapter
, skb
, &pxmitframe
->attrib
);
1869 RT_TRACE(_module_xmit_osdep_c_
, _drv_err_
,
1870 "rtw_xmit23a: update attrib fail\n");
1871 rtw_free_xmitframe23a(pxmitpriv
, pxmitframe
);
1874 pxmitframe
->pkt
= skb
;
1876 pxmitframe
->attrib
.qsel
= pxmitframe
->attrib
.priority
;
1878 #ifdef CONFIG_8723AU_AP_MODE
1879 spin_lock_bh(&pxmitpriv
->lock
);
1880 if (xmitframe_enqueue_for_sleeping_sta23a(padapter
, pxmitframe
)) {
1881 spin_unlock_bh(&pxmitpriv
->lock
);
1884 spin_unlock_bh(&pxmitpriv
->lock
);
1887 if (rtl8723au_hal_xmit(padapter
, pxmitframe
) == false)
1893 #if defined(CONFIG_8723AU_AP_MODE)
1895 int xmitframe_enqueue_for_sleeping_sta23a(struct rtw_adapter
*padapter
, struct xmit_frame
*pxmitframe
)
1898 struct sta_info
*psta
= NULL
;
1899 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1900 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
1901 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1902 int bmcst
= is_multicast_ether_addr(pattrib
->ra
);
1904 if (!check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
1907 if (pattrib
->psta
) {
1908 psta
= pattrib
->psta
;
1910 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__
);
1911 psta
= rtw_get_stainfo23a(pstapriv
, pattrib
->ra
);
1915 DBG_8723A("%s, psta == NUL\n", __func__
);
1919 if (!(psta
->state
& _FW_LINKED
)) {
1920 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__
,
1925 if (pattrib
->triggered
== 1) {
1927 pattrib
->qsel
= 0x11;/* HIQ */
1932 spin_lock_bh(&psta
->sleep_q
.lock
);
1934 if (pstapriv
->sta_dz_bitmap
) {
1935 /* if anyone sta is in ps mode */
1936 list_del_init(&pxmitframe
->list
);
1938 /* spin_lock_bh(&psta->sleep_q.lock); */
1940 list_add_tail(&pxmitframe
->list
, get_list_head(&psta
->sleep_q
));
1944 pstapriv
->tim_bitmap
|= BIT(0);/* */
1945 pstapriv
->sta_dz_bitmap
|= BIT(0);
1947 /* DBG_8723A("enqueue, sq_len =%d, tim =%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
1949 /* tx bc/mc packets after update bcn */
1950 update_beacon23a(padapter
, WLAN_EID_TIM
, NULL
, false);
1952 /* spin_unlock_bh(&psta->sleep_q.lock); */
1958 spin_unlock_bh(&psta
->sleep_q
.lock
);
1964 spin_lock_bh(&psta
->sleep_q
.lock
);
1966 if (psta
->state
&WIFI_SLEEP_STATE
) {
1969 if (pstapriv
->sta_dz_bitmap
& CHKBIT(psta
->aid
)) {
1970 list_del_init(&pxmitframe
->list
);
1972 /* spin_lock_bh(&psta->sleep_q.lock); */
1974 list_add_tail(&pxmitframe
->list
, get_list_head(&psta
->sleep_q
));
1978 switch (pattrib
->priority
) {
1981 wmmps_ac
= psta
->uapsd_bk
& BIT(0);
1985 wmmps_ac
= psta
->uapsd_vi
& BIT(0);
1989 wmmps_ac
= psta
->uapsd_vo
& BIT(0);
1994 wmmps_ac
= psta
->uapsd_be
& BIT(0);
1999 psta
->sleepq_ac_len
++;
2001 if (((psta
->has_legacy_ac
) && (!wmmps_ac
)) ||
2002 ((!psta
->has_legacy_ac
) && (wmmps_ac
))) {
2003 pstapriv
->tim_bitmap
|= CHKBIT(psta
->aid
);
2005 if (psta
->sleepq_len
== 1) {
2006 /* update BCN for TIM IE */
2007 update_beacon23a(padapter
, WLAN_EID_TIM
,
2012 /* spin_unlock_bh(&psta->sleep_q.lock); */
2014 /* if (psta->sleepq_len > (NR_XMITFRAME>>3)) */
2016 /* wakeup_sta_to_xmit23a(padapter, psta); */
2025 spin_unlock_bh(&psta
->sleep_q
.lock
);
2031 dequeue_xmitframes_to_sleeping_queue(struct rtw_adapter
*padapter
,
2032 struct sta_info
*psta
,
2033 struct rtw_queue
*pframequeue
)
2036 struct list_head
*phead
;
2038 struct tx_servq
*ptxservq
;
2039 struct pkt_attrib
*pattrib
;
2040 struct xmit_frame
*pxmitframe
, *ptmp
;
2041 struct hw_xmit
*phwxmits
= padapter
->xmitpriv
.hwxmits
;
2043 phead
= get_list_head(pframequeue
);
2044 list_for_each_entry_safe(pxmitframe
, ptmp
, phead
, list
) {
2045 ret
= xmitframe_enqueue_for_sleeping_sta23a(padapter
, pxmitframe
);
2048 pattrib
= &pxmitframe
->attrib
;
2050 ptxservq
= rtw_get_sta_pending23a(padapter
, psta
, pattrib
->priority
, (u8
*)(&ac_index
));
2053 phwxmits
[ac_index
].accnt
--;
2055 /* DBG_8723A("xmitframe_enqueue_for_sleeping_sta23a return false\n"); */
2060 void stop_sta_xmit23a(struct rtw_adapter
*padapter
, struct sta_info
*psta
)
2062 struct sta_info
*psta_bmc
;
2063 struct sta_xmit_priv
*pstaxmitpriv
;
2064 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2065 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2067 pstaxmitpriv
= &psta
->sta_xmitpriv
;
2069 /* for BC/MC Frames */
2070 psta_bmc
= rtw_get_bcmc_stainfo23a(padapter
);
2072 spin_lock_bh(&pxmitpriv
->lock
);
2074 psta
->state
|= WIFI_SLEEP_STATE
;
2076 pstapriv
->sta_dz_bitmap
|= CHKBIT(psta
->aid
);
2078 dequeue_xmitframes_to_sleeping_queue(padapter
, psta
, &pstaxmitpriv
->vo_q
.sta_pending
);
2079 list_del_init(&pstaxmitpriv
->vo_q
.tx_pending
);
2081 dequeue_xmitframes_to_sleeping_queue(padapter
, psta
, &pstaxmitpriv
->vi_q
.sta_pending
);
2082 list_del_init(&pstaxmitpriv
->vi_q
.tx_pending
);
2084 dequeue_xmitframes_to_sleeping_queue(padapter
, psta
,
2085 &pstaxmitpriv
->be_q
.sta_pending
);
2086 list_del_init(&pstaxmitpriv
->be_q
.tx_pending
);
2088 dequeue_xmitframes_to_sleeping_queue(padapter
, psta
,
2089 &pstaxmitpriv
->bk_q
.sta_pending
);
2090 list_del_init(&pstaxmitpriv
->bk_q
.tx_pending
);
2092 /* for BC/MC Frames */
2093 pstaxmitpriv
= &psta_bmc
->sta_xmitpriv
;
2094 dequeue_xmitframes_to_sleeping_queue(padapter
, psta_bmc
,
2095 &pstaxmitpriv
->be_q
.sta_pending
);
2096 list_del_init(&pstaxmitpriv
->be_q
.tx_pending
);
2098 spin_unlock_bh(&pxmitpriv
->lock
);
2101 void wakeup_sta_to_xmit23a(struct rtw_adapter
*padapter
, struct sta_info
*psta
)
2103 u8 update_mask
= 0, wmmps_ac
= 0;
2104 struct sta_info
*psta_bmc
;
2105 struct list_head
*phead
;
2106 struct xmit_frame
*pxmitframe
= NULL
, *ptmp
;
2107 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2108 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2110 spin_lock_bh(&pxmitpriv
->lock
);
2111 phead
= get_list_head(&psta
->sleep_q
);
2112 list_for_each_entry_safe(pxmitframe
, ptmp
, phead
, list
) {
2113 list_del_init(&pxmitframe
->list
);
2115 switch (pxmitframe
->attrib
.priority
) {
2118 wmmps_ac
= psta
->uapsd_bk
& BIT(1);
2122 wmmps_ac
= psta
->uapsd_vi
& BIT(1);
2126 wmmps_ac
= psta
->uapsd_vo
& BIT(1);
2131 wmmps_ac
= psta
->uapsd_be
& BIT(1);
2136 if (psta
->sleepq_len
> 0)
2137 pxmitframe
->attrib
.mdata
= 1;
2139 pxmitframe
->attrib
.mdata
= 0;
2142 psta
->sleepq_ac_len
--;
2143 if (psta
->sleepq_ac_len
> 0) {
2144 pxmitframe
->attrib
.mdata
= 1;
2145 pxmitframe
->attrib
.eosp
= 0;
2147 pxmitframe
->attrib
.mdata
= 0;
2148 pxmitframe
->attrib
.eosp
= 1;
2152 pxmitframe
->attrib
.triggered
= 1;
2153 rtl8723au_hal_xmitframe_enqueue(padapter
, pxmitframe
);
2156 if (psta
->sleepq_len
== 0) {
2157 pstapriv
->tim_bitmap
&= ~CHKBIT(psta
->aid
);
2159 /* update BCN for TIM IE */
2160 update_mask
= BIT(0);
2162 if (psta
->state
&WIFI_SLEEP_STATE
)
2163 psta
->state
^= WIFI_SLEEP_STATE
;
2165 if (psta
->state
& WIFI_STA_ALIVE_CHK_STATE
) {
2166 psta
->expire_to
= pstapriv
->expire_to
;
2167 psta
->state
^= WIFI_STA_ALIVE_CHK_STATE
;
2170 pstapriv
->sta_dz_bitmap
&= ~CHKBIT(psta
->aid
);
2172 /* spin_unlock_bh(&psta->sleep_q.lock); */
2173 spin_unlock_bh(&pxmitpriv
->lock
);
2175 /* for BC/MC Frames */
2176 psta_bmc
= rtw_get_bcmc_stainfo23a(padapter
);
2180 if ((pstapriv
->sta_dz_bitmap
&0xfffe) == 0x0) {
2181 /* no any sta in ps mode */
2182 spin_lock_bh(&pxmitpriv
->lock
);
2183 phead
= get_list_head(&psta_bmc
->sleep_q
);
2184 list_for_each_entry_safe(pxmitframe
, ptmp
, phead
, list
) {
2185 list_del_init(&pxmitframe
->list
);
2187 psta_bmc
->sleepq_len
--;
2188 if (psta_bmc
->sleepq_len
> 0)
2189 pxmitframe
->attrib
.mdata
= 1;
2191 pxmitframe
->attrib
.mdata
= 0;
2193 pxmitframe
->attrib
.triggered
= 1;
2194 rtl8723au_hal_xmitframe_enqueue(padapter
, pxmitframe
);
2196 if (psta_bmc
->sleepq_len
== 0) {
2197 pstapriv
->tim_bitmap
&= ~BIT(0);
2198 pstapriv
->sta_dz_bitmap
&= ~BIT(0);
2200 /* update BCN for TIM IE */
2201 /* update_BCNTIM(padapter); */
2202 update_mask
|= BIT(1);
2204 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
2205 spin_unlock_bh(&pxmitpriv
->lock
);
2209 update_beacon23a(padapter
, WLAN_EID_TIM
, NULL
, false);
2212 void xmit_delivery_enabled_frames23a(struct rtw_adapter
*padapter
,
2213 struct sta_info
*psta
)
2216 struct list_head
*phead
;
2217 struct xmit_frame
*pxmitframe
, *ptmp
;
2218 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2219 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2221 /* spin_lock_bh(&psta->sleep_q.lock); */
2222 spin_lock_bh(&pxmitpriv
->lock
);
2223 phead
= get_list_head(&psta
->sleep_q
);
2224 list_for_each_entry_safe(pxmitframe
, ptmp
, phead
, list
) {
2225 switch (pxmitframe
->attrib
.priority
) {
2228 wmmps_ac
= psta
->uapsd_bk
& BIT(1);
2232 wmmps_ac
= psta
->uapsd_vi
& BIT(1);
2236 wmmps_ac
= psta
->uapsd_vo
& BIT(1);
2241 wmmps_ac
= psta
->uapsd_be
& BIT(1);
2248 list_del_init(&pxmitframe
->list
);
2251 psta
->sleepq_ac_len
--;
2253 if (psta
->sleepq_ac_len
> 0) {
2254 pxmitframe
->attrib
.mdata
= 1;
2255 pxmitframe
->attrib
.eosp
= 0;
2257 pxmitframe
->attrib
.mdata
= 0;
2258 pxmitframe
->attrib
.eosp
= 1;
2261 pxmitframe
->attrib
.triggered
= 1;
2263 rtl8723au_hal_xmitframe_enqueue(padapter
, pxmitframe
);
2265 if ((psta
->sleepq_ac_len
== 0) && (!psta
->has_legacy_ac
) &&
2267 pstapriv
->tim_bitmap
&= ~CHKBIT(psta
->aid
);
2269 /* update BCN for TIM IE */
2270 update_beacon23a(padapter
, WLAN_EID_TIM
, NULL
, false);
2273 spin_unlock_bh(&pxmitpriv
->lock
);
2278 void rtw_sctx_init23a(struct submit_ctx
*sctx
, int timeout_ms
)
2280 sctx
->timeout_ms
= timeout_ms
;
2281 init_completion(&sctx
->done
);
2282 sctx
->status
= RTW_SCTX_SUBMITTED
;
2285 int rtw_sctx_wait23a(struct submit_ctx
*sctx
)
2288 unsigned long expire
;
2291 expire
= sctx
->timeout_ms
? msecs_to_jiffies(sctx
->timeout_ms
) :
2292 MAX_SCHEDULE_TIMEOUT
;
2293 if (!wait_for_completion_timeout(&sctx
->done
, expire
)) {
2294 /* timeout, do something?? */
2295 status
= RTW_SCTX_DONE_TIMEOUT
;
2296 DBG_8723A("%s timeout\n", __func__
);
2298 status
= sctx
->status
;
2301 if (status
== RTW_SCTX_DONE_SUCCESS
)
2307 static bool rtw_sctx_chk_waring_status(int status
)
2310 case RTW_SCTX_DONE_UNKNOWN
:
2311 case RTW_SCTX_DONE_BUF_ALLOC
:
2312 case RTW_SCTX_DONE_BUF_FREE
:
2313 case RTW_SCTX_DONE_DRV_STOP
:
2314 case RTW_SCTX_DONE_DEV_REMOVE
:
2321 void rtw23a_sctx_done_err(struct submit_ctx
**sctx
, int status
)
2324 if (rtw_sctx_chk_waring_status(status
))
2325 DBG_8723A("%s status:%d\n", __func__
, status
);
2326 (*sctx
)->status
= status
;
2327 complete(&(*sctx
)->done
);
2332 int rtw_ack_tx_wait23a(struct xmit_priv
*pxmitpriv
, u32 timeout_ms
)
2334 struct submit_ctx
*pack_tx_ops
= &pxmitpriv
->ack_tx_ops
;
2336 pack_tx_ops
->timeout_ms
= timeout_ms
;
2337 pack_tx_ops
->status
= RTW_SCTX_SUBMITTED
;
2339 return rtw_sctx_wait23a(pack_tx_ops
);