[go: nahoru, domu]

rtw_xmit.c revision f2f97035f08a5ea1f0c23e65f6ea9cd2f3cd2586
1/******************************************************************************
2 *
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 ******************************************************************************/
15#define _RTW_XMIT_C_
16
17#include <osdep_service.h>
18#include <drv_types.h>
19#include <wifi.h>
20#include <osdep_intf.h>
21#include <linux/ip.h>
22#include <usb_ops.h>
23#include <rtl8723a_xmit.h>
24
25static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
26static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
27
28static void _init_txservq(struct tx_servq *ptxservq)
29{
30
31	INIT_LIST_HEAD(&ptxservq->tx_pending);
32	_rtw_init_queue23a(&ptxservq->sta_pending);
33	ptxservq->qcnt = 0;
34
35}
36
37void	_rtw_init_sta_xmit_priv23a(struct sta_xmit_priv *psta_xmitpriv)
38{
39
40	spin_lock_init(&psta_xmitpriv->lock);
41
42	/* for (i = 0 ; i < MAX_NUMBLKS; i++) */
43	/*	_init_txservq(&psta_xmitpriv->blk_q[i]); */
44
45	_init_txservq(&psta_xmitpriv->be_q);
46	_init_txservq(&psta_xmitpriv->bk_q);
47	_init_txservq(&psta_xmitpriv->vi_q);
48	_init_txservq(&psta_xmitpriv->vo_q);
49	INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
50	INIT_LIST_HEAD(&psta_xmitpriv->apsd);
51
52}
53
54int _rtw_init_xmit_priv23a(struct xmit_priv *pxmitpriv,
55			   struct rtw_adapter *padapter)
56{
57	int i;
58	struct xmit_buf *pxmitbuf;
59	struct xmit_frame *pxframe;
60	int res = _SUCCESS;
61	u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
62	u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
63
64	spin_lock_init(&pxmitpriv->lock);
65	spin_lock_init(&pxmitpriv->lock_sctx);
66	sema_init(&pxmitpriv->xmit_sema, 0);
67	sema_init(&pxmitpriv->terminate_xmitthread_sema, 0);
68
69	pxmitpriv->adapter = padapter;
70
71	_rtw_init_queue23a(&pxmitpriv->be_pending);
72	_rtw_init_queue23a(&pxmitpriv->bk_pending);
73	_rtw_init_queue23a(&pxmitpriv->vi_pending);
74	_rtw_init_queue23a(&pxmitpriv->vo_pending);
75	_rtw_init_queue23a(&pxmitpriv->bm_pending);
76
77	_rtw_init_queue23a(&pxmitpriv->free_xmit_queue);
78
79	for (i = 0; i < NR_XMITFRAME; i++) {
80		pxframe = (struct xmit_frame *)
81			kzalloc(sizeof(struct xmit_frame), GFP_KERNEL);
82		if (!pxframe)
83			break;
84		INIT_LIST_HEAD(&pxframe->list);
85
86		pxframe->padapter = padapter;
87		pxframe->frame_tag = NULL_FRAMETAG;
88
89		list_add_tail(&pxframe->list,
90			      &pxmitpriv->free_xmit_queue.queue);
91	}
92
93	pxmitpriv->free_xmitframe_cnt = i;
94
95	pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
96
97	/* init xmit_buf */
98	_rtw_init_queue23a(&pxmitpriv->free_xmitbuf_queue);
99	INIT_LIST_HEAD(&pxmitpriv->xmitbuf_list);
100	_rtw_init_queue23a(&pxmitpriv->pending_xmitbuf_queue);
101
102	for (i = 0; i < NR_XMITBUFF; i++) {
103		pxmitbuf = kzalloc(sizeof(struct xmit_buf), GFP_KERNEL);
104		if (!pxmitbuf)
105			goto fail;
106		INIT_LIST_HEAD(&pxmitbuf->list);
107		INIT_LIST_HEAD(&pxmitbuf->list2);
108
109		pxmitbuf->padapter = padapter;
110
111		/* Tx buf allocation may fail sometimes, so sleep and retry. */
112		res = rtw_os_xmit_resource_alloc23a(padapter, pxmitbuf,
113						 (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
114		if (res == _FAIL) {
115			goto fail;
116		}
117
118		list_add_tail(&pxmitbuf->list,
119			      &pxmitpriv->free_xmitbuf_queue.queue);
120		list_add_tail(&pxmitbuf->list2,
121			      &pxmitpriv->xmitbuf_list);
122	}
123
124	pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
125
126	/* init xframe_ext queue,  the same count as extbuf  */
127	_rtw_init_queue23a(&pxmitpriv->free_xframe_ext_queue);
128
129	for (i = 0; i < num_xmit_extbuf; i++) {
130		pxframe = (struct xmit_frame *)
131			kzalloc(sizeof(struct xmit_frame), GFP_KERNEL);
132		if (!pxframe)
133			break;
134		INIT_LIST_HEAD(&pxframe->list);
135
136		pxframe->padapter = padapter;
137		pxframe->frame_tag = NULL_FRAMETAG;
138
139		pxframe->pkt = NULL;
140
141		pxframe->buf_addr = NULL;
142		pxframe->pxmitbuf = NULL;
143
144		pxframe->ext_tag = 1;
145
146		list_add_tail(&pxframe->list,
147			      &pxmitpriv->free_xframe_ext_queue.queue);
148	}
149	pxmitpriv->free_xframe_ext_cnt = i;
150
151	/*  Init xmit extension buff */
152	_rtw_init_queue23a(&pxmitpriv->free_xmit_extbuf_queue);
153	INIT_LIST_HEAD(&pxmitpriv->xmitextbuf_list);
154
155	for (i = 0; i < num_xmit_extbuf; i++) {
156		pxmitbuf = kzalloc(sizeof(struct xmit_buf), GFP_KERNEL);
157		if (!pxmitbuf)
158			goto fail;
159		INIT_LIST_HEAD(&pxmitbuf->list);
160		INIT_LIST_HEAD(&pxmitbuf->list2);
161
162		pxmitbuf->padapter = padapter;
163
164		/* Tx buf allocation may fail sometimes, so sleep and retry. */
165		res = rtw_os_xmit_resource_alloc23a(padapter, pxmitbuf,
166						 max_xmit_extbuf_size + XMITBUF_ALIGN_SZ);
167		if (res == _FAIL) {
168			goto exit;
169		}
170
171		list_add_tail(&pxmitbuf->list,
172			      &pxmitpriv->free_xmit_extbuf_queue.queue);
173		list_add_tail(&pxmitbuf->list2,
174			      &pxmitpriv->xmitextbuf_list);
175	}
176
177	pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
178
179	rtw_alloc_hwxmits23a(padapter);
180	rtw_init_hwxmits23a(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
181
182	for (i = 0; i < 4; i ++)
183		pxmitpriv->wmm_para_seq[i] = i;
184
185	pxmitpriv->txirp_cnt = 1;
186
187	sema_init(&pxmitpriv->tx_retevt, 0);
188
189	/* per AC pending irp */
190	pxmitpriv->beq_cnt = 0;
191	pxmitpriv->bkq_cnt = 0;
192	pxmitpriv->viq_cnt = 0;
193	pxmitpriv->voq_cnt = 0;
194
195	pxmitpriv->ack_tx = false;
196	mutex_init(&pxmitpriv->ack_tx_mutex);
197	rtw_sctx_init23a(&pxmitpriv->ack_tx_ops, 0);
198	tasklet_init(&padapter->xmitpriv.xmit_tasklet,
199		     (void(*)(unsigned long))rtl8723au_xmit_tasklet,
200		     (unsigned long)padapter);
201
202exit:
203
204	return res;
205fail:
206	goto exit;
207}
208
209void _rtw_free_xmit_priv23a (struct xmit_priv *pxmitpriv)
210{
211	struct rtw_adapter *padapter = pxmitpriv->adapter;
212	struct xmit_frame *pxframe;
213	struct xmit_buf *pxmitbuf;
214	struct list_head *plist, *ptmp;
215
216	list_for_each_safe(plist, ptmp, &pxmitpriv->free_xmit_queue.queue) {
217		pxframe = container_of(plist, struct xmit_frame, list);
218		list_del_init(&pxframe->list);
219		rtw_os_xmit_complete23a(padapter, pxframe);
220		kfree(pxframe);
221	}
222
223	list_for_each_safe(plist, ptmp, &pxmitpriv->xmitbuf_list) {
224		pxmitbuf = container_of(plist, struct xmit_buf, list2);
225		list_del_init(&pxmitbuf->list2);
226		rtw_os_xmit_resource_free23a(padapter, pxmitbuf);
227		kfree(pxmitbuf);
228	}
229
230	/* free xframe_ext queue,  the same count as extbuf  */
231	list_for_each_safe(plist, ptmp,
232			   &pxmitpriv->free_xframe_ext_queue.queue) {
233		pxframe = container_of(plist, struct xmit_frame, list);
234		list_del_init(&pxframe->list);
235		rtw_os_xmit_complete23a(padapter, pxframe);
236		kfree(pxframe);
237	}
238
239	/*  free xmit extension buff */
240	list_for_each_safe(plist, ptmp, &pxmitpriv->xmitextbuf_list) {
241		pxmitbuf = container_of(plist, struct xmit_buf, list2);
242		list_del_init(&pxmitbuf->list2);
243		rtw_os_xmit_resource_free23a(padapter, pxmitbuf);
244		kfree(pxmitbuf);
245	}
246
247	rtw_free_hwxmits23a(padapter);
248	mutex_destroy(&pxmitpriv->ack_tx_mutex);
249}
250
251static void update_attrib_vcs_info(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe)
252{
253	u32	sz;
254	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
255	struct sta_info	*psta = pattrib->psta;
256	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
257	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
258
259        if (pattrib->psta) {
260		psta = pattrib->psta;
261	} else {
262		DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
263		psta = rtw_get_stainfo23a(&padapter->stapriv, &pattrib->ra[0]);
264	}
265
266        if (psta == NULL) {
267		DBG_8723A("%s, psta == NUL\n", __func__);
268		return;
269	}
270
271	if (!(psta->state &_FW_LINKED)) {
272		DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
273		return;
274	}
275
276	if (pattrib->nr_frags != 1)
277		sz = padapter->xmitpriv.frag_len;
278	else /* no frag */
279		sz = pattrib->last_txcmdsz;
280
281	/*  (1) RTS_Threshold is compared to the MPDU, not MSDU. */
282	/*  (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame. */
283	/*		Other fragments are protected by previous fragment. */
284	/*		So we only need to check the length of first fragment. */
285	if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N  || padapter->registrypriv.wifi_spec) {
286		if (sz > padapter->registrypriv.rts_thresh) {
287			pattrib->vcs_mode = RTS_CTS;
288		} else {
289			if (psta->rtsen)
290				pattrib->vcs_mode = RTS_CTS;
291			else if (psta->cts2self)
292				pattrib->vcs_mode = CTS_TO_SELF;
293			else
294				pattrib->vcs_mode = NONE_VCS;
295		}
296	} else {
297		while (true) {
298			/* IOT action */
299			if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS &&
300			    pattrib->ampdu_en &&
301			    padapter->securitypriv.dot11PrivacyAlgrthm ==
302			    WLAN_CIPHER_SUITE_CCMP) {
303				pattrib->vcs_mode = CTS_TO_SELF;
304				break;
305			}
306
307			/* check ERP protection */
308			if (psta->rtsen || psta->cts2self) {
309				if (psta->rtsen)
310					pattrib->vcs_mode = RTS_CTS;
311				else if (psta->cts2self)
312					pattrib->vcs_mode = CTS_TO_SELF;
313
314				break;
315			}
316
317			/* check HT op mode */
318			if (pattrib->ht_en) {
319				u8 HTOpMode = pmlmeinfo->HT_protection;
320				if ((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) ||
321				    (!pmlmeext->cur_bwmode && HTOpMode == 3)) {
322					pattrib->vcs_mode = RTS_CTS;
323					break;
324				}
325			}
326
327			/* check rts */
328			if (sz > padapter->registrypriv.rts_thresh) {
329				pattrib->vcs_mode = RTS_CTS;
330				break;
331			}
332
333			/* to do list: check MIMO power save condition. */
334
335			/* check AMPDU aggregation for TXOP */
336			if (pattrib->ampdu_en) {
337				pattrib->vcs_mode = RTS_CTS;
338				break;
339			}
340
341			pattrib->vcs_mode = NONE_VCS;
342			break;
343		}
344	}
345}
346
347static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *psta)
348{
349	/*if (psta->rtsen)
350		pattrib->vcs_mode = RTS_CTS;
351	else if (psta->cts2self)
352		pattrib->vcs_mode = CTS_TO_SELF;
353	else
354		pattrib->vcs_mode = NONE_VCS;*/
355
356	pattrib->mdata = 0;
357	pattrib->eosp = 0;
358	pattrib->triggered = 0;
359
360	/* qos_en, ht_en, init rate, , bw, ch_offset, sgi */
361	pattrib->qos_en = psta->qos_option;
362
363	pattrib->raid = psta->raid;
364	pattrib->ht_en = psta->htpriv.ht_option;
365	pattrib->bwmode = psta->htpriv.bwmode;
366	pattrib->ch_offset = psta->htpriv.ch_offset;
367	pattrib->sgi = psta->htpriv.sgi;
368	pattrib->ampdu_en = false;
369
370	pattrib->retry_ctrl = false;
371}
372
373u8 qos_acm23a(u8 acm_mask, u8 priority)
374{
375	u8 change_priority = priority;
376
377	switch (priority) {
378	case 0:
379	case 3:
380		if (acm_mask & BIT(1))
381			change_priority = 1;
382		break;
383	case 1:
384	case 2:
385		break;
386	case 4:
387	case 5:
388		if (acm_mask & BIT(2))
389			change_priority = 0;
390		break;
391	case 6:
392	case 7:
393		if (acm_mask & BIT(3))
394			change_priority = 5;
395		break;
396	default:
397		DBG_8723A("qos_acm23a(): invalid pattrib->priority: %d!!!\n",
398			  priority);
399		change_priority = 0;
400		break;
401	}
402
403	return change_priority;
404}
405
406static void set_qos(struct sk_buff *skb, struct pkt_attrib *pattrib)
407{
408	u8 *pframe = skb->data;
409	struct iphdr *ip_hdr;
410	u8 UserPriority = 0;
411
412	/*  get UserPriority from IP hdr */
413	if (pattrib->ether_type == ETH_P_IP) {
414		ip_hdr = (struct iphdr *)(pframe + ETH_HLEN);
415		UserPriority = ip_hdr->tos >> 5;
416	} else if (pattrib->ether_type == ETH_P_PAE) {
417		/*  "When priority processing of data frames is supported, */
418		/*  a STA's SME should send EAPOL-Key frames at the highest
419		    priority." */
420		UserPriority = 7;
421	}
422
423	pattrib->priority = UserPriority;
424	pattrib->hdrlen = sizeof(struct ieee80211_qos_hdr);
425	pattrib->type = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
426}
427
428static int update_attrib(struct rtw_adapter *padapter,
429			 struct sk_buff *skb, struct pkt_attrib *pattrib)
430{
431	struct sta_info *psta = NULL;
432	int bmcast;
433	struct sta_priv	*pstapriv = &padapter->stapriv;
434	struct security_priv *psecuritypriv = &padapter->securitypriv;
435	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
436	int res = _SUCCESS;
437	struct ethhdr *ehdr = (struct ethhdr *) skb->data;
438
439	pattrib->ether_type = ntohs(ehdr->h_proto);
440
441	ether_addr_copy(pattrib->dst, ehdr->h_dest);
442	ether_addr_copy(pattrib->src, ehdr->h_source);
443
444	pattrib->pctrl = 0;
445
446	if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
447	    check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
448		ether_addr_copy(pattrib->ra, pattrib->dst);
449		ether_addr_copy(pattrib->ta, pattrib->src);
450	} else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
451		ether_addr_copy(pattrib->ra, get_bssid(pmlmepriv));
452		ether_addr_copy(pattrib->ta, pattrib->src);
453	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
454		ether_addr_copy(pattrib->ra, pattrib->dst);
455		ether_addr_copy(pattrib->ta, get_bssid(pmlmepriv));
456	}
457
458	pattrib->pktlen = skb->len - ETH_HLEN;
459
460	if (pattrib->ether_type == ETH_P_IP) {
461		/*  The following is for DHCP and ARP packet, we use cck1M
462		    to tx these packets and let LPS awake some time */
463		/*  to prevent DHCP protocol fail */
464		pattrib->dhcp_pkt = 0;
465		/* MINIMUM_DHCP_PACKET_SIZE) { */
466		if (pattrib->pktlen > 282 + 24) {
467			if (pattrib->ether_type == ETH_P_IP) {/*  IP header */
468				u8 *pframe = skb->data;
469				pframe += ETH_HLEN;
470
471				if ((pframe[21] == 68 && pframe[23] == 67) ||
472				    (pframe[21] == 67 && pframe[23] == 68)) {
473					/*  68 : UDP BOOTP client */
474					/*  67 : UDP BOOTP server */
475					RT_TRACE(_module_rtl871x_xmit_c_,
476						 _drv_err_,
477						 ("======================"
478						  "update_attrib: get DHCP "
479						  "Packet\n"));
480					pattrib->dhcp_pkt = 1;
481				}
482			}
483		}
484	} else if (pattrib->ether_type == ETH_P_PAE) {
485		DBG_8723A_LEVEL(_drv_always_, "send eapol packet\n");
486	}
487
488	if ((pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1)) {
489		rtw_set_scan_deny(padapter, 3000);
490	}
491
492	/*  If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */
493	if ((pattrib->ether_type == ETH_P_ARP) ||
494	    (pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1)) {
495		rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
496	}
497
498	bmcast = is_multicast_ether_addr(pattrib->ra);
499
500	/*  get sta_info */
501	if (bmcast) {
502		psta = rtw_get_bcmc_stainfo23a(padapter);
503	} else {
504		psta = rtw_get_stainfo23a(pstapriv, pattrib->ra);
505		if (psta == NULL) { /*  if we cannot get psta => drrp the pkt */
506			RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_,
507				 ("\nupdate_attrib => get sta_info fail, ra:"
508				  MAC_FMT"\n", MAC_ARG(pattrib->ra)));
509			res = _FAIL;
510			goto exit;
511		} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) &&
512			   (!(psta->state & _FW_LINKED))) {
513			res = _FAIL;
514			goto exit;
515		}
516	}
517
518	if (psta) {
519		pattrib->mac_id = psta->mac_id;
520		/* DBG_8723A("%s ==> mac_id(%d)\n", __func__, pattrib->mac_id); */
521		pattrib->psta = psta;
522	} else {
523		/*  if we cannot get psta => drop the pkt */
524		RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_,
525			 ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT
526			  "\n", MAC_ARG(pattrib->ra)));
527		res = _FAIL;
528		goto exit;
529	}
530
531	pattrib->ack_policy = 0;
532	/*  get ether_hdr_len */
533
534	/* pattrib->ether_type == 0x8100) ? (14 + 4): 14; vlan tag */
535	pattrib->pkt_hdrlen = ETH_HLEN;
536
537	pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
538	pattrib->type = IEEE80211_FTYPE_DATA;
539	pattrib->priority = 0;
540
541	if (check_fwstate(pmlmepriv, WIFI_AP_STATE | WIFI_ADHOC_STATE |
542			  WIFI_ADHOC_MASTER_STATE)) {
543		if (psta->qos_option)
544			set_qos(skb, pattrib);
545	} else {
546		if (pmlmepriv->qos_option) {
547			set_qos(skb, pattrib);
548
549			if (pmlmepriv->acm_mask != 0) {
550				pattrib->priority = qos_acm23a(pmlmepriv->acm_mask,
551							    pattrib->priority);
552			}
553		}
554	}
555
556	if (psta->ieee8021x_blocked == true) {
557		RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
558			 ("\n psta->ieee8021x_blocked == true\n"));
559
560		pattrib->encrypt = 0;
561
562		if ((pattrib->ether_type != ETH_P_PAE) &&
563		    (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)) {
564			RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
565				 ("\npsta->ieee8021x_blocked == true,  "
566				  "pattrib->ether_type(%.4x) != 0x888e\n",
567				  pattrib->ether_type));
568			res = _FAIL;
569			goto exit;
570		}
571	} else {
572		GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
573
574		switch (psecuritypriv->dot11AuthAlgrthm) {
575		case dot11AuthAlgrthm_Open:
576		case dot11AuthAlgrthm_Shared:
577		case dot11AuthAlgrthm_Auto:
578			pattrib->key_idx =
579				(u8)psecuritypriv->dot11PrivacyKeyIndex;
580			break;
581		case dot11AuthAlgrthm_8021X:
582			if (bmcast)
583				pattrib->key_idx =
584					(u8)psecuritypriv->dot118021XGrpKeyid;
585			else
586				pattrib->key_idx = 0;
587			break;
588		default:
589			pattrib->key_idx = 0;
590			break;
591		}
592
593	}
594
595	switch (pattrib->encrypt) {
596	case WLAN_CIPHER_SUITE_WEP40:
597	case WLAN_CIPHER_SUITE_WEP104:
598		pattrib->iv_len = IEEE80211_WEP_IV_LEN;
599		pattrib->icv_len = IEEE80211_WEP_ICV_LEN;
600		break;
601
602	case WLAN_CIPHER_SUITE_TKIP:
603		pattrib->iv_len = IEEE80211_TKIP_IV_LEN;
604		pattrib->icv_len = IEEE80211_TKIP_ICV_LEN;
605
606		if (!padapter->securitypriv.busetkipkey) {
607			RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
608				 ("\npadapter->securitypriv.busetkip"
609				  "key(%d) == false drop packet\n",
610				  padapter->securitypriv.busetkipkey));
611			res = _FAIL;
612			goto exit;
613		}
614
615		break;
616	case WLAN_CIPHER_SUITE_CCMP:
617		RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
618			 ("pattrib->encrypt =%d (WLAN_CIPHER_SUITE_CCMP)\n",
619			  pattrib->encrypt));
620		pattrib->iv_len = IEEE80211_CCMP_HDR_LEN;
621		pattrib->icv_len = IEEE80211_CCMP_MIC_LEN;
622		break;
623
624	default:
625		pattrib->iv_len = 0;
626		pattrib->icv_len = 0;
627		break;
628	}
629
630	RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
631		 ("update_attrib: encrypt =%d\n", pattrib->encrypt));
632
633	if (pattrib->encrypt && !psecuritypriv->hw_decrypted) {
634		pattrib->bswenc = true;
635		RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
636			 ("update_attrib: encrypt =%d bswenc = true\n",
637			  pattrib->encrypt));
638	} else {
639		pattrib->bswenc = false;
640		RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
641			 ("update_attrib: bswenc = false\n"));
642	}
643	update_attrib_phy_info(pattrib, psta);
644
645exit:
646
647	return res;
648}
649
650static int xmitframe_addmic(struct rtw_adapter *padapter,
651			    struct xmit_frame *pxmitframe) {
652	struct mic_data micdata;
653	struct sta_info *stainfo;
654	struct pkt_attrib *pattrib = &pxmitframe->attrib;
655	struct security_priv *psecuritypriv = &padapter->securitypriv;
656	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
657	int curfragnum, length;
658	u8 *pframe, *payload, mic[8];
659	u8 priority[4]= {0x0, 0x0, 0x0, 0x0};
660	u8 hw_hdr_offset = 0;
661	int bmcst = is_multicast_ether_addr(pattrib->ra);
662
663	if (pattrib->psta) {
664		stainfo = pattrib->psta;
665	} else {
666		DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
667		stainfo = rtw_get_stainfo23a(&padapter->stapriv, &pattrib->ra[0]);
668	}
669
670	if (!stainfo) {
671		DBG_8723A("%s, psta == NUL\n", __func__);
672		return _FAIL;
673	}
674
675	if (!(stainfo->state &_FW_LINKED)) {
676		DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
677			  __func__, stainfo->state);
678		return _FAIL;
679	}
680
681	hw_hdr_offset = TXDESC_OFFSET;
682
683	if (pattrib->encrypt == WLAN_CIPHER_SUITE_TKIP) {
684		/* encode mic code */
685		if (stainfo) {
686			u8 null_key[16]={0x0, 0x0, 0x0, 0x0,
687					 0x0, 0x0, 0x0, 0x0,
688					 0x0, 0x0, 0x0, 0x0,
689					 0x0, 0x0, 0x0, 0x0};
690
691			pframe = pxmitframe->buf_addr + hw_hdr_offset;
692
693			if (bmcst) {
694				if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16)) {
695					return _FAIL;
696				}
697				/* start to calculate the mic code */
698				rtw_secmicsetkey23a(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
699			} else {
700				if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0],
701					    null_key, 16)) {
702					return _FAIL;
703				}
704				/* start to calculate the mic code */
705				rtw_secmicsetkey23a(&micdata, &stainfo->dot11tkiptxmickey.skey[0]);
706			}
707
708			if (pframe[1] & 1) {   /* ToDS == 1 */
709				/* DA */
710				rtw_secmicappend23a(&micdata, &pframe[16], 6);
711				if (pframe[1] & 2)  /* From Ds == 1 */
712					rtw_secmicappend23a(&micdata,
713							 &pframe[24], 6);
714				else
715					rtw_secmicappend23a(&micdata,
716							 &pframe[10], 6);
717			} else {	/* ToDS == 0 */
718				/* DA */
719				rtw_secmicappend23a(&micdata, &pframe[4], 6);
720				if (pframe[1] & 2)  /* From Ds == 1 */
721					rtw_secmicappend23a(&micdata,
722							 &pframe[16], 6);
723				else
724					rtw_secmicappend23a(&micdata,
725							 &pframe[10], 6);
726			}
727
728			/* if (pmlmepriv->qos_option == 1) */
729			if (pattrib->qos_en)
730				priority[0] = (u8)pxmitframe->attrib.priority;
731
732			rtw_secmicappend23a(&micdata, &priority[0], 4);
733
734			payload = pframe;
735
736			for (curfragnum = 0; curfragnum < pattrib->nr_frags;
737			     curfragnum++) {
738				payload = PTR_ALIGN(payload, 4);
739				RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
740					 ("=== curfragnum =%d, pframe = 0x%.2x, "
741					  "0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x"
742					  "%.2x, 0x%.2x, 0x%.2x,!!!\n",
743					  curfragnum, *payload, *(payload + 1),
744					  *(payload + 2), *(payload + 3),
745					  *(payload + 4), *(payload + 5),
746					  *(payload + 6), *(payload + 7)));
747
748				payload = payload + pattrib->hdrlen +
749					pattrib->iv_len;
750				RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
751					 ("curfragnum =%d pattrib->hdrlen =%d "
752					  "pattrib->iv_len =%d", curfragnum,
753					  pattrib->hdrlen, pattrib->iv_len));
754				if ((curfragnum + 1) == pattrib->nr_frags) {
755					length = pattrib->last_txcmdsz -
756						pattrib->hdrlen -
757						pattrib->iv_len -
758						((pattrib->bswenc) ?
759						 pattrib->icv_len : 0);
760					rtw_secmicappend23a(&micdata, payload,
761							 length);
762					payload = payload + length;
763				} else {
764					length = pxmitpriv->frag_len -
765						pattrib->hdrlen -
766						pattrib->iv_len -
767						((pattrib->bswenc) ?
768						 pattrib->icv_len : 0);
769					rtw_secmicappend23a(&micdata, payload,
770							 length);
771					payload = payload + length +
772						pattrib->icv_len;
773					RT_TRACE(_module_rtl871x_xmit_c_,
774						 _drv_err_,
775						 ("curfragnum =%d length =%d "
776						  "pattrib->icv_len =%d",
777						  curfragnum, length,
778						  pattrib->icv_len));
779				}
780			}
781			rtw_secgetmic23a(&micdata, &mic[0]);
782			RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
783				 ("xmitframe_addmic: before add mic code!!\n"));
784			RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
785				 ("xmitframe_addmic: pattrib->last_txcmdsz ="
786				  "%d!!!\n", pattrib->last_txcmdsz));
787			RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
788				 ("xmitframe_addmic: mic[0]= 0x%.2x , mic[1]="
789				  "0x%.2x , mic[2]= 0x%.2x , mic[3]= 0x%.2x\n"
790				  "mic[4]= 0x%.2x , mic[5]= 0x%.2x , mic[6]= 0x%.2x "
791				  ", mic[7]= 0x%.2x !!!!\n", mic[0], mic[1],
792				  mic[2], mic[3], mic[4], mic[5], mic[6],
793				  mic[7]));
794			/* add mic code  and add the mic code length
795			   in last_txcmdsz */
796
797			memcpy(payload, &mic[0], 8);
798			pattrib->last_txcmdsz += 8;
799
800			RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
801				 ("\n ======== last pkt ========\n"));
802			payload = payload - pattrib->last_txcmdsz + 8;
803			for (curfragnum = 0; curfragnum < pattrib->last_txcmdsz;
804			     curfragnum = curfragnum + 8)
805				RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
806					 (" %.2x,  %.2x,  %.2x,  %.2x,  %.2x, "
807					  " %.2x,  %.2x,  %.2x ",
808					  *(payload + curfragnum),
809					  *(payload + curfragnum + 1),
810					  *(payload + curfragnum + 2),
811					  *(payload + curfragnum + 3),
812					  *(payload + curfragnum + 4),
813					  *(payload + curfragnum + 5),
814					  *(payload + curfragnum + 6),
815					  *(payload + curfragnum + 7)));
816			} else {
817				RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
818					 ("xmitframe_addmic: rtw_get_stainfo23a =="
819					  "NULL!!!\n"));
820		}
821	}
822
823	return _SUCCESS;
824}
825
826static int xmitframe_swencrypt(struct rtw_adapter *padapter,
827			       struct xmit_frame *pxmitframe)
828{
829	struct pkt_attrib *pattrib = &pxmitframe->attrib;
830
831	/* if ((psecuritypriv->sw_encrypt)||(pattrib->bswenc)) */
832	if (pattrib->bswenc) {
833		/* DBG_8723A("start xmitframe_swencrypt\n"); */
834		RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_,
835			 ("### xmitframe_swencrypt\n"));
836		switch (pattrib->encrypt) {
837		case WLAN_CIPHER_SUITE_WEP40:
838		case WLAN_CIPHER_SUITE_WEP104:
839			rtw_wep_encrypt23a(padapter, pxmitframe);
840			break;
841		case WLAN_CIPHER_SUITE_TKIP:
842			rtw_tkip_encrypt23a(padapter, pxmitframe);
843			break;
844		case WLAN_CIPHER_SUITE_CCMP:
845			rtw_aes_encrypt23a(padapter, pxmitframe);
846			break;
847		default:
848				break;
849		}
850
851	} else {
852		RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
853			 ("### xmitframe_hwencrypt\n"));
854	}
855
856	return _SUCCESS;
857}
858
859static int rtw_make_wlanhdr(struct rtw_adapter *padapter, u8 *hdr,
860			    struct pkt_attrib *pattrib)
861{
862	struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
863	struct ieee80211_qos_hdr *qoshdr;
864	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
865	u8 qos_option = false;
866	int res = _SUCCESS;
867
868	struct sta_info *psta;
869
870	int bmcst = is_multicast_ether_addr(pattrib->ra);
871
872	if (pattrib->psta) {
873		psta = pattrib->psta;
874	} else {
875		DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
876		if (bmcst) {
877			psta = rtw_get_bcmc_stainfo23a(padapter);
878		} else {
879			psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra);
880		}
881	}
882
883	if (psta == NULL) {
884		DBG_8723A("%s, psta == NUL\n", __func__);
885		return _FAIL;
886	}
887
888	if (!(psta->state &_FW_LINKED)) {
889		DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
890		return _FAIL;
891	}
892
893	memset(hdr, 0, WLANHDR_OFFSET);
894
895	pwlanhdr->frame_control = cpu_to_le16(pattrib->type);
896
897	if (pattrib->type & IEEE80211_FTYPE_DATA) {
898		if (check_fwstate(pmlmepriv,  WIFI_STATION_STATE)) {
899			/* to_ds = 1, fr_ds = 0; */
900			/* Data transfer to AP */
901			pwlanhdr->frame_control |=
902				cpu_to_le16(IEEE80211_FCTL_TODS);
903			ether_addr_copy(pwlanhdr->addr1, get_bssid(pmlmepriv));
904			ether_addr_copy(pwlanhdr->addr2, pattrib->src);
905			ether_addr_copy(pwlanhdr->addr3, pattrib->dst);
906
907			if (pmlmepriv->qos_option)
908				qos_option = true;
909
910		} else if (check_fwstate(pmlmepriv,  WIFI_AP_STATE)) {
911			/* to_ds = 0, fr_ds = 1; */
912			pwlanhdr->frame_control |=
913				cpu_to_le16(IEEE80211_FCTL_FROMDS);
914			ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
915			ether_addr_copy(pwlanhdr->addr2, get_bssid(pmlmepriv));
916			ether_addr_copy(pwlanhdr->addr3, pattrib->src);
917
918			if (psta->qos_option)
919				qos_option = true;
920		} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
921			   check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
922			ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
923			ether_addr_copy(pwlanhdr->addr2, pattrib->src);
924			ether_addr_copy(pwlanhdr->addr3, get_bssid(pmlmepriv));
925
926			if (psta->qos_option)
927				qos_option = true;
928		}
929		else {
930			RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("fw_state:%x is not allowed to xmit frame\n", get_fwstate(pmlmepriv)));
931			res = _FAIL;
932			goto exit;
933		}
934		if (pattrib->mdata)
935			pwlanhdr->frame_control |=
936				cpu_to_le16(IEEE80211_FCTL_MOREDATA);
937		if (pattrib->encrypt)
938			pwlanhdr->frame_control |=
939				cpu_to_le16(IEEE80211_FCTL_PROTECTED);
940		if (qos_option) {
941			qoshdr = (struct ieee80211_qos_hdr *)hdr;
942
943			qoshdr->qos_ctrl = cpu_to_le16(
944				pattrib->priority & IEEE80211_QOS_CTL_TID_MASK);
945
946			qoshdr->qos_ctrl |= cpu_to_le16(
947				(pattrib->ack_policy << 5) &
948				IEEE80211_QOS_CTL_ACK_POLICY_MASK);
949
950			if (pattrib->eosp)
951				qoshdr->qos_ctrl |=
952					cpu_to_le16(IEEE80211_QOS_CTL_EOSP);
953		}
954		/* TODO: fill HT Control Field */
955
956		/* Update Seq Num will be handled by f/w */
957		if (psta) {
958			psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
959			psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
960			pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
961			/* We dont need to worry about frag bits here */
962			pwlanhdr->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(
963							      pattrib->seqnum));
964			/* check if enable ampdu */
965			if (pattrib->ht_en && psta->htpriv.ampdu_enable) {
966				if (pattrib->priority >= 16)
967					printk(KERN_WARNING "%s: Invalid "
968					       "pattrib->priority %i\n",
969					       __func__, pattrib->priority);
970				if (psta->htpriv.agg_enable_bitmap &
971				    BIT(pattrib->priority))
972					pattrib->ampdu_en = true;
973			}
974			/* re-check if enable ampdu by BA_starting_seqctrl */
975			if (pattrib->ampdu_en) {
976				u16 tx_seq;
977
978				tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
979
980				/* check BA_starting_seqctrl */
981				if (SN_LESS(pattrib->seqnum, tx_seq)) {
982					/* DBG_8723A("tx ampdu seqnum(%d) < tx_seq(%d)\n", pattrib->seqnum, tx_seq); */
983					pattrib->ampdu_en = false;/* AGG BK */
984				} else if (SN_EQUAL(pattrib->seqnum, tx_seq)) {
985					psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff;
986					pattrib->ampdu_en = true;/* AGG EN */
987				} else {
988					/* DBG_8723A("tx ampdu over run\n"); */
989					psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff;
990					pattrib->ampdu_en = true;/* AGG EN */
991				}
992			}
993		}
994	}
995exit:
996	return res;
997}
998
999s32 rtw_txframes_pending23a(struct rtw_adapter *padapter)
1000{
1001	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1002
1003	return (!list_empty(&pxmitpriv->be_pending.queue)) ||
1004		(!list_empty(&pxmitpriv->bk_pending.queue)) ||
1005		(!list_empty(&pxmitpriv->vi_pending.queue)) ||
1006		(!list_empty(&pxmitpriv->vo_pending.queue));
1007}
1008
1009s32 rtw_txframes_sta_ac_pending23a(struct rtw_adapter *padapter,
1010				struct pkt_attrib *pattrib)
1011{
1012	struct sta_info *psta;
1013	struct tx_servq *ptxservq;
1014	int priority = pattrib->priority;
1015
1016	if (pattrib->psta) {
1017		psta = pattrib->psta;
1018	} else {
1019		DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
1020		psta = rtw_get_stainfo23a(&padapter->stapriv, &pattrib->ra[0]);
1021	}
1022	if (psta == NULL) {
1023		DBG_8723A("%s, psta == NUL\n", __func__);
1024		return 0;
1025	}
1026	if (!(psta->state &_FW_LINKED)) {
1027		DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__,
1028			  psta->state);
1029		return 0;
1030	}
1031	switch (priority) {
1032	case 1:
1033	case 2:
1034		ptxservq = &psta->sta_xmitpriv.bk_q;
1035		break;
1036	case 4:
1037	case 5:
1038		ptxservq = &psta->sta_xmitpriv.vi_q;
1039		break;
1040	case 6:
1041	case 7:
1042		ptxservq = &psta->sta_xmitpriv.vo_q;
1043		break;
1044	case 0:
1045	case 3:
1046	default:
1047		ptxservq = &psta->sta_xmitpriv.be_q;
1048		break;
1049	}
1050	return ptxservq->qcnt;
1051}
1052
1053/*
1054 * Calculate wlan 802.11 packet MAX size from pkt_attrib
1055 * This function doesn't consider fragment case
1056 */
1057u32 rtw_calculate_wlan_pkt_size_by_attribue23a(struct pkt_attrib *pattrib)
1058{
1059	u32	len = 0;
1060
1061	len = pattrib->hdrlen + pattrib->iv_len; /*  WLAN Header and IV */
1062	len += SNAP_SIZE + sizeof(u16); /*  LLC */
1063	len += pattrib->pktlen;
1064	if (pattrib->encrypt == WLAN_CIPHER_SUITE_TKIP) len += 8; /*  MIC */
1065	len += ((pattrib->bswenc) ? pattrib->icv_len : 0); /*  ICV */
1066
1067	return len;
1068}
1069
1070/*
1071
1072This sub-routine will perform all the following:
1073
10741. remove 802.3 header.
10752. create wlan_header, based on the info in pxmitframe
10763. append sta's iv/ext-iv
10774. append LLC
10785. move frag chunk from pframe to pxmitframe->mem
10796. apply sw-encrypt, if necessary.
1080
1081*/
1082int rtw_xmitframe_coalesce23a(struct rtw_adapter *padapter, struct sk_buff *skb,
1083			      struct xmit_frame *pxmitframe)
1084{
1085	struct sta_info *psta;
1086	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1087	struct pkt_attrib *pattrib = &pxmitframe->attrib;
1088	struct ieee80211_hdr *hdr;
1089	s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
1090	u8 *pframe, *mem_start;
1091	u8 hw_hdr_offset;
1092	u8 *pbuf_start;
1093	u8 *pdata = skb->data;
1094	int data_len = skb->len;
1095	s32 bmcst = is_multicast_ether_addr(pattrib->ra);
1096	int res = _SUCCESS;
1097
1098	if (pattrib->psta)
1099		psta = pattrib->psta;
1100	else {
1101		DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
1102		psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra);
1103	}
1104
1105	if (!psta) {
1106		DBG_8723A("%s, psta == NUL\n", __func__);
1107		return _FAIL;
1108	}
1109
1110	if (!(psta->state &_FW_LINKED)) {
1111		DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
1112			  __func__, psta->state);
1113		return _FAIL;
1114	}
1115
1116	if (!pxmitframe->buf_addr) {
1117		DBG_8723A("==> %s buf_addr == NULL\n", __func__);
1118		return _FAIL;
1119	}
1120
1121	pbuf_start = pxmitframe->buf_addr;
1122
1123	hw_hdr_offset = TXDESC_OFFSET;
1124
1125	mem_start = pbuf_start + hw_hdr_offset;
1126
1127	if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
1128		RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
1129			 ("%s: rtw_make_wlanhdr fail; drop pkt\n", __func__));
1130		res = _FAIL;
1131		goto exit;
1132	}
1133
1134	pdata += pattrib->pkt_hdrlen;
1135	data_len -= pattrib->pkt_hdrlen;
1136
1137	frg_inx = 0;
1138	frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
1139
1140	while (1) {
1141		llc_sz = 0;
1142
1143		mpdu_len = frg_len;
1144
1145		pframe = mem_start;
1146		hdr = (struct ieee80211_hdr *)mem_start;
1147
1148		pframe += pattrib->hdrlen;
1149		mpdu_len -= pattrib->hdrlen;
1150
1151		/* adding icv, if necessary... */
1152		if (pattrib->iv_len) {
1153			if (psta) {
1154				switch (pattrib->encrypt) {
1155				case WLAN_CIPHER_SUITE_WEP40:
1156				case WLAN_CIPHER_SUITE_WEP104:
1157					WEP_IV(pattrib->iv, psta->dot11txpn,
1158					       pattrib->key_idx);
1159					break;
1160				case WLAN_CIPHER_SUITE_TKIP:
1161					if (bmcst)
1162						TKIP_IV(pattrib->iv,
1163							psta->dot11txpn,
1164							pattrib->key_idx);
1165					else
1166						TKIP_IV(pattrib->iv,
1167							psta->dot11txpn, 0);
1168					break;
1169				case WLAN_CIPHER_SUITE_CCMP:
1170					if (bmcst)
1171						AES_IV(pattrib->iv,
1172						       psta->dot11txpn,
1173						       pattrib->key_idx);
1174					else
1175						AES_IV(pattrib->iv,
1176						       psta->dot11txpn, 0);
1177					break;
1178				}
1179			}
1180
1181			memcpy(pframe, pattrib->iv, pattrib->iv_len);
1182
1183			RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
1184				 ("rtw_xmiaframe_coalesce23a: keyid =%d pattrib"
1185				  "->iv[3]=%.2x pframe =%.2x %.2x %.2x %.2x\n",
1186				  padapter->securitypriv.dot11PrivacyKeyIndex,
1187				  pattrib->iv[3], *pframe, *(pframe+1),
1188				  *(pframe+2), *(pframe+3)));
1189			pframe += pattrib->iv_len;
1190			mpdu_len -= pattrib->iv_len;
1191		}
1192		if (frg_inx == 0) {
1193			llc_sz = rtw_put_snap23a(pframe, pattrib->ether_type);
1194			pframe += llc_sz;
1195			mpdu_len -= llc_sz;
1196		}
1197
1198		if (pattrib->icv_len > 0 && pattrib->bswenc)
1199			mpdu_len -= pattrib->icv_len;
1200
1201		if (bmcst)
1202			/*  don't do fragment to broadcat/multicast packets */
1203			mem_sz = min_t(s32, data_len, pattrib->pktlen);
1204		else
1205			mem_sz = min_t(s32, data_len, mpdu_len);
1206
1207		memcpy(pframe, pdata, mem_sz);
1208
1209		pframe += mem_sz;
1210		pdata += mem_sz;
1211		data_len -= mem_sz;
1212
1213		if ((pattrib->icv_len >0) && (pattrib->bswenc)) {
1214			memcpy(pframe, pattrib->icv, pattrib->icv_len);
1215			pframe += pattrib->icv_len;
1216		}
1217
1218		frg_inx++;
1219
1220		if (bmcst || data_len <= 0) {
1221			pattrib->nr_frags = frg_inx;
1222
1223			pattrib->last_txcmdsz = pattrib->hdrlen +
1224						pattrib->iv_len +
1225						((pattrib->nr_frags == 1) ?
1226						llc_sz : 0) +
1227						((pattrib->bswenc) ?
1228						pattrib->icv_len : 0) + mem_sz;
1229			hdr->frame_control &=
1230				~cpu_to_le16(IEEE80211_FCTL_MOREFRAGS);
1231
1232			break;
1233		} else {
1234			RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
1235				 ("%s: There're still something in packet!\n",
1236				  __func__));
1237		}
1238		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREFRAGS);
1239
1240		mem_start = PTR_ALIGN(pframe, 4) + hw_hdr_offset;
1241		memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
1242	}
1243
1244	if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
1245		RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
1246			 ("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n"));
1247		DBG_8723A("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n");
1248		res = _FAIL;
1249		goto exit;
1250	}
1251
1252	xmitframe_swencrypt(padapter, pxmitframe);
1253
1254	if (bmcst == false)
1255		update_attrib_vcs_info(padapter, pxmitframe);
1256	else
1257		pattrib->vcs_mode = NONE_VCS;
1258
1259exit:
1260	return res;
1261}
1262
1263/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
1264 * IEEE LLC/SNAP header contains 8 octets
1265 * First 3 octets comprise the LLC portion
1266 * SNAP portion, 5 octets, is divided into two fields:
1267 *	Organizationally Unique Identifier(OUI), 3 octets,
1268 *	type, defined by that organization, 2 octets.
1269 */
1270s32 rtw_put_snap23a(u8 *data, u16 h_proto)
1271{
1272	struct ieee80211_snap_hdr *snap;
1273	u8 *oui;
1274
1275	snap = (struct ieee80211_snap_hdr *)data;
1276	snap->dsap = 0xaa;
1277	snap->ssap = 0xaa;
1278	snap->ctrl = 0x03;
1279
1280	if (h_proto == 0x8137 || h_proto == 0x80f3)
1281		oui = P802_1H_OUI;
1282	else
1283		oui = RFC1042_OUI;
1284	snap->oui[0] = oui[0];
1285	snap->oui[1] = oui[1];
1286	snap->oui[2] = oui[2];
1287	*(u16 *)(data + SNAP_SIZE) = htons(h_proto);
1288	return SNAP_SIZE + sizeof(u16);
1289}
1290
1291void rtw_update_protection23a(struct rtw_adapter *padapter, u8 *ie, uint ie_len)
1292{
1293	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1294	struct registry_priv *pregistrypriv = &padapter->registrypriv;
1295	uint protection;
1296	const u8 *p;
1297
1298	switch (pxmitpriv->vcs_setting) {
1299	case DISABLE_VCS:
1300		pxmitpriv->vcs = NONE_VCS;
1301		break;
1302	case ENABLE_VCS:
1303		break;
1304	case AUTO_VCS:
1305	default:
1306		p = cfg80211_find_ie(WLAN_EID_ERP_INFO, ie, ie_len);
1307		if (!p)
1308			pxmitpriv->vcs = NONE_VCS;
1309		else {
1310			protection = (*(p + 2)) & BIT(1);
1311			if (protection) {
1312				if (pregistrypriv->vcs_type == RTS_CTS)
1313					pxmitpriv->vcs = RTS_CTS;
1314				else
1315					pxmitpriv->vcs = CTS_TO_SELF;
1316			} else {
1317				pxmitpriv->vcs = NONE_VCS;
1318			}
1319		}
1320		break;
1321	}
1322}
1323
1324void rtw_count_tx_stats23a(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe, int sz)
1325{
1326	struct sta_info *psta = NULL;
1327	struct stainfo_stats *pstats = NULL;
1328	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
1329	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1330
1331	if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) {
1332		pxmitpriv->tx_bytes += sz;
1333		pmlmepriv->LinkDetectInfo.NumTxOkInPeriod++;
1334
1335		psta = pxmitframe->attrib.psta;
1336		if (psta) {
1337			pstats = &psta->sta_stats;
1338			pstats->tx_pkts++;
1339			pstats->tx_bytes += sz;
1340		}
1341	}
1342}
1343
1344struct xmit_buf *rtw_alloc_xmitbuf23a_ext(struct xmit_priv *pxmitpriv)
1345{
1346	unsigned long irqL;
1347	struct xmit_buf *pxmitbuf =  NULL;
1348	struct list_head *phead;
1349	struct rtw_queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1350
1351	spin_lock_irqsave(&pfree_queue->lock, irqL);
1352
1353	phead = get_list_head(pfree_queue);
1354
1355	if (!list_empty(phead)) {
1356		pxmitbuf = list_first_entry(phead, struct xmit_buf, list);
1357
1358		list_del_init(&pxmitbuf->list);
1359
1360		pxmitpriv->free_xmit_extbuf_cnt--;
1361		pxmitbuf->priv_data = NULL;
1362		pxmitbuf->ext_tag = true;
1363
1364		if (pxmitbuf->sctx) {
1365			DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__);
1366			rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1367		}
1368	}
1369
1370	spin_unlock_irqrestore(&pfree_queue->lock, irqL);
1371
1372	return pxmitbuf;
1373}
1374
1375int rtw_free_xmitbuf_ext23a(struct xmit_priv *pxmitpriv,
1376			    struct xmit_buf *pxmitbuf)
1377{
1378	unsigned long irqL;
1379	struct rtw_queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1380
1381	if (pxmitbuf == NULL)
1382		return _FAIL;
1383
1384	spin_lock_irqsave(&pfree_queue->lock, irqL);
1385
1386	list_del_init(&pxmitbuf->list);
1387
1388	list_add_tail(&pxmitbuf->list, get_list_head(pfree_queue));
1389	pxmitpriv->free_xmit_extbuf_cnt++;
1390
1391	spin_unlock_irqrestore(&pfree_queue->lock, irqL);
1392
1393	return _SUCCESS;
1394}
1395
1396struct xmit_buf *rtw_alloc_xmitbuf23a(struct xmit_priv *pxmitpriv)
1397{
1398	unsigned long irqL;
1399	struct xmit_buf *pxmitbuf =  NULL;
1400	struct list_head *phead;
1401	struct rtw_queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
1402
1403	/* DBG_8723A("+rtw_alloc_xmitbuf23a\n"); */
1404
1405	spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
1406
1407	phead = get_list_head(pfree_xmitbuf_queue);
1408
1409	if (!list_empty(phead)) {
1410		pxmitbuf = list_first_entry(phead, struct xmit_buf, list);
1411
1412		list_del_init(&pxmitbuf->list);
1413
1414		pxmitpriv->free_xmitbuf_cnt--;
1415		pxmitbuf->priv_data = NULL;
1416		pxmitbuf->ext_tag = false;
1417		pxmitbuf->flags = XMIT_VO_QUEUE;
1418
1419		if (pxmitbuf->sctx) {
1420			DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__);
1421			rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1422		}
1423	}
1424
1425	spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
1426
1427	return pxmitbuf;
1428}
1429
1430int rtw_free_xmitbuf23a(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
1431{
1432	unsigned long irqL;
1433	struct rtw_queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
1434
1435	/* DBG_8723A("+rtw_free_xmitbuf23a\n"); */
1436
1437	if (pxmitbuf == NULL)
1438		return _FAIL;
1439
1440	if (pxmitbuf->sctx) {
1441		DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__);
1442		rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
1443	}
1444
1445	if (pxmitbuf->ext_tag) {
1446		rtw_free_xmitbuf_ext23a(pxmitpriv, pxmitbuf);
1447	} else {
1448		spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
1449
1450		list_del_init(&pxmitbuf->list);
1451
1452		list_add_tail(&pxmitbuf->list,
1453			      get_list_head(pfree_xmitbuf_queue));
1454
1455		pxmitpriv->free_xmitbuf_cnt++;
1456		spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
1457	}
1458
1459	return _SUCCESS;
1460}
1461
1462static void rtw_init_xmitframe(struct xmit_frame *pxframe)
1463{
1464	if (pxframe !=  NULL) {
1465		/* default value setting */
1466		pxframe->buf_addr = NULL;
1467		pxframe->pxmitbuf = NULL;
1468
1469		memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
1470		/* pxframe->attrib.psta = NULL; */
1471
1472		pxframe->frame_tag = DATA_FRAMETAG;
1473
1474		pxframe->pkt = NULL;
1475		pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */
1476
1477		pxframe->ack_report = 0;
1478	}
1479}
1480
1481/*
1482Calling context:
14831. OS_TXENTRY
14842. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
1485
1486If we turn on USE_RXTHREAD, then, no need for critical section.
1487Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
1488
1489Must be very very cautious...
1490
1491*/
1492static struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)
1493{
1494	struct xmit_frame *pxframe = NULL;
1495	struct list_head *plist, *phead;
1496	struct rtw_queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
1497
1498	spin_lock_bh(&pfree_xmit_queue->lock);
1499
1500	if (list_empty(&pfree_xmit_queue->queue)) {
1501		RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
1502			 ("rtw_alloc_xmitframe:%d\n",
1503			  pxmitpriv->free_xmitframe_cnt));
1504		pxframe =  NULL;
1505	} else {
1506		phead = get_list_head(pfree_xmit_queue);
1507
1508		plist = phead->next;
1509
1510		pxframe = container_of(plist, struct xmit_frame, list);
1511
1512		list_del_init(&pxframe->list);
1513		pxmitpriv->free_xmitframe_cnt--;
1514		RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
1515			 ("rtw_alloc_xmitframe():free_xmitframe_cnt =%d\n",
1516			  pxmitpriv->free_xmitframe_cnt));
1517	}
1518
1519	spin_unlock_bh(&pfree_xmit_queue->lock);
1520
1521	rtw_init_xmitframe(pxframe);
1522
1523	return pxframe;
1524}
1525
1526struct xmit_frame *rtw_alloc_xmitframe23a_ext(struct xmit_priv *pxmitpriv)
1527{
1528	struct xmit_frame *pxframe = NULL;
1529	struct list_head *plist, *phead;
1530	struct rtw_queue *queue = &pxmitpriv->free_xframe_ext_queue;
1531
1532	spin_lock_bh(&queue->lock);
1533
1534	if (list_empty(&queue->queue)) {
1535		RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe23a_ext:%d\n", pxmitpriv->free_xframe_ext_cnt));
1536		pxframe =  NULL;
1537	} else {
1538		phead = get_list_head(queue);
1539		plist = phead->next;
1540		pxframe = container_of(plist, struct xmit_frame, list);
1541
1542		list_del_init(&pxframe->list);
1543		pxmitpriv->free_xframe_ext_cnt--;
1544		RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe23a_ext():free_xmitframe_cnt =%d\n", pxmitpriv->free_xframe_ext_cnt));
1545	}
1546
1547	spin_unlock_bh(&queue->lock);
1548
1549	rtw_init_xmitframe(pxframe);
1550
1551	return pxframe;
1552}
1553
1554s32 rtw_free_xmitframe23a(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
1555{
1556	struct rtw_queue *queue = NULL;
1557	struct rtw_adapter *padapter = pxmitpriv->adapter;
1558	struct sk_buff *pndis_pkt = NULL;
1559
1560	if (pxmitframe == NULL) {
1561		RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("====== rtw_free_xmitframe23a():pxmitframe == NULL!!!!!!!!!!\n"));
1562		goto exit;
1563	}
1564
1565	if (pxmitframe->pkt) {
1566		pndis_pkt = pxmitframe->pkt;
1567		pxmitframe->pkt = NULL;
1568	}
1569
1570	if (pxmitframe->ext_tag == 0)
1571		queue = &pxmitpriv->free_xmit_queue;
1572	else if (pxmitframe->ext_tag == 1)
1573		queue = &pxmitpriv->free_xframe_ext_queue;
1574
1575	if (!queue)
1576		goto check_pkt_complete;
1577	spin_lock_bh(&queue->lock);
1578
1579	list_del_init(&pxmitframe->list);
1580	list_add_tail(&pxmitframe->list, get_list_head(queue));
1581	if (pxmitframe->ext_tag == 0) {
1582		pxmitpriv->free_xmitframe_cnt++;
1583		RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe23a():free_xmitframe_cnt =%d\n", pxmitpriv->free_xmitframe_cnt));
1584	} else if (pxmitframe->ext_tag == 1) {
1585		pxmitpriv->free_xframe_ext_cnt++;
1586		RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe23a():free_xframe_ext_cnt =%d\n", pxmitpriv->free_xframe_ext_cnt));
1587	}
1588
1589	spin_unlock_bh(&queue->lock);
1590
1591check_pkt_complete:
1592
1593	if (pndis_pkt)
1594		rtw_os_pkt_complete23a(padapter, pndis_pkt);
1595
1596exit:
1597
1598	return _SUCCESS;
1599}
1600
1601void rtw_free_xmitframe_queue23a(struct xmit_priv *pxmitpriv,
1602				 struct rtw_queue *pframequeue)
1603{
1604	struct list_head *plist, *phead, *ptmp;
1605	struct	xmit_frame *pxmitframe;
1606
1607	spin_lock_bh(&pframequeue->lock);
1608
1609	phead = get_list_head(pframequeue);
1610
1611	list_for_each_safe(plist, ptmp, phead) {
1612		pxmitframe = container_of(plist, struct xmit_frame, list);
1613
1614		rtw_free_xmitframe23a(pxmitpriv, pxmitframe);
1615	}
1616	spin_unlock_bh(&pframequeue->lock);
1617
1618}
1619
1620int rtw_xmitframe_enqueue23a(struct rtw_adapter *padapter,
1621			     struct xmit_frame *pxmitframe)
1622{
1623	if (rtw_xmit23a_classifier(padapter, pxmitframe) == _FAIL) {
1624		RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
1625			 ("rtw_xmitframe_enqueue23a: drop xmit pkt for "
1626			  "classifier fail\n"));
1627		return _FAIL;
1628	}
1629
1630	return _SUCCESS;
1631}
1632
1633static struct xmit_frame *
1634dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit,
1635		      struct tx_servq *ptxservq, struct rtw_queue *pframe_queue)
1636{
1637	struct list_head *phead;
1638	struct xmit_frame *pxmitframe = NULL;
1639
1640	phead = get_list_head(pframe_queue);
1641
1642	if (!list_empty(phead)) {
1643		pxmitframe = list_first_entry(phead, struct xmit_frame, list);
1644		list_del_init(&pxmitframe->list);
1645		ptxservq->qcnt--;
1646	}
1647	return pxmitframe;
1648}
1649
1650struct xmit_frame *
1651rtw_dequeue_xframe23a(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i,
1652		   int entry)
1653{
1654	struct list_head *sta_plist, *sta_phead, *ptmp;
1655	struct hw_xmit *phwxmit;
1656	struct tx_servq *ptxservq = NULL;
1657	struct rtw_queue *pframe_queue = NULL;
1658	struct xmit_frame *pxmitframe = NULL;
1659	struct rtw_adapter *padapter = pxmitpriv->adapter;
1660	struct registry_priv	*pregpriv = &padapter->registrypriv;
1661	int i, inx[4];
1662
1663	inx[0] = 0;
1664	inx[1] = 1;
1665	inx[2] = 2;
1666	inx[3] = 3;
1667	if (pregpriv->wifi_spec == 1) {
1668		int j;
1669
1670		for (j = 0; j < 4; j++)
1671			inx[j] = pxmitpriv->wmm_para_seq[j];
1672	}
1673
1674	spin_lock_bh(&pxmitpriv->lock);
1675
1676	for (i = 0; i < entry; i++) {
1677		phwxmit = phwxmit_i + inx[i];
1678
1679		sta_phead = get_list_head(phwxmit->sta_queue);
1680
1681		list_for_each_safe(sta_plist, ptmp, sta_phead) {
1682			ptxservq = container_of(sta_plist, struct tx_servq,
1683						tx_pending);
1684
1685			pframe_queue = &ptxservq->sta_pending;
1686
1687			pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
1688
1689			if (pxmitframe) {
1690				phwxmit->accnt--;
1691
1692				/* Remove sta node when there is no pending packets. */
1693				/* must be done after get_next and
1694				   before break */
1695				if (list_empty(&pframe_queue->queue))
1696					list_del_init(&ptxservq->tx_pending);
1697				goto exit;
1698			}
1699		}
1700	}
1701exit:
1702	spin_unlock_bh(&pxmitpriv->lock);
1703	return pxmitframe;
1704}
1705
1706struct tx_servq *rtw_get_sta_pending23a(struct rtw_adapter *padapter, struct sta_info *psta, int up, u8 *ac)
1707{
1708	struct tx_servq *ptxservq = NULL;
1709
1710	switch (up) {
1711	case 1:
1712	case 2:
1713		ptxservq = &psta->sta_xmitpriv.bk_q;
1714		*(ac) = 3;
1715		RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending23a : BK\n"));
1716		break;
1717	case 4:
1718	case 5:
1719		ptxservq = &psta->sta_xmitpriv.vi_q;
1720		*(ac) = 1;
1721		RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending23a : VI\n"));
1722		break;
1723	case 6:
1724	case 7:
1725		ptxservq = &psta->sta_xmitpriv.vo_q;
1726		*(ac) = 0;
1727		RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending23a : VO\n"));
1728		break;
1729	case 0:
1730	case 3:
1731	default:
1732		ptxservq = &psta->sta_xmitpriv.be_q;
1733		*(ac) = 2;
1734		RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending23a : BE\n"));
1735		break;
1736	}
1737	return ptxservq;
1738}
1739
1740/*
1741 * Will enqueue pxmitframe to the proper queue,
1742 * and indicate it to xx_pending list.....
1743 */
1744int rtw_xmit23a_classifier(struct rtw_adapter *padapter,
1745			   struct xmit_frame *pxmitframe)
1746{
1747	struct sta_info	*psta;
1748	struct tx_servq	*ptxservq;
1749	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
1750	struct sta_priv	*pstapriv = &padapter->stapriv;
1751	struct hw_xmit	*phwxmits =  padapter->xmitpriv.hwxmits;
1752	u8	ac_index;
1753	int res = _SUCCESS;
1754
1755	if (pattrib->psta) {
1756		psta = pattrib->psta;
1757	} else {
1758		DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
1759		psta = rtw_get_stainfo23a(pstapriv, pattrib->ra);
1760	}
1761	if (psta == NULL) {
1762		res = _FAIL;
1763		DBG_8723A("rtw_xmit23a_classifier: psta == NULL\n");
1764		RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
1765			 ("rtw_xmit23a_classifier: psta == NULL\n"));
1766		goto exit;
1767	}
1768	if (!(psta->state & _FW_LINKED)) {
1769		DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__,
1770			  psta->state);
1771		return _FAIL;
1772	}
1773	ptxservq = rtw_get_sta_pending23a(padapter, psta, pattrib->priority,
1774				       (u8 *)(&ac_index));
1775
1776	if (list_empty(&ptxservq->tx_pending)) {
1777		list_add_tail(&ptxservq->tx_pending,
1778			      get_list_head(phwxmits[ac_index].sta_queue));
1779	}
1780
1781	list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
1782	ptxservq->qcnt++;
1783	phwxmits[ac_index].accnt++;
1784exit:
1785	return res;
1786}
1787
1788void rtw_alloc_hwxmits23a(struct rtw_adapter *padapter)
1789{
1790	struct hw_xmit *hwxmits;
1791	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1792	int size;
1793
1794	pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
1795
1796	size = sizeof(struct hw_xmit) * (pxmitpriv->hwxmit_entry + 1);
1797	pxmitpriv->hwxmits = kzalloc(size, GFP_KERNEL);
1798
1799	hwxmits = pxmitpriv->hwxmits;
1800
1801	if (pxmitpriv->hwxmit_entry == 5) {
1802		/* pxmitpriv->bmc_txqueue.head = 0; */
1803		/* hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; */
1804		hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
1805
1806		/* pxmitpriv->vo_txqueue.head = 0; */
1807		/* hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; */
1808		hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
1809
1810		/* pxmitpriv->vi_txqueue.head = 0; */
1811		/* hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; */
1812		hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
1813
1814		/* pxmitpriv->bk_txqueue.head = 0; */
1815		/* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
1816		hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
1817
1818		/* pxmitpriv->be_txqueue.head = 0; */
1819		/* hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; */
1820		hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
1821
1822	} else if (pxmitpriv->hwxmit_entry == 4) {
1823
1824		/* pxmitpriv->vo_txqueue.head = 0; */
1825		/* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */
1826		hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
1827
1828		/* pxmitpriv->vi_txqueue.head = 0; */
1829		/* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */
1830		hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
1831
1832		/* pxmitpriv->be_txqueue.head = 0; */
1833		/* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */
1834		hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
1835
1836		/* pxmitpriv->bk_txqueue.head = 0; */
1837		/* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
1838		hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
1839	} else {
1840
1841	}
1842}
1843
1844void rtw_free_hwxmits23a(struct rtw_adapter *padapter)
1845{
1846	struct hw_xmit *hwxmits;
1847	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1848
1849	hwxmits = pxmitpriv->hwxmits;
1850	kfree(hwxmits);
1851}
1852
1853void rtw_init_hwxmits23a(struct hw_xmit *phwxmit, int entry)
1854{
1855	int i;
1856
1857	for (i = 0; i < entry; i++, phwxmit++)
1858		phwxmit->accnt = 0;
1859}
1860
1861u32 rtw_get_ff_hwaddr23a(struct xmit_frame *pxmitframe)
1862{
1863	u32 addr;
1864	struct pkt_attrib *pattrib = &pxmitframe->attrib;
1865
1866	switch (pattrib->qsel) {
1867	case 0:
1868	case 3:
1869		addr = BE_QUEUE_INX;
1870		break;
1871	case 1:
1872	case 2:
1873		addr = BK_QUEUE_INX;
1874		break;
1875	case 4:
1876	case 5:
1877		addr = VI_QUEUE_INX;
1878		break;
1879	case 6:
1880	case 7:
1881		addr = VO_QUEUE_INX;
1882		break;
1883	case 0x10:
1884		addr = BCN_QUEUE_INX;
1885		break;
1886	case 0x11:/* BC/MC in PS (HIQ) */
1887		addr = HIGH_QUEUE_INX;
1888		break;
1889	case 0x12:
1890	default:
1891		addr = MGT_QUEUE_INX;
1892		break;
1893	}
1894
1895	return addr;
1896}
1897
1898static void do_queue_select(struct rtw_adapter	*padapter, struct pkt_attrib *pattrib)
1899{
1900	u8 qsel;
1901
1902	qsel = pattrib->priority;
1903	RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
1904		 ("### do_queue_select priority =%d , qsel = %d\n",
1905		  pattrib->priority, qsel));
1906
1907	pattrib->qsel = qsel;
1908}
1909
1910/*
1911 * The main transmit(tx) entry
1912 *
1913 * Return
1914 *	1	enqueue
1915 *	0	success, hardware will handle this xmit frame(packet)
1916 *	<0	fail
1917 */
1918int rtw_xmit23a(struct rtw_adapter *padapter, struct sk_buff *skb)
1919{
1920	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1921	struct xmit_frame *pxmitframe = NULL;
1922	int res;
1923
1924	pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
1925
1926	if (pxmitframe == NULL) {
1927		RT_TRACE(_module_xmit_osdep_c_, _drv_err_,
1928			 ("rtw_xmit23a: no more pxmitframe\n"));
1929		return -1;
1930	}
1931
1932	res = update_attrib(padapter, skb, &pxmitframe->attrib);
1933
1934	if (res == _FAIL) {
1935		RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit23a: update attrib fail\n"));
1936		rtw_free_xmitframe23a(pxmitpriv, pxmitframe);
1937		return -1;
1938	}
1939	pxmitframe->pkt = skb;
1940
1941	rtw_led_control(padapter, LED_CTL_TX);
1942
1943	do_queue_select(padapter, &pxmitframe->attrib);
1944
1945#ifdef CONFIG_8723AU_AP_MODE
1946	spin_lock_bh(&pxmitpriv->lock);
1947	if (xmitframe_enqueue_for_sleeping_sta23a(padapter, pxmitframe)) {
1948		spin_unlock_bh(&pxmitpriv->lock);
1949		return 1;
1950	}
1951	spin_unlock_bh(&pxmitpriv->lock);
1952#endif
1953
1954	if (rtl8723au_hal_xmit(padapter, pxmitframe) == false)
1955		return 1;
1956
1957	return 0;
1958}
1959
1960#if defined(CONFIG_8723AU_AP_MODE)
1961
1962int xmitframe_enqueue_for_sleeping_sta23a(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe)
1963{
1964	int ret = false;
1965	struct sta_info *psta = NULL;
1966	struct sta_priv *pstapriv = &padapter->stapriv;
1967	struct pkt_attrib *pattrib = &pxmitframe->attrib;
1968	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1969	int bmcst = is_multicast_ether_addr(pattrib->ra);
1970
1971	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == false)
1972		return ret;
1973
1974	if (pattrib->psta) {
1975		psta = pattrib->psta;
1976	} else {
1977		DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
1978		psta = rtw_get_stainfo23a(pstapriv, pattrib->ra);
1979	}
1980
1981	if (psta == NULL) {
1982		DBG_8723A("%s, psta == NUL\n", __func__);
1983		return false;
1984	}
1985
1986	if (!(psta->state & _FW_LINKED)) {
1987		DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__,
1988			  psta->state);
1989		return false;
1990	}
1991
1992	if (pattrib->triggered == 1) {
1993		if (bmcst)
1994			pattrib->qsel = 0x11;/* HIQ */
1995		return ret;
1996	}
1997
1998	if (bmcst) {
1999		spin_lock_bh(&psta->sleep_q.lock);
2000
2001		if (pstapriv->sta_dz_bitmap) {
2002			/* if anyone sta is in ps mode */
2003			list_del_init(&pxmitframe->list);
2004
2005			/* spin_lock_bh(&psta->sleep_q.lock); */
2006
2007			list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
2008
2009			psta->sleepq_len++;
2010
2011			pstapriv->tim_bitmap |= BIT(0);/*  */
2012			pstapriv->sta_dz_bitmap |= BIT(0);
2013
2014			/* DBG_8723A("enqueue, sq_len =%d, tim =%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
2015
2016			/* tx bc/mc packets after upate bcn */
2017			update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
2018
2019			/* spin_unlock_bh(&psta->sleep_q.lock); */
2020
2021			ret = true;
2022
2023		}
2024
2025		spin_unlock_bh(&psta->sleep_q.lock);
2026
2027		return ret;
2028
2029	}
2030
2031	spin_lock_bh(&psta->sleep_q.lock);
2032
2033	if (psta->state&WIFI_SLEEP_STATE) {
2034		u8 wmmps_ac = 0;
2035
2036		if (pstapriv->sta_dz_bitmap & CHKBIT(psta->aid)) {
2037			list_del_init(&pxmitframe->list);
2038
2039			/* spin_lock_bh(&psta->sleep_q.lock); */
2040
2041			list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
2042
2043			psta->sleepq_len++;
2044
2045			switch (pattrib->priority) {
2046			case 1:
2047			case 2:
2048				wmmps_ac = psta->uapsd_bk & BIT(0);
2049				break;
2050			case 4:
2051			case 5:
2052				wmmps_ac = psta->uapsd_vi & BIT(0);
2053				break;
2054			case 6:
2055			case 7:
2056				wmmps_ac = psta->uapsd_vo & BIT(0);
2057				break;
2058			case 0:
2059			case 3:
2060			default:
2061				wmmps_ac = psta->uapsd_be & BIT(0);
2062				break;
2063			}
2064
2065			if (wmmps_ac)
2066				psta->sleepq_ac_len++;
2067
2068			if (((psta->has_legacy_ac) && (!wmmps_ac)) ||
2069			   ((!psta->has_legacy_ac) && (wmmps_ac))) {
2070				pstapriv->tim_bitmap |= CHKBIT(psta->aid);
2071
2072				if (psta->sleepq_len == 1) {
2073					/* upate BCN for TIM IE */
2074					update_beacon23a(padapter, WLAN_EID_TIM,
2075							 NULL, false);
2076				}
2077			}
2078
2079			/* spin_unlock_bh(&psta->sleep_q.lock); */
2080
2081			/* if (psta->sleepq_len > (NR_XMITFRAME>>3)) */
2082			/*  */
2083			/*	wakeup_sta_to_xmit23a(padapter, psta); */
2084			/*  */
2085
2086			ret = true;
2087
2088		}
2089
2090	}
2091
2092	spin_unlock_bh(&psta->sleep_q.lock);
2093
2094	return ret;
2095}
2096
2097static void
2098dequeue_xmitframes_to_sleeping_queue(struct rtw_adapter *padapter,
2099				     struct sta_info *psta,
2100				     struct rtw_queue *pframequeue)
2101{
2102	int ret;
2103	struct list_head *plist, *phead, *ptmp;
2104	u8	ac_index;
2105	struct tx_servq	*ptxservq;
2106	struct pkt_attrib	*pattrib;
2107	struct xmit_frame	*pxmitframe;
2108	struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
2109
2110	phead = get_list_head(pframequeue);
2111
2112	list_for_each_safe(plist, ptmp, phead) {
2113		pxmitframe = container_of(plist, struct xmit_frame, list);
2114
2115		ret = xmitframe_enqueue_for_sleeping_sta23a(padapter, pxmitframe);
2116
2117		if (ret == true) {
2118			pattrib = &pxmitframe->attrib;
2119
2120			ptxservq = rtw_get_sta_pending23a(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
2121
2122			ptxservq->qcnt--;
2123			phwxmits[ac_index].accnt--;
2124		} else {
2125			/* DBG_8723A("xmitframe_enqueue_for_sleeping_sta23a return false\n"); */
2126		}
2127	}
2128}
2129
2130void stop_sta_xmit23a(struct rtw_adapter *padapter, struct sta_info *psta)
2131{
2132	struct sta_info *psta_bmc;
2133	struct sta_xmit_priv *pstaxmitpriv;
2134	struct sta_priv *pstapriv = &padapter->stapriv;
2135	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2136
2137	pstaxmitpriv = &psta->sta_xmitpriv;
2138
2139	/* for BC/MC Frames */
2140	psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
2141
2142	spin_lock_bh(&pxmitpriv->lock);
2143
2144	psta->state |= WIFI_SLEEP_STATE;
2145
2146	pstapriv->sta_dz_bitmap |= CHKBIT(psta->aid);
2147
2148	dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
2149	list_del_init(&pstaxmitpriv->vo_q.tx_pending);
2150
2151	dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
2152	list_del_init(&pstaxmitpriv->vi_q.tx_pending);
2153
2154	dequeue_xmitframes_to_sleeping_queue(padapter, psta,
2155					     &pstaxmitpriv->be_q.sta_pending);
2156	list_del_init(&pstaxmitpriv->be_q.tx_pending);
2157
2158	dequeue_xmitframes_to_sleeping_queue(padapter, psta,
2159					     &pstaxmitpriv->bk_q.sta_pending);
2160	list_del_init(&pstaxmitpriv->bk_q.tx_pending);
2161
2162	/* for BC/MC Frames */
2163	pstaxmitpriv = &psta_bmc->sta_xmitpriv;
2164	dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc,
2165					     &pstaxmitpriv->be_q.sta_pending);
2166	list_del_init(&pstaxmitpriv->be_q.tx_pending);
2167
2168	spin_unlock_bh(&pxmitpriv->lock);
2169}
2170
2171void wakeup_sta_to_xmit23a(struct rtw_adapter *padapter, struct sta_info *psta)
2172{
2173	u8 update_mask = 0, wmmps_ac = 0;
2174	struct sta_info *psta_bmc;
2175	struct list_head *plist, *phead, *ptmp;
2176	struct xmit_frame *pxmitframe = NULL;
2177	struct sta_priv *pstapriv = &padapter->stapriv;
2178	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2179
2180	spin_lock_bh(&pxmitpriv->lock);
2181
2182	phead = get_list_head(&psta->sleep_q);
2183
2184	list_for_each_safe(plist, ptmp, phead) {
2185		pxmitframe = container_of(plist, struct xmit_frame, list);
2186		list_del_init(&pxmitframe->list);
2187
2188		switch (pxmitframe->attrib.priority) {
2189		case 1:
2190		case 2:
2191			wmmps_ac = psta->uapsd_bk & BIT(1);
2192			break;
2193		case 4:
2194		case 5:
2195			wmmps_ac = psta->uapsd_vi & BIT(1);
2196			break;
2197		case 6:
2198		case 7:
2199			wmmps_ac = psta->uapsd_vo & BIT(1);
2200			break;
2201		case 0:
2202		case 3:
2203		default:
2204			wmmps_ac = psta->uapsd_be & BIT(1);
2205			break;
2206		}
2207
2208		psta->sleepq_len--;
2209		if (psta->sleepq_len > 0)
2210			pxmitframe->attrib.mdata = 1;
2211		else
2212			pxmitframe->attrib.mdata = 0;
2213
2214		if (wmmps_ac) {
2215			psta->sleepq_ac_len--;
2216			if (psta->sleepq_ac_len > 0) {
2217				pxmitframe->attrib.mdata = 1;
2218				pxmitframe->attrib.eosp = 0;
2219			} else {
2220				pxmitframe->attrib.mdata = 0;
2221				pxmitframe->attrib.eosp = 1;
2222			}
2223		}
2224
2225		pxmitframe->attrib.triggered = 1;
2226		rtl8723au_hal_xmitframe_enqueue(padapter, pxmitframe);
2227	}
2228
2229	if (psta->sleepq_len == 0) {
2230		pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
2231
2232		/* upate BCN for TIM IE */
2233		update_mask = BIT(0);
2234
2235		if (psta->state&WIFI_SLEEP_STATE)
2236			psta->state ^= WIFI_SLEEP_STATE;
2237
2238		if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
2239			psta->expire_to = pstapriv->expire_to;
2240			psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
2241		}
2242
2243		pstapriv->sta_dz_bitmap &= ~CHKBIT(psta->aid);
2244	}
2245
2246	/* spin_unlock_bh(&psta->sleep_q.lock); */
2247	spin_unlock_bh(&pxmitpriv->lock);
2248
2249	/* for BC/MC Frames */
2250	psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
2251	if (!psta_bmc)
2252		return;
2253
2254	if ((pstapriv->sta_dz_bitmap&0xfffe) == 0x0) {
2255		/* no any sta in ps mode */
2256		spin_lock_bh(&pxmitpriv->lock);
2257
2258		phead = get_list_head(&psta_bmc->sleep_q);
2259
2260		list_for_each_safe(plist, ptmp, phead) {
2261			pxmitframe = container_of(plist, struct xmit_frame,
2262						  list);
2263
2264			list_del_init(&pxmitframe->list);
2265
2266			psta_bmc->sleepq_len--;
2267			if (psta_bmc->sleepq_len > 0)
2268				pxmitframe->attrib.mdata = 1;
2269			else
2270				pxmitframe->attrib.mdata = 0;
2271
2272			pxmitframe->attrib.triggered = 1;
2273			rtl8723au_hal_xmitframe_enqueue(padapter, pxmitframe);
2274		}
2275		if (psta_bmc->sleepq_len == 0) {
2276			pstapriv->tim_bitmap &= ~BIT(0);
2277			pstapriv->sta_dz_bitmap &= ~BIT(0);
2278
2279			/* upate BCN for TIM IE */
2280			/* update_BCNTIM(padapter); */
2281			update_mask |= BIT(1);
2282		}
2283
2284		/* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
2285		spin_unlock_bh(&pxmitpriv->lock);
2286	}
2287
2288	if (update_mask)
2289		update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
2290}
2291
2292void xmit_delivery_enabled_frames23a(struct rtw_adapter *padapter,
2293				  struct sta_info *psta)
2294{
2295	u8 wmmps_ac = 0;
2296	struct list_head *plist, *phead, *ptmp;
2297	struct xmit_frame *pxmitframe;
2298	struct sta_priv *pstapriv = &padapter->stapriv;
2299	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2300
2301	/* spin_lock_bh(&psta->sleep_q.lock); */
2302	spin_lock_bh(&pxmitpriv->lock);
2303
2304	phead = get_list_head(&psta->sleep_q);
2305
2306	list_for_each_safe(plist, ptmp, phead) {
2307		pxmitframe = container_of(plist, struct xmit_frame, list);
2308
2309		switch (pxmitframe->attrib.priority) {
2310		case 1:
2311		case 2:
2312			wmmps_ac = psta->uapsd_bk & BIT(1);
2313			break;
2314		case 4:
2315		case 5:
2316			wmmps_ac = psta->uapsd_vi & BIT(1);
2317			break;
2318		case 6:
2319		case 7:
2320			wmmps_ac = psta->uapsd_vo & BIT(1);
2321			break;
2322		case 0:
2323		case 3:
2324		default:
2325			wmmps_ac = psta->uapsd_be & BIT(1);
2326			break;
2327		}
2328
2329		if (!wmmps_ac)
2330			continue;
2331
2332		list_del_init(&pxmitframe->list);
2333
2334		psta->sleepq_len--;
2335		psta->sleepq_ac_len--;
2336
2337		if (psta->sleepq_ac_len > 0) {
2338			pxmitframe->attrib.mdata = 1;
2339			pxmitframe->attrib.eosp = 0;
2340		} else {
2341			pxmitframe->attrib.mdata = 0;
2342			pxmitframe->attrib.eosp = 1;
2343		}
2344
2345		pxmitframe->attrib.triggered = 1;
2346
2347		rtl8723au_hal_xmitframe_enqueue(padapter, pxmitframe);
2348
2349		if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) &&
2350		    (wmmps_ac)) {
2351			pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
2352
2353			/* upate BCN for TIM IE */
2354			update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
2355		}
2356	}
2357	spin_unlock_bh(&pxmitpriv->lock);
2358}
2359
2360#endif
2361
2362void rtw_sctx_init23a(struct submit_ctx *sctx, int timeout_ms)
2363{
2364	sctx->timeout_ms = timeout_ms;
2365	init_completion(&sctx->done);
2366	sctx->status = RTW_SCTX_SUBMITTED;
2367}
2368
2369int rtw_sctx_wait23a(struct submit_ctx *sctx)
2370{
2371	int ret = _FAIL;
2372	unsigned long expire;
2373	int status = 0;
2374
2375	expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) :
2376		 MAX_SCHEDULE_TIMEOUT;
2377	if (!wait_for_completion_timeout(&sctx->done, expire)) {
2378		/* timeout, do something?? */
2379		status = RTW_SCTX_DONE_TIMEOUT;
2380		DBG_8723A("%s timeout\n", __func__);
2381	} else {
2382		status = sctx->status;
2383	}
2384
2385	if (status == RTW_SCTX_DONE_SUCCESS)
2386		ret = _SUCCESS;
2387
2388	return ret;
2389}
2390
2391static bool rtw_sctx_chk_waring_status(int status)
2392{
2393	switch (status) {
2394	case RTW_SCTX_DONE_UNKNOWN:
2395	case RTW_SCTX_DONE_BUF_ALLOC:
2396	case RTW_SCTX_DONE_BUF_FREE:
2397	case RTW_SCTX_DONE_DRV_STOP:
2398	case RTW_SCTX_DONE_DEV_REMOVE:
2399		return true;
2400	default:
2401		return false;
2402	}
2403}
2404
2405void rtw23a_sctx_done_err(struct submit_ctx **sctx, int status)
2406{
2407	if (*sctx) {
2408		if (rtw_sctx_chk_waring_status(status))
2409			DBG_8723A("%s status:%d\n", __func__, status);
2410		(*sctx)->status = status;
2411		complete(&(*sctx)->done);
2412		*sctx = NULL;
2413	}
2414}
2415
2416void rtw_sctx_done23a(struct submit_ctx **sctx)
2417{
2418	rtw23a_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS);
2419}
2420
2421int rtw_ack_tx_wait23a(struct xmit_priv *pxmitpriv, u32 timeout_ms)
2422{
2423	struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
2424
2425	pack_tx_ops->timeout_ms = timeout_ms;
2426	pack_tx_ops->status = RTW_SCTX_SUBMITTED;
2427
2428	return rtw_sctx_wait23a(pack_tx_ops);
2429}
2430
2431void rtw_ack_tx_done23a(struct xmit_priv *pxmitpriv, int status)
2432{
2433	struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
2434
2435	if (pxmitpriv->ack_tx)
2436		rtw23a_sctx_done_err(&pack_tx_ops, status);
2437	else
2438		DBG_8723A("%s ack_tx not set\n", __func__);
2439}
2440