net: wireless: rockchip_wlan: add rtl8723cs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723cs / core / rtw_xmit.c
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  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _RTW_XMIT_C_
21
22 #include <drv_types.h>
23 #include <hal_data.h>
24
25 #if defined(PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
26         #error "Shall be Linux or Windows, but not both!\n"
27 #endif
28
29
30 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
31 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
32
33 static void _init_txservq(struct tx_servq *ptxservq)
34 {
35         _rtw_init_listhead(&ptxservq->tx_pending);
36         _rtw_init_queue(&ptxservq->sta_pending);
37         ptxservq->qcnt = 0;
38 }
39
40
41 void    _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
42 {
43
44
45         _rtw_memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv));
46
47         _rtw_spinlock_init(&psta_xmitpriv->lock);
48
49         /* for(i = 0 ; i < MAX_NUMBLKS; i++) */
50         /*      _init_txservq(&(psta_xmitpriv->blk_q[i])); */
51
52         _init_txservq(&psta_xmitpriv->be_q);
53         _init_txservq(&psta_xmitpriv->bk_q);
54         _init_txservq(&psta_xmitpriv->vi_q);
55         _init_txservq(&psta_xmitpriv->vo_q);
56         _rtw_init_listhead(&psta_xmitpriv->legacy_dz);
57         _rtw_init_listhead(&psta_xmitpriv->apsd);
58
59
60 }
61
62 s32     _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter)
63 {
64         int i;
65         struct xmit_buf *pxmitbuf;
66         struct xmit_frame *pxframe;
67         sint    res = _SUCCESS;
68
69
70         /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
71         /* _rtw_memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); */
72
73         _rtw_spinlock_init(&pxmitpriv->lock);
74         _rtw_spinlock_init(&pxmitpriv->lock_sctx);
75         _rtw_init_sema(&pxmitpriv->xmit_sema, 0);
76         _rtw_init_sema(&pxmitpriv->terminate_xmitthread_sema, 0);
77
78         /*
79         Please insert all the queue initializaiton using _rtw_init_queue below
80         */
81
82         pxmitpriv->adapter = padapter;
83
84         /* for(i = 0 ; i < MAX_NUMBLKS; i++) */
85         /*      _rtw_init_queue(&pxmitpriv->blk_strms[i]); */
86
87         _rtw_init_queue(&pxmitpriv->be_pending);
88         _rtw_init_queue(&pxmitpriv->bk_pending);
89         _rtw_init_queue(&pxmitpriv->vi_pending);
90         _rtw_init_queue(&pxmitpriv->vo_pending);
91         _rtw_init_queue(&pxmitpriv->bm_pending);
92
93         /* _rtw_init_queue(&pxmitpriv->legacy_dz_queue); */
94         /* _rtw_init_queue(&pxmitpriv->apsd_queue); */
95
96         _rtw_init_queue(&pxmitpriv->free_xmit_queue);
97
98         /*
99         Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
100         and initialize free_xmit_frame below.
101         Please also apply  free_txobj to link_up all the xmit_frames...
102         */
103
104         pxmitpriv->pallocated_frame_buf = rtw_zvmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
105
106         if (pxmitpriv->pallocated_frame_buf  == NULL) {
107                 pxmitpriv->pxmit_frame_buf = NULL;
108                 res = _FAIL;
109                 goto exit;
110         }
111         pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_frame_buf), 4);
112         /* pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - */
113         /*                                              ((SIZE_PTR) (pxmitpriv->pallocated_frame_buf) &3); */
114
115         pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
116
117         for (i = 0; i < NR_XMITFRAME; i++) {
118                 _rtw_init_listhead(&(pxframe->list));
119
120                 pxframe->padapter = padapter;
121                 pxframe->frame_tag = NULL_FRAMETAG;
122
123                 pxframe->pkt = NULL;
124
125                 pxframe->buf_addr = NULL;
126                 pxframe->pxmitbuf = NULL;
127
128                 rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue));
129
130                 pxframe++;
131         }
132
133         pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
134
135         pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
136
137
138         /* init xmit_buf */
139         _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue);
140         _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue);
141
142         pxmitpriv->pallocated_xmitbuf = rtw_zvmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
143
144         if (pxmitpriv->pallocated_xmitbuf  == NULL) {
145                 res = _FAIL;
146                 goto exit;
147         }
148
149         pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmitbuf), 4);
150         /* pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - */
151         /*                                              ((SIZE_PTR) (pxmitpriv->pallocated_xmitbuf) &3); */
152
153         pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
154
155         for (i = 0; i < NR_XMITBUFF; i++) {
156                 _rtw_init_listhead(&pxmitbuf->list);
157
158                 pxmitbuf->priv_data = NULL;
159                 pxmitbuf->padapter = padapter;
160                 pxmitbuf->buf_tag = XMITBUF_DATA;
161
162                 /* Tx buf allocation may fail sometimes, so sleep and retry. */
163                 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
164                 if (res == _FAIL) {
165                         rtw_msleep_os(10);
166                         res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
167                         if (res == _FAIL)
168                                 goto exit;
169                 }
170
171 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
172                 pxmitbuf->phead = pxmitbuf->pbuf;
173                 pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMITBUF_SZ;
174                 pxmitbuf->len = 0;
175                 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
176 #endif
177
178                 pxmitbuf->flags = XMIT_VO_QUEUE;
179
180                 rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue));
181 #ifdef DBG_XMIT_BUF
182                 pxmitbuf->no = i;
183 #endif
184
185                 pxmitbuf++;
186
187         }
188
189         pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
190
191         /* init xframe_ext queue,  the same count as extbuf */
192         _rtw_init_queue(&pxmitpriv->free_xframe_ext_queue);
193
194         pxmitpriv->xframe_ext_alloc_addr = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4);
195
196         if (pxmitpriv->xframe_ext_alloc_addr  == NULL) {
197                 pxmitpriv->xframe_ext = NULL;
198                 res = _FAIL;
199                 goto exit;
200         }
201         pxmitpriv->xframe_ext = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->xframe_ext_alloc_addr), 4);
202         pxframe = (struct xmit_frame *)pxmitpriv->xframe_ext;
203
204         for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
205                 _rtw_init_listhead(&(pxframe->list));
206
207                 pxframe->padapter = padapter;
208                 pxframe->frame_tag = NULL_FRAMETAG;
209
210                 pxframe->pkt = NULL;
211
212                 pxframe->buf_addr = NULL;
213                 pxframe->pxmitbuf = NULL;
214
215                 pxframe->ext_tag = 1;
216
217                 rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xframe_ext_queue.queue));
218
219                 pxframe++;
220         }
221         pxmitpriv->free_xframe_ext_cnt = NR_XMIT_EXTBUFF;
222
223         /* Init xmit extension buff */
224         _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
225
226         pxmitpriv->pallocated_xmit_extbuf = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4);
227
228         if (pxmitpriv->pallocated_xmit_extbuf  == NULL) {
229                 res = _FAIL;
230                 goto exit;
231         }
232
233         pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmit_extbuf), 4);
234
235         pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
236
237         for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
238                 _rtw_init_listhead(&pxmitbuf->list);
239
240                 pxmitbuf->priv_data = NULL;
241                 pxmitbuf->padapter = padapter;
242                 pxmitbuf->buf_tag = XMITBUF_MGNT;
243
244                 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ, _TRUE);
245                 if (res == _FAIL) {
246                         res = _FAIL;
247                         goto exit;
248                 }
249
250 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
251                 pxmitbuf->phead = pxmitbuf->pbuf;
252                 pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMIT_EXTBUF_SZ;
253                 pxmitbuf->len = 0;
254                 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
255 #endif
256
257                 rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue));
258 #ifdef DBG_XMIT_BUF_EXT
259                 pxmitbuf->no = i;
260 #endif
261                 pxmitbuf++;
262
263         }
264
265         pxmitpriv->free_xmit_extbuf_cnt = NR_XMIT_EXTBUFF;
266
267         for (i = 0; i < CMDBUF_MAX; i++) {
268                 pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i];
269                 if (pxmitbuf) {
270                         _rtw_init_listhead(&pxmitbuf->list);
271
272                         pxmitbuf->priv_data = NULL;
273                         pxmitbuf->padapter = padapter;
274                         pxmitbuf->buf_tag = XMITBUF_CMD;
275
276                         res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ, _TRUE);
277                         if (res == _FAIL) {
278                                 res = _FAIL;
279                                 goto exit;
280                         }
281
282 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
283                         pxmitbuf->phead = pxmitbuf->pbuf;
284                         pxmitbuf->pend = pxmitbuf->pbuf + MAX_CMDBUF_SZ;
285                         pxmitbuf->len = 0;
286                         pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
287 #endif
288                         pxmitbuf->alloc_sz = MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ;
289                 }
290         }
291
292         rtw_alloc_hwxmits(padapter);
293         rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
294
295         for (i = 0; i < 4; i++)
296                 pxmitpriv->wmm_para_seq[i] = i;
297
298 #ifdef CONFIG_USB_HCI
299         pxmitpriv->txirp_cnt = 1;
300
301         _rtw_init_sema(&(pxmitpriv->tx_retevt), 0);
302
303         /* per AC pending irp */
304         pxmitpriv->beq_cnt = 0;
305         pxmitpriv->bkq_cnt = 0;
306         pxmitpriv->viq_cnt = 0;
307         pxmitpriv->voq_cnt = 0;
308 #endif
309
310
311 #ifdef CONFIG_XMIT_ACK
312         pxmitpriv->ack_tx = _FALSE;
313         _rtw_mutex_init(&pxmitpriv->ack_tx_mutex);
314         rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0);
315 #endif
316
317 #ifdef CONFIG_TX_AMSDU
318         _init_timer(&(pxmitpriv->amsdu_vo_timer), padapter->pnetdev,
319                 rtw_amsdu_vo_timeout_handler, padapter);
320         pxmitpriv->amsdu_vo_timeout = RTW_AMSDU_TIMER_UNSET;
321
322         _init_timer(&(pxmitpriv->amsdu_vi_timer), padapter->pnetdev,
323                 rtw_amsdu_vi_timeout_handler, padapter);
324         pxmitpriv->amsdu_vi_timeout = RTW_AMSDU_TIMER_UNSET;
325
326         _init_timer(&(pxmitpriv->amsdu_be_timer), padapter->pnetdev,
327                 rtw_amsdu_be_timeout_handler, padapter);
328         pxmitpriv->amsdu_be_timeout = RTW_AMSDU_TIMER_UNSET;
329
330         _init_timer(&(pxmitpriv->amsdu_bk_timer), padapter->pnetdev,
331                 rtw_amsdu_bk_timeout_handler, padapter);
332         pxmitpriv->amsdu_bk_timeout = RTW_AMSDU_TIMER_UNSET;
333
334         pxmitpriv->amsdu_debug_set_timer = 0;
335         pxmitpriv->amsdu_debug_timeout = 0;
336         pxmitpriv->amsdu_debug_coalesce_one = 0;
337         pxmitpriv->amsdu_debug_coalesce_two = 0;
338 #endif
339         rtw_hal_init_xmit_priv(padapter);
340
341 exit:
342
343
344         return res;
345 }
346
347 void  rtw_mfree_xmit_priv_lock(struct xmit_priv *pxmitpriv);
348 void  rtw_mfree_xmit_priv_lock(struct xmit_priv *pxmitpriv)
349 {
350         _rtw_spinlock_free(&pxmitpriv->lock);
351         _rtw_free_sema(&pxmitpriv->xmit_sema);
352         _rtw_free_sema(&pxmitpriv->terminate_xmitthread_sema);
353
354         _rtw_spinlock_free(&pxmitpriv->be_pending.lock);
355         _rtw_spinlock_free(&pxmitpriv->bk_pending.lock);
356         _rtw_spinlock_free(&pxmitpriv->vi_pending.lock);
357         _rtw_spinlock_free(&pxmitpriv->vo_pending.lock);
358         _rtw_spinlock_free(&pxmitpriv->bm_pending.lock);
359
360         /* _rtw_spinlock_free(&pxmitpriv->legacy_dz_queue.lock); */
361         /* _rtw_spinlock_free(&pxmitpriv->apsd_queue.lock); */
362
363         _rtw_spinlock_free(&pxmitpriv->free_xmit_queue.lock);
364         _rtw_spinlock_free(&pxmitpriv->free_xmitbuf_queue.lock);
365         _rtw_spinlock_free(&pxmitpriv->pending_xmitbuf_queue.lock);
366 }
367
368
369 void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv)
370 {
371         int i;
372         _adapter *padapter = pxmitpriv->adapter;
373         struct xmit_frame       *pxmitframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
374         struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
375
376
377         rtw_hal_free_xmit_priv(padapter);
378
379         rtw_mfree_xmit_priv_lock(pxmitpriv);
380
381         if (pxmitpriv->pxmit_frame_buf == NULL)
382                 goto out;
383
384         for (i = 0; i < NR_XMITFRAME; i++) {
385                 rtw_os_xmit_complete(padapter, pxmitframe);
386
387                 pxmitframe++;
388         }
389
390         for (i = 0; i < NR_XMITBUFF; i++) {
391                 rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
392
393                 pxmitbuf++;
394         }
395
396         if (pxmitpriv->pallocated_frame_buf)
397                 rtw_vmfree(pxmitpriv->pallocated_frame_buf, NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
398
399
400         if (pxmitpriv->pallocated_xmitbuf)
401                 rtw_vmfree(pxmitpriv->pallocated_xmitbuf, NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
402
403         /* free xframe_ext queue,  the same count as extbuf */
404         if ((pxmitframe = (struct xmit_frame *)pxmitpriv->xframe_ext)) {
405                 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
406                         rtw_os_xmit_complete(padapter, pxmitframe);
407                         pxmitframe++;
408                 }
409         }
410         if (pxmitpriv->xframe_ext_alloc_addr)
411                 rtw_vmfree(pxmitpriv->xframe_ext_alloc_addr, NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4);
412         _rtw_spinlock_free(&pxmitpriv->free_xframe_ext_queue.lock);
413
414         /* free xmit extension buff */
415         _rtw_spinlock_free(&pxmitpriv->free_xmit_extbuf_queue.lock);
416
417         pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
418         for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
419                 rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
420
421                 pxmitbuf++;
422         }
423
424         if (pxmitpriv->pallocated_xmit_extbuf)
425                 rtw_vmfree(pxmitpriv->pallocated_xmit_extbuf, NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4);
426
427         for (i = 0; i < CMDBUF_MAX; i++) {
428                 pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i];
429                 if (pxmitbuf != NULL)
430                         rtw_os_xmit_resource_free(padapter, pxmitbuf, MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ , _TRUE);
431         }
432
433         rtw_free_hwxmits(padapter);
434
435 #ifdef CONFIG_XMIT_ACK
436         _rtw_mutex_free(&pxmitpriv->ack_tx_mutex);
437 #endif
438
439 out:
440         return;
441 }
442
443 u8 rtw_get_tx_bw_mode(_adapter *adapter, struct sta_info *sta)
444 {
445         u8 bw;
446
447         bw = sta->bw_mode;
448         if (MLME_STATE(adapter) & WIFI_ASOC_STATE) {
449                 if (adapter->mlmeextpriv.cur_channel <= 14)
450                         bw = rtw_min(bw, ADAPTER_TX_BW_2G(adapter));
451                 else
452                         bw = rtw_min(bw, ADAPTER_TX_BW_5G(adapter));
453         }
454
455         return bw;
456 }
457
458 void rtw_get_adapter_tx_rate_bmp_by_bw(_adapter *adapter, u8 bw, u16 *r_bmp_cck_ofdm, u32 *r_bmp_ht, u32 *r_bmp_vht)
459 {
460         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
461         struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
462         struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
463         u8 fix_bw = 0xFF;
464         u16 bmp_cck_ofdm = 0;
465         u32 bmp_ht = 0;
466         u32 bmp_vht = 0;
467         int i;
468
469         if (adapter->fix_rate != 0xFF && adapter->fix_bw != 0xFF)
470                 fix_bw = adapter->fix_bw;
471
472         /* TODO: adapter->fix_rate */
473
474         for (i = 0; i < macid_ctl->num; i++) {
475                 if (!rtw_macid_is_used(macid_ctl, i))
476                         continue;
477                 if (rtw_macid_get_if_g(macid_ctl, i) != adapter->iface_id)
478                         continue;
479
480                 if (bw == CHANNEL_WIDTH_20) /* CCK, OFDM always 20MHz */
481                         bmp_cck_ofdm |= macid_ctl->rate_bmp0[i] & 0x00000FFF;
482
483                 /* bypass mismatch bandwidth for HT, VHT */
484                 if ((fix_bw != 0xFF && fix_bw != bw) || (fix_bw == 0xFF && macid_ctl->bw[i] != bw))
485                         continue;
486
487                 if (macid_ctl->vht_en[i])
488                         bmp_vht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
489                 else
490                         bmp_ht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
491         }
492
493         /* TODO: mlmeext->tx_rate*/
494
495 exit:
496         if (r_bmp_cck_ofdm)
497                 *r_bmp_cck_ofdm = bmp_cck_ofdm;
498         if (r_bmp_ht)
499                 *r_bmp_ht = bmp_ht;
500         if (r_bmp_vht)
501                 *r_bmp_vht = bmp_vht;
502 }
503
504 void rtw_get_shared_macid_tx_rate_bmp_by_bw(struct dvobj_priv *dvobj, u8 bw, u16 *r_bmp_cck_ofdm, u32 *r_bmp_ht, u32 *r_bmp_vht)
505 {
506         struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
507         u16 bmp_cck_ofdm = 0;
508         u32 bmp_ht = 0;
509         u32 bmp_vht = 0;
510         int i;
511
512         for (i = 0; i < macid_ctl->num; i++) {
513                 if (!rtw_macid_is_used(macid_ctl, i))
514                         continue;
515                 if (rtw_macid_get_if_g(macid_ctl, i) != -1)
516                         continue;
517
518                 if (bw == CHANNEL_WIDTH_20) /* CCK, OFDM always 20MHz */
519                         bmp_cck_ofdm |= macid_ctl->rate_bmp0[i] & 0x00000FFF;
520
521                 /* bypass mismatch bandwidth for HT, VHT */
522                 if (macid_ctl->bw[i] != bw)
523                         continue;
524
525                 if (macid_ctl->vht_en[i])
526                         bmp_vht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
527                 else
528                         bmp_ht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
529         }
530
531         if (r_bmp_cck_ofdm)
532                 *r_bmp_cck_ofdm = bmp_cck_ofdm;
533         if (r_bmp_ht)
534                 *r_bmp_ht = bmp_ht;
535         if (r_bmp_vht)
536                 *r_bmp_vht = bmp_vht;
537 }
538
539 void rtw_update_tx_rate_bmp(struct dvobj_priv *dvobj)
540 {
541         struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
542         _adapter *adapter = dvobj_get_primary_adapter(dvobj);
543         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
544         u8 bw;
545         u16 bmp_cck_ofdm, tmp_cck_ofdm;
546         u32 bmp_ht, tmp_ht, ori_bmp_ht[2];
547         u8 ori_highest_ht_rate_bw_bmp;
548         u32 bmp_vht, tmp_vht, ori_bmp_vht[4];
549         u8 ori_highest_vht_rate_bw_bmp;
550         int i;
551
552         /* backup the original ht & vht highest bw bmp */
553         ori_highest_ht_rate_bw_bmp = rf_ctl->highest_ht_rate_bw_bmp;
554         ori_highest_vht_rate_bw_bmp = rf_ctl->highest_vht_rate_bw_bmp;
555
556         for (bw = CHANNEL_WIDTH_20; bw <= CHANNEL_WIDTH_160; bw++) {
557                 /* backup the original ht & vht bmp */
558                 if (bw <= CHANNEL_WIDTH_40)
559                         ori_bmp_ht[bw] = rf_ctl->rate_bmp_ht_by_bw[bw];
560                 if (bw <= CHANNEL_WIDTH_160)
561                         ori_bmp_vht[bw] = rf_ctl->rate_bmp_vht_by_bw[bw];
562
563                 bmp_cck_ofdm = bmp_ht = bmp_vht = 0;
564                 if (hal_is_bw_support(dvobj_get_primary_adapter(dvobj), bw)) {
565                         for (i = 0; i < dvobj->iface_nums; i++) {
566                                 if (!dvobj->padapters[i])
567                                         continue;
568                                 rtw_get_adapter_tx_rate_bmp_by_bw(dvobj->padapters[i], bw, &tmp_cck_ofdm, &tmp_ht, &tmp_vht);
569                                 bmp_cck_ofdm |= tmp_cck_ofdm;
570                                 bmp_ht |= tmp_ht;
571                                 bmp_vht |= tmp_vht;
572                         }
573                         rtw_get_shared_macid_tx_rate_bmp_by_bw(dvobj, bw, &tmp_cck_ofdm, &tmp_ht, &tmp_vht);
574                         bmp_cck_ofdm |= tmp_cck_ofdm;
575                         bmp_ht |= tmp_ht;
576                         bmp_vht |= tmp_vht;
577                 }
578                 if (bw == CHANNEL_WIDTH_20)
579                         rf_ctl->rate_bmp_cck_ofdm = bmp_cck_ofdm;
580                 if (bw <= CHANNEL_WIDTH_40)
581                         rf_ctl->rate_bmp_ht_by_bw[bw] = bmp_ht;
582                 if (bw <= CHANNEL_WIDTH_160)
583                         rf_ctl->rate_bmp_vht_by_bw[bw] = bmp_vht;
584         }
585
586 #ifndef DBG_HIGHEST_RATE_BMP_BW_CHANGE
587 #define DBG_HIGHEST_RATE_BMP_BW_CHANGE 0
588 #endif
589
590         {
591                 u8 highest_rate_bw;
592                 u8 highest_rate_bw_bmp;
593                 u8 update_ht_rs = _FALSE;
594                 u8 update_vht_rs = _FALSE;
595
596                 highest_rate_bw_bmp = BW_CAP_20M;
597                 highest_rate_bw = CHANNEL_WIDTH_20;
598                 for (bw = CHANNEL_WIDTH_20; bw <= CHANNEL_WIDTH_40; bw++) {
599                         if (rf_ctl->rate_bmp_ht_by_bw[highest_rate_bw] < rf_ctl->rate_bmp_ht_by_bw[bw]) {
600                                 highest_rate_bw_bmp = ch_width_to_bw_cap(bw);
601                                 highest_rate_bw = bw;
602                         } else if (rf_ctl->rate_bmp_ht_by_bw[highest_rate_bw] == rf_ctl->rate_bmp_ht_by_bw[bw])
603                                 highest_rate_bw_bmp |= ch_width_to_bw_cap(bw);
604                 }
605                 rf_ctl->highest_ht_rate_bw_bmp = highest_rate_bw_bmp;
606
607                 if (ori_highest_ht_rate_bw_bmp != rf_ctl->highest_ht_rate_bw_bmp
608                         || largest_bit(ori_bmp_ht[highest_rate_bw]) != largest_bit(rf_ctl->rate_bmp_ht_by_bw[highest_rate_bw])
609                 ) {
610                         if (DBG_HIGHEST_RATE_BMP_BW_CHANGE) {
611                                 RTW_INFO("highest_ht_rate_bw_bmp:0x%02x=>0x%02x\n", ori_highest_ht_rate_bw_bmp, rf_ctl->highest_ht_rate_bw_bmp);
612                                 RTW_INFO("rate_bmp_ht_by_bw[%u]:0x%08x=>0x%08x\n", highest_rate_bw, ori_bmp_ht[highest_rate_bw], rf_ctl->rate_bmp_ht_by_bw[highest_rate_bw]);
613                         }
614                         update_ht_rs = _TRUE;
615                 }
616
617                 highest_rate_bw_bmp = BW_CAP_20M;
618                 highest_rate_bw = CHANNEL_WIDTH_20;
619                 for (bw = CHANNEL_WIDTH_20; bw <= CHANNEL_WIDTH_160; bw++) {
620                         if (rf_ctl->rate_bmp_vht_by_bw[highest_rate_bw] < rf_ctl->rate_bmp_vht_by_bw[bw]) {
621                                 highest_rate_bw_bmp = ch_width_to_bw_cap(bw);
622                                 highest_rate_bw = bw;
623                         } else if (rf_ctl->rate_bmp_vht_by_bw[highest_rate_bw] == rf_ctl->rate_bmp_vht_by_bw[bw])
624                                 highest_rate_bw_bmp |= ch_width_to_bw_cap(bw);
625                 }
626                 rf_ctl->highest_vht_rate_bw_bmp = highest_rate_bw_bmp;
627
628                 if (ori_highest_vht_rate_bw_bmp != rf_ctl->highest_vht_rate_bw_bmp
629                         || largest_bit(ori_bmp_vht[highest_rate_bw]) != largest_bit(rf_ctl->rate_bmp_vht_by_bw[highest_rate_bw])
630                 ) {
631                         if (DBG_HIGHEST_RATE_BMP_BW_CHANGE) {
632                                 RTW_INFO("highest_vht_rate_bw_bmp:0x%02x=>0x%02x\n", ori_highest_vht_rate_bw_bmp, rf_ctl->highest_vht_rate_bw_bmp);
633                                 RTW_INFO("rate_bmp_vht_by_bw[%u]:0x%08x=>0x%08x\n", highest_rate_bw, ori_bmp_vht[highest_rate_bw], rf_ctl->rate_bmp_vht_by_bw[highest_rate_bw]);
634                         }
635                         update_vht_rs = _TRUE;
636                 }
637
638                 /* TODO: per rfpath and rate section handling? */
639                 if (update_ht_rs == _TRUE || update_vht_rs == _TRUE)
640                         rtw_hal_set_tx_power_level(dvobj_get_primary_adapter(dvobj), hal_data->current_channel);
641         }
642 }
643
644 inline u16 rtw_get_tx_rate_bmp_cck_ofdm(struct dvobj_priv *dvobj)
645 {
646         struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
647
648         return rf_ctl->rate_bmp_cck_ofdm;
649 }
650
651 inline u32 rtw_get_tx_rate_bmp_ht_by_bw(struct dvobj_priv *dvobj, u8 bw)
652 {
653         struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
654
655         return rf_ctl->rate_bmp_ht_by_bw[bw];
656 }
657
658 inline u32 rtw_get_tx_rate_bmp_vht_by_bw(struct dvobj_priv *dvobj, u8 bw)
659 {
660         struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
661
662         return rf_ctl->rate_bmp_vht_by_bw[bw];
663 }
664
665 u8 rtw_get_tx_bw_bmp_of_ht_rate(struct dvobj_priv *dvobj, u8 rate, u8 max_bw)
666 {
667         struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
668         u8 bw;
669         u8 bw_bmp = 0;
670         u32 rate_bmp;
671
672         if (!IS_HT_RATE(rate)) {
673                 rtw_warn_on(1);
674                 goto exit;
675         }
676
677         rate_bmp = 1 << (rate - MGN_MCS0);
678
679         if (max_bw > CHANNEL_WIDTH_40)
680                 max_bw = CHANNEL_WIDTH_40;
681
682         for (bw = CHANNEL_WIDTH_20; bw <= max_bw; bw++) {
683                 /* RA may use lower rate for retry */
684                 if (rf_ctl->rate_bmp_ht_by_bw[bw] >= rate_bmp)
685                         bw_bmp |= ch_width_to_bw_cap(bw);
686         }
687
688 exit:
689         return bw_bmp;
690 }
691
692 u8 rtw_get_tx_bw_bmp_of_vht_rate(struct dvobj_priv *dvobj, u8 rate, u8 max_bw)
693 {
694         struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
695         u8 bw;
696         u8 bw_bmp = 0;
697         u32 rate_bmp;
698
699         if (!IS_VHT_RATE(rate)) {
700                 rtw_warn_on(1);
701                 goto exit;
702         }
703
704         rate_bmp = 1 << (rate - MGN_VHT1SS_MCS0);
705
706         if (max_bw > CHANNEL_WIDTH_160)
707                 max_bw = CHANNEL_WIDTH_160;
708
709         for (bw = CHANNEL_WIDTH_20; bw <= max_bw; bw++) {
710                 /* RA may use lower rate for retry */
711                 if (rf_ctl->rate_bmp_vht_by_bw[bw] >= rate_bmp)
712                         bw_bmp |= ch_width_to_bw_cap(bw);
713         }
714
715 exit:
716         return bw_bmp;
717 }
718
719 u8 query_ra_short_GI(struct sta_info *psta, u8 bw)
720 {
721         u8      sgi = _FALSE, sgi_20m = _FALSE, sgi_40m = _FALSE, sgi_80m = _FALSE;
722
723 #ifdef CONFIG_80211N_HT
724 #ifdef CONFIG_80211AC_VHT
725         if (psta->vhtpriv.vht_option)
726                 sgi_80m = psta->vhtpriv.sgi_80m;
727 #endif
728         sgi_20m = psta->htpriv.sgi_20m;
729         sgi_40m = psta->htpriv.sgi_40m;
730 #endif
731
732         switch (bw) {
733         case CHANNEL_WIDTH_80:
734                 sgi = sgi_80m;
735                 break;
736         case CHANNEL_WIDTH_40:
737                 sgi = sgi_40m;
738                 break;
739         case CHANNEL_WIDTH_20:
740         default:
741                 sgi = sgi_20m;
742                 break;
743         }
744
745         return sgi;
746 }
747
748 static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe)
749 {
750         u32     sz;
751         struct pkt_attrib       *pattrib = &pxmitframe->attrib;
752         /* struct sta_info      *psta = pattrib->psta; */
753         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
754         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
755
756         /*
757                 if(pattrib->psta)
758                 {
759                         psta = pattrib->psta;
760                 }
761                 else
762                 {
763                         RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
764                         psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] );
765                 }
766
767                 if(psta==NULL)
768                 {
769                         RTW_INFO("%s, psta==NUL\n", __func__);
770                         return;
771                 }
772
773                 if(!(psta->state &_FW_LINKED))
774                 {
775                         RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
776                         return;
777                 }
778         */
779
780         if (pattrib->nr_frags != 1)
781                 sz = padapter->xmitpriv.frag_len;
782         else /* no frag */
783                 sz = pattrib->last_txcmdsz;
784
785         /* (1) RTS_Threshold is compared to the MPDU, not MSDU. */
786         /* (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame. */
787         /*              Other fragments are protected by previous fragment. */
788         /*              So we only need to check the length of first fragment. */
789         if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N  || padapter->registrypriv.wifi_spec) {
790                 if (sz > padapter->registrypriv.rts_thresh)
791                         pattrib->vcs_mode = RTS_CTS;
792                 else {
793                         if (pattrib->rtsen)
794                                 pattrib->vcs_mode = RTS_CTS;
795                         else if (pattrib->cts2self)
796                                 pattrib->vcs_mode = CTS_TO_SELF;
797                         else
798                                 pattrib->vcs_mode = NONE_VCS;
799                 }
800         } else {
801                 while (_TRUE) {
802 #if 0 /* Todo */
803                         /* check IOT action */
804                         if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) {
805                                 pattrib->vcs_mode = CTS_TO_SELF;
806                                 pattrib->rts_rate = MGN_24M;
807                                 break;
808                         } else if (pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS | HT_IOT_ACT_PURE_N_MODE)) {
809                                 pattrib->vcs_mode = RTS_CTS;
810                                 pattrib->rts_rate = MGN_24M;
811                                 break;
812                         }
813 #endif
814
815                         /* IOT action */
816                         if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && (pattrib->ampdu_en == _TRUE) &&
817                             (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
818                                 pattrib->vcs_mode = CTS_TO_SELF;
819                                 break;
820                         }
821
822
823                         /* check ERP protection */
824                         if (pattrib->rtsen || pattrib->cts2self) {
825                                 if (pattrib->rtsen)
826                                         pattrib->vcs_mode = RTS_CTS;
827                                 else if (pattrib->cts2self)
828                                         pattrib->vcs_mode = CTS_TO_SELF;
829
830                                 break;
831                         }
832
833                         /* check HT op mode */
834                         if (pattrib->ht_en) {
835                                 u8 HTOpMode = pmlmeinfo->HT_protection;
836                                 if ((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) ||
837                                     (!pmlmeext->cur_bwmode && HTOpMode == 3)) {
838                                         pattrib->vcs_mode = RTS_CTS;
839                                         break;
840                                 }
841                         }
842
843                         /* check rts */
844                         if (sz > padapter->registrypriv.rts_thresh) {
845                                 pattrib->vcs_mode = RTS_CTS;
846                                 break;
847                         }
848
849                         /* to do list: check MIMO power save condition. */
850
851                         /* check AMPDU aggregation for TXOP */
852                         if ((pattrib->ampdu_en == _TRUE) && (!IS_HARDWARE_TYPE_8812(padapter))) {
853                                 pattrib->vcs_mode = RTS_CTS;
854                                 break;
855                         }
856
857                         pattrib->vcs_mode = NONE_VCS;
858                         break;
859                 }
860         }
861
862         /* for debug : force driver control vrtl_carrier_sense. */
863         if (padapter->driver_vcs_en == 1) {
864                 /* u8 driver_vcs_en; */ /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */
865                 /* u8 driver_vcs_type; */ /* force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1. */
866                 pattrib->vcs_mode = padapter->driver_vcs_type;
867         }
868
869 }
870
871 static void update_attrib_phy_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
872 {
873         struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
874         u8 bw;
875
876         pattrib->rtsen = psta->rtsen;
877         pattrib->cts2self = psta->cts2self;
878
879         pattrib->mdata = 0;
880         pattrib->eosp = 0;
881         pattrib->triggered = 0;
882         pattrib->ampdu_spacing = 0;
883
884         /* qos_en, ht_en, init rate, ,bw, ch_offset, sgi */
885         pattrib->qos_en = psta->qos_option;
886
887         pattrib->raid = psta->raid;
888
889         bw = rtw_get_tx_bw_mode(padapter, psta);
890         pattrib->bwmode = rtw_min(bw, mlmeext->cur_bwmode);
891         pattrib->sgi = query_ra_short_GI(psta, pattrib->bwmode);
892
893         pattrib->ldpc = psta->ldpc;
894         pattrib->stbc = psta->stbc;
895
896 #ifdef CONFIG_80211N_HT
897         pattrib->ht_en = psta->htpriv.ht_option;
898         pattrib->ch_offset = psta->htpriv.ch_offset;
899         pattrib->ampdu_en = _FALSE;
900
901         if (padapter->driver_ampdu_spacing != 0xFF) /* driver control AMPDU Density for peer sta's rx */
902                 pattrib->ampdu_spacing = padapter->driver_ampdu_spacing;
903         else
904                 pattrib->ampdu_spacing = psta->htpriv.rx_ampdu_min_spacing;
905 #endif /* CONFIG_80211N_HT */
906         /* if(pattrib->ht_en && psta->htpriv.ampdu_enable) */
907         /* { */
908         /*      if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) */
909         /*              pattrib->ampdu_en = _TRUE; */
910         /* }     */
911
912 #ifdef CONFIG_TDLS
913         if (pattrib->direct_link == _TRUE) {
914                 psta = pattrib->ptdls_sta;
915
916                 pattrib->raid = psta->raid;
917 #ifdef CONFIG_80211N_HT
918                 pattrib->bwmode = rtw_get_tx_bw_mode(padapter, psta);
919                 pattrib->ht_en = psta->htpriv.ht_option;
920                 pattrib->ch_offset = psta->htpriv.ch_offset;
921                 pattrib->sgi = query_ra_short_GI(psta, pattrib->bwmode);
922 #endif /* CONFIG_80211N_HT */
923         }
924 #endif /* CONFIG_TDLS */
925
926         pattrib->retry_ctrl = _FALSE;
927
928 #ifdef CONFIG_AUTO_AP_MODE
929         if (psta->isrc && psta->pid > 0)
930                 pattrib->pctrl = _TRUE;
931 #endif
932
933 }
934
935 static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
936 {
937         sint res = _SUCCESS;
938         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
939         struct security_priv *psecuritypriv = &padapter->securitypriv;
940         sint bmcast = IS_MCAST(pattrib->ra);
941
942         _rtw_memset(pattrib->dot118021x_UncstKey.skey,  0, 16);
943         _rtw_memset(pattrib->dot11tkiptxmickey.skey,  0, 16);
944         pattrib->mac_id = psta->mac_id;
945
946         if (psta->ieee8021x_blocked == _TRUE) {
947
948                 pattrib->encrypt = 0;
949
950                 if ((pattrib->ether_type != 0x888e) && (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _FALSE)) {
951 #ifdef DBG_TX_DROP_FRAME
952                         RTW_INFO("DBG_TX_DROP_FRAME %s psta->ieee8021x_blocked == _TRUE,  pattrib->ether_type(%04x) != 0x888e\n", __FUNCTION__, pattrib->ether_type);
953 #endif
954                         res = _FAIL;
955                         goto exit;
956                 }
957         } else {
958                 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
959
960 #ifdef CONFIG_WAPI_SUPPORT
961                 if (pattrib->ether_type == 0x88B4)
962                         pattrib->encrypt = _NO_PRIVACY_;
963 #endif
964
965                 switch (psecuritypriv->dot11AuthAlgrthm) {
966                 case dot11AuthAlgrthm_Open:
967                 case dot11AuthAlgrthm_Shared:
968                 case dot11AuthAlgrthm_Auto:
969                         pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
970                         break;
971                 case dot11AuthAlgrthm_8021X:
972                         if (bmcast)
973                                 pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
974                         else
975                                 pattrib->key_idx = 0;
976                         break;
977                 default:
978                         pattrib->key_idx = 0;
979                         break;
980                 }
981
982                 /* For WPS 1.0 WEP, driver should not encrypt EAPOL Packet for WPS handshake. */
983                 if (((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) && (pattrib->ether_type == 0x888e))
984                         pattrib->encrypt = _NO_PRIVACY_;
985
986         }
987
988 #ifdef CONFIG_TDLS
989         if (pattrib->direct_link == _TRUE) {
990                 if (pattrib->encrypt > 0)
991                         pattrib->encrypt = _AES_;
992         }
993 #endif
994
995         switch (pattrib->encrypt) {
996         case _WEP40_:
997         case _WEP104_:
998                 pattrib->iv_len = 4;
999                 pattrib->icv_len = 4;
1000                 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1001                 break;
1002
1003         case _TKIP_:
1004                 pattrib->iv_len = 8;
1005                 pattrib->icv_len = 4;
1006
1007                 if (psecuritypriv->busetkipkey == _FAIL) {
1008 #ifdef DBG_TX_DROP_FRAME
1009                         RTW_INFO("DBG_TX_DROP_FRAME %s psecuritypriv->busetkipkey(%d)==_FAIL drop packet\n", __FUNCTION__, psecuritypriv->busetkipkey);
1010 #endif
1011                         res = _FAIL;
1012                         goto exit;
1013                 }
1014
1015                 if (bmcast)
1016                         TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1017                 else
1018                         TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
1019
1020
1021                 _rtw_memcpy(pattrib->dot11tkiptxmickey.skey, psta->dot11tkiptxmickey.skey, 16);
1022
1023                 break;
1024
1025         case _AES_:
1026
1027                 pattrib->iv_len = 8;
1028                 pattrib->icv_len = 8;
1029
1030                 if (bmcast)
1031                         AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1032                 else
1033                         AES_IV(pattrib->iv, psta->dot11txpn, 0);
1034
1035                 break;
1036
1037 #ifdef CONFIG_WAPI_SUPPORT
1038         case _SMS4_:
1039                 pattrib->iv_len = 18;
1040                 pattrib->icv_len = 16;
1041                 rtw_wapi_get_iv(padapter, pattrib->ra, pattrib->iv);
1042                 break;
1043 #endif
1044         default:
1045                 pattrib->iv_len = 0;
1046                 pattrib->icv_len = 0;
1047                 break;
1048         }
1049
1050         if (pattrib->encrypt > 0)
1051                 _rtw_memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16);
1052
1053
1054         if (pattrib->encrypt &&
1055             ((padapter->securitypriv.sw_encrypt == _TRUE) || (psecuritypriv->hw_decrypted == _FALSE))) {
1056                 pattrib->bswenc = _TRUE;
1057         } else {
1058                 pattrib->bswenc = _FALSE;
1059         }
1060
1061 #if defined(CONFIG_CONCURRENT_MODE)
1062         pattrib->bmc_camid = padapter->securitypriv.dot118021x_bmc_cam_id;
1063 #endif
1064
1065         if (pattrib->encrypt && bmcast && _rtw_camctl_chk_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
1066                 pattrib->bswenc = _TRUE;
1067
1068 #ifdef CONFIG_WAPI_SUPPORT
1069         if (pattrib->encrypt == _SMS4_)
1070                 pattrib->bswenc = _FALSE;
1071 #endif
1072
1073 exit:
1074
1075         return res;
1076
1077 }
1078
1079 u8      qos_acm(u8 acm_mask, u8 priority)
1080 {
1081         u8      change_priority = priority;
1082
1083         switch (priority) {
1084         case 0:
1085         case 3:
1086                 if (acm_mask & BIT(1))
1087                         change_priority = 1;
1088                 break;
1089         case 1:
1090         case 2:
1091                 break;
1092         case 4:
1093         case 5:
1094                 if (acm_mask & BIT(2))
1095                         change_priority = 0;
1096                 break;
1097         case 6:
1098         case 7:
1099                 if (acm_mask & BIT(3))
1100                         change_priority = 5;
1101                 break;
1102         default:
1103                 RTW_INFO("qos_acm(): invalid pattrib->priority: %d!!!\n", priority);
1104                 break;
1105         }
1106
1107         return change_priority;
1108 }
1109
1110 static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
1111 {
1112         struct ethhdr etherhdr;
1113         struct iphdr ip_hdr;
1114         s32 UserPriority = 0;
1115
1116
1117         _rtw_open_pktfile(ppktfile->pkt, ppktfile);
1118         _rtw_pktfile_read(ppktfile, (unsigned char *)&etherhdr, ETH_HLEN);
1119
1120         /* get UserPriority from IP hdr */
1121         if (pattrib->ether_type == 0x0800) {
1122                 _rtw_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr));
1123                 /*              UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3; */
1124                 UserPriority = ip_hdr.tos >> 5;
1125         }
1126         /*
1127                 else if (pattrib->ether_type == 0x888e) {
1128
1129
1130                         UserPriority = 7;
1131                 }
1132         */
1133         pattrib->priority = UserPriority;
1134         pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
1135         pattrib->subtype = WIFI_QOS_DATA_TYPE;
1136 }
1137
1138 #ifdef CONFIG_TDLS
1139 u8 rtw_check_tdls_established(_adapter *padapter, struct pkt_attrib *pattrib)
1140 {
1141         pattrib->ptdls_sta = NULL;
1142
1143         pattrib->direct_link = _FALSE;
1144         if (padapter->tdlsinfo.link_established == _TRUE) {
1145                 pattrib->ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
1146 #if 1
1147                 if ((pattrib->ptdls_sta != NULL) &&
1148                     (pattrib->ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) &&
1149                     (pattrib->ether_type != 0x0806)) {
1150                         pattrib->direct_link = _TRUE;
1151                         /* RTW_INFO("send ptk to "MAC_FMT" using direct link\n", MAC_ARG(pattrib->dst)); */
1152                 }
1153 #else
1154                 if (pattrib->ptdls_sta != NULL &&
1155                     pattrib->ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
1156                         pattrib->direct_link = _TRUE;
1157 #if 0
1158                         RTW_INFO("send ptk to "MAC_FMT" using direct link\n", MAC_ARG(pattrib->dst));
1159 #endif
1160                 }
1161
1162                 /* ARP frame may be helped by AP*/
1163                 if (pattrib->ether_type != 0x0806)
1164                         pattrib->direct_link = _FALSE;
1165 #endif
1166         }
1167
1168         return pattrib->direct_link;
1169 }
1170
1171 s32 update_tdls_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
1172 {
1173
1174         struct sta_info *psta = NULL;
1175         struct sta_priv         *pstapriv = &padapter->stapriv;
1176         struct security_priv    *psecuritypriv = &padapter->securitypriv;
1177         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
1178         struct qos_priv         *pqospriv = &pmlmepriv->qospriv;
1179
1180         s32 res = _SUCCESS;
1181
1182         psta = rtw_get_stainfo(pstapriv, pattrib->ra);
1183         if (psta == NULL)       {
1184                 res = _FAIL;
1185                 goto exit;
1186         }
1187
1188         pattrib->mac_id = psta->mac_id;
1189         pattrib->psta = psta;
1190         pattrib->ack_policy = 0;
1191         /* get ether_hdr_len */
1192         pattrib->pkt_hdrlen = ETH_HLEN;
1193
1194         /* [TDLS] TODO: setup req/rsp should be AC_BK */
1195         if (pqospriv->qos_option &&  psta->qos_option) {
1196                 pattrib->priority = 4;  /* tdls management frame should be AC_VI */
1197                 pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
1198                 pattrib->subtype = WIFI_QOS_DATA_TYPE;
1199         } else {
1200                 pattrib->priority = 0;
1201                 pattrib->hdrlen = WLAN_HDR_A3_LEN;
1202                 pattrib->subtype = WIFI_DATA_TYPE;
1203         }
1204
1205         /* TODO:_lock */
1206         if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) {
1207                 res = _FAIL;
1208                 goto exit;
1209         }
1210
1211         update_attrib_phy_info(padapter, pattrib, psta);
1212
1213
1214 exit:
1215
1216         return res;
1217 }
1218
1219 #endif /* CONFIG_TDLS */
1220
1221 /*get non-qos hw_ssn control register,mapping to REG_HW_SEQ0,1,2,3*/
1222 inline u8 rtw_get_hwseq_no(_adapter *padapter)
1223 {
1224         u8 hwseq_num = 0;
1225 #ifdef CONFIG_CONCURRENT_MODE
1226         if (padapter->adapter_type != PRIMARY_ADAPTER)
1227                 hwseq_num = 1;
1228         /* else */
1229         /*      hwseq_num = 2; */
1230 #endif /* CONFIG_CONCURRENT_MODE */
1231         return hwseq_num;
1232 }
1233 static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib)
1234 {
1235         uint i;
1236         struct pkt_file pktfile;
1237         struct sta_info *psta = NULL;
1238         struct ethhdr etherhdr;
1239
1240         sint bmcast;
1241         struct sta_priv         *pstapriv = &padapter->stapriv;
1242         struct security_priv    *psecuritypriv = &padapter->securitypriv;
1243         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
1244         struct qos_priv         *pqospriv = &pmlmepriv->qospriv;
1245         struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
1246         sint res = _SUCCESS;
1247
1248
1249         DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib);
1250
1251         _rtw_open_pktfile(pkt, &pktfile);
1252         i = _rtw_pktfile_read(&pktfile, (u8 *)&etherhdr, ETH_HLEN);
1253
1254         pattrib->ether_type = ntohs(etherhdr.h_proto);
1255
1256
1257         _rtw_memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
1258         _rtw_memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
1259
1260
1261         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1262             (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
1263                 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1264                 _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN);
1265                 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_adhoc);
1266         } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1267 #ifdef CONFIG_TDLS
1268                 if (rtw_check_tdls_established(padapter, pattrib) == _TRUE)
1269                         _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);       /* For TDLS direct link Tx, set ra to be same to dst */
1270                 else
1271 #endif
1272                         _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1273                 _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN);
1274                 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_sta);
1275         } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1276                 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1277                 _rtw_memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
1278                 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_ap);
1279         } else
1280                 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_unknown);
1281
1282         bmcast = IS_MCAST(pattrib->ra);
1283         if (bmcast) {
1284                 psta = rtw_get_bcmc_stainfo(padapter);
1285                 if (psta == NULL) { /* if we cannot get psta => drop the pkt */
1286                         DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sta);
1287 #ifdef DBG_TX_DROP_FRAME
1288                         RTW_INFO("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __func__, MAC_ARG(pattrib->ra));
1289 #endif
1290                         res = _FAIL;
1291                         goto exit;
1292                 }
1293         } else {
1294                 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
1295                 if (psta == NULL) { /* if we cannot get psta => drop the pkt */
1296                         DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_sta);
1297 #ifdef DBG_TX_DROP_FRAME
1298                         RTW_INFO("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __func__, MAC_ARG(pattrib->ra));
1299 #endif
1300                         res = _FAIL;
1301                         goto exit;
1302                 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE && !(psta->state & _FW_LINKED)) {
1303                         DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_ap_link);
1304                         res = _FAIL;
1305                         goto exit;
1306                 }
1307         }
1308
1309         if (!(psta->state & _FW_LINKED)) {
1310                 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_link);
1311                 RTW_INFO("%s-"ADPT_FMT" psta("MAC_FMT")->state(0x%x) != _FW_LINKED\n", __func__, ADPT_ARG(padapter), MAC_ARG(psta->hwaddr), psta->state);
1312                 res = _FAIL;
1313                 goto exit;
1314         }
1315
1316         pattrib->pktlen = pktfile.pkt_len;
1317
1318         /* TODO: 802.1Q VLAN header */
1319         /* TODO: IPV6 */
1320
1321         if (ETH_P_IP == pattrib->ether_type) {
1322                 u8 ip[20];
1323
1324                 _rtw_pktfile_read(&pktfile, ip, 20);
1325
1326                 if (GET_IPV4_IHL(ip) * 4 > 20)
1327                         _rtw_pktfile_read(&pktfile, NULL, GET_IPV4_IHL(ip) - 20);
1328
1329                 pattrib->icmp_pkt = 0;
1330                 pattrib->dhcp_pkt = 0;
1331
1332                 if (GET_IPV4_PROTOCOL(ip) == 0x01) { /* ICMP */
1333                         pattrib->icmp_pkt = 1;
1334                         DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_icmp);
1335
1336                 } else if (GET_IPV4_PROTOCOL(ip) == 0x11) { /* UDP */
1337                         u8 udp[8];
1338
1339                         _rtw_pktfile_read(&pktfile, udp, 8);
1340
1341                         if ((GET_UDP_SRC(udp) == 68 && GET_UDP_DST(udp) == 67)
1342                                 || (GET_UDP_SRC(udp) == 67 && GET_UDP_DST(udp) == 68)
1343                         ) {
1344                                 /* 67 : UDP BOOTP server, 68 : UDP BOOTP client */
1345                                 if (pattrib->pktlen > 282) { /* MINIMUM_DHCP_PACKET_SIZE */
1346                                         pattrib->dhcp_pkt = 1;
1347                                         DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_dhcp);
1348                                         if (0)
1349                                                 RTW_INFO("send DHCP packet\n");
1350                                 }
1351                         }
1352
1353                 } else if (GET_IPV4_PROTOCOL(ip) == 0x06 /* TCP */
1354                         && rtw_st_ctl_chk_reg_s_proto(&psta->st_ctl, 0x06) == _TRUE
1355                 ) {
1356                         u8 tcp[20];
1357
1358                         _rtw_pktfile_read(&pktfile, tcp, 20);
1359
1360                         if (rtw_st_ctl_chk_reg_rule(&psta->st_ctl, padapter, IPV4_SRC(ip), TCP_SRC(tcp), IPV4_DST(ip), TCP_DST(tcp)) == _TRUE) {
1361                                 if (GET_TCP_SYN(tcp) && GET_TCP_ACK(tcp)) {
1362                                         session_tracker_add_cmd(padapter, psta
1363                                                 , IPV4_SRC(ip), TCP_SRC(tcp)
1364                                                 , IPV4_SRC(ip), TCP_DST(tcp));
1365                                         if (DBG_SESSION_TRACKER)
1366                                                 RTW_INFO(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" SYN-ACK\n"
1367                                                         , FUNC_ADPT_ARG(padapter)
1368                                                         , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp))
1369                                                         , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp)));
1370                                 }
1371                                 if (GET_TCP_FIN(tcp)) {
1372                                         session_tracker_del_cmd(padapter, psta
1373                                                 , IPV4_SRC(ip), TCP_SRC(tcp)
1374                                                 , IPV4_SRC(ip), TCP_DST(tcp));
1375                                         if (DBG_SESSION_TRACKER)
1376                                                 RTW_INFO(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" FIN\n"
1377                                                         , FUNC_ADPT_ARG(padapter)
1378                                                         , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp))
1379                                                         , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp)));
1380                                 }
1381                         }
1382                 }
1383
1384         } else if (0x888e == pattrib->ether_type)
1385                 RTW_PRINT("send eapol packet\n");
1386
1387         if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
1388                 rtw_mi_set_scan_deny(padapter, 3000);
1389
1390 #ifdef CONFIG_LPS
1391         /* If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */
1392 #ifdef CONFIG_WAPI_SUPPORT
1393         if ((pattrib->ether_type == 0x88B4) || (pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
1394 #else /* !CONFIG_WAPI_SUPPORT */
1395 #if 0
1396         if ((pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
1397 #else /* only ICMP/DHCP packets is as SPECIAL_PACKET, and leave LPS when tx IMCP/DHCP packets. */
1398         /* if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) ) */
1399         if (pattrib->icmp_pkt == 1)
1400                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1);
1401         else if (pattrib->dhcp_pkt == 1)
1402 #endif
1403 #endif
1404         {
1405                 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_active);
1406                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
1407         }
1408 #endif /* CONFIG_LPS */
1409
1410 #ifdef CONFIG_BEAMFORMING
1411         update_attrib_txbf_info(padapter, pattrib, psta);
1412 #endif
1413
1414         /* TODO:_lock */
1415         if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) {
1416                 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sec);
1417                 res = _FAIL;
1418                 goto exit;
1419         }
1420
1421         update_attrib_phy_info(padapter, pattrib, psta);
1422
1423         /* RTW_INFO("%s ==> mac_id(%d)\n",__FUNCTION__,pattrib->mac_id ); */
1424
1425         pattrib->psta = psta;
1426         /* TODO:_unlock */
1427
1428         pattrib->pctrl = 0;
1429
1430         pattrib->ack_policy = 0;
1431         /* get ether_hdr_len */
1432         pattrib->pkt_hdrlen = ETH_HLEN;/* (pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; */ /* vlan tag */
1433
1434         pattrib->hdrlen = WLAN_HDR_A3_LEN;
1435         pattrib->subtype = WIFI_DATA_TYPE;
1436         pattrib->priority = 0;
1437
1438         if (check_fwstate(pmlmepriv, WIFI_AP_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
1439                 if (pattrib->qos_en)
1440                         set_qos(&pktfile, pattrib);
1441         } else {
1442 #ifdef CONFIG_TDLS
1443                 if (pattrib->direct_link == _TRUE) {
1444                         if (pattrib->qos_en)
1445                                 set_qos(&pktfile, pattrib);
1446                 } else
1447 #endif
1448                 {
1449                         if (pqospriv->qos_option) {
1450                                 set_qos(&pktfile, pattrib);
1451
1452                                 if (pmlmepriv->acm_mask != 0)
1453                                         pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority);
1454                         }
1455                 }
1456         }
1457
1458         /* pattrib->priority = 5; */ /* force to used VI queue, for testing */
1459         pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
1460         rtw_set_tx_chksum_offload(pkt, pattrib);
1461
1462 exit:
1463
1464
1465         return res;
1466 }
1467
1468 static s32 xmitframe_addmic(_adapter *padapter, struct xmit_frame *pxmitframe)
1469 {
1470         sint                    curfragnum, length;
1471         u8      *pframe, *payload, mic[8];
1472         struct  mic_data                micdata;
1473         /* struct       sta_info                *stainfo; */
1474         struct  qos_priv   *pqospriv = &(padapter->mlmepriv.qospriv);
1475         struct  pkt_attrib      *pattrib = &pxmitframe->attrib;
1476         struct  security_priv   *psecuritypriv = &padapter->securitypriv;
1477         struct  xmit_priv               *pxmitpriv = &padapter->xmitpriv;
1478         u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
1479         u8 hw_hdr_offset = 0;
1480         sint bmcst = IS_MCAST(pattrib->ra);
1481
1482         /*
1483                 if(pattrib->psta)
1484                 {
1485                         stainfo = pattrib->psta;
1486                 }
1487                 else
1488                 {
1489                         RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
1490                         stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
1491                 }
1492
1493                 if(stainfo==NULL)
1494                 {
1495                         RTW_INFO("%s, psta==NUL\n", __func__);
1496                         return _FAIL;
1497                 }
1498
1499                 if(!(stainfo->state &_FW_LINKED))
1500                 {
1501                         RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state);
1502                         return _FAIL;
1503                 }
1504         */
1505
1506
1507 #ifdef CONFIG_USB_TX_AGGREGATION
1508         hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);;
1509 #else
1510 #ifdef CONFIG_TX_EARLY_MODE
1511         hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
1512 #else
1513         hw_hdr_offset = TXDESC_OFFSET;
1514 #endif
1515 #endif
1516
1517         if (pattrib->encrypt == _TKIP_) { /* if(psecuritypriv->dot11PrivacyAlgrthm==_TKIP_PRIVACY_) */
1518                 /* encode mic code */
1519                 /* if(stainfo!= NULL) */
1520                 {
1521                         u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1522
1523                         pframe = pxmitframe->buf_addr + hw_hdr_offset;
1524
1525                         if (bmcst) {
1526                                 if (_rtw_memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16) == _TRUE) {
1527                                         /* DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); */
1528                                         /* rtw_msleep_os(10); */
1529                                         return _FAIL;
1530                                 }
1531                                 /* start to calculate the mic code */
1532                                 rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
1533                         } else {
1534                                 if (_rtw_memcmp(&pattrib->dot11tkiptxmickey.skey[0], null_key, 16) == _TRUE) {
1535                                         /* DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); */
1536                                         /* rtw_msleep_os(10); */
1537                                         return _FAIL;
1538                                 }
1539                                 /* start to calculate the mic code */
1540                                 rtw_secmicsetkey(&micdata, &pattrib->dot11tkiptxmickey.skey[0]);
1541                         }
1542
1543                         if (pframe[1] & 1) { /* ToDS==1 */
1544                                 rtw_secmicappend(&micdata, &pframe[16], 6);  /* DA */
1545                                 if (pframe[1] & 2) /* From Ds==1 */
1546                                         rtw_secmicappend(&micdata, &pframe[24], 6);
1547                                 else
1548                                         rtw_secmicappend(&micdata, &pframe[10], 6);
1549                         } else {        /* ToDS==0 */
1550                                 rtw_secmicappend(&micdata, &pframe[4], 6);   /* DA */
1551                                 if (pframe[1] & 2) /* From Ds==1 */
1552                                         rtw_secmicappend(&micdata, &pframe[16], 6);
1553                                 else
1554                                         rtw_secmicappend(&micdata, &pframe[10], 6);
1555
1556                         }
1557
1558                         /* if(pqospriv->qos_option==1) */
1559                         if (pattrib->qos_en)
1560                                 priority[0] = (u8)pxmitframe->attrib.priority;
1561
1562
1563                         rtw_secmicappend(&micdata, &priority[0], 4);
1564
1565                         payload = pframe;
1566
1567                         for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
1568                                 payload = (u8 *)RND4((SIZE_PTR)(payload));
1569
1570                                 payload = payload + pattrib->hdrlen + pattrib->iv_len;
1571                                 if ((curfragnum + 1) == pattrib->nr_frags) {
1572                                         length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0);
1573                                         rtw_secmicappend(&micdata, payload, length);
1574                                         payload = payload + length;
1575                                 } else {
1576                                         length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0);
1577                                         rtw_secmicappend(&micdata, payload, length);
1578                                         payload = payload + length + pattrib->icv_len;
1579                                 }
1580                         }
1581                         rtw_secgetmic(&micdata, &(mic[0]));
1582                         /* add mic code  and add the mic code length in last_txcmdsz */
1583
1584                         _rtw_memcpy(payload, &(mic[0]), 8);
1585                         pattrib->last_txcmdsz += 8;
1586
1587                         payload = payload - pattrib->last_txcmdsz + 8;
1588                 }
1589         }
1590
1591
1592         return _SUCCESS;
1593 }
1594
1595 /*#define DBG_TX_SW_ENCRYPTOR*/
1596
1597 static s32 xmitframe_swencrypt(_adapter *padapter, struct xmit_frame *pxmitframe)
1598 {
1599
1600         struct  pkt_attrib      *pattrib = &pxmitframe->attrib;
1601         /* struct       security_priv   *psecuritypriv=&padapter->securitypriv; */
1602
1603
1604         /* if((psecuritypriv->sw_encrypt)||(pattrib->bswenc))    */
1605         if (pattrib->bswenc) {
1606 #ifdef DBG_TX_SW_ENCRYPTOR
1607                 RTW_INFO(ADPT_FMT" - sec_type:%s DO SW encryption\n",
1608                         ADPT_ARG(padapter), security_type_str(pattrib->encrypt));
1609 #endif
1610
1611                 switch (pattrib->encrypt) {
1612                 case _WEP40_:
1613                 case _WEP104_:
1614                         rtw_wep_encrypt(padapter, (u8 *)pxmitframe);
1615                         break;
1616                 case _TKIP_:
1617                         rtw_tkip_encrypt(padapter, (u8 *)pxmitframe);
1618                         break;
1619                 case _AES_:
1620                         rtw_aes_encrypt(padapter, (u8 *)pxmitframe);
1621                         break;
1622 #ifdef CONFIG_WAPI_SUPPORT
1623                 case _SMS4_:
1624                         rtw_sms4_encrypt(padapter, (u8 *)pxmitframe);
1625 #endif
1626                 default:
1627                         break;
1628                 }
1629
1630         }
1631
1632
1633         return _SUCCESS;
1634 }
1635
1636 s32 rtw_make_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib)
1637 {
1638         u16 *qc;
1639
1640         struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr;
1641         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1642         struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1643         u8 qos_option = _FALSE;
1644         sint res = _SUCCESS;
1645         u16 *fctrl = &pwlanhdr->frame_ctl;
1646
1647         /* struct sta_info *psta; */
1648
1649         /* sint bmcst = IS_MCAST(pattrib->ra); */
1650
1651
1652         /*
1653                 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1654                 if(pattrib->psta != psta)
1655                 {
1656                         RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
1657                         return;
1658                 }
1659
1660                 if(psta==NULL)
1661                 {
1662                         RTW_INFO("%s, psta==NUL\n", __func__);
1663                         return _FAIL;
1664                 }
1665
1666                 if(!(psta->state &_FW_LINKED))
1667                 {
1668                         RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1669                         return _FAIL;
1670                 }
1671         */
1672
1673         _rtw_memset(hdr, 0, WLANHDR_OFFSET);
1674
1675         set_frame_sub_type(fctrl, pattrib->subtype);
1676
1677         if (pattrib->subtype & WIFI_DATA_TYPE) {
1678                 if ((check_fwstate(pmlmepriv,  WIFI_STATION_STATE) == _TRUE)) {
1679 #ifdef CONFIG_TDLS
1680                         if (pattrib->direct_link == _TRUE) {
1681                                 /* TDLS data transfer, ToDS=0, FrDs=0 */
1682                                 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1683                                 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1684                                 _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1685
1686                                 if (pattrib->qos_en)
1687                                         qos_option = _TRUE;
1688                         } else
1689 #endif /* CONFIG_TDLS */
1690                         {
1691                                 /* to_ds = 1, fr_ds = 0; */
1692                                 /* 1.Data transfer to AP */
1693                                 /* 2.Arp pkt will relayed by AP */
1694                                 SetToDs(fctrl);
1695                                 _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1696                                 _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN);
1697                                 _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1698
1699                                 if (pqospriv->qos_option)
1700                                         qos_option = _TRUE;
1701                         }
1702                 } else if ((check_fwstate(pmlmepriv,  WIFI_AP_STATE) == _TRUE)) {
1703                         /* to_ds = 0, fr_ds = 1; */
1704                         SetFrDs(fctrl);
1705                         _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1706                         _rtw_memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN);
1707                         _rtw_memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
1708
1709                         if (pattrib->qos_en)
1710                                 qos_option = _TRUE;
1711                 } else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1712                         (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
1713                         _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1714                         _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN);
1715                         _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1716
1717                         if (pattrib->qos_en)
1718                                 qos_option = _TRUE;
1719                 } else {
1720                         res = _FAIL;
1721                         goto exit;
1722                 }
1723
1724                 if (pattrib->mdata)
1725                         SetMData(fctrl);
1726
1727                 if (pattrib->encrypt)
1728                         SetPrivacy(fctrl);
1729
1730                 if (qos_option) {
1731                         qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
1732
1733                         if (pattrib->priority)
1734                                 SetPriority(qc, pattrib->priority);
1735
1736                         SetEOSP(qc, pattrib->eosp);
1737
1738                         SetAckpolicy(qc, pattrib->ack_policy);
1739
1740                         if(pattrib->amsdu)
1741                                 SetAMsdu(qc, pattrib->amsdu);
1742                 }
1743
1744                 /* TODO: fill HT Control Field */
1745
1746                 /* Update Seq Num will be handled by f/w */
1747                 {
1748                         struct sta_info *psta;
1749                         psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1750                         if (pattrib->psta != psta) {
1751                                 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
1752                                 return _FAIL;
1753                         }
1754
1755                         if (psta == NULL) {
1756                                 RTW_INFO("%s, psta==NUL\n", __func__);
1757                                 return _FAIL;
1758                         }
1759
1760                         if (!(psta->state & _FW_LINKED)) {
1761                                 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1762                                 return _FAIL;
1763                         }
1764
1765
1766                         if (psta) {
1767                                 psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
1768                                 psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
1769                                 pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
1770
1771                                 SetSeqNum(hdr, pattrib->seqnum);
1772
1773 #ifdef CONFIG_80211N_HT
1774                                 /* check if enable ampdu */
1775                                 if (pattrib->ht_en && psta->htpriv.ampdu_enable) {
1776                                         if (psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
1777                                                 pattrib->ampdu_en = _TRUE;
1778                                 }
1779
1780                                 /* re-check if enable ampdu by BA_starting_seqctrl */
1781                                 if (pattrib->ampdu_en == _TRUE) {
1782                                         u16 tx_seq;
1783
1784                                         tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
1785
1786                                         /* check BA_starting_seqctrl */
1787                                         if (SN_LESS(pattrib->seqnum, tx_seq)) {
1788                                                 /* RTW_INFO("tx ampdu seqnum(%d) < tx_seq(%d)\n", pattrib->seqnum, tx_seq); */
1789                                                 pattrib->ampdu_en = _FALSE;/* AGG BK */
1790                                         } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) {
1791                                                 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq + 1) & 0xfff;
1792
1793                                                 pattrib->ampdu_en = _TRUE;/* AGG EN */
1794                                         } else {
1795                                                 /* RTW_INFO("tx ampdu over run\n"); */
1796                                                 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum + 1) & 0xfff;
1797                                                 pattrib->ampdu_en = _TRUE;/* AGG EN */
1798                                         }
1799
1800                                 }
1801 #endif /* CONFIG_80211N_HT */
1802                         }
1803                 }
1804
1805         } else {
1806
1807         }
1808
1809 exit:
1810
1811
1812         return res;
1813 }
1814
1815 s32 rtw_txframes_pending(_adapter *padapter)
1816 {
1817         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1818
1819         return ((_rtw_queue_empty(&pxmitpriv->be_pending) == _FALSE) ||
1820                 (_rtw_queue_empty(&pxmitpriv->bk_pending) == _FALSE) ||
1821                 (_rtw_queue_empty(&pxmitpriv->vi_pending) == _FALSE) ||
1822                 (_rtw_queue_empty(&pxmitpriv->vo_pending) == _FALSE));
1823 }
1824
1825 s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib)
1826 {
1827         struct sta_info *psta;
1828         struct tx_servq *ptxservq;
1829         int priority = pattrib->priority;
1830         /*
1831                 if(pattrib->psta)
1832                 {
1833                         psta = pattrib->psta;
1834                 }
1835                 else
1836                 {
1837                         RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
1838                         psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
1839                 }
1840         */
1841         psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1842         if (pattrib->psta != psta) {
1843                 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
1844                 return 0;
1845         }
1846
1847         if (psta == NULL) {
1848                 RTW_INFO("%s, psta==NUL\n", __func__);
1849                 return 0;
1850         }
1851
1852         if (!(psta->state & _FW_LINKED)) {
1853                 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1854                 return 0;
1855         }
1856
1857         switch (priority) {
1858         case 1:
1859         case 2:
1860                 ptxservq = &(psta->sta_xmitpriv.bk_q);
1861                 break;
1862         case 4:
1863         case 5:
1864                 ptxservq = &(psta->sta_xmitpriv.vi_q);
1865                 break;
1866         case 6:
1867         case 7:
1868                 ptxservq = &(psta->sta_xmitpriv.vo_q);
1869                 break;
1870         case 0:
1871         case 3:
1872         default:
1873                 ptxservq = &(psta->sta_xmitpriv.be_q);
1874                 break;
1875
1876         }
1877
1878         return ptxservq->qcnt;
1879 }
1880
1881 #ifdef CONFIG_TDLS
1882
1883 int rtw_build_tdls_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
1884 {
1885         int res = _SUCCESS;
1886
1887         switch (ptxmgmt->action_code) {
1888         case TDLS_SETUP_REQUEST:
1889                 rtw_build_tdls_setup_req_ies(padapter, pxmitframe, pframe, ptxmgmt);
1890                 break;
1891         case TDLS_SETUP_RESPONSE:
1892                 rtw_build_tdls_setup_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt);
1893                 break;
1894         case TDLS_SETUP_CONFIRM:
1895                 rtw_build_tdls_setup_cfm_ies(padapter, pxmitframe, pframe, ptxmgmt);
1896                 break;
1897         case TDLS_TEARDOWN:
1898                 rtw_build_tdls_teardown_ies(padapter, pxmitframe, pframe, ptxmgmt);
1899                 break;
1900         case TDLS_DISCOVERY_REQUEST:
1901                 rtw_build_tdls_dis_req_ies(padapter, pxmitframe, pframe, ptxmgmt);
1902                 break;
1903         case TDLS_PEER_TRAFFIC_INDICATION:
1904                 rtw_build_tdls_peer_traffic_indication_ies(padapter, pxmitframe, pframe, ptxmgmt);
1905                 break;
1906 #ifdef CONFIG_TDLS_CH_SW
1907         case TDLS_CHANNEL_SWITCH_REQUEST:
1908                 rtw_build_tdls_ch_switch_req_ies(padapter, pxmitframe, pframe, ptxmgmt);
1909                 break;
1910         case TDLS_CHANNEL_SWITCH_RESPONSE:
1911                 rtw_build_tdls_ch_switch_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt);
1912                 break;
1913 #endif
1914         case TDLS_PEER_TRAFFIC_RESPONSE:
1915                 rtw_build_tdls_peer_traffic_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt);
1916                 break;
1917 #ifdef CONFIG_WFD
1918         case TUNNELED_PROBE_REQ:
1919                 rtw_build_tunneled_probe_req_ies(padapter, pxmitframe, pframe);
1920                 break;
1921         case TUNNELED_PROBE_RSP:
1922                 rtw_build_tunneled_probe_rsp_ies(padapter, pxmitframe, pframe);
1923                 break;
1924 #endif /* CONFIG_WFD */
1925         default:
1926                 res = _FAIL;
1927                 break;
1928         }
1929
1930         return res;
1931 }
1932
1933 s32 rtw_make_tdls_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt)
1934 {
1935         u16 *qc;
1936         struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr;
1937         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1938         struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1939         struct sta_priv *pstapriv = &padapter->stapriv;
1940         struct sta_info *psta = NULL, *ptdls_sta = NULL;
1941         u8 tdls_seq = 0, baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1942
1943         sint res = _SUCCESS;
1944         u16 *fctrl = &pwlanhdr->frame_ctl;
1945
1946
1947         _rtw_memset(hdr, 0, WLANHDR_OFFSET);
1948
1949         set_frame_sub_type(fctrl, pattrib->subtype);
1950
1951         switch (ptxmgmt->action_code) {
1952         case TDLS_SETUP_REQUEST:
1953         case TDLS_SETUP_RESPONSE:
1954         case TDLS_SETUP_CONFIRM:
1955         case TDLS_PEER_TRAFFIC_INDICATION:
1956         case TDLS_PEER_PSM_REQUEST:
1957         case TUNNELED_PROBE_REQ:
1958         case TUNNELED_PROBE_RSP:
1959         case TDLS_DISCOVERY_REQUEST:
1960                 SetToDs(fctrl);
1961                 _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1962                 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1963                 _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1964                 break;
1965         case TDLS_CHANNEL_SWITCH_REQUEST:
1966         case TDLS_CHANNEL_SWITCH_RESPONSE:
1967         case TDLS_PEER_PSM_RESPONSE:
1968         case TDLS_PEER_TRAFFIC_RESPONSE:
1969                 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1970                 _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1971                 _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1972                 tdls_seq = 1;
1973                 break;
1974         case TDLS_TEARDOWN:
1975                 if (ptxmgmt->status_code == _RSON_TDLS_TEAR_UN_RSN_) {
1976                         _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1977                         _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1978                         _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1979                         tdls_seq = 1;
1980                 } else {
1981                         SetToDs(fctrl);
1982                         _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1983                         _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1984                         _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1985                 }
1986                 break;
1987         }
1988
1989         if (pattrib->encrypt)
1990                 SetPrivacy(fctrl);
1991
1992         if (ptxmgmt->action_code == TDLS_PEER_TRAFFIC_RESPONSE)
1993                 SetPwrMgt(fctrl);
1994
1995         if (pqospriv->qos_option) {
1996                 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
1997                 if (pattrib->priority)
1998                         SetPriority(qc, pattrib->priority);
1999                 SetAckpolicy(qc, pattrib->ack_policy);
2000         }
2001
2002         psta = pattrib->psta;
2003
2004         /* 1. update seq_num per link by sta_info */
2005         /* 2. rewrite encrypt to _AES_, also rewrite iv_len, icv_len */
2006         if (tdls_seq == 1) {
2007                 ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
2008                 if (ptdls_sta) {
2009                         ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
2010                         ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
2011                         pattrib->seqnum = ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority];
2012                         SetSeqNum(hdr, pattrib->seqnum);
2013
2014                         if (pattrib->encrypt) {
2015                                 pattrib->encrypt = _AES_;
2016                                 pattrib->iv_len = 8;
2017                                 pattrib->icv_len = 8;
2018                                 pattrib->bswenc = _FALSE;
2019                         }
2020                         pattrib->mac_id = ptdls_sta->mac_id;
2021                 } else {
2022                         res = _FAIL;
2023                         goto exit;
2024                 }
2025         } else if (psta) {
2026                 psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
2027                 psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
2028                 pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
2029                 SetSeqNum(hdr, pattrib->seqnum);
2030         }
2031
2032
2033 exit:
2034
2035
2036         return res;
2037 }
2038
2039 s32 rtw_xmit_tdls_coalesce(_adapter *padapter, struct xmit_frame *pxmitframe, struct tdls_txmgmt *ptxmgmt)
2040 {
2041         s32 llc_sz;
2042
2043         u8 *pframe, *mem_start;
2044
2045         struct sta_info         *psta;
2046         struct sta_priv         *pstapriv = &padapter->stapriv;
2047         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
2048         struct pkt_attrib       *pattrib = &pxmitframe->attrib;
2049         u8 *pbuf_start;
2050         s32 bmcst = IS_MCAST(pattrib->ra);
2051         s32 res = _SUCCESS;
2052
2053
2054         if (pattrib->psta)
2055                 psta = pattrib->psta;
2056         else {
2057                 if (bmcst)
2058                         psta = rtw_get_bcmc_stainfo(padapter);
2059                 else
2060                         psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2061         }
2062
2063         if (psta == NULL) {
2064                 res = _FAIL;
2065                 goto exit;
2066         }
2067
2068         if (pxmitframe->buf_addr == NULL) {
2069                 res = _FAIL;
2070                 goto exit;
2071         }
2072
2073         pbuf_start = pxmitframe->buf_addr;
2074         mem_start = pbuf_start + TXDESC_OFFSET;
2075
2076         if (rtw_make_tdls_wlanhdr(padapter, mem_start, pattrib, ptxmgmt) == _FAIL) {
2077                 res = _FAIL;
2078                 goto exit;
2079         }
2080
2081         pframe = mem_start;
2082         pframe += pattrib->hdrlen;
2083
2084         /* adding icv, if necessary... */
2085         if (pattrib->iv_len) {
2086                 if (psta != NULL) {
2087                         switch (pattrib->encrypt) {
2088                         case _WEP40_:
2089                         case _WEP104_:
2090                                 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2091                                 break;
2092                         case _TKIP_:
2093                                 if (bmcst)
2094                                         TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2095                                 else
2096                                         TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
2097                                 break;
2098                         case _AES_:
2099                                 if (bmcst)
2100                                         AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2101                                 else
2102                                         AES_IV(pattrib->iv, psta->dot11txpn, 0);
2103                                 break;
2104                         }
2105                 }
2106
2107                 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
2108                 pframe += pattrib->iv_len;
2109
2110         }
2111
2112         llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
2113         pframe += llc_sz;
2114
2115         /* pattrib->pktlen will be counted in rtw_build_tdls_ies */
2116         pattrib->pktlen = 0;
2117
2118         rtw_build_tdls_ies(padapter, pxmitframe, pframe, ptxmgmt);
2119
2120         if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2121                 pframe += pattrib->pktlen;
2122                 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2123                 pframe += pattrib->icv_len;
2124         }
2125
2126         pattrib->nr_frags = 1;
2127         pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + llc_sz +
2128                 ((pattrib->bswenc) ? pattrib->icv_len : 0) + pattrib->pktlen;
2129
2130         if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
2131                 res = _FAIL;
2132                 goto exit;
2133         }
2134
2135         xmitframe_swencrypt(padapter, pxmitframe);
2136
2137         update_attrib_vcs_info(padapter, pxmitframe);
2138
2139 exit:
2140
2141
2142         return res;
2143 }
2144 #endif /* CONFIG_TDLS */
2145
2146 /*
2147  * Calculate wlan 802.11 packet MAX size from pkt_attrib
2148  * This function doesn't consider fragment case
2149  */
2150 u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib)
2151 {
2152         u32     len = 0;
2153
2154         len = pattrib->hdrlen + pattrib->iv_len; /* WLAN Header and IV */
2155         len += SNAP_SIZE + sizeof(u16); /* LLC */
2156         len += pattrib->pktlen;
2157         if (pattrib->encrypt == _TKIP_)
2158                 len += 8; /* MIC */
2159         len += ((pattrib->bswenc) ? pattrib->icv_len : 0); /* ICV */
2160
2161         return len;
2162 }
2163
2164 #ifdef CONFIG_TX_AMSDU
2165 s32 check_amsdu(struct xmit_frame *pxmitframe)
2166 {
2167         struct pkt_attrib *pattrib;
2168         int ret = _TRUE;
2169
2170         if (!pxmitframe)
2171                 ret = _FALSE;
2172
2173         pattrib = &pxmitframe->attrib;
2174
2175         if (IS_MCAST(pattrib->ra))
2176                 ret = _FALSE;
2177
2178         if ((pattrib->ether_type == 0x888e) ||
2179                 (pattrib->ether_type == 0x0806) ||
2180                 (pattrib->ether_type == 0x88b4) ||
2181                 (pattrib->dhcp_pkt == 1))
2182                 ret = _FALSE;
2183
2184         if ((pattrib->encrypt == _WEP40_) ||
2185             (pattrib->encrypt == _WEP104_) ||
2186             (pattrib->encrypt == _TKIP_))
2187                 ret = _FALSE;
2188
2189         if (!pattrib->qos_en)
2190                 ret = _FALSE;
2191
2192         return ret;
2193 }
2194
2195
2196 s32 rtw_xmitframe_coalesce_amsdu(_adapter *padapter, struct xmit_frame *pxmitframe, struct xmit_frame *pxmitframe_queue)
2197 {
2198
2199         struct pkt_file pktfile;
2200         struct pkt_attrib *pattrib;
2201         _pkt *pkt;
2202
2203         struct pkt_file pktfile_queue;
2204         struct pkt_attrib *pattrib_queue;
2205         _pkt *pkt_queue;
2206
2207         s32 llc_sz, mem_sz;
2208
2209         s32 padding = 0;
2210
2211         u8 *pframe, *mem_start;
2212         u8 hw_hdr_offset;
2213
2214         u16* len;
2215         u8 *pbuf_start;
2216         s32 res = _SUCCESS;
2217
2218         if (pxmitframe->buf_addr == NULL) {
2219                 RTW_INFO("==> %s buf_addr==NULL\n", __FUNCTION__);
2220                 return _FAIL;
2221         }
2222
2223
2224         pbuf_start = pxmitframe->buf_addr;
2225
2226 #ifdef CONFIG_USB_TX_AGGREGATION
2227         hw_hdr_offset =  TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
2228 #else
2229 #ifdef CONFIG_TX_EARLY_MODE /* for SDIO && Tx Agg */
2230         hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
2231 #else
2232         hw_hdr_offset = TXDESC_OFFSET;
2233 #endif
2234 #endif
2235
2236         mem_start = pbuf_start + hw_hdr_offset; //for DMA
2237
2238         pattrib = &pxmitframe->attrib;
2239
2240         pattrib->amsdu = 1;
2241
2242         if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
2243                 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n"));
2244                 RTW_INFO("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n");
2245                 res = _FAIL;
2246                 goto exit;
2247         }
2248
2249         llc_sz = 0;
2250
2251         pframe = mem_start;
2252
2253         //SetMFrag(mem_start);
2254         ClearMFrag(mem_start);
2255
2256         pframe += pattrib->hdrlen;
2257
2258         /* adding icv, if necessary... */
2259         if (pattrib->iv_len) {
2260                 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len); // queue or new?
2261
2262                 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
2263                         ("rtw_xmitframe_coalesce: keyid=%d pattrib->iv[3]=%.2x pframe=%.2x %.2x %.2x %.2x\n",
2264                         padapter->securitypriv.dot11PrivacyKeyIndex, pattrib->iv[3], *pframe, *(pframe + 1), *(pframe + 2), *(pframe + 3)));
2265
2266                 pframe += pattrib->iv_len;
2267         }
2268
2269         pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len;
2270
2271         if(pxmitframe_queue)
2272         {
2273                 pattrib_queue = &pxmitframe_queue->attrib;
2274                 pkt_queue = pxmitframe_queue->pkt;
2275
2276                 _rtw_open_pktfile(pkt_queue, &pktfile_queue);
2277                 _rtw_pktfile_read(&pktfile_queue, NULL, pattrib_queue->pkt_hdrlen);
2278
2279                 /* 802.3 MAC Header DA(6)  SA(6)  Len(2)*/
2280
2281                 _rtw_memcpy(pframe, pattrib_queue->dst, ETH_ALEN);
2282                 pframe += ETH_ALEN;
2283
2284                 _rtw_memcpy(pframe, pattrib_queue->src, ETH_ALEN);
2285                 pframe += ETH_ALEN;
2286
2287                 len = (u16*) pframe;
2288                 pframe += 2;
2289
2290                 llc_sz = rtw_put_snap(pframe, pattrib_queue->ether_type);
2291                 pframe += llc_sz;
2292
2293                 mem_sz = _rtw_pktfile_read(&pktfile_queue, pframe, pattrib_queue->pktlen);
2294                 pframe += mem_sz;
2295
2296                 *len = htons(llc_sz + mem_sz);
2297
2298                 //calc padding
2299                 padding = 4 - ((ETH_HLEN + llc_sz + mem_sz) & (4-1));
2300                 if(padding == 4)
2301                         padding = 0;
2302
2303                 //_rtw_memset(pframe,0xaa, padding);
2304                 pframe += padding;
2305
2306                 pattrib->last_txcmdsz += ETH_HLEN + llc_sz + mem_sz + padding ;
2307         }
2308
2309         //2nd mpdu
2310
2311         pkt = pxmitframe->pkt;
2312         _rtw_open_pktfile(pkt, &pktfile);
2313         _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
2314
2315         /* 802.3 MAC Header  DA(6)  SA(6)  Len(2) */
2316
2317         _rtw_memcpy(pframe, pattrib->dst, ETH_ALEN);
2318         pframe += ETH_ALEN;
2319
2320         _rtw_memcpy(pframe, pattrib->src, ETH_ALEN);
2321         pframe += ETH_ALEN;
2322
2323         len = (u16*) pframe;
2324         pframe += 2;
2325
2326         llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
2327         pframe += llc_sz;
2328
2329         mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
2330
2331         pframe += mem_sz;
2332
2333         *len = htons(llc_sz + mem_sz);
2334
2335         //the last ampdu has no padding
2336         padding = 0;
2337
2338         pattrib->nr_frags = 1;
2339
2340         pattrib->last_txcmdsz += ETH_HLEN + llc_sz + mem_sz + padding +
2341                 ((pattrib->bswenc) ? pattrib->icv_len : 0) ;
2342
2343         if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2344                 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2345                 pframe += pattrib->icv_len;
2346         }
2347
2348         if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
2349                 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n"));
2350                 RTW_INFO("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n");
2351                 res = _FAIL;
2352                 goto exit;
2353         }
2354
2355         xmitframe_swencrypt(padapter, pxmitframe);
2356
2357         pattrib->vcs_mode = NONE_VCS;
2358
2359 exit:
2360         return res;
2361 }
2362 #endif /* CONFIG_TX_AMSDU */
2363
2364 /*
2365
2366 This sub-routine will perform all the following:
2367
2368 1. remove 802.3 header.
2369 2. create wlan_header, based on the info in pxmitframe
2370 3. append sta's iv/ext-iv
2371 4. append LLC
2372 5. move frag chunk from pframe to pxmitframe->mem
2373 6. apply sw-encrypt, if necessary.
2374
2375 */
2376 s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
2377 {
2378         struct pkt_file pktfile;
2379
2380         s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
2381
2382         SIZE_PTR addr;
2383
2384         u8 *pframe, *mem_start;
2385         u8 hw_hdr_offset;
2386
2387         /* struct sta_info              *psta; */
2388         /* struct sta_priv              *pstapriv = &padapter->stapriv; */
2389         /* struct mlme_priv     *pmlmepriv = &padapter->mlmepriv; */
2390         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
2391
2392         struct pkt_attrib       *pattrib = &pxmitframe->attrib;
2393
2394         u8 *pbuf_start;
2395
2396         s32 bmcst = IS_MCAST(pattrib->ra);
2397         s32 res = _SUCCESS;
2398
2399
2400         /*
2401                 if (pattrib->psta)
2402                 {
2403                         psta = pattrib->psta;
2404                 } else
2405                 {
2406                         RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
2407                         psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2408                 }
2409
2410                 if(psta==NULL)
2411                 {
2412
2413                         RTW_INFO("%s, psta==NUL\n", __func__);
2414                         return _FAIL;
2415                 }
2416
2417
2418                 if(!(psta->state &_FW_LINKED))
2419                 {
2420                         RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
2421                         return _FAIL;
2422                 }
2423         */
2424         if (pxmitframe->buf_addr == NULL) {
2425                 RTW_INFO("==> %s buf_addr==NULL\n", __FUNCTION__);
2426                 return _FAIL;
2427         }
2428
2429         pbuf_start = pxmitframe->buf_addr;
2430
2431 #ifdef CONFIG_USB_TX_AGGREGATION
2432         hw_hdr_offset =  TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
2433 #else
2434 #ifdef CONFIG_TX_EARLY_MODE /* for SDIO && Tx Agg */
2435         hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
2436 #else
2437         hw_hdr_offset = TXDESC_OFFSET;
2438 #endif
2439 #endif
2440
2441         mem_start = pbuf_start +        hw_hdr_offset;
2442
2443         if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
2444                 RTW_INFO("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n");
2445                 res = _FAIL;
2446                 goto exit;
2447         }
2448
2449         _rtw_open_pktfile(pkt, &pktfile);
2450         _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
2451
2452         frg_inx = 0;
2453         frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
2454
2455         while (1) {
2456                 llc_sz = 0;
2457
2458                 mpdu_len = frg_len;
2459
2460                 pframe = mem_start;
2461
2462                 SetMFrag(mem_start);
2463
2464                 pframe += pattrib->hdrlen;
2465                 mpdu_len -= pattrib->hdrlen;
2466
2467                 /* adding icv, if necessary... */
2468                 if (pattrib->iv_len) {
2469 #if 0
2470                         /* if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) */
2471                         /*      psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); */
2472                         /* else */
2473                         /*      psta = rtw_get_stainfo(pstapriv, pattrib->ra); */
2474
2475                         if (psta != NULL) {
2476                                 switch (pattrib->encrypt) {
2477                                 case _WEP40_:
2478                                 case _WEP104_:
2479                                         WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2480                                         break;
2481                                 case _TKIP_:
2482                                         if (bmcst)
2483                                                 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2484                                         else
2485                                                 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
2486                                         break;
2487                                 case _AES_:
2488                                         if (bmcst)
2489                                                 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2490                                         else
2491                                                 AES_IV(pattrib->iv, psta->dot11txpn, 0);
2492                                         break;
2493 #ifdef CONFIG_WAPI_SUPPORT
2494                                 case _SMS4_:
2495                                         rtw_wapi_get_iv(padapter, pattrib->ra, pattrib->iv);
2496                                         break;
2497 #endif
2498                                 }
2499                         }
2500 #endif
2501                         _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
2502
2503
2504                         pframe += pattrib->iv_len;
2505
2506                         mpdu_len -= pattrib->iv_len;
2507                 }
2508
2509                 if (frg_inx == 0) {
2510                         llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
2511                         pframe += llc_sz;
2512                         mpdu_len -= llc_sz;
2513                 }
2514
2515                 if ((pattrib->icv_len > 0) && (pattrib->bswenc))
2516                         mpdu_len -= pattrib->icv_len;
2517
2518
2519                 if (bmcst) {
2520                         /* don't do fragment to broadcat/multicast packets */
2521                         mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
2522                 } else
2523                         mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len);
2524
2525                 pframe += mem_sz;
2526
2527                 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2528                         _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2529                         pframe += pattrib->icv_len;
2530                 }
2531
2532                 frg_inx++;
2533
2534                 if (bmcst || (rtw_endofpktfile(&pktfile) == _TRUE)) {
2535                         pattrib->nr_frags = frg_inx;
2536
2537                         pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags == 1) ? llc_sz : 0) +
2538                                 ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz;
2539
2540                         ClearMFrag(mem_start);
2541
2542                         break;
2543                 }
2544
2545                 addr = (SIZE_PTR)(pframe);
2546
2547                 mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset;
2548                 _rtw_memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
2549
2550         }
2551
2552         if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
2553                 RTW_INFO("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n");
2554                 res = _FAIL;
2555                 goto exit;
2556         }
2557
2558         xmitframe_swencrypt(padapter, pxmitframe);
2559
2560         if (bmcst == _FALSE)
2561                 update_attrib_vcs_info(padapter, pxmitframe);
2562         else
2563                 pattrib->vcs_mode = NONE_VCS;
2564
2565 exit:
2566
2567
2568         return res;
2569 }
2570
2571 #ifdef CONFIG_IEEE80211W
2572 /* broadcast or multicast management pkt use BIP, unicast management pkt use CCMP encryption */
2573 s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
2574 {
2575         struct pkt_file pktfile;
2576         s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
2577         SIZE_PTR addr;
2578         u8 *pframe, *mem_start = NULL, *tmp_buf = NULL;
2579         u8 hw_hdr_offset, subtype ;
2580         struct sta_info         *psta = NULL;
2581         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
2582         struct pkt_attrib       *pattrib = &pxmitframe->attrib;
2583         u8 *pbuf_start;
2584         s32 bmcst = IS_MCAST(pattrib->ra);
2585         s32 res = _FAIL;
2586         u8 *BIP_AAD = NULL;
2587         u8 *MGMT_body = NULL;
2588
2589         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2590         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
2591         struct rtw_ieee80211_hdr        *pwlanhdr;
2592         u8 MME[_MME_IE_LENGTH_];
2593
2594         _irqL irqL;
2595         u32     ori_len;
2596         mem_start = pframe = (u8 *)(pxmitframe->buf_addr) + TXDESC_OFFSET;
2597         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2598
2599         ori_len = BIP_AAD_SIZE + pattrib->pktlen;
2600         tmp_buf = BIP_AAD = rtw_zmalloc(ori_len);
2601         subtype = get_frame_sub_type(pframe); /* bit(7)~bit(2) */
2602
2603         if (BIP_AAD == NULL)
2604                 return _FAIL;
2605
2606         _enter_critical_bh(&padapter->security_key_mutex, &irqL);
2607
2608
2609         /* IGTK key is not install, it may not support 802.11w */
2610         if (padapter->securitypriv.binstallBIPkey != _TRUE) {
2611                 RTW_INFO("no instll BIP key\n");
2612                 goto xmitframe_coalesce_success;
2613         }
2614         /* station mode doesn't need TX BIP, just ready the code */
2615         if (bmcst) {
2616                 int frame_body_len;
2617                 u8 mic[16];
2618
2619                 _rtw_memset(MME, 0, _MME_IE_LENGTH_);
2620
2621                 /* other types doesn't need the BIP */
2622                 if (get_frame_sub_type(pframe) != WIFI_DEAUTH && get_frame_sub_type(pframe) != WIFI_DISASSOC)
2623                         goto xmitframe_coalesce_fail;
2624
2625                 MGMT_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
2626                 pframe += pattrib->pktlen;
2627
2628                 /* octent 0 and 1 is key index ,BIP keyid is 4 or 5, LSB only need octent 0 */
2629                 MME[0] = padapter->securitypriv.dot11wBIPKeyid;
2630                 /* copy packet number */
2631                 _rtw_memcpy(&MME[2], &pmlmeext->mgnt_80211w_IPN, 6);
2632                 /* increase the packet number */
2633                 pmlmeext->mgnt_80211w_IPN++;
2634
2635                 /* add MME IE with MIC all zero, MME string doesn't include element id and length */
2636                 pframe = rtw_set_ie(pframe, _MME_IE_ , 16 , MME, &(pattrib->pktlen));
2637                 pattrib->last_txcmdsz = pattrib->pktlen;
2638                 /* total frame length - header length */
2639                 frame_body_len = pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr);
2640
2641                 /* conscruct AAD, copy frame control field */
2642                 _rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2);
2643                 ClearRetry(BIP_AAD);
2644                 ClearPwrMgt(BIP_AAD);
2645                 ClearMData(BIP_AAD);
2646                 /* conscruct AAD, copy address 1 to address 3 */
2647                 _rtw_memcpy(BIP_AAD + 2, pwlanhdr->addr1, 18);
2648                 /* copy management fram body */
2649                 _rtw_memcpy(BIP_AAD + BIP_AAD_SIZE, MGMT_body, frame_body_len);
2650 #if 0
2651                 /* dump total packet include MME with zero MIC */
2652                 {
2653                         int i;
2654                         printk("Total packet: ");
2655                         for (i = 0; i < BIP_AAD_SIZE + frame_body_len; i++)
2656                                 printk(" %02x ", BIP_AAD[i]);
2657                         printk("\n");
2658                 }
2659 #endif
2660                 /* calculate mic */
2661                 if (omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey
2662                           , BIP_AAD, BIP_AAD_SIZE + frame_body_len, mic))
2663                         goto xmitframe_coalesce_fail;
2664
2665 #if 0
2666                 /* dump calculated mic result */
2667                 {
2668                         int i;
2669                         printk("Calculated mic result: ");
2670                         for (i = 0; i < 16; i++)
2671                                 printk(" %02x ", mic[i]);
2672                         printk("\n");
2673                 }
2674 #endif
2675                 /* copy right BIP mic value, total is 128bits, we use the 0~63 bits */
2676                 _rtw_memcpy(pframe - 8, mic, 8);
2677                 /*/dump all packet after mic ok
2678                 {
2679                         int pp;
2680                         printk("pattrib->pktlen = %d\n", pattrib->pktlen);
2681                         for(pp=0;pp< pattrib->pktlen; pp++)
2682                                 printk(" %02x ", mem_start[pp]);
2683                         printk("\n");
2684                 }*/
2685         } else { /* unicast mgmt frame TX */
2686                 /* start to encrypt mgmt frame */
2687                 if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC ||
2688                     subtype == WIFI_REASSOCREQ || subtype == WIFI_ACTION) {
2689                         if (pattrib->psta)
2690                                 psta = pattrib->psta;
2691                         else
2692                                 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2693
2694                         if (psta == NULL) {
2695
2696                                 RTW_INFO("%s, psta==NUL\n", __func__);
2697                                 goto xmitframe_coalesce_fail;
2698                         }
2699
2700                         if (pxmitframe->buf_addr == NULL) {
2701                                 RTW_INFO("%s, pxmitframe->buf_addr\n", __func__);
2702                                 goto xmitframe_coalesce_fail;
2703                         }
2704
2705                         /* RTW_INFO("%s, action frame category=%d\n", __func__, pframe[WLAN_HDR_A3_LEN]); */
2706                         /* according 802.11-2012 standard, these five types are not robust types */
2707                         if (subtype == WIFI_ACTION &&
2708                             (pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_PUBLIC ||
2709                              pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_HT ||
2710                              pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_UNPROTECTED_WNM ||
2711                              pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_SELF_PROTECTED  ||
2712                              pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_P2P))
2713                                 goto xmitframe_coalesce_fail;
2714                         /* before encrypt dump the management packet content */
2715                         /*{
2716                                 int i;
2717                                 printk("Management pkt: ");
2718                                 for(i=0; i<pattrib->pktlen; i++)
2719                                 printk(" %02x ", pframe[i]);
2720                                 printk("=======\n");
2721                         }*/
2722                         if (pattrib->encrypt > 0)
2723                                 _rtw_memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16);
2724
2725                         /* To use wrong key */
2726                         if (pattrib->key_type == IEEE80211W_WRONG_KEY) {
2727                                 RTW_INFO("use wrong key\n");
2728                                 pattrib->dot118021x_UncstKey.skey[0] = 0xff;
2729                         }
2730
2731                         /* bakeup original management packet */
2732                         _rtw_memcpy(tmp_buf, pframe, pattrib->pktlen);
2733                         /* move to data portion */
2734                         pframe += pattrib->hdrlen;
2735
2736                         /* 802.11w unicast management packet must be _AES_ */
2737                         pattrib->iv_len = 8;
2738                         /* it's MIC of AES */
2739                         pattrib->icv_len = 8;
2740
2741                         switch (pattrib->encrypt) {
2742                         case _AES_:
2743                                 /* set AES IV header */
2744                                 AES_IV(pattrib->iv, psta->dot11wtxpn, 0);
2745                                 break;
2746                         default:
2747                                 goto xmitframe_coalesce_fail;
2748                         }
2749                         /* insert iv header into management frame */
2750                         _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
2751                         pframe += pattrib->iv_len;
2752                         /* copy mgmt data portion after CCMP header */
2753                         _rtw_memcpy(pframe, tmp_buf + pattrib->hdrlen, pattrib->pktlen - pattrib->hdrlen);
2754                         /* move pframe to end of mgmt pkt */
2755                         pframe += pattrib->pktlen - pattrib->hdrlen;
2756                         /* add 8 bytes CCMP IV header to length */
2757                         pattrib->pktlen += pattrib->iv_len;
2758 #if 0
2759                         /* dump management packet include AES IV header */
2760                         {
2761                                 int i;
2762                                 printk("Management pkt + IV: ");
2763                                 /* for(i=0; i<pattrib->pktlen; i++) */
2764
2765                                 printk("@@@@@@@@@@@@@\n");
2766                         }
2767 #endif
2768
2769                         if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2770                                 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2771                                 pframe += pattrib->icv_len;
2772                         }
2773                         /* add 8 bytes MIC */
2774                         pattrib->pktlen += pattrib->icv_len;
2775                         /* set final tx command size */
2776                         pattrib->last_txcmdsz = pattrib->pktlen;
2777
2778                         /* set protected bit must be beofre SW encrypt */
2779                         SetPrivacy(mem_start);
2780 #if 0
2781                         /* dump management packet include AES header */
2782                         {
2783                                 int i;
2784                                 printk("prepare to enc Management pkt + IV: ");
2785                                 for (i = 0; i < pattrib->pktlen; i++)
2786                                         printk(" %02x ", mem_start[i]);
2787                                 printk("@@@@@@@@@@@@@\n");
2788                         }
2789 #endif
2790                         /* software encrypt */
2791                         xmitframe_swencrypt(padapter, pxmitframe);
2792                 }
2793         }
2794
2795 xmitframe_coalesce_success:
2796         _exit_critical_bh(&padapter->security_key_mutex, &irqL);
2797         rtw_mfree(BIP_AAD, ori_len);
2798         return _SUCCESS;
2799
2800 xmitframe_coalesce_fail:
2801         _exit_critical_bh(&padapter->security_key_mutex, &irqL);
2802         rtw_mfree(BIP_AAD, ori_len);
2803
2804         return _FAIL;
2805 }
2806 #endif /* CONFIG_IEEE80211W */
2807
2808 /* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
2809  * IEEE LLC/SNAP header contains 8 octets
2810  * First 3 octets comprise the LLC portion
2811  * SNAP portion, 5 octets, is divided into two fields:
2812  *      Organizationally Unique Identifier(OUI), 3 octets,
2813  *      type, defined by that organization, 2 octets.
2814  */
2815 s32 rtw_put_snap(u8 *data, u16 h_proto)
2816 {
2817         struct ieee80211_snap_hdr *snap;
2818         u8 *oui;
2819
2820
2821         snap = (struct ieee80211_snap_hdr *)data;
2822         snap->dsap = 0xaa;
2823         snap->ssap = 0xaa;
2824         snap->ctrl = 0x03;
2825
2826         if (h_proto == 0x8137 || h_proto == 0x80f3)
2827                 oui = P802_1H_OUI;
2828         else
2829                 oui = RFC1042_OUI;
2830
2831         snap->oui[0] = oui[0];
2832         snap->oui[1] = oui[1];
2833         snap->oui[2] = oui[2];
2834
2835         *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
2836
2837
2838         return SNAP_SIZE + sizeof(u16);
2839 }
2840
2841 void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len)
2842 {
2843
2844         uint    protection;
2845         u8      *perp;
2846         sint     erp_len;
2847         struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
2848         struct  registry_priv *pregistrypriv = &padapter->registrypriv;
2849
2850
2851         switch (pxmitpriv->vcs_setting) {
2852         case DISABLE_VCS:
2853                 pxmitpriv->vcs = NONE_VCS;
2854                 break;
2855
2856         case ENABLE_VCS:
2857                 break;
2858
2859         case AUTO_VCS:
2860         default:
2861                 perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
2862                 if (perp == NULL)
2863                         pxmitpriv->vcs = NONE_VCS;
2864                 else {
2865                         protection = (*(perp + 2)) & BIT(1);
2866                         if (protection) {
2867                                 if (pregistrypriv->vcs_type == RTS_CTS)
2868                                         pxmitpriv->vcs = RTS_CTS;
2869                                 else
2870                                         pxmitpriv->vcs = CTS_TO_SELF;
2871                         } else
2872                                 pxmitpriv->vcs = NONE_VCS;
2873                 }
2874
2875                 break;
2876
2877         }
2878
2879
2880 }
2881
2882 void rtw_count_tx_stats(PADAPTER padapter, struct xmit_frame *pxmitframe, int sz)
2883 {
2884         struct sta_info *psta = NULL;
2885         struct stainfo_stats *pstats = NULL;
2886         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
2887         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
2888         u8      pkt_num = 1;
2889
2890         if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
2891 #if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2892                 pkt_num = pxmitframe->agg_num;
2893 #endif
2894                 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pkt_num;
2895
2896                 pxmitpriv->tx_pkts += pkt_num;
2897
2898                 pxmitpriv->tx_bytes += sz;
2899
2900                 psta = pxmitframe->attrib.psta;
2901                 if (psta) {
2902                         pstats = &psta->sta_stats;
2903
2904                         pstats->tx_pkts += pkt_num;
2905
2906                         pstats->tx_bytes += sz;
2907 #ifdef CONFIG_TDLS
2908                         if (pxmitframe->attrib.ptdls_sta != NULL) {
2909                                 pstats = &(pxmitframe->attrib.ptdls_sta->sta_stats);
2910                                 pstats->tx_pkts += pkt_num;
2911                                 pstats->tx_bytes += sz;
2912                         }
2913 #endif /* CONFIG_TDLS */
2914                 }
2915
2916 #ifdef CONFIG_CHECK_LEAVE_LPS
2917                 /* traffic_check_for_leave_lps(padapter, _TRUE); */
2918 #endif /* CONFIG_LPS */
2919
2920         }
2921 }
2922
2923 static struct xmit_buf *__rtw_alloc_cmd_xmitbuf(struct xmit_priv *pxmitpriv,
2924                 enum cmdbuf_type buf_type)
2925 {
2926         struct xmit_buf *pxmitbuf =  NULL;
2927
2928
2929         pxmitbuf = &pxmitpriv->pcmd_xmitbuf[buf_type];
2930         if (pxmitbuf !=  NULL) {
2931                 pxmitbuf->priv_data = NULL;
2932
2933 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2934                 pxmitbuf->len = 0;
2935                 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
2936                 pxmitbuf->agg_num = 0;
2937                 pxmitbuf->pg_num = 0;
2938 #endif
2939 #ifdef CONFIG_PCI_HCI
2940                 pxmitbuf->len = 0;
2941 #ifdef CONFIG_TRX_BD_ARCH
2942                 /*pxmitbuf->buf_desc = NULL;*/
2943 #else
2944                 pxmitbuf->desc = NULL;
2945 #endif
2946 #endif
2947
2948                 if (pxmitbuf->sctx) {
2949                         RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
2950                         rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
2951                 }
2952         } else
2953                 RTW_INFO("%s fail, no xmitbuf available !!!\n", __func__);
2954
2955 exit:
2956
2957
2958         return pxmitbuf;
2959 }
2960
2961 struct xmit_frame *__rtw_alloc_cmdxmitframe(struct xmit_priv *pxmitpriv,
2962                 enum cmdbuf_type buf_type)
2963 {
2964         struct xmit_frame               *pcmdframe;
2965         struct xmit_buf         *pxmitbuf;
2966
2967         pcmdframe = rtw_alloc_xmitframe(pxmitpriv);
2968         if (pcmdframe == NULL) {
2969                 RTW_INFO("%s, alloc xmitframe fail\n", __FUNCTION__);
2970                 return NULL;
2971         }
2972
2973         pxmitbuf = __rtw_alloc_cmd_xmitbuf(pxmitpriv, buf_type);
2974         if (pxmitbuf == NULL) {
2975                 RTW_INFO("%s, alloc xmitbuf fail\n", __FUNCTION__);
2976                 rtw_free_xmitframe(pxmitpriv, pcmdframe);
2977                 return NULL;
2978         }
2979
2980         pcmdframe->frame_tag = MGNT_FRAMETAG;
2981
2982         pcmdframe->pxmitbuf = pxmitbuf;
2983
2984         pcmdframe->buf_addr = pxmitbuf->pbuf;
2985
2986         /* initial memory to zero */
2987         _rtw_memset(pcmdframe->buf_addr, 0, pxmitbuf->alloc_sz);
2988
2989         pxmitbuf->priv_data = pcmdframe;
2990
2991         return pcmdframe;
2992
2993 }
2994
2995 struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
2996 {
2997         _irqL irqL;
2998         struct xmit_buf *pxmitbuf =  NULL;
2999         _list *plist, *phead;
3000         _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
3001
3002
3003         _enter_critical(&pfree_queue->lock, &irqL);
3004
3005         if (_rtw_queue_empty(pfree_queue) == _TRUE)
3006                 pxmitbuf = NULL;
3007         else {
3008
3009                 phead = get_list_head(pfree_queue);
3010
3011                 plist = get_next(phead);
3012
3013                 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
3014
3015                 rtw_list_delete(&(pxmitbuf->list));
3016         }
3017
3018         if (pxmitbuf !=  NULL) {
3019                 pxmitpriv->free_xmit_extbuf_cnt--;
3020 #ifdef DBG_XMIT_BUF_EXT
3021                 RTW_INFO("DBG_XMIT_BUF_EXT ALLOC no=%d,  free_xmit_extbuf_cnt=%d\n", pxmitbuf->no, pxmitpriv->free_xmit_extbuf_cnt);
3022 #endif
3023
3024
3025                 pxmitbuf->priv_data = NULL;
3026
3027 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3028                 pxmitbuf->len = 0;
3029                 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
3030                 pxmitbuf->agg_num = 1;
3031 #endif
3032 #ifdef CONFIG_PCI_HCI
3033                 pxmitbuf->len = 0;
3034 #ifdef CONFIG_TRX_BD_ARCH
3035                 /*pxmitbuf->buf_desc = NULL;*/
3036 #else
3037                 pxmitbuf->desc = NULL;
3038 #endif
3039 #endif
3040
3041                 if (pxmitbuf->sctx) {
3042                         RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
3043                         rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
3044                 }
3045
3046         }
3047
3048         _exit_critical(&pfree_queue->lock, &irqL);
3049
3050
3051         return pxmitbuf;
3052 }
3053
3054 s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
3055 {
3056         _irqL irqL;
3057         _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
3058
3059
3060         if (pxmitbuf == NULL)
3061                 return _FAIL;
3062
3063         _enter_critical(&pfree_queue->lock, &irqL);
3064
3065         rtw_list_delete(&pxmitbuf->list);
3066
3067         rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_queue));
3068         pxmitpriv->free_xmit_extbuf_cnt++;
3069 #ifdef DBG_XMIT_BUF_EXT
3070         RTW_INFO("DBG_XMIT_BUF_EXT FREE no=%d, free_xmit_extbuf_cnt=%d\n", pxmitbuf->no , pxmitpriv->free_xmit_extbuf_cnt);
3071 #endif
3072
3073         _exit_critical(&pfree_queue->lock, &irqL);
3074
3075
3076         return _SUCCESS;
3077 }
3078
3079 struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
3080 {
3081         _irqL irqL;
3082         struct xmit_buf *pxmitbuf =  NULL;
3083         _list *plist, *phead;
3084         _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
3085
3086
3087         /* RTW_INFO("+rtw_alloc_xmitbuf\n"); */
3088
3089         _enter_critical(&pfree_xmitbuf_queue->lock, &irqL);
3090
3091         if (_rtw_queue_empty(pfree_xmitbuf_queue) == _TRUE)
3092                 pxmitbuf = NULL;
3093         else {
3094
3095                 phead = get_list_head(pfree_xmitbuf_queue);
3096
3097                 plist = get_next(phead);
3098
3099                 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
3100
3101                 rtw_list_delete(&(pxmitbuf->list));
3102         }
3103
3104         if (pxmitbuf !=  NULL) {
3105                 pxmitpriv->free_xmitbuf_cnt--;
3106 #ifdef DBG_XMIT_BUF
3107                 RTW_INFO("DBG_XMIT_BUF ALLOC no=%d,  free_xmitbuf_cnt=%d\n", pxmitbuf->no, pxmitpriv->free_xmitbuf_cnt);
3108 #endif
3109                 /* RTW_INFO("alloc, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); */
3110
3111                 pxmitbuf->priv_data = NULL;
3112
3113 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3114                 pxmitbuf->len = 0;
3115                 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
3116                 pxmitbuf->agg_num = 0;
3117                 pxmitbuf->pg_num = 0;
3118 #endif
3119 #ifdef CONFIG_PCI_HCI
3120                 pxmitbuf->len = 0;
3121 #ifdef CONFIG_TRX_BD_ARCH
3122                 /*pxmitbuf->buf_desc = NULL;*/
3123 #else
3124                 pxmitbuf->desc = NULL;
3125 #endif
3126 #endif
3127
3128                 if (pxmitbuf->sctx) {
3129                         RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
3130                         rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
3131                 }
3132         }
3133 #ifdef DBG_XMIT_BUF
3134         else
3135                 RTW_INFO("DBG_XMIT_BUF rtw_alloc_xmitbuf return NULL\n");
3136 #endif
3137
3138         _exit_critical(&pfree_xmitbuf_queue->lock, &irqL);
3139
3140
3141         return pxmitbuf;
3142 }
3143
3144 s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
3145 {
3146         _irqL irqL;
3147         _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
3148
3149
3150         /* RTW_INFO("+rtw_free_xmitbuf\n"); */
3151
3152         if (pxmitbuf == NULL)
3153                 return _FAIL;
3154
3155         if (pxmitbuf->sctx) {
3156                 RTW_INFO("%s pxmitbuf->sctx is not NULL\n", __func__);
3157                 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
3158         }
3159
3160         if (pxmitbuf->buf_tag == XMITBUF_CMD) {
3161         } else if (pxmitbuf->buf_tag == XMITBUF_MGNT)
3162                 rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf);
3163         else {
3164                 _enter_critical(&pfree_xmitbuf_queue->lock, &irqL);
3165
3166                 rtw_list_delete(&pxmitbuf->list);
3167
3168                 rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
3169
3170                 pxmitpriv->free_xmitbuf_cnt++;
3171                 /* RTW_INFO("FREE, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); */
3172 #ifdef DBG_XMIT_BUF
3173                 RTW_INFO("DBG_XMIT_BUF FREE no=%d, free_xmitbuf_cnt=%d\n", pxmitbuf->no , pxmitpriv->free_xmitbuf_cnt);
3174 #endif
3175                 _exit_critical(&pfree_xmitbuf_queue->lock, &irqL);
3176         }
3177
3178
3179         return _SUCCESS;
3180 }
3181
3182 void rtw_init_xmitframe(struct xmit_frame *pxframe)
3183 {
3184         if (pxframe !=  NULL) { /* default value setting */
3185                 pxframe->buf_addr = NULL;
3186                 pxframe->pxmitbuf = NULL;
3187
3188                 _rtw_memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
3189                 /* pxframe->attrib.psta = NULL; */
3190
3191                 pxframe->frame_tag = DATA_FRAMETAG;
3192
3193 #ifdef CONFIG_USB_HCI
3194                 pxframe->pkt = NULL;
3195 #ifdef USB_PACKET_OFFSET_SZ
3196                 pxframe->pkt_offset = (PACKET_OFFSET_SZ / 8);
3197 #else
3198                 pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */
3199 #endif
3200
3201 #ifdef CONFIG_USB_TX_AGGREGATION
3202                 pxframe->agg_num = 1;
3203 #endif
3204
3205 #endif /* #ifdef CONFIG_USB_HCI */
3206
3207 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3208                 pxframe->pg_num = 1;
3209                 pxframe->agg_num = 1;
3210 #endif
3211
3212 #ifdef CONFIG_XMIT_ACK
3213                 pxframe->ack_report = 0;
3214 #endif
3215
3216         }
3217 }
3218
3219 /*
3220 Calling context:
3221 1. OS_TXENTRY
3222 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
3223
3224 If we turn on USE_RXTHREAD, then, no need for critical section.
3225 Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
3226
3227 Must be very very cautious...
3228
3229 */
3230 struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* (_queue *pfree_xmit_queue) */
3231 {
3232         /*
3233                 Please remember to use all the osdep_service api,
3234                 and lock/unlock or _enter/_exit critical to protect
3235                 pfree_xmit_queue
3236         */
3237
3238         _irqL irqL;
3239         struct xmit_frame *pxframe = NULL;
3240         _list *plist, *phead;
3241         _queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
3242
3243
3244         _enter_critical_bh(&pfree_xmit_queue->lock, &irqL);
3245
3246         if (_rtw_queue_empty(pfree_xmit_queue) == _TRUE) {
3247                 pxframe =  NULL;
3248         } else {
3249                 phead = get_list_head(pfree_xmit_queue);
3250
3251                 plist = get_next(phead);
3252
3253                 pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3254
3255                 rtw_list_delete(&(pxframe->list));
3256                 pxmitpriv->free_xmitframe_cnt--;
3257         }
3258
3259         _exit_critical_bh(&pfree_xmit_queue->lock, &irqL);
3260
3261         rtw_init_xmitframe(pxframe);
3262
3263
3264         return pxframe;
3265 }
3266
3267 struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv)
3268 {
3269         _irqL irqL;
3270         struct xmit_frame *pxframe = NULL;
3271         _list *plist, *phead;
3272         _queue *queue = &pxmitpriv->free_xframe_ext_queue;
3273
3274
3275         _enter_critical_bh(&queue->lock, &irqL);
3276
3277         if (_rtw_queue_empty(queue) == _TRUE) {
3278                 pxframe =  NULL;
3279         } else {
3280                 phead = get_list_head(queue);
3281                 plist = get_next(phead);
3282                 pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3283
3284                 rtw_list_delete(&(pxframe->list));
3285                 pxmitpriv->free_xframe_ext_cnt--;
3286         }
3287
3288         _exit_critical_bh(&queue->lock, &irqL);
3289
3290         rtw_init_xmitframe(pxframe);
3291
3292
3293         return pxframe;
3294 }
3295
3296 struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv)
3297 {
3298         struct xmit_frame *pxframe = NULL;
3299         u8 *alloc_addr;
3300
3301         alloc_addr = rtw_zmalloc(sizeof(struct xmit_frame) + 4);
3302
3303         if (alloc_addr == NULL)
3304                 goto exit;
3305
3306         pxframe = (struct xmit_frame *)N_BYTE_ALIGMENT((SIZE_PTR)(alloc_addr), 4);
3307         pxframe->alloc_addr = alloc_addr;
3308
3309         pxframe->padapter = pxmitpriv->adapter;
3310         pxframe->frame_tag = NULL_FRAMETAG;
3311
3312         pxframe->pkt = NULL;
3313
3314         pxframe->buf_addr = NULL;
3315         pxframe->pxmitbuf = NULL;
3316
3317         rtw_init_xmitframe(pxframe);
3318
3319         RTW_INFO("################## %s ##################\n", __func__);
3320
3321 exit:
3322         return pxframe;
3323 }
3324
3325 s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
3326 {
3327         _irqL irqL;
3328         _queue *queue = NULL;
3329         _adapter *padapter = pxmitpriv->adapter;
3330         _pkt *pndis_pkt = NULL;
3331
3332
3333         if (pxmitframe == NULL) {
3334                 goto exit;
3335         }
3336
3337         if (pxmitframe->pkt) {
3338                 pndis_pkt = pxmitframe->pkt;
3339                 pxmitframe->pkt = NULL;
3340         }
3341
3342         if (pxmitframe->alloc_addr) {
3343                 RTW_INFO("################## %s with alloc_addr ##################\n", __func__);
3344                 rtw_mfree(pxmitframe->alloc_addr, sizeof(struct xmit_frame) + 4);
3345                 goto check_pkt_complete;
3346         }
3347
3348         if (pxmitframe->ext_tag == 0)
3349                 queue = &pxmitpriv->free_xmit_queue;
3350         else if (pxmitframe->ext_tag == 1)
3351                 queue = &pxmitpriv->free_xframe_ext_queue;
3352         else
3353                 rtw_warn_on(1);
3354
3355         _enter_critical_bh(&queue->lock, &irqL);
3356
3357         rtw_list_delete(&pxmitframe->list);
3358         rtw_list_insert_tail(&pxmitframe->list, get_list_head(queue));
3359         if (pxmitframe->ext_tag == 0) {
3360                 pxmitpriv->free_xmitframe_cnt++;
3361         } else if (pxmitframe->ext_tag == 1) {
3362                 pxmitpriv->free_xframe_ext_cnt++;
3363         } else {
3364         }
3365
3366         _exit_critical_bh(&queue->lock, &irqL);
3367
3368 check_pkt_complete:
3369
3370         if (pndis_pkt)
3371                 rtw_os_pkt_complete(padapter, pndis_pkt);
3372
3373 exit:
3374
3375
3376         return _SUCCESS;
3377 }
3378
3379 void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue)
3380 {
3381         _irqL irqL;
3382         _list   *plist, *phead;
3383         struct  xmit_frame      *pxmitframe;
3384
3385
3386         _enter_critical_bh(&(pframequeue->lock), &irqL);
3387
3388         phead = get_list_head(pframequeue);
3389         plist = get_next(phead);
3390
3391         while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
3392
3393                 pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3394
3395                 plist = get_next(plist);
3396
3397                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
3398
3399         }
3400         _exit_critical_bh(&(pframequeue->lock), &irqL);
3401
3402 }
3403
3404 s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
3405 {
3406         DBG_COUNTER(padapter->tx_logs.core_tx_enqueue);
3407         if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) {
3408                 /*              pxmitframe->pkt = NULL; */
3409                 return _FAIL;
3410         }
3411
3412         return _SUCCESS;
3413 }
3414
3415 static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue)
3416 {
3417         _list   *xmitframe_plist, *xmitframe_phead;
3418         struct  xmit_frame      *pxmitframe = NULL;
3419
3420         xmitframe_phead = get_list_head(pframe_queue);
3421         xmitframe_plist = get_next(xmitframe_phead);
3422
3423         while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
3424                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
3425
3426                 /* xmitframe_plist = get_next(xmitframe_plist); */
3427
3428                 /*#ifdef RTK_DMP_PLATFORM
3429                 #ifdef CONFIG_USB_TX_AGGREGATION
3430                                 if((ptxservq->qcnt>0) && (ptxservq->qcnt<=2))
3431                                 {
3432                                         pxmitframe = NULL;
3433
3434                                         tasklet_schedule(&pxmitpriv->xmit_tasklet);
3435
3436                                         break;
3437                                 }
3438                 #endif
3439                 #endif*/
3440                 rtw_list_delete(&pxmitframe->list);
3441
3442                 ptxservq->qcnt--;
3443
3444                 /* rtw_list_insert_tail(&pxmitframe->list, &phwxmit->pending); */
3445
3446                 /* ptxservq->qcnt--; */
3447
3448                 break;
3449
3450                 /* pxmitframe = NULL; */
3451
3452         }
3453
3454         return pxmitframe;
3455 }
3456
3457 static struct xmit_frame *get_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue)
3458 {
3459         _list   *xmitframe_plist, *xmitframe_phead;
3460         struct  xmit_frame      *pxmitframe = NULL;
3461
3462         xmitframe_phead = get_list_head(pframe_queue);
3463         xmitframe_plist = get_next(xmitframe_phead);
3464
3465         while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
3466                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
3467                 break;
3468         }
3469
3470         return pxmitframe;
3471 }
3472
3473 struct xmit_frame *rtw_get_xframe(struct xmit_priv *pxmitpriv, int *num_frame)
3474 {
3475         _irqL irqL0;
3476         _list *sta_plist, *sta_phead;
3477         struct hw_xmit *phwxmit_i = pxmitpriv->hwxmits;
3478         sint entry =  pxmitpriv->hwxmit_entry;
3479
3480         struct hw_xmit *phwxmit;
3481         struct tx_servq *ptxservq = NULL;
3482         _queue *pframe_queue = NULL;
3483         struct xmit_frame *pxmitframe = NULL;
3484         _adapter *padapter = pxmitpriv->adapter;
3485         struct registry_priv    *pregpriv = &padapter->registrypriv;
3486         int i, inx[4];
3487
3488 #ifdef CONFIG_USB_HCI
3489         /*      int j, tmp, acirp_cnt[4]; */
3490 #endif
3491
3492         inx[0] = 0;
3493         inx[1] = 1;
3494         inx[2] = 2;
3495         inx[3] = 3;
3496
3497         *num_frame = 0;
3498
3499         /*No amsdu when wifi_spec on*/
3500         if (pregpriv->wifi_spec == 1) {
3501                 return NULL;
3502         }
3503
3504         _enter_critical_bh(&pxmitpriv->lock, &irqL0);
3505
3506         for (i = 0; i < entry; i++) {
3507                 phwxmit = phwxmit_i + inx[i];
3508
3509                 sta_phead = get_list_head(phwxmit->sta_queue);
3510                 sta_plist = get_next(sta_phead);
3511
3512                 while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) {
3513
3514                         ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
3515                         pframe_queue = &ptxservq->sta_pending;
3516
3517                         if(ptxservq->qcnt)
3518                         {
3519                                 *num_frame = ptxservq->qcnt;
3520                                 pxmitframe = get_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
3521                                 goto exit;
3522                         }
3523                         sta_plist = get_next(sta_plist);
3524                 }
3525         }
3526
3527 exit:
3528
3529         _exit_critical_bh(&pxmitpriv->lock, &irqL0);
3530
3531         return pxmitframe;
3532 }
3533
3534
3535 struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry)
3536 {
3537         _irqL irqL0;
3538         _list *sta_plist, *sta_phead;
3539         struct hw_xmit *phwxmit;
3540         struct tx_servq *ptxservq = NULL;
3541         _queue *pframe_queue = NULL;
3542         struct xmit_frame *pxmitframe = NULL;
3543         _adapter *padapter = pxmitpriv->adapter;
3544         struct registry_priv    *pregpriv = &padapter->registrypriv;
3545         int i, inx[4];
3546 #ifdef CONFIG_USB_HCI
3547         /*      int j, tmp, acirp_cnt[4]; */
3548 #endif
3549
3550
3551         inx[0] = 0;
3552         inx[1] = 1;
3553         inx[2] = 2;
3554         inx[3] = 3;
3555
3556         if (pregpriv->wifi_spec == 1) {
3557                 int j, tmp, acirp_cnt[4];
3558 #if 0
3559                 if (flags < XMIT_QUEUE_ENTRY) {
3560                         /* priority exchange according to the completed xmitbuf flags. */
3561                         inx[flags] = 0;
3562                         inx[0] = flags;
3563                 }
3564 #endif
3565
3566 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_PCI_HCI)
3567                 for (j = 0; j < 4; j++)
3568                         inx[j] = pxmitpriv->wmm_para_seq[j];
3569 #endif
3570         }
3571
3572         _enter_critical_bh(&pxmitpriv->lock, &irqL0);
3573
3574         for (i = 0; i < entry; i++) {
3575                 phwxmit = phwxmit_i + inx[i];
3576
3577                 /* _enter_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
3578
3579                 sta_phead = get_list_head(phwxmit->sta_queue);
3580                 sta_plist = get_next(sta_phead);
3581
3582                 while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) {
3583
3584                         ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
3585
3586                         pframe_queue = &ptxservq->sta_pending;
3587
3588                         pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
3589
3590                         if (pxmitframe) {
3591                                 phwxmit->accnt--;
3592
3593                                 /* Remove sta node when there is no pending packets. */
3594                                 if (_rtw_queue_empty(pframe_queue)) /* must be done after get_next and before break */
3595                                         rtw_list_delete(&ptxservq->tx_pending);
3596
3597                                 /* _exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
3598
3599                                 goto exit;
3600                         }
3601
3602                         sta_plist = get_next(sta_plist);
3603
3604                 }
3605
3606                 /* _exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
3607
3608         }
3609
3610 exit:
3611
3612         _exit_critical_bh(&pxmitpriv->lock, &irqL0);
3613
3614         return pxmitframe;
3615 }
3616
3617 #if 1
3618 struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac)
3619 {
3620         struct tx_servq *ptxservq = NULL;
3621
3622
3623         switch (up) {
3624         case 1:
3625         case 2:
3626                 ptxservq = &(psta->sta_xmitpriv.bk_q);
3627                 *(ac) = 3;
3628                 break;
3629
3630         case 4:
3631         case 5:
3632                 ptxservq = &(psta->sta_xmitpriv.vi_q);
3633                 *(ac) = 1;
3634                 break;
3635
3636         case 6:
3637         case 7:
3638                 ptxservq = &(psta->sta_xmitpriv.vo_q);
3639                 *(ac) = 0;
3640                 break;
3641
3642         case 0:
3643         case 3:
3644         default:
3645                 ptxservq = &(psta->sta_xmitpriv.be_q);
3646                 *(ac) = 2;
3647                 break;
3648
3649         }
3650
3651
3652         return ptxservq;
3653 }
3654 #else
3655 __inline static struct tx_servq *rtw_get_sta_pending
3656 (_adapter *padapter, _queue **ppstapending, struct sta_info *psta, sint up)
3657 {
3658         struct tx_servq *ptxservq;
3659         struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
3660
3661
3662 #ifdef CONFIG_RTL8711
3663
3664         if (IS_MCAST(psta->hwaddr)) {
3665                 ptxservq = &(psta->sta_xmitpriv.be_q); /* we will use be_q to queue bc/mc frames in BCMC_stainfo */
3666                 *ppstapending = &padapter->xmitpriv.bm_pending;
3667         } else
3668 #endif
3669         {
3670                 switch (up) {
3671                 case 1:
3672                 case 2:
3673                         ptxservq = &(psta->sta_xmitpriv.bk_q);
3674                         *ppstapending = &padapter->xmitpriv.bk_pending;
3675                         (phwxmits + 3)->accnt++;
3676                         break;
3677
3678                 case 4:
3679                 case 5:
3680                         ptxservq = &(psta->sta_xmitpriv.vi_q);
3681                         *ppstapending = &padapter->xmitpriv.vi_pending;
3682                         (phwxmits + 1)->accnt++;
3683                         break;
3684
3685                 case 6:
3686                 case 7:
3687                         ptxservq = &(psta->sta_xmitpriv.vo_q);
3688                         *ppstapending = &padapter->xmitpriv.vo_pending;
3689                         (phwxmits + 0)->accnt++;
3690                         break;
3691
3692                 case 0:
3693                 case 3:
3694                 default:
3695                         ptxservq = &(psta->sta_xmitpriv.be_q);
3696                         *ppstapending = &padapter->xmitpriv.be_pending;
3697                         (phwxmits + 2)->accnt++;
3698                         break;
3699
3700                 }
3701
3702         }
3703
3704
3705         return ptxservq;
3706 }
3707 #endif
3708
3709 /*
3710  * Will enqueue pxmitframe to the proper queue,
3711  * and indicate it to xx_pending list.....
3712  */
3713 s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe)
3714 {
3715         /* _irqL irqL0; */
3716         u8      ac_index;
3717         struct sta_info *psta;
3718         struct tx_servq *ptxservq;
3719         struct pkt_attrib       *pattrib = &pxmitframe->attrib;
3720         struct sta_priv *pstapriv = &padapter->stapriv;
3721         struct hw_xmit  *phwxmits =  padapter->xmitpriv.hwxmits;
3722         sint res = _SUCCESS;
3723
3724
3725         DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class);
3726
3727         /*
3728                 if (pattrib->psta) {
3729                         psta = pattrib->psta;
3730                 } else {
3731                         RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
3732                         psta = rtw_get_stainfo(pstapriv, pattrib->ra);
3733                 }
3734         */
3735
3736         psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
3737         if (pattrib->psta != psta) {
3738                 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_sta);
3739                 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
3740                 return _FAIL;
3741         }
3742
3743         if (psta == NULL) {
3744                 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_nosta);
3745                 res = _FAIL;
3746                 RTW_INFO("rtw_xmit_classifier: psta == NULL\n");
3747                 goto exit;
3748         }
3749
3750         if (!(psta->state & _FW_LINKED)) {
3751                 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_fwlink);
3752                 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
3753                 return _FAIL;
3754         }
3755
3756         ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
3757
3758         /* _enter_critical(&pstapending->lock, &irqL0); */
3759
3760         if (rtw_is_list_empty(&ptxservq->tx_pending))
3761                 rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
3762
3763         /* _enter_critical(&ptxservq->sta_pending.lock, &irqL1); */
3764
3765         rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
3766         ptxservq->qcnt++;
3767         phwxmits[ac_index].accnt++;
3768
3769         /* _exit_critical(&ptxservq->sta_pending.lock, &irqL1); */
3770
3771         /* _exit_critical(&pstapending->lock, &irqL0); */
3772
3773 exit:
3774
3775
3776         return res;
3777 }
3778
3779 void rtw_alloc_hwxmits(_adapter *padapter)
3780 {
3781         struct hw_xmit *hwxmits;
3782         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3783
3784         pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
3785
3786         pxmitpriv->hwxmits = NULL;
3787
3788         pxmitpriv->hwxmits = (struct hw_xmit *)rtw_zmalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry);
3789
3790         if (pxmitpriv->hwxmits == NULL) {
3791                 RTW_INFO("alloc hwxmits fail!...\n");
3792                 return;
3793         }
3794
3795         hwxmits = pxmitpriv->hwxmits;
3796
3797         if (pxmitpriv->hwxmit_entry == 5) {
3798                 /* pxmitpriv->bmc_txqueue.head = 0; */
3799                 /* hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; */
3800                 hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
3801
3802                 /* pxmitpriv->vo_txqueue.head = 0; */
3803                 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; */
3804                 hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
3805
3806                 /* pxmitpriv->vi_txqueue.head = 0; */
3807                 /* hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; */
3808                 hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
3809
3810                 /* pxmitpriv->bk_txqueue.head = 0; */
3811                 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
3812                 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
3813
3814                 /* pxmitpriv->be_txqueue.head = 0; */
3815                 /* hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; */
3816                 hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
3817
3818         } else if (pxmitpriv->hwxmit_entry == 4) {
3819
3820                 /* pxmitpriv->vo_txqueue.head = 0; */
3821                 /* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */
3822                 hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
3823
3824                 /* pxmitpriv->vi_txqueue.head = 0; */
3825                 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */
3826                 hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
3827
3828                 /* pxmitpriv->be_txqueue.head = 0; */
3829                 /* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */
3830                 hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
3831
3832                 /* pxmitpriv->bk_txqueue.head = 0; */
3833                 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
3834                 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
3835         } else {
3836
3837
3838         }
3839
3840
3841 }
3842
3843 void rtw_free_hwxmits(_adapter *padapter)
3844 {
3845         struct hw_xmit *hwxmits;
3846         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3847
3848         hwxmits = pxmitpriv->hwxmits;
3849         if (hwxmits)
3850                 rtw_mfree((u8 *)hwxmits, (sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry));
3851 }
3852
3853 void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry)
3854 {
3855         sint i;
3856         for (i = 0; i < entry; i++, phwxmit++) {
3857                 /* _rtw_spinlock_init(&phwxmit->xmit_lock); */
3858                 /* _rtw_init_listhead(&phwxmit->pending);                */
3859                 /* phwxmit->txcmdcnt = 0; */
3860                 phwxmit->accnt = 0;
3861         }
3862 }
3863
3864 #ifdef CONFIG_BR_EXT
3865 int rtw_br_client_tx(_adapter *padapter, struct sk_buff **pskb)
3866 {
3867         struct sk_buff *skb = *pskb;
3868         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3869         _irqL irqL;
3870         /* if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) */
3871         {
3872                 void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb);
3873                 int res, is_vlan_tag = 0, i, do_nat25 = 1;
3874                 unsigned short vlan_hdr = 0;
3875                 void *br_port = NULL;
3876
3877                 /* mac_clone_handle_frame(priv, skb); */
3878
3879 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3880                 br_port = padapter->pnetdev->br_port;
3881 #else   /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
3882                 rcu_read_lock();
3883                 br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
3884                 rcu_read_unlock();
3885 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
3886                 _enter_critical_bh(&padapter->br_ext_lock, &irqL);
3887                 if (!(skb->data[0] & 1) &&
3888                     br_port &&
3889                     memcmp(skb->data + MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
3890                     *((unsigned short *)(skb->data + MACADDRLEN * 2)) != __constant_htons(ETH_P_8021Q) &&
3891                     *((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP) &&
3892                     !memcmp(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN) && padapter->scdb_entry) {
3893                         memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
3894                         padapter->scdb_entry->ageing_timer = jiffies;
3895                         _exit_critical_bh(&padapter->br_ext_lock, &irqL);
3896                 } else
3897                         /* if (!priv->pmib->ethBrExtInfo.nat25_disable)          */
3898                 {
3899                         /*                      if (priv->dev->br_port &&
3900                          *                               !memcmp(skb->data+MACADDRLEN, priv->br_mac, MACADDRLEN)) { */
3901 #if 1
3902                         if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q)) {
3903                                 is_vlan_tag = 1;
3904                                 vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2));
3905                                 for (i = 0; i < 6; i++)
3906                                         *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2));
3907                                 skb_pull(skb, 4);
3908                         }
3909                         /* if SA == br_mac && skb== IP  => copy SIP to br_ip ?? why */
3910                         if (!memcmp(skb->data + MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
3911                             (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP)))
3912                                 memcpy(padapter->br_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4);
3913
3914                         if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP)) {
3915                                 if (memcmp(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN)) {
3916                                         void *scdb_findEntry(_adapter *priv, unsigned char *macAddr, unsigned char *ipAddr);
3917
3918                                         padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter,
3919                                                 skb->data + MACADDRLEN, skb->data + WLAN_ETHHDR_LEN + 12);
3920                                         if (padapter->scdb_entry != NULL) {
3921                                                 memcpy(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN);
3922                                                 memcpy(padapter->scdb_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4);
3923                                                 padapter->scdb_entry->ageing_timer = jiffies;
3924                                                 do_nat25 = 0;
3925                                         }
3926                                 } else {
3927                                         if (padapter->scdb_entry) {
3928                                                 padapter->scdb_entry->ageing_timer = jiffies;
3929                                                 do_nat25 = 0;
3930                                         } else {
3931                                                 memset(padapter->scdb_mac, 0, MACADDRLEN);
3932                                                 memset(padapter->scdb_ip, 0, 4);
3933                                         }
3934                                 }
3935                         }
3936                         _exit_critical_bh(&padapter->br_ext_lock, &irqL);
3937 #endif /* 1 */
3938                         if (do_nat25) {
3939                                 int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method);
3940                                 if (nat25_db_handle(padapter, skb, NAT25_CHECK) == 0) {
3941                                         struct sk_buff *newskb;
3942
3943                                         if (is_vlan_tag) {
3944                                                 skb_push(skb, 4);
3945                                                 for (i = 0; i < 6; i++)
3946                                                         *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2));
3947                                                 *((unsigned short *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q);
3948                                                 *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr;
3949                                         }
3950
3951                                         newskb = rtw_skb_copy(skb);
3952                                         if (newskb == NULL) {
3953                                                 /* priv->ext_stats.tx_drops++; */
3954                                                 DEBUG_ERR("TX DROP: rtw_skb_copy fail!\n");
3955                                                 /* goto stop_proc; */
3956                                                 return -1;
3957                                         }
3958                                         rtw_skb_free(skb);
3959
3960                                         *pskb = skb = newskb;
3961                                         if (is_vlan_tag) {
3962                                                 vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2));
3963                                                 for (i = 0; i < 6; i++)
3964                                                         *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2));
3965                                                 skb_pull(skb, 4);
3966                                         }
3967                                 }
3968
3969                                 if (skb_is_nonlinear(skb))
3970                                         DEBUG_ERR("%s(): skb_is_nonlinear!!\n", __FUNCTION__);
3971
3972
3973 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
3974                                 res = skb_linearize(skb, GFP_ATOMIC);
3975 #else   /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) */
3976                                 res = skb_linearize(skb);
3977 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) */
3978                                 if (res < 0) {
3979                                         DEBUG_ERR("TX DROP: skb_linearize fail!\n");
3980                                         /* goto free_and_stop; */
3981                                         return -1;
3982                                 }
3983
3984                                 res = nat25_db_handle(padapter, skb, NAT25_INSERT);
3985                                 if (res < 0) {
3986                                         if (res == -2) {
3987                                                 /* priv->ext_stats.tx_drops++; */
3988                                                 DEBUG_ERR("TX DROP: nat25_db_handle fail!\n");
3989                                                 /* goto free_and_stop; */
3990                                                 return -1;
3991
3992                                         }
3993                                         /* we just print warning message and let it go */
3994                                         /* DEBUG_WARN("%s()-%d: nat25_db_handle INSERT Warning!\n", __FUNCTION__, __LINE__); */
3995                                         /* return -1; */ /* return -1 will cause system crash on 2011/08/30! */
3996                                         return 0;
3997                                 }
3998                         }
3999
4000                         memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
4001
4002                         dhcp_flag_bcast(padapter, skb);
4003
4004                         if (is_vlan_tag) {
4005                                 skb_push(skb, 4);
4006                                 for (i = 0; i < 6; i++)
4007                                         *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2));
4008                                 *((unsigned short *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q);
4009                                 *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr;
4010                         }
4011                 }
4012 #if 0
4013                 else {
4014                         if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q))
4015                                 is_vlan_tag = 1;
4016
4017                         if (is_vlan_tag) {
4018                                 if (ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A_VALN(skb->data))
4019                                         memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
4020                         } else {
4021                                 if (ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A(skb->data))
4022                                         memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
4023                         }
4024                 }
4025 #endif /* 0 */
4026
4027                 /* check if SA is equal to our MAC */
4028                 if (memcmp(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN)) {
4029                         /* priv->ext_stats.tx_drops++; */
4030                         DEBUG_ERR("TX DROP: untransformed frame SA:%02X%02X%02X%02X%02X%02X!\n",
4031                                 skb->data[6], skb->data[7], skb->data[8], skb->data[9], skb->data[10], skb->data[11]);
4032                         /* goto free_and_stop; */
4033                         return -1;
4034                 }
4035         }
4036         return 0;
4037 }
4038 #endif /* CONFIG_BR_EXT */
4039
4040 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
4041 {
4042         u32 addr;
4043         struct pkt_attrib *pattrib = &pxmitframe->attrib;
4044
4045         switch (pattrib->qsel) {
4046         case 0:
4047         case 3:
4048                 addr = BE_QUEUE_INX;
4049                 break;
4050         case 1:
4051         case 2:
4052                 addr = BK_QUEUE_INX;
4053                 break;
4054         case 4:
4055         case 5:
4056                 addr = VI_QUEUE_INX;
4057                 break;
4058         case 6:
4059         case 7:
4060                 addr = VO_QUEUE_INX;
4061                 break;
4062         case 0x10:
4063                 addr = BCN_QUEUE_INX;
4064                 break;
4065         case 0x11: /* BC/MC in PS (HIQ) */
4066                 addr = HIGH_QUEUE_INX;
4067                 break;
4068         case 0x13:
4069                 addr = TXCMD_QUEUE_INX;
4070                 break;
4071         case 0x12:
4072         default:
4073                 addr = MGT_QUEUE_INX;
4074                 break;
4075
4076         }
4077
4078         return addr;
4079
4080 }
4081
4082 static void do_queue_select(_adapter    *padapter, struct pkt_attrib *pattrib)
4083 {
4084         u8 qsel;
4085
4086         qsel = pattrib->priority;
4087
4088 #ifdef CONFIG_CONCURRENT_MODE
4089         /*      if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
4090          *              qsel = 7; */
4091 #endif
4092
4093 #ifdef CONFIG_MCC_MODE
4094         if (MCC_EN(padapter)) {
4095                 /* Under MCC */
4096                 if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC)) {
4097                         if (padapter->mcc_adapterpriv.role == MCC_ROLE_GO
4098                             || padapter->mcc_adapterpriv.role == MCC_ROLE_AP) {
4099                                 pattrib->qsel = QSLT_VO; /* AP interface VO queue */
4100                         } else {
4101                                 pattrib->qsel = QSLT_BE; /* STA interface BE queue */
4102                         }
4103                 } else
4104                         /* Not Under MCC */
4105                         pattrib->qsel = qsel;
4106         } else
4107                 /* Not enable MCC */
4108                 pattrib->qsel = qsel;
4109 #else /* !CONFIG_MCC_MODE */
4110         pattrib->qsel = qsel;
4111 #endif /* CONFIG_MCC_MODE */
4112 }
4113
4114 /*
4115  * The main transmit(tx) entry
4116  *
4117  * Return
4118  *      1       enqueue
4119  *      0       success, hardware will handle this xmit frame(packet)
4120  *      <0      fail
4121  */
4122  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
4123 s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
4124 {
4125         int ret = 0;
4126         int rtap_len;
4127         int qos_len = 0;
4128         int dot11_hdr_len = 24;
4129         int snap_len = 6;
4130         unsigned char *pdata;
4131         u16 frame_ctl;
4132         unsigned char src_mac_addr[6];
4133         unsigned char dst_mac_addr[6];
4134         struct rtw_ieee80211_hdr *dot11_hdr;
4135         struct ieee80211_radiotap_header *rtap_hdr;
4136         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4137
4138         if (skb)
4139                 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
4140
4141         if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
4142                 goto fail;
4143
4144         rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
4145         if (unlikely(rtap_hdr->it_version))
4146                 goto fail;
4147
4148         rtap_len = ieee80211_get_radiotap_len(skb->data);
4149         if (unlikely(skb->len < rtap_len))
4150                 goto fail;
4151
4152         if (rtap_len != 12) {
4153                 RTW_INFO("radiotap len (should be 14): %d\n", rtap_len);
4154                 goto fail;
4155         }
4156
4157         /* Skip the ratio tap header */
4158         skb_pull(skb, rtap_len);
4159
4160         dot11_hdr = (struct rtw_ieee80211_hdr *)skb->data;
4161         frame_ctl = le16_to_cpu(dot11_hdr->frame_ctl);
4162         /* Check if the QoS bit is set */
4163
4164         if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
4165
4166                 struct xmit_frame               *pmgntframe;
4167                 struct pkt_attrib       *pattrib;
4168                 unsigned char   *pframe;
4169                 struct rtw_ieee80211_hdr *pwlanhdr;
4170                 struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
4171                 struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4172                 u8 *buf = skb->data;
4173                 u32 len = skb->len;
4174                 u8 category, action;
4175                 int type = -1;
4176
4177                 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4178                 if (pmgntframe == NULL) {
4179                         rtw_udelay_os(500);
4180                         goto fail;
4181                 }
4182                 pattrib = &pmgntframe->attrib;
4183
4184                 update_monitor_frame_attrib(padapter, pattrib);
4185
4186                 pattrib->retry_ctrl = _FALSE;
4187
4188                 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4189
4190                 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4191
4192                 _rtw_memcpy(pframe, (void *)buf, len);
4193
4194                 pattrib->pktlen = len;
4195
4196                 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4197
4198                 if (is_broadcast_mac_addr(pwlanhdr->addr3) || is_broadcast_mac_addr(pwlanhdr->addr1))
4199                         pattrib->rate = MGN_24M;
4200
4201                 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4202                 pattrib->seqnum = pmlmeext->mgnt_seq;
4203                 pmlmeext->mgnt_seq++;
4204
4205                 pattrib->last_txcmdsz = pattrib->pktlen;
4206
4207                 dump_mgntframe(padapter, pmgntframe);
4208
4209         } else {
4210                 struct xmit_frame               *pmgntframe;
4211                 struct pkt_attrib       *pattrib;
4212                 unsigned char   *pframe;
4213                 struct rtw_ieee80211_hdr *pwlanhdr;
4214                 struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
4215                 struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4216                 u8 *buf = skb->data;
4217                 u32 len = skb->len;
4218                 u8 category, action;
4219                 int type = -1;
4220
4221                 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4222                 if (pmgntframe == NULL)
4223                         goto fail;
4224
4225                 pattrib = &pmgntframe->attrib;
4226                 update_mgntframe_attrib(padapter, pattrib);
4227                 pattrib->retry_ctrl = _FALSE;
4228
4229                 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4230
4231                 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4232
4233                 _rtw_memcpy(pframe, (void *)buf, len);
4234
4235                 pattrib->pktlen = len;
4236
4237                 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4238
4239                 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4240                 pattrib->seqnum = pmlmeext->mgnt_seq;
4241                 pmlmeext->mgnt_seq++;
4242
4243                 pattrib->last_txcmdsz = pattrib->pktlen;
4244
4245                 dump_mgntframe(padapter, pmgntframe);
4246
4247         }
4248
4249 fail:
4250
4251         rtw_skb_free(skb);
4252
4253         return 0;
4254 }
4255 #endif
4256 /*
4257  * The main transmit(tx) entry
4258  *
4259  * Return
4260  *      1       enqueue
4261  *      0       success, hardware will handle this xmit frame(packet)
4262  *      <0      fail
4263  */
4264 s32 rtw_xmit(_adapter *padapter, _pkt **ppkt)
4265 {
4266         static u32 start = 0;
4267         static u32 drop_cnt = 0;
4268 #ifdef CONFIG_AP_MODE
4269         _irqL irqL0;
4270 #endif
4271         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4272         struct xmit_frame *pxmitframe = NULL;
4273 #ifdef CONFIG_BR_EXT
4274         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
4275         void *br_port = NULL;
4276 #endif /* CONFIG_BR_EXT */
4277
4278         s32 res;
4279
4280         DBG_COUNTER(padapter->tx_logs.core_tx);
4281
4282         if (start == 0)
4283                 start = rtw_get_current_time();
4284
4285         pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
4286
4287         if (rtw_get_passing_time_ms(start) > 2000) {
4288                 if (drop_cnt)
4289                         RTW_INFO("DBG_TX_DROP_FRAME %s no more pxmitframe, drop_cnt:%u\n", __FUNCTION__, drop_cnt);
4290                 start = rtw_get_current_time();
4291                 drop_cnt = 0;
4292         }
4293
4294         if (pxmitframe == NULL) {
4295                 drop_cnt++;
4296                 /*RTW_INFO("%s-"ADPT_FMT" no more xmitframe\n", __func__, ADPT_ARG(padapter));*/
4297                 DBG_COUNTER(padapter->tx_logs.core_tx_err_pxmitframe);
4298                 return -1;
4299         }
4300
4301 #ifdef CONFIG_BR_EXT
4302
4303 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
4304         br_port = padapter->pnetdev->br_port;
4305 #else   /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
4306         rcu_read_lock();
4307         br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
4308         rcu_read_unlock();
4309 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
4310
4311         if (br_port && check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) {
4312                 res = rtw_br_client_tx(padapter, ppkt);
4313                 if (res == -1) {
4314                         rtw_free_xmitframe(pxmitpriv, pxmitframe);
4315                         DBG_COUNTER(padapter->tx_logs.core_tx_err_brtx);
4316                         return -1;
4317                 }
4318         }
4319
4320 #endif /* CONFIG_BR_EXT */
4321
4322         res = update_attrib(padapter, *ppkt, &pxmitframe->attrib);
4323
4324 #ifdef CONFIG_MCC_MODE
4325         /* record data kernel TX to driver to check MCC concurrent TX */
4326         rtw_hal_mcc_calc_tx_bytes_from_kernel(padapter, pxmitframe->attrib.pktlen);
4327 #endif /* CONFIG_MCC_MODE */
4328
4329 #ifdef CONFIG_WAPI_SUPPORT
4330         if (pxmitframe->attrib.ether_type != 0x88B4) {
4331                 if (rtw_wapi_drop_for_key_absent(padapter, pxmitframe->attrib.ra)) {
4332                         WAPI_TRACE(WAPI_RX, "drop for key absend when tx\n");
4333                         res = _FAIL;
4334                 }
4335         }
4336 #endif
4337         if (res == _FAIL) {
4338                 /*RTW_INFO("%s-"ADPT_FMT" update attrib fail\n", __func__, ADPT_ARG(padapter));*/
4339 #ifdef DBG_TX_DROP_FRAME
4340                 RTW_INFO("DBG_TX_DROP_FRAME %s update attrib fail\n", __FUNCTION__);
4341 #endif
4342                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
4343                 return -1;
4344         }
4345         pxmitframe->pkt = *ppkt;
4346
4347         rtw_led_control(padapter, LED_CTL_TX);
4348
4349         do_queue_select(padapter, &pxmitframe->attrib);
4350
4351 #ifdef CONFIG_AP_MODE
4352         _enter_critical_bh(&pxmitpriv->lock, &irqL0);
4353         if (xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE) {
4354                 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
4355                 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue);
4356                 return 1;
4357         }
4358         _exit_critical_bh(&pxmitpriv->lock, &irqL0);
4359 #endif
4360
4361         /* pre_xmitframe */
4362         if (rtw_hal_xmit(padapter, pxmitframe) == _FALSE)
4363                 return 1;
4364
4365         return 0;
4366 }
4367
4368 #ifdef CONFIG_TDLS
4369 sint xmitframe_enqueue_for_tdls_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
4370 {
4371         sint ret = _FALSE;
4372
4373         _irqL irqL;
4374         struct sta_info *ptdls_sta = NULL;
4375         struct sta_priv *pstapriv = &padapter->stapriv;
4376         struct pkt_attrib *pattrib = &pxmitframe->attrib;
4377         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4378         int i;
4379
4380         ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
4381         if (ptdls_sta == NULL)
4382                 return ret;
4383         else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
4384
4385                 if (pattrib->triggered == 1) {
4386                         ret = _TRUE;
4387                         return ret;
4388                 }
4389
4390                 _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
4391
4392                 if (ptdls_sta->state & WIFI_SLEEP_STATE) {
4393                         rtw_list_delete(&pxmitframe->list);
4394
4395                         /* _enter_critical_bh(&psta->sleep_q.lock, &irqL);       */
4396
4397                         rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptdls_sta->sleep_q));
4398
4399                         ptdls_sta->sleepq_len++;
4400                         ptdls_sta->sleepq_ac_len++;
4401
4402                         /* indicate 4-AC queue bit in TDLS peer traffic indication */
4403                         switch (pattrib->priority) {
4404                         case 1:
4405                         case 2:
4406                                 ptdls_sta->uapsd_bk |= BIT(1);
4407                                 break;
4408                         case 4:
4409                         case 5:
4410                                 ptdls_sta->uapsd_vi |= BIT(1);
4411                                 break;
4412                         case 6:
4413                         case 7:
4414                                 ptdls_sta->uapsd_vo |= BIT(1);
4415                                 break;
4416                         case 0:
4417                         case 3:
4418                         default:
4419                                 ptdls_sta->uapsd_be |= BIT(1);
4420                                 break;
4421                         }
4422
4423                         /* Transmit TDLS PTI via AP */
4424                         if (ptdls_sta->sleepq_len == 1)
4425                                 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ISSUE_PTI);
4426
4427                         ret = _TRUE;
4428                 }
4429
4430                 _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
4431         }
4432
4433         return ret;
4434
4435 }
4436 #endif /* CONFIG_TDLS */
4437
4438 #define RTW_HIQ_FILTER_ALLOW_ALL 0
4439 #define RTW_HIQ_FILTER_ALLOW_SPECIAL 1
4440 #define RTW_HIQ_FILTER_DENY_ALL 2
4441
4442 inline bool xmitframe_hiq_filter(struct xmit_frame *xmitframe)
4443 {
4444         bool allow = _FALSE;
4445         _adapter *adapter = xmitframe->padapter;
4446         struct registry_priv *registry = &adapter->registrypriv;
4447
4448         if (rtw_get_intf_type(adapter) != RTW_PCIE) {
4449
4450                 if (adapter->registrypriv.wifi_spec == 1)
4451                         allow = _TRUE;
4452                 else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_SPECIAL) {
4453
4454                         struct pkt_attrib *attrib = &xmitframe->attrib;
4455
4456                         if (attrib->ether_type == 0x0806
4457                             || attrib->ether_type == 0x888e
4458 #ifdef CONFIG_WAPI_SUPPORT
4459                             || attrib->ether_type == 0x88B4
4460 #endif
4461                             || attrib->dhcp_pkt
4462                            ) {
4463                                 if (0)
4464                                         RTW_INFO(FUNC_ADPT_FMT" ether_type:0x%04x%s\n", FUNC_ADPT_ARG(xmitframe->padapter)
4465                                                 , attrib->ether_type, attrib->dhcp_pkt ? " DHCP" : "");
4466                                 allow = _TRUE;
4467                         }
4468                 } else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_ALL)
4469                         allow = _TRUE;
4470                 else if (registry->hiq_filter == RTW_HIQ_FILTER_DENY_ALL) {
4471                 } else
4472                         rtw_warn_on(1);
4473         }
4474         return allow;
4475 }
4476
4477 #if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS)
4478
4479 sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
4480 {
4481         _irqL irqL;
4482         sint ret = _FALSE;
4483         struct sta_info *psta = NULL;
4484         struct sta_priv *pstapriv = &padapter->stapriv;
4485         struct pkt_attrib *pattrib = &pxmitframe->attrib;
4486         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4487         sint bmcst = IS_MCAST(pattrib->ra);
4488         bool update_tim = _FALSE;
4489 #ifdef CONFIG_TDLS
4490
4491         if (padapter->tdlsinfo.link_established == _TRUE)
4492                 ret = xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pxmitframe);
4493 #endif /* CONFIG_TDLS */
4494
4495         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _FALSE) {
4496                 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_fwstate);
4497                 return ret;
4498         }
4499         /*
4500                 if(pattrib->psta)
4501                 {
4502                         psta = pattrib->psta;
4503                 }
4504                 else
4505                 {
4506                         RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
4507                         psta=rtw_get_stainfo(pstapriv, pattrib->ra);
4508                 }
4509         */
4510         psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
4511         if (pattrib->psta != psta) {
4512                 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_sta);
4513                 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
4514                 return _FALSE;
4515         }
4516
4517         if (psta == NULL) {
4518                 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_nosta);
4519                 RTW_INFO("%s, psta==NUL\n", __func__);
4520                 return _FALSE;
4521         }
4522
4523         if (!(psta->state & _FW_LINKED)) {
4524                 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_link);
4525                 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
4526                 return _FALSE;
4527         }
4528
4529         if (pattrib->triggered == 1) {
4530                 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_trigger);
4531                 /* RTW_INFO("directly xmit pspoll_triggered packet\n"); */
4532
4533                 /* pattrib->triggered=0; */
4534                 if (bmcst && xmitframe_hiq_filter(pxmitframe) == _TRUE)
4535                         pattrib->qsel = QSLT_HIGH;/* HIQ */
4536
4537                 return ret;
4538         }
4539
4540
4541         if (bmcst) {
4542                 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
4543
4544                 if (pstapriv->sta_dz_bitmap) { /* if anyone sta is in ps mode */
4545                         /* pattrib->qsel = QSLT_HIGH; */ /* HIQ */
4546
4547                         rtw_list_delete(&pxmitframe->list);
4548
4549                         /*_enter_critical_bh(&psta->sleep_q.lock, &irqL);*/
4550
4551                         rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
4552
4553                         psta->sleepq_len++;
4554
4555                         if (!(pstapriv->tim_bitmap & BIT(0)))
4556                                 update_tim = _TRUE;
4557
4558                         pstapriv->tim_bitmap |= BIT(0);
4559                         pstapriv->sta_dz_bitmap |= BIT(0);
4560
4561                         /* RTW_INFO("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
4562                         if (update_tim == _TRUE) {
4563                                 if (is_broadcast_mac_addr(pattrib->ra))
4564                                         _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer BC");
4565                                 else
4566                                         _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer MC");
4567                         } else
4568                                 chk_bmc_sleepq_cmd(padapter);
4569
4570                         /*_exit_critical_bh(&psta->sleep_q.lock, &irqL);*/
4571
4572                         ret = _TRUE;
4573
4574                         DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_mcast);
4575
4576                 }
4577
4578                 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
4579
4580                 return ret;
4581
4582         }
4583
4584
4585         _enter_critical_bh(&psta->sleep_q.lock, &irqL);
4586
4587         if (psta->state & WIFI_SLEEP_STATE) {
4588                 u8 wmmps_ac = 0;
4589
4590                 if (pstapriv->sta_dz_bitmap & BIT(psta->aid)) {
4591                         rtw_list_delete(&pxmitframe->list);
4592
4593                         /* _enter_critical_bh(&psta->sleep_q.lock, &irqL);       */
4594
4595                         rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
4596
4597                         psta->sleepq_len++;
4598
4599                         switch (pattrib->priority) {
4600                         case 1:
4601                         case 2:
4602                                 wmmps_ac = psta->uapsd_bk & BIT(0);
4603                                 break;
4604                         case 4:
4605                         case 5:
4606                                 wmmps_ac = psta->uapsd_vi & BIT(0);
4607                                 break;
4608                         case 6:
4609                         case 7:
4610                                 wmmps_ac = psta->uapsd_vo & BIT(0);
4611                                 break;
4612                         case 0:
4613                         case 3:
4614                         default:
4615                                 wmmps_ac = psta->uapsd_be & BIT(0);
4616                                 break;
4617                         }
4618
4619                         if (wmmps_ac)
4620                                 psta->sleepq_ac_len++;
4621
4622                         if (((psta->has_legacy_ac) && (!wmmps_ac)) || ((!psta->has_legacy_ac) && (wmmps_ac))) {
4623                                 if (!(pstapriv->tim_bitmap & BIT(psta->aid)))
4624                                         update_tim = _TRUE;
4625
4626                                 pstapriv->tim_bitmap |= BIT(psta->aid);
4627
4628                                 /* RTW_INFO("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
4629
4630                                 if (update_tim == _TRUE) {
4631                                         /* RTW_INFO("sleepq_len==1, update BCNTIM\n"); */
4632                                         /* upate BCN for TIM IE */
4633                                         _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer UC");
4634                                 }
4635                         }
4636
4637                         /* _exit_critical_bh(&psta->sleep_q.lock, &irqL);                        */
4638
4639                         /* if(psta->sleepq_len > (NR_XMITFRAME>>3)) */
4640                         /* { */
4641                         /*      wakeup_sta_to_xmit(padapter, psta); */
4642                         /* }     */
4643
4644                         ret = _TRUE;
4645
4646                         DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_ucast);
4647                 }
4648
4649         }
4650
4651         _exit_critical_bh(&psta->sleep_q.lock, &irqL);
4652
4653         return ret;
4654
4655 }
4656
4657 static void dequeue_xmitframes_to_sleeping_queue(_adapter *padapter, struct sta_info *psta, _queue *pframequeue)
4658 {
4659         sint ret;
4660         _list   *plist, *phead;
4661         u8      ac_index;
4662         struct tx_servq *ptxservq;
4663         struct pkt_attrib       *pattrib;
4664         struct xmit_frame       *pxmitframe;
4665         struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
4666
4667         phead = get_list_head(pframequeue);
4668         plist = get_next(phead);
4669
4670         while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
4671                 pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
4672
4673                 plist = get_next(plist);
4674
4675                 pattrib = &pxmitframe->attrib;
4676
4677                 pattrib->triggered = 0;
4678
4679                 ret = xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
4680
4681                 if (_TRUE == ret) {
4682                         ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
4683
4684                         ptxservq->qcnt--;
4685                         phwxmits[ac_index].accnt--;
4686                 } else {
4687                         /* RTW_INFO("xmitframe_enqueue_for_sleeping_sta return _FALSE\n"); */
4688                 }
4689
4690         }
4691
4692 }
4693
4694 void stop_sta_xmit(_adapter *padapter, struct sta_info *psta)
4695 {
4696         _irqL irqL0;
4697         struct sta_info *psta_bmc;
4698         struct sta_xmit_priv *pstaxmitpriv;
4699         struct sta_priv *pstapriv = &padapter->stapriv;
4700         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4701
4702         pstaxmitpriv = &psta->sta_xmitpriv;
4703
4704         /* for BC/MC Frames */
4705         psta_bmc = rtw_get_bcmc_stainfo(padapter);
4706
4707
4708         _enter_critical_bh(&pxmitpriv->lock, &irqL0);
4709
4710         psta->state |= WIFI_SLEEP_STATE;
4711
4712 #ifdef CONFIG_TDLS
4713         if (!(psta->tdls_sta_state & TDLS_LINKED_STATE))
4714 #endif /* CONFIG_TDLS */
4715                 pstapriv->sta_dz_bitmap |= BIT(psta->aid);
4716
4717
4718
4719         dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
4720         rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));
4721
4722
4723         dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
4724         rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));
4725
4726
4727         dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
4728         rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
4729
4730
4731         dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
4732         rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));
4733
4734 #ifdef CONFIG_TDLS
4735         if (!(psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta_bmc != NULL)) {
4736 #endif /* CONFIG_TDLS */
4737
4738
4739                 /* for BC/MC Frames */
4740                 pstaxmitpriv = &psta_bmc->sta_xmitpriv;
4741                 dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending);
4742                 rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
4743
4744
4745 #ifdef CONFIG_TDLS
4746         }
4747 #endif /* CONFIG_TDLS    */
4748         _exit_critical_bh(&pxmitpriv->lock, &irqL0);
4749
4750
4751 }
4752
4753 void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta)
4754 {
4755         _irqL irqL;
4756         u8 update_mask = 0, wmmps_ac = 0;
4757         struct sta_info *psta_bmc;
4758         _list   *xmitframe_plist, *xmitframe_phead;
4759         struct xmit_frame *pxmitframe = NULL;
4760         struct sta_priv *pstapriv = &padapter->stapriv;
4761         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4762
4763         psta_bmc = rtw_get_bcmc_stainfo(padapter);
4764
4765
4766         /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
4767         _enter_critical_bh(&pxmitpriv->lock, &irqL);
4768
4769         xmitframe_phead = get_list_head(&psta->sleep_q);
4770         xmitframe_plist = get_next(xmitframe_phead);
4771
4772         while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
4773                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4774
4775                 xmitframe_plist = get_next(xmitframe_plist);
4776
4777                 rtw_list_delete(&pxmitframe->list);
4778
4779                 switch (pxmitframe->attrib.priority) {
4780                 case 1:
4781                 case 2:
4782                         wmmps_ac = psta->uapsd_bk & BIT(1);
4783                         break;
4784                 case 4:
4785                 case 5:
4786                         wmmps_ac = psta->uapsd_vi & BIT(1);
4787                         break;
4788                 case 6:
4789                 case 7:
4790                         wmmps_ac = psta->uapsd_vo & BIT(1);
4791                         break;
4792                 case 0:
4793                 case 3:
4794                 default:
4795                         wmmps_ac = psta->uapsd_be & BIT(1);
4796                         break;
4797                 }
4798
4799                 psta->sleepq_len--;
4800                 if (psta->sleepq_len > 0)
4801                         pxmitframe->attrib.mdata = 1;
4802                 else
4803                         pxmitframe->attrib.mdata = 0;
4804
4805                 if (wmmps_ac) {
4806                         psta->sleepq_ac_len--;
4807                         if (psta->sleepq_ac_len > 0) {
4808                                 pxmitframe->attrib.mdata = 1;
4809                                 pxmitframe->attrib.eosp = 0;
4810                         } else {
4811                                 pxmitframe->attrib.mdata = 0;
4812                                 pxmitframe->attrib.eosp = 1;
4813                         }
4814                 }
4815
4816                 pxmitframe->attrib.triggered = 1;
4817
4818                 /*
4819                                 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
4820                                 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
4821                                 {
4822                                         rtw_os_xmit_complete(padapter, pxmitframe);
4823                                 }
4824                                 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
4825                 */
4826                 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
4827
4828
4829         }
4830
4831         if (psta->sleepq_len == 0) {
4832 #ifdef CONFIG_TDLS
4833                 if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
4834                         if (psta->state & WIFI_SLEEP_STATE)
4835                                 psta->state ^= WIFI_SLEEP_STATE;
4836
4837                         _exit_critical_bh(&pxmitpriv->lock, &irqL);
4838                         return;
4839                 }
4840 #endif /* CONFIG_TDLS */
4841
4842                 if (pstapriv->tim_bitmap & BIT(psta->aid)) {
4843                         /* RTW_INFO("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); */
4844                         /* upate BCN for TIM IE */
4845                         /* update_BCNTIM(padapter); */
4846                         update_mask = BIT(0);
4847                 }
4848
4849                 pstapriv->tim_bitmap &= ~BIT(psta->aid);
4850
4851                 if (psta->state & WIFI_SLEEP_STATE)
4852                         psta->state ^= WIFI_SLEEP_STATE;
4853
4854                 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
4855                         RTW_INFO("%s alive check\n", __func__);
4856                         psta->expire_to = pstapriv->expire_to;
4857                         psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
4858                 }
4859
4860                 pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
4861         }
4862
4863         /* for BC/MC Frames */
4864         if (!psta_bmc)
4865                 goto _exit;
4866
4867         if ((pstapriv->sta_dz_bitmap & 0xfffe) == 0x0) { /* no any sta in ps mode */
4868                 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
4869                 xmitframe_plist = get_next(xmitframe_phead);
4870
4871                 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
4872                         pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4873
4874                         xmitframe_plist = get_next(xmitframe_plist);
4875
4876                         rtw_list_delete(&pxmitframe->list);
4877
4878                         psta_bmc->sleepq_len--;
4879                         if (psta_bmc->sleepq_len > 0)
4880                                 pxmitframe->attrib.mdata = 1;
4881                         else
4882                                 pxmitframe->attrib.mdata = 0;
4883
4884
4885                         pxmitframe->attrib.triggered = 1;
4886                         /*
4887                                                 _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
4888                                                 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
4889                                                 {
4890                                                         rtw_os_xmit_complete(padapter, pxmitframe);
4891                                                 }
4892                                                 _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
4893
4894                         */
4895                         rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
4896
4897                 }
4898
4899                 if (psta_bmc->sleepq_len == 0) {
4900                         if (pstapriv->tim_bitmap & BIT(0)) {
4901                                 /* RTW_INFO("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); */
4902                                 /* upate BCN for TIM IE */
4903                                 /* update_BCNTIM(padapter); */
4904                                 update_mask |= BIT(1);
4905                         }
4906                         pstapriv->tim_bitmap &= ~BIT(0);
4907                         pstapriv->sta_dz_bitmap &= ~BIT(0);
4908                 }
4909
4910         }
4911
4912 _exit:
4913
4914         /* _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);    */
4915         _exit_critical_bh(&pxmitpriv->lock, &irqL);
4916
4917         if (update_mask) {
4918                 /* update_BCNTIM(padapter); */
4919                 if ((update_mask & (BIT(0) | BIT(1))) == (BIT(0) | BIT(1)))
4920                         _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear UC&BMC");
4921                 else if ((update_mask & BIT(1)) == BIT(1))
4922                         _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear BMC");
4923                 else
4924                         _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear UC");
4925         }
4926
4927 }
4928
4929 void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta)
4930 {
4931         _irqL irqL;
4932         u8 wmmps_ac = 0;
4933         _list   *xmitframe_plist, *xmitframe_phead;
4934         struct xmit_frame *pxmitframe = NULL;
4935         struct sta_priv *pstapriv = &padapter->stapriv;
4936         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4937
4938
4939         /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
4940         _enter_critical_bh(&pxmitpriv->lock, &irqL);
4941
4942         xmitframe_phead = get_list_head(&psta->sleep_q);
4943         xmitframe_plist = get_next(xmitframe_phead);
4944
4945         while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
4946                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4947
4948                 xmitframe_plist = get_next(xmitframe_plist);
4949
4950                 switch (pxmitframe->attrib.priority) {
4951                 case 1:
4952                 case 2:
4953                         wmmps_ac = psta->uapsd_bk & BIT(1);
4954                         break;
4955                 case 4:
4956                 case 5:
4957                         wmmps_ac = psta->uapsd_vi & BIT(1);
4958                         break;
4959                 case 6:
4960                 case 7:
4961                         wmmps_ac = psta->uapsd_vo & BIT(1);
4962                         break;
4963                 case 0:
4964                 case 3:
4965                 default:
4966                         wmmps_ac = psta->uapsd_be & BIT(1);
4967                         break;
4968                 }
4969
4970                 if (!wmmps_ac)
4971                         continue;
4972
4973                 rtw_list_delete(&pxmitframe->list);
4974
4975                 psta->sleepq_len--;
4976                 psta->sleepq_ac_len--;
4977
4978                 if (psta->sleepq_ac_len > 0) {
4979                         pxmitframe->attrib.mdata = 1;
4980                         pxmitframe->attrib.eosp = 0;
4981                 } else {
4982                         pxmitframe->attrib.mdata = 0;
4983                         pxmitframe->attrib.eosp = 1;
4984                 }
4985
4986                 pxmitframe->attrib.triggered = 1;
4987                 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
4988
4989                 if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) {
4990 #ifdef CONFIG_TDLS
4991                         if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
4992                                 /* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
4993                                 goto exit;
4994                         }
4995 #endif /* CONFIG_TDLS */
4996                         pstapriv->tim_bitmap &= ~BIT(psta->aid);
4997
4998                         /* RTW_INFO("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); */
4999                         /* upate BCN for TIM IE */
5000                         /* update_BCNTIM(padapter); */
5001                         update_beacon(padapter, _TIM_IE_, NULL, _TRUE);
5002                         /* update_mask = BIT(0); */
5003                 }
5004
5005         }
5006
5007 exit:
5008         /* _exit_critical_bh(&psta->sleep_q.lock, &irqL);        */
5009         _exit_critical_bh(&pxmitpriv->lock, &irqL);
5010
5011         return;
5012 }
5013
5014 #endif /* defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) */
5015
5016 #ifdef CONFIG_XMIT_THREAD_MODE
5017 void enqueue_pending_xmitbuf(
5018         struct xmit_priv *pxmitpriv,
5019         struct xmit_buf *pxmitbuf)
5020 {
5021         _irqL irql;
5022         _queue *pqueue;
5023         _adapter *pri_adapter = pxmitpriv->adapter;
5024
5025         pqueue = &pxmitpriv->pending_xmitbuf_queue;
5026
5027         _enter_critical_bh(&pqueue->lock, &irql);
5028         rtw_list_delete(&pxmitbuf->list);
5029         rtw_list_insert_tail(&pxmitbuf->list, get_list_head(pqueue));
5030         _exit_critical_bh(&pqueue->lock, &irql);
5031
5032 #if defined(CONFIG_SDIO_HCI) && defined(CONFIG_CONCURRENT_MODE)
5033         pri_adapter = GET_PRIMARY_ADAPTER(pri_adapter);
5034 #endif /*SDIO_HCI + CONCURRENT*/
5035         _rtw_up_sema(&(pri_adapter->xmitpriv.xmit_sema));
5036 }
5037
5038 void enqueue_pending_xmitbuf_to_head(
5039         struct xmit_priv *pxmitpriv,
5040         struct xmit_buf *pxmitbuf)
5041 {
5042         _irqL irql;
5043         _queue *pqueue = &pxmitpriv->pending_xmitbuf_queue;
5044
5045         _enter_critical_bh(&pqueue->lock, &irql);
5046         rtw_list_delete(&pxmitbuf->list);
5047         rtw_list_insert_head(&pxmitbuf->list, get_list_head(pqueue));
5048         _exit_critical_bh(&pqueue->lock, &irql);
5049 }
5050
5051 struct xmit_buf *dequeue_pending_xmitbuf(
5052         struct xmit_priv *pxmitpriv)
5053 {
5054         _irqL irql;
5055         struct xmit_buf *pxmitbuf;
5056         _queue *pqueue;
5057
5058
5059         pxmitbuf = NULL;
5060         pqueue = &pxmitpriv->pending_xmitbuf_queue;
5061
5062         _enter_critical_bh(&pqueue->lock, &irql);
5063
5064         if (_rtw_queue_empty(pqueue) == _FALSE) {
5065                 _list *plist, *phead;
5066
5067                 phead = get_list_head(pqueue);
5068                 plist = get_next(phead);
5069                 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
5070                 rtw_list_delete(&pxmitbuf->list);
5071         }
5072
5073         _exit_critical_bh(&pqueue->lock, &irql);
5074
5075         return pxmitbuf;
5076 }
5077
5078 static struct xmit_buf *dequeue_pending_xmitbuf_under_survey(
5079         struct xmit_priv *pxmitpriv)
5080 {
5081         _irqL irql;
5082         struct xmit_buf *pxmitbuf;
5083 #ifdef CONFIG_USB_HCI
5084         struct xmit_frame *pxmitframe;
5085 #endif
5086         _queue *pqueue;
5087
5088
5089         pxmitbuf = NULL;
5090         pqueue = &pxmitpriv->pending_xmitbuf_queue;
5091
5092         _enter_critical_bh(&pqueue->lock, &irql);
5093
5094         if (_rtw_queue_empty(pqueue) == _FALSE) {
5095                 _list *plist, *phead;
5096                 u8 type = 0;
5097
5098                 phead = get_list_head(pqueue);
5099                 plist = phead;
5100                 do {
5101                         plist = get_next(plist);
5102                         if (plist == phead)
5103                                 break;
5104
5105                         pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
5106
5107 #ifdef CONFIG_USB_HCI
5108                         pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
5109                         if (pxmitframe)
5110                                 type = get_frame_sub_type(pxmitbuf->pbuf + TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
5111                         else
5112                                 RTW_INFO("%s, !!!ERROR!!! For USB, TODO ITEM\n", __FUNCTION__);
5113 #else
5114                         type = get_frame_sub_type(pxmitbuf->pbuf + TXDESC_OFFSET);
5115 #endif
5116
5117                         if ((type == WIFI_PROBEREQ) ||
5118                             (type == WIFI_DATA_NULL) ||
5119                             (type == WIFI_QOS_DATA_NULL)) {
5120                                 rtw_list_delete(&pxmitbuf->list);
5121                                 break;
5122                         }
5123                         pxmitbuf = NULL;
5124                 } while (1);
5125         }
5126
5127         _exit_critical_bh(&pqueue->lock, &irql);
5128
5129         return pxmitbuf;
5130 }
5131
5132 static struct xmit_buf *dequeue_pending_xmitbuf_ext(
5133         struct xmit_priv *pxmitpriv)
5134 {
5135         _irqL irql;
5136         struct xmit_buf *pxmitbuf;
5137         _queue *pqueue;
5138
5139         pxmitbuf = NULL;
5140         pqueue = &pxmitpriv->pending_xmitbuf_queue;
5141
5142         _enter_critical_bh(&pqueue->lock, &irql);
5143
5144         if (_rtw_queue_empty(pqueue) == _FALSE) {
5145                 _list *plist, *phead;
5146                 u8 type = 0;
5147
5148                 phead = get_list_head(pqueue);
5149                 plist = phead;
5150                 do {
5151                         plist = get_next(plist);
5152                         if (plist == phead)
5153                                 break;
5154
5155                         pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
5156
5157                         if (pxmitbuf->buf_tag == XMITBUF_MGNT) {
5158                                 rtw_list_delete(&pxmitbuf->list);
5159                                 break;
5160                         }
5161                         pxmitbuf = NULL;
5162                 } while (1);
5163         }
5164
5165         _exit_critical_bh(&pqueue->lock, &irql);
5166
5167         return pxmitbuf;
5168 }
5169
5170 struct xmit_buf *select_and_dequeue_pending_xmitbuf(_adapter *padapter)
5171 {
5172         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5173         struct xmit_buf *pxmitbuf = NULL;
5174
5175         if (rtw_xmit_ac_blocked(padapter) == _TRUE)
5176                 pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv);
5177         else {
5178                 pxmitbuf = dequeue_pending_xmitbuf_ext(pxmitpriv);
5179                 if (pxmitbuf == NULL)
5180                         pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
5181         }
5182
5183         return pxmitbuf;
5184 }
5185
5186 sint check_pending_xmitbuf(
5187         struct xmit_priv *pxmitpriv)
5188 {
5189         _irqL irql;
5190         _queue *pqueue;
5191         sint    ret = _FALSE;
5192
5193         pqueue = &pxmitpriv->pending_xmitbuf_queue;
5194
5195         _enter_critical_bh(&pqueue->lock, &irql);
5196
5197         if (_rtw_queue_empty(pqueue) == _FALSE)
5198                 ret = _TRUE;
5199
5200         _exit_critical_bh(&pqueue->lock, &irql);
5201
5202         return ret;
5203 }
5204
5205 thread_return rtw_xmit_thread(thread_context context)
5206 {
5207         s32 err;
5208         PADAPTER padapter;
5209
5210
5211         err = _SUCCESS;
5212         padapter = (PADAPTER)context;
5213
5214         thread_enter("RTW_XMIT_THREAD");
5215
5216         do {
5217                 err = rtw_hal_xmit_thread_handler(padapter);
5218                 flush_signals_thread();
5219         } while (_SUCCESS == err);
5220
5221         _rtw_up_sema(&padapter->xmitpriv.terminate_xmitthread_sema);
5222
5223         thread_exit();
5224 }
5225 #endif
5226
5227 bool rtw_xmit_ac_blocked(_adapter *adapter)
5228 {
5229         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5230         _adapter *iface;
5231         struct mlme_ext_priv *mlmeext;
5232         struct mlme_ext_info *mlmeextinfo;
5233         bool blocked = _FALSE;
5234         int i;
5235
5236         for (i = 0; i < dvobj->iface_nums; i++) {
5237                 iface = dvobj->padapters[i];
5238                 mlmeext = &iface->mlmeextpriv;
5239
5240                 /* check scan state */
5241                 if (mlmeext_scan_state(mlmeext) != SCAN_DISABLE
5242                         && mlmeext_scan_state(mlmeext) != SCAN_BACK_OP
5243                 ) {
5244                         blocked = _TRUE;
5245                         goto exit;
5246                 }
5247
5248                 if (mlmeext_scan_state(mlmeext) == SCAN_BACK_OP
5249                         && !mlmeext_chk_scan_backop_flags(mlmeext, SS_BACKOP_TX_RESUME)
5250                 ) {
5251                         blocked = _TRUE;
5252                         goto exit;
5253                 }
5254         }
5255
5256 #ifdef CONFIG_MCC_MODE
5257         if (MCC_EN(adapter)) {
5258                 if (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC)) {
5259                         if (MCC_STOP(adapter)) {
5260                                 blocked = _TRUE;
5261                                 goto exit;
5262                         }
5263                 }
5264         }
5265 #endif /*  CONFIG_MCC_MODE */
5266
5267 exit:
5268         return blocked;
5269 }
5270
5271 #ifdef CONFIG_TX_AMSDU
5272 void rtw_amsdu_vo_timeout_handler(void *FunctionContext)
5273 {
5274         _adapter *adapter = (_adapter *)FunctionContext;
5275
5276         adapter->xmitpriv.amsdu_vo_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5277
5278         tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5279 }
5280
5281 void rtw_amsdu_vi_timeout_handler(void *FunctionContext)
5282 {
5283         _adapter *adapter = (_adapter *)FunctionContext;
5284
5285         adapter->xmitpriv.amsdu_vi_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5286
5287         tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5288 }
5289
5290 void rtw_amsdu_be_timeout_handler(void *FunctionContext)
5291 {
5292         _adapter *adapter = (_adapter *)FunctionContext;
5293
5294         adapter->xmitpriv.amsdu_be_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5295
5296         if (printk_ratelimit())
5297                 RTW_INFO("%s Timeout!\n",__FUNCTION__);
5298
5299         tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5300 }
5301
5302 void rtw_amsdu_bk_timeout_handler(void *FunctionContext)
5303 {
5304         _adapter *adapter = (_adapter *)FunctionContext;
5305
5306         adapter->xmitpriv.amsdu_bk_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5307
5308         tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5309 }
5310
5311 u8 rtw_amsdu_get_timer_status(_adapter *padapter, u8 priority)
5312 {
5313         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
5314
5315         u8 status =  RTW_AMSDU_TIMER_UNSET;
5316
5317         switch(priority)
5318         {
5319                 case 1:
5320                 case 2:
5321                         status = pxmitpriv->amsdu_bk_timeout;
5322                         break;
5323                 case 4:
5324                 case 5:
5325                         status = pxmitpriv->amsdu_vi_timeout;
5326                         break;
5327                 case 6:
5328                 case 7:
5329                         status = pxmitpriv->amsdu_vo_timeout;
5330                         break;
5331                 case 0:
5332                 case 3:
5333                 default:
5334                         status = pxmitpriv->amsdu_be_timeout;
5335                         break;
5336         }
5337         return status;
5338 }
5339
5340 void rtw_amsdu_set_timer_status(_adapter *padapter, u8 priority, u8 status)
5341 {
5342         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
5343
5344         switch(priority)
5345         {
5346                 case 1:
5347                 case 2:
5348                         pxmitpriv->amsdu_bk_timeout = status;
5349                         break;
5350                 case 4:
5351                 case 5:
5352                         pxmitpriv->amsdu_vi_timeout = status;
5353                         break;
5354                 case 6:
5355                 case 7:
5356                         pxmitpriv->amsdu_vo_timeout = status;
5357                         break;
5358                 case 0:
5359                 case 3:
5360                 default:
5361                         pxmitpriv->amsdu_be_timeout = status;
5362                         break;
5363         }
5364 }
5365
5366 void rtw_amsdu_set_timer(_adapter *padapter, u8 priority)
5367 {
5368         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
5369
5370         _timer* amsdu_timer = NULL;
5371
5372         switch(priority)
5373         {
5374                 case 1:
5375                 case 2:
5376                         amsdu_timer = &pxmitpriv->amsdu_bk_timer;
5377                         break;
5378                 case 4:
5379                 case 5:
5380                         amsdu_timer = &pxmitpriv->amsdu_vi_timer;
5381                         break;
5382                 case 6:
5383                 case 7:
5384                         amsdu_timer = &pxmitpriv->amsdu_vo_timer;
5385                         break;
5386                 case 0:
5387                 case 3:
5388                 default:
5389                         amsdu_timer = &pxmitpriv->amsdu_be_timer;
5390                         break;
5391         }
5392         _set_timer(amsdu_timer, 1);
5393 }
5394
5395 void rtw_amsdu_cancel_timer(_adapter *padapter, u8 priority)
5396 {
5397         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
5398         _timer* amsdu_timer = NULL;
5399         u8 cancel;
5400
5401         switch(priority)
5402         {
5403                 case 1:
5404                 case 2:
5405                         amsdu_timer = &pxmitpriv->amsdu_bk_timer;
5406                         break;
5407                 case 4:
5408                 case 5:
5409                         amsdu_timer = &pxmitpriv->amsdu_vi_timer;
5410                         break;
5411                 case 6:
5412                 case 7:
5413                         amsdu_timer = &pxmitpriv->amsdu_vo_timer;
5414                         break;
5415                 case 0:
5416                 case 3:
5417                 default:
5418                         amsdu_timer = &pxmitpriv->amsdu_be_timer;
5419                         break;
5420         }
5421         _cancel_timer(amsdu_timer, &cancel);
5422 }
5423 #endif /* CONFIG_TX_AMSDU */
5424
5425 void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms)
5426 {
5427         sctx->timeout_ms = timeout_ms;
5428         sctx->submit_time = rtw_get_current_time();
5429 #ifdef PLATFORM_LINUX /* TODO: add condition wating interface for other os */
5430         init_completion(&sctx->done);
5431 #endif
5432         sctx->status = RTW_SCTX_SUBMITTED;
5433 }
5434
5435 int rtw_sctx_wait(struct submit_ctx *sctx, const char *msg)
5436 {
5437         int ret = _FAIL;
5438         unsigned long expire;
5439         int status = 0;
5440
5441 #ifdef PLATFORM_LINUX
5442         expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT;
5443         if (!wait_for_completion_timeout(&sctx->done, expire)) {
5444                 /* timeout, do something?? */
5445                 status = RTW_SCTX_DONE_TIMEOUT;
5446                 RTW_INFO("%s timeout: %s\n", __func__, msg);
5447         } else
5448                 status = sctx->status;
5449 #endif
5450
5451         if (status == RTW_SCTX_DONE_SUCCESS)
5452                 ret = _SUCCESS;
5453
5454         return ret;
5455 }
5456
5457 bool rtw_sctx_chk_waring_status(int status)
5458 {
5459         switch (status) {
5460         case RTW_SCTX_DONE_UNKNOWN:
5461         case RTW_SCTX_DONE_BUF_ALLOC:
5462         case RTW_SCTX_DONE_BUF_FREE:
5463
5464         case RTW_SCTX_DONE_DRV_STOP:
5465         case RTW_SCTX_DONE_DEV_REMOVE:
5466                 return _TRUE;
5467         default:
5468                 return _FALSE;
5469         }
5470 }
5471
5472 void rtw_sctx_done_err(struct submit_ctx **sctx, int status)
5473 {
5474         if (*sctx) {
5475                 if (rtw_sctx_chk_waring_status(status))
5476                         RTW_INFO("%s status:%d\n", __func__, status);
5477                 (*sctx)->status = status;
5478 #ifdef PLATFORM_LINUX
5479                 complete(&((*sctx)->done));
5480 #endif
5481                 *sctx = NULL;
5482         }
5483 }
5484
5485 void rtw_sctx_done(struct submit_ctx **sctx)
5486 {
5487         rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS);
5488 }
5489
5490 #ifdef CONFIG_XMIT_ACK
5491 int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
5492 {
5493         struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
5494
5495         pack_tx_ops->submit_time = rtw_get_current_time();
5496         pack_tx_ops->timeout_ms = timeout_ms;
5497         pack_tx_ops->status = RTW_SCTX_SUBMITTED;
5498
5499         return rtw_sctx_wait(pack_tx_ops, __func__);
5500 }
5501
5502 void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)
5503 {
5504         struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
5505
5506         if (pxmitpriv->ack_tx)
5507                 rtw_sctx_done_err(&pack_tx_ops, status);
5508         else
5509                 RTW_INFO("%s ack_tx not set\n", __func__);
5510 }
5511 #endif /* CONFIG_XMIT_ACK */