1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
22 #include <drv_types.h>
25 #if defined(PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
26 #error "Shall be Linux or Windows, but not both!\n"
30 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
31 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
33 static void _init_txservq(struct tx_servq *ptxservq)
35 _rtw_init_listhead(&ptxservq->tx_pending);
36 _rtw_init_queue(&ptxservq->sta_pending);
41 void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
45 _rtw_memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv));
47 _rtw_spinlock_init(&psta_xmitpriv->lock);
49 /* for(i = 0 ; i < MAX_NUMBLKS; i++) */
50 /* _init_txservq(&(psta_xmitpriv->blk_q[i])); */
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);
62 s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter)
65 struct xmit_buf *pxmitbuf;
66 struct xmit_frame *pxframe;
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)); */
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);
79 Please insert all the queue initializaiton using _rtw_init_queue below
82 pxmitpriv->adapter = padapter;
84 /* for(i = 0 ; i < MAX_NUMBLKS; i++) */
85 /* _rtw_init_queue(&pxmitpriv->blk_strms[i]); */
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);
93 /* _rtw_init_queue(&pxmitpriv->legacy_dz_queue); */
94 /* _rtw_init_queue(&pxmitpriv->apsd_queue); */
96 _rtw_init_queue(&pxmitpriv->free_xmit_queue);
99 Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
100 and initialize free_xmit_frame below.
101 Please also apply free_txobj to link_up all the xmit_frames...
104 pxmitpriv->pallocated_frame_buf = rtw_zvmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
106 if (pxmitpriv->pallocated_frame_buf == NULL) {
107 pxmitpriv->pxmit_frame_buf = NULL;
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); */
115 pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
117 for (i = 0; i < NR_XMITFRAME; i++) {
118 _rtw_init_listhead(&(pxframe->list));
120 pxframe->padapter = padapter;
121 pxframe->frame_tag = NULL_FRAMETAG;
125 pxframe->buf_addr = NULL;
126 pxframe->pxmitbuf = NULL;
128 rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue));
133 pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
135 pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
139 _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue);
140 _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue);
142 pxmitpriv->pallocated_xmitbuf = rtw_zvmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
144 if (pxmitpriv->pallocated_xmitbuf == NULL) {
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); */
153 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
155 for (i = 0; i < NR_XMITBUFF; i++) {
156 _rtw_init_listhead(&pxmitbuf->list);
158 pxmitbuf->priv_data = NULL;
159 pxmitbuf->padapter = padapter;
160 pxmitbuf->buf_tag = XMITBUF_DATA;
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);
166 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
171 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
172 pxmitbuf->phead = pxmitbuf->pbuf;
173 pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMITBUF_SZ;
175 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
178 pxmitbuf->flags = XMIT_VO_QUEUE;
180 rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue));
189 pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
191 /* init xframe_ext queue, the same count as extbuf */
192 _rtw_init_queue(&pxmitpriv->free_xframe_ext_queue);
194 pxmitpriv->xframe_ext_alloc_addr = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4);
196 if (pxmitpriv->xframe_ext_alloc_addr == NULL) {
197 pxmitpriv->xframe_ext = NULL;
201 pxmitpriv->xframe_ext = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->xframe_ext_alloc_addr), 4);
202 pxframe = (struct xmit_frame *)pxmitpriv->xframe_ext;
204 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
205 _rtw_init_listhead(&(pxframe->list));
207 pxframe->padapter = padapter;
208 pxframe->frame_tag = NULL_FRAMETAG;
212 pxframe->buf_addr = NULL;
213 pxframe->pxmitbuf = NULL;
215 pxframe->ext_tag = 1;
217 rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xframe_ext_queue.queue));
221 pxmitpriv->free_xframe_ext_cnt = NR_XMIT_EXTBUFF;
223 /* Init xmit extension buff */
224 _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
226 pxmitpriv->pallocated_xmit_extbuf = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4);
228 if (pxmitpriv->pallocated_xmit_extbuf == NULL) {
233 pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmit_extbuf), 4);
235 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
237 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
238 _rtw_init_listhead(&pxmitbuf->list);
240 pxmitbuf->priv_data = NULL;
241 pxmitbuf->padapter = padapter;
242 pxmitbuf->buf_tag = XMITBUF_MGNT;
244 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ, _TRUE);
250 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
251 pxmitbuf->phead = pxmitbuf->pbuf;
252 pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMIT_EXTBUF_SZ;
254 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
257 rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue));
258 #ifdef DBG_XMIT_BUF_EXT
265 pxmitpriv->free_xmit_extbuf_cnt = NR_XMIT_EXTBUFF;
267 for (i = 0; i < CMDBUF_MAX; i++) {
268 pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i];
270 _rtw_init_listhead(&pxmitbuf->list);
272 pxmitbuf->priv_data = NULL;
273 pxmitbuf->padapter = padapter;
274 pxmitbuf->buf_tag = XMITBUF_CMD;
276 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ, _TRUE);
282 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
283 pxmitbuf->phead = pxmitbuf->pbuf;
284 pxmitbuf->pend = pxmitbuf->pbuf + MAX_CMDBUF_SZ;
286 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
288 pxmitbuf->alloc_sz = MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ;
292 rtw_alloc_hwxmits(padapter);
293 rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
295 for (i = 0; i < 4; i++)
296 pxmitpriv->wmm_para_seq[i] = i;
298 #ifdef CONFIG_USB_HCI
299 pxmitpriv->txirp_cnt = 1;
301 _rtw_init_sema(&(pxmitpriv->tx_retevt), 0);
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;
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);
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;
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;
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;
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;
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;
339 rtw_hal_init_xmit_priv(padapter);
347 void rtw_mfree_xmit_priv_lock(struct xmit_priv *pxmitpriv);
348 void rtw_mfree_xmit_priv_lock(struct xmit_priv *pxmitpriv)
350 _rtw_spinlock_free(&pxmitpriv->lock);
351 _rtw_free_sema(&pxmitpriv->xmit_sema);
352 _rtw_free_sema(&pxmitpriv->terminate_xmitthread_sema);
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);
360 /* _rtw_spinlock_free(&pxmitpriv->legacy_dz_queue.lock); */
361 /* _rtw_spinlock_free(&pxmitpriv->apsd_queue.lock); */
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);
369 void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv)
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;
377 rtw_hal_free_xmit_priv(padapter);
379 rtw_mfree_xmit_priv_lock(pxmitpriv);
381 if (pxmitpriv->pxmit_frame_buf == NULL)
384 for (i = 0; i < NR_XMITFRAME; i++) {
385 rtw_os_xmit_complete(padapter, pxmitframe);
390 for (i = 0; i < NR_XMITBUFF; i++) {
391 rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE);
396 if (pxmitpriv->pallocated_frame_buf)
397 rtw_vmfree(pxmitpriv->pallocated_frame_buf, NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
400 if (pxmitpriv->pallocated_xmitbuf)
401 rtw_vmfree(pxmitpriv->pallocated_xmitbuf, NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
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);
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);
414 /* free xmit extension buff */
415 _rtw_spinlock_free(&pxmitpriv->free_xmit_extbuf_queue.lock);
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);
424 if (pxmitpriv->pallocated_xmit_extbuf)
425 rtw_vmfree(pxmitpriv->pallocated_xmit_extbuf, NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4);
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);
433 rtw_free_hwxmits(padapter);
435 #ifdef CONFIG_XMIT_ACK
436 _rtw_mutex_free(&pxmitpriv->ack_tx_mutex);
443 u8 rtw_get_tx_bw_mode(_adapter *adapter, struct sta_info *sta)
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));
452 bw = rtw_min(bw, ADAPTER_TX_BW_5G(adapter));
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)
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;
464 u16 bmp_cck_ofdm = 0;
469 if (adapter->fix_rate != 0xFF && adapter->fix_bw != 0xFF)
470 fix_bw = adapter->fix_bw;
472 /* TODO: adapter->fix_rate */
474 for (i = 0; i < macid_ctl->num; i++) {
475 if (!rtw_macid_is_used(macid_ctl, i))
477 if (rtw_macid_get_if_g(macid_ctl, i) != adapter->iface_id)
480 if (bw == CHANNEL_WIDTH_20) /* CCK, OFDM always 20MHz */
481 bmp_cck_ofdm |= macid_ctl->rate_bmp0[i] & 0x00000FFF;
483 /* bypass mismatch bandwidth for HT, VHT */
484 if ((fix_bw != 0xFF && fix_bw != bw) || (fix_bw == 0xFF && macid_ctl->bw[i] != bw))
487 if (macid_ctl->vht_en[i])
488 bmp_vht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
490 bmp_ht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
493 /* TODO: mlmeext->tx_rate*/
497 *r_bmp_cck_ofdm = bmp_cck_ofdm;
501 *r_bmp_vht = bmp_vht;
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)
506 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
507 u16 bmp_cck_ofdm = 0;
512 for (i = 0; i < macid_ctl->num; i++) {
513 if (!rtw_macid_is_used(macid_ctl, i))
515 if (rtw_macid_get_if_g(macid_ctl, i) != -1)
518 if (bw == CHANNEL_WIDTH_20) /* CCK, OFDM always 20MHz */
519 bmp_cck_ofdm |= macid_ctl->rate_bmp0[i] & 0x00000FFF;
521 /* bypass mismatch bandwidth for HT, VHT */
522 if (macid_ctl->bw[i] != bw)
525 if (macid_ctl->vht_en[i])
526 bmp_vht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
528 bmp_ht |= (macid_ctl->rate_bmp0[i] >> 12) | (macid_ctl->rate_bmp1[i] << 20);
532 *r_bmp_cck_ofdm = bmp_cck_ofdm;
536 *r_bmp_vht = bmp_vht;
539 void rtw_update_tx_rate_bmp(struct dvobj_priv *dvobj)
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);
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;
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;
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];
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])
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;
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;
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;
586 #ifndef DBG_HIGHEST_RATE_BMP_BW_CHANGE
587 #define DBG_HIGHEST_RATE_BMP_BW_CHANGE 0
592 u8 highest_rate_bw_bmp;
593 u8 update_ht_rs = _FALSE;
594 u8 update_vht_rs = _FALSE;
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);
605 rf_ctl->highest_ht_rate_bw_bmp = highest_rate_bw_bmp;
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])
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]);
614 update_ht_rs = _TRUE;
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);
626 rf_ctl->highest_vht_rate_bw_bmp = highest_rate_bw_bmp;
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])
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]);
635 update_vht_rs = _TRUE;
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);
644 inline u16 rtw_get_tx_rate_bmp_cck_ofdm(struct dvobj_priv *dvobj)
646 struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
648 return rf_ctl->rate_bmp_cck_ofdm;
651 inline u32 rtw_get_tx_rate_bmp_ht_by_bw(struct dvobj_priv *dvobj, u8 bw)
653 struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
655 return rf_ctl->rate_bmp_ht_by_bw[bw];
658 inline u32 rtw_get_tx_rate_bmp_vht_by_bw(struct dvobj_priv *dvobj, u8 bw)
660 struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
662 return rf_ctl->rate_bmp_vht_by_bw[bw];
665 u8 rtw_get_tx_bw_bmp_of_ht_rate(struct dvobj_priv *dvobj, u8 rate, u8 max_bw)
667 struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
672 if (!IS_HT_RATE(rate)) {
677 rate_bmp = 1 << (rate - MGN_MCS0);
679 if (max_bw > CHANNEL_WIDTH_40)
680 max_bw = CHANNEL_WIDTH_40;
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);
692 u8 rtw_get_tx_bw_bmp_of_vht_rate(struct dvobj_priv *dvobj, u8 rate, u8 max_bw)
694 struct rf_ctl_t *rf_ctl = dvobj_to_rfctl(dvobj);
699 if (!IS_VHT_RATE(rate)) {
704 rate_bmp = 1 << (rate - MGN_VHT1SS_MCS0);
706 if (max_bw > CHANNEL_WIDTH_160)
707 max_bw = CHANNEL_WIDTH_160;
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);
719 u8 query_ra_short_GI(struct sta_info *psta, u8 bw)
721 u8 sgi = _FALSE, sgi_20m = _FALSE, sgi_40m = _FALSE, sgi_80m = _FALSE;
723 #ifdef CONFIG_80211N_HT
724 #ifdef CONFIG_80211AC_VHT
725 if (psta->vhtpriv.vht_option)
726 sgi_80m = psta->vhtpriv.sgi_80m;
728 sgi_20m = psta->htpriv.sgi_20m;
729 sgi_40m = psta->htpriv.sgi_40m;
733 case CHANNEL_WIDTH_80:
736 case CHANNEL_WIDTH_40:
739 case CHANNEL_WIDTH_20:
748 static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe)
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);
759 psta = pattrib->psta;
763 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
764 psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] );
769 RTW_INFO("%s, psta==NUL\n", __func__);
773 if(!(psta->state &_FW_LINKED))
775 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
780 if (pattrib->nr_frags != 1)
781 sz = padapter->xmitpriv.frag_len;
783 sz = pattrib->last_txcmdsz;
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;
794 pattrib->vcs_mode = RTS_CTS;
795 else if (pattrib->cts2self)
796 pattrib->vcs_mode = CTS_TO_SELF;
798 pattrib->vcs_mode = NONE_VCS;
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;
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;
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;
823 /* check ERP protection */
824 if (pattrib->rtsen || pattrib->cts2self) {
826 pattrib->vcs_mode = RTS_CTS;
827 else if (pattrib->cts2self)
828 pattrib->vcs_mode = CTS_TO_SELF;
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;
844 if (sz > padapter->registrypriv.rts_thresh) {
845 pattrib->vcs_mode = RTS_CTS;
849 /* to do list: check MIMO power save condition. */
851 /* check AMPDU aggregation for TXOP */
852 if ((pattrib->ampdu_en == _TRUE) && (!IS_HARDWARE_TYPE_8812(padapter))) {
853 pattrib->vcs_mode = RTS_CTS;
857 pattrib->vcs_mode = NONE_VCS;
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;
871 static void update_attrib_phy_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
873 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
876 pattrib->rtsen = psta->rtsen;
877 pattrib->cts2self = psta->cts2self;
881 pattrib->triggered = 0;
882 pattrib->ampdu_spacing = 0;
884 /* qos_en, ht_en, init rate, ,bw, ch_offset, sgi */
885 pattrib->qos_en = psta->qos_option;
887 pattrib->raid = psta->raid;
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);
893 pattrib->ldpc = psta->ldpc;
894 pattrib->stbc = psta->stbc;
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;
901 if (padapter->driver_ampdu_spacing != 0xFF) /* driver control AMPDU Density for peer sta's rx */
902 pattrib->ampdu_spacing = padapter->driver_ampdu_spacing;
904 pattrib->ampdu_spacing = psta->htpriv.rx_ampdu_min_spacing;
905 #endif /* CONFIG_80211N_HT */
906 /* if(pattrib->ht_en && psta->htpriv.ampdu_enable) */
908 /* if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) */
909 /* pattrib->ampdu_en = _TRUE; */
913 if (pattrib->direct_link == _TRUE) {
914 psta = pattrib->ptdls_sta;
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 */
924 #endif /* CONFIG_TDLS */
926 pattrib->retry_ctrl = _FALSE;
928 #ifdef CONFIG_AUTO_AP_MODE
929 if (psta->isrc && psta->pid > 0)
930 pattrib->pctrl = _TRUE;
935 static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
938 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
939 struct security_priv *psecuritypriv = &padapter->securitypriv;
940 sint bmcast = IS_MCAST(pattrib->ra);
942 _rtw_memset(pattrib->dot118021x_UncstKey.skey, 0, 16);
943 _rtw_memset(pattrib->dot11tkiptxmickey.skey, 0, 16);
944 pattrib->mac_id = psta->mac_id;
946 if (psta->ieee8021x_blocked == _TRUE) {
948 pattrib->encrypt = 0;
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);
958 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
960 #ifdef CONFIG_WAPI_SUPPORT
961 if (pattrib->ether_type == 0x88B4)
962 pattrib->encrypt = _NO_PRIVACY_;
965 switch (psecuritypriv->dot11AuthAlgrthm) {
966 case dot11AuthAlgrthm_Open:
967 case dot11AuthAlgrthm_Shared:
968 case dot11AuthAlgrthm_Auto:
969 pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
971 case dot11AuthAlgrthm_8021X:
973 pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
975 pattrib->key_idx = 0;
978 pattrib->key_idx = 0;
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_;
989 if (pattrib->direct_link == _TRUE) {
990 if (pattrib->encrypt > 0)
991 pattrib->encrypt = _AES_;
995 switch (pattrib->encrypt) {
999 pattrib->icv_len = 4;
1000 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1004 pattrib->iv_len = 8;
1005 pattrib->icv_len = 4;
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);
1016 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1018 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
1021 _rtw_memcpy(pattrib->dot11tkiptxmickey.skey, psta->dot11tkiptxmickey.skey, 16);
1027 pattrib->iv_len = 8;
1028 pattrib->icv_len = 8;
1031 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1033 AES_IV(pattrib->iv, psta->dot11txpn, 0);
1037 #ifdef CONFIG_WAPI_SUPPORT
1039 pattrib->iv_len = 18;
1040 pattrib->icv_len = 16;
1041 rtw_wapi_get_iv(padapter, pattrib->ra, pattrib->iv);
1045 pattrib->iv_len = 0;
1046 pattrib->icv_len = 0;
1050 if (pattrib->encrypt > 0)
1051 _rtw_memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16);
1054 if (pattrib->encrypt &&
1055 ((padapter->securitypriv.sw_encrypt == _TRUE) || (psecuritypriv->hw_decrypted == _FALSE))) {
1056 pattrib->bswenc = _TRUE;
1058 pattrib->bswenc = _FALSE;
1061 #if defined(CONFIG_CONCURRENT_MODE)
1062 pattrib->bmc_camid = padapter->securitypriv.dot118021x_bmc_cam_id;
1065 if (pattrib->encrypt && bmcast && _rtw_camctl_chk_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
1066 pattrib->bswenc = _TRUE;
1068 #ifdef CONFIG_WAPI_SUPPORT
1069 if (pattrib->encrypt == _SMS4_)
1070 pattrib->bswenc = _FALSE;
1079 u8 qos_acm(u8 acm_mask, u8 priority)
1081 u8 change_priority = priority;
1086 if (acm_mask & BIT(1))
1087 change_priority = 1;
1094 if (acm_mask & BIT(2))
1095 change_priority = 0;
1099 if (acm_mask & BIT(3))
1100 change_priority = 5;
1103 RTW_INFO("qos_acm(): invalid pattrib->priority: %d!!!\n", priority);
1107 return change_priority;
1110 static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
1112 struct ethhdr etherhdr;
1113 struct iphdr ip_hdr;
1114 s32 UserPriority = 0;
1117 _rtw_open_pktfile(ppktfile->pkt, ppktfile);
1118 _rtw_pktfile_read(ppktfile, (unsigned char *)ðerhdr, ETH_HLEN);
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;
1127 else if (pattrib->ether_type == 0x888e) {
1133 pattrib->priority = UserPriority;
1134 pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
1135 pattrib->subtype = WIFI_QOS_DATA_TYPE;
1139 u8 rtw_check_tdls_established(_adapter *padapter, struct pkt_attrib *pattrib)
1141 pattrib->ptdls_sta = NULL;
1143 pattrib->direct_link = _FALSE;
1144 if (padapter->tdlsinfo.link_established == _TRUE) {
1145 pattrib->ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
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)); */
1154 if (pattrib->ptdls_sta != NULL &&
1155 pattrib->ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
1156 pattrib->direct_link = _TRUE;
1158 RTW_INFO("send ptk to "MAC_FMT" using direct link\n", MAC_ARG(pattrib->dst));
1162 /* ARP frame may be helped by AP*/
1163 if (pattrib->ether_type != 0x0806)
1164 pattrib->direct_link = _FALSE;
1168 return pattrib->direct_link;
1171 s32 update_tdls_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
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;
1182 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
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;
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;
1200 pattrib->priority = 0;
1201 pattrib->hdrlen = WLAN_HDR_A3_LEN;
1202 pattrib->subtype = WIFI_DATA_TYPE;
1206 if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) {
1211 update_attrib_phy_info(padapter, pattrib, psta);
1219 #endif /* CONFIG_TDLS */
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)
1225 #ifdef CONFIG_CONCURRENT_MODE
1226 if (padapter->adapter_type != PRIMARY_ADAPTER)
1229 /* hwseq_num = 2; */
1230 #endif /* CONFIG_CONCURRENT_MODE */
1233 static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib)
1236 struct pkt_file pktfile;
1237 struct sta_info *psta = NULL;
1238 struct ethhdr etherhdr;
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;
1249 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib);
1251 _rtw_open_pktfile(pkt, &pktfile);
1252 i = _rtw_pktfile_read(&pktfile, (u8 *)ðerhdr, ETH_HLEN);
1254 pattrib->ether_type = ntohs(etherhdr.h_proto);
1257 _rtw_memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN);
1258 _rtw_memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN);
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)) {
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 */
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);
1280 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_unknown);
1282 bmcast = IS_MCAST(pattrib->ra);
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));
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));
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);
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);
1316 pattrib->pktlen = pktfile.pkt_len;
1318 /* TODO: 802.1Q VLAN header */
1321 if (ETH_P_IP == pattrib->ether_type) {
1324 _rtw_pktfile_read(&pktfile, ip, 20);
1326 if (GET_IPV4_IHL(ip) * 4 > 20)
1327 _rtw_pktfile_read(&pktfile, NULL, GET_IPV4_IHL(ip) - 20);
1329 pattrib->icmp_pkt = 0;
1330 pattrib->dhcp_pkt = 0;
1332 if (GET_IPV4_PROTOCOL(ip) == 0x01) { /* ICMP */
1333 pattrib->icmp_pkt = 1;
1334 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_icmp);
1336 } else if (GET_IPV4_PROTOCOL(ip) == 0x11) { /* UDP */
1339 _rtw_pktfile_read(&pktfile, udp, 8);
1341 if ((GET_UDP_SRC(udp) == 68 && GET_UDP_DST(udp) == 67)
1342 || (GET_UDP_SRC(udp) == 67 && GET_UDP_DST(udp) == 68)
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);
1349 RTW_INFO("send DHCP packet\n");
1353 } else if (GET_IPV4_PROTOCOL(ip) == 0x06 /* TCP */
1354 && rtw_st_ctl_chk_reg_s_proto(&psta->st_ctl, 0x06) == _TRUE
1358 _rtw_pktfile_read(&pktfile, tcp, 20);
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)));
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)));
1384 } else if (0x888e == pattrib->ether_type)
1385 RTW_PRINT("send eapol packet\n");
1387 if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
1388 rtw_mi_set_scan_deny(padapter, 3000);
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 */
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)
1405 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_active);
1406 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
1408 #endif /* CONFIG_LPS */
1410 #ifdef CONFIG_BEAMFORMING
1411 update_attrib_txbf_info(padapter, pattrib, psta);
1415 if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) {
1416 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sec);
1421 update_attrib_phy_info(padapter, pattrib, psta);
1423 /* RTW_INFO("%s ==> mac_id(%d)\n",__FUNCTION__,pattrib->mac_id ); */
1425 pattrib->psta = psta;
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 */
1434 pattrib->hdrlen = WLAN_HDR_A3_LEN;
1435 pattrib->subtype = WIFI_DATA_TYPE;
1436 pattrib->priority = 0;
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);
1443 if (pattrib->direct_link == _TRUE) {
1444 if (pattrib->qos_en)
1445 set_qos(&pktfile, pattrib);
1449 if (pqospriv->qos_option) {
1450 set_qos(&pktfile, pattrib);
1452 if (pmlmepriv->acm_mask != 0)
1453 pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority);
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);
1468 static s32 xmitframe_addmic(_adapter *padapter, struct xmit_frame *pxmitframe)
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);
1485 stainfo = pattrib->psta;
1489 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
1490 stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
1495 RTW_INFO("%s, psta==NUL\n", __func__);
1499 if(!(stainfo->state &_FW_LINKED))
1501 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state);
1507 #ifdef CONFIG_USB_TX_AGGREGATION
1508 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);;
1510 #ifdef CONFIG_TX_EARLY_MODE
1511 hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
1513 hw_hdr_offset = TXDESC_OFFSET;
1517 if (pattrib->encrypt == _TKIP_) { /* if(psecuritypriv->dot11PrivacyAlgrthm==_TKIP_PRIVACY_) */
1518 /* encode mic code */
1519 /* if(stainfo!= NULL) */
1521 u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1523 pframe = pxmitframe->buf_addr + hw_hdr_offset;
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); */
1531 /* start to calculate the mic code */
1532 rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
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); */
1539 /* start to calculate the mic code */
1540 rtw_secmicsetkey(&micdata, &pattrib->dot11tkiptxmickey.skey[0]);
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);
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);
1554 rtw_secmicappend(&micdata, &pframe[10], 6);
1558 /* if(pqospriv->qos_option==1) */
1559 if (pattrib->qos_en)
1560 priority[0] = (u8)pxmitframe->attrib.priority;
1563 rtw_secmicappend(&micdata, &priority[0], 4);
1567 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
1568 payload = (u8 *)RND4((SIZE_PTR)(payload));
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;
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;
1581 rtw_secgetmic(&micdata, &(mic[0]));
1582 /* add mic code and add the mic code length in last_txcmdsz */
1584 _rtw_memcpy(payload, &(mic[0]), 8);
1585 pattrib->last_txcmdsz += 8;
1587 payload = payload - pattrib->last_txcmdsz + 8;
1595 /*#define DBG_TX_SW_ENCRYPTOR*/
1597 static s32 xmitframe_swencrypt(_adapter *padapter, struct xmit_frame *pxmitframe)
1600 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1601 /* struct security_priv *psecuritypriv=&padapter->securitypriv; */
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));
1611 switch (pattrib->encrypt) {
1614 rtw_wep_encrypt(padapter, (u8 *)pxmitframe);
1617 rtw_tkip_encrypt(padapter, (u8 *)pxmitframe);
1620 rtw_aes_encrypt(padapter, (u8 *)pxmitframe);
1622 #ifdef CONFIG_WAPI_SUPPORT
1624 rtw_sms4_encrypt(padapter, (u8 *)pxmitframe);
1636 s32 rtw_make_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib)
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;
1647 /* struct sta_info *psta; */
1649 /* sint bmcst = IS_MCAST(pattrib->ra); */
1653 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1654 if(pattrib->psta != psta)
1656 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
1662 RTW_INFO("%s, psta==NUL\n", __func__);
1666 if(!(psta->state &_FW_LINKED))
1668 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1673 _rtw_memset(hdr, 0, WLANHDR_OFFSET);
1675 set_frame_sub_type(fctrl, pattrib->subtype);
1677 if (pattrib->subtype & WIFI_DATA_TYPE) {
1678 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) {
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);
1686 if (pattrib->qos_en)
1689 #endif /* CONFIG_TDLS */
1691 /* to_ds = 1, fr_ds = 0; */
1692 /* 1.Data transfer to AP */
1693 /* 2.Arp pkt will relayed by AP */
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);
1699 if (pqospriv->qos_option)
1702 } else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)) {
1703 /* to_ds = 0, fr_ds = 1; */
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);
1709 if (pattrib->qos_en)
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);
1717 if (pattrib->qos_en)
1727 if (pattrib->encrypt)
1731 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
1733 if (pattrib->priority)
1734 SetPriority(qc, pattrib->priority);
1736 SetEOSP(qc, pattrib->eosp);
1738 SetAckpolicy(qc, pattrib->ack_policy);
1741 SetAMsdu(qc, pattrib->amsdu);
1744 /* TODO: fill HT Control Field */
1746 /* Update Seq Num will be handled by f/w */
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);
1756 RTW_INFO("%s, psta==NUL\n", __func__);
1760 if (!(psta->state & _FW_LINKED)) {
1761 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
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];
1771 SetSeqNum(hdr, pattrib->seqnum);
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;
1780 /* re-check if enable ampdu by BA_starting_seqctrl */
1781 if (pattrib->ampdu_en == _TRUE) {
1784 tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
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;
1793 pattrib->ampdu_en = _TRUE;/* AGG EN */
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 */
1801 #endif /* CONFIG_80211N_HT */
1815 s32 rtw_txframes_pending(_adapter *padapter)
1817 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
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));
1825 s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib)
1827 struct sta_info *psta;
1828 struct tx_servq *ptxservq;
1829 int priority = pattrib->priority;
1833 psta = pattrib->psta;
1837 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
1838 psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
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);
1848 RTW_INFO("%s, psta==NUL\n", __func__);
1852 if (!(psta->state & _FW_LINKED)) {
1853 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1860 ptxservq = &(psta->sta_xmitpriv.bk_q);
1864 ptxservq = &(psta->sta_xmitpriv.vi_q);
1868 ptxservq = &(psta->sta_xmitpriv.vo_q);
1873 ptxservq = &(psta->sta_xmitpriv.be_q);
1878 return ptxservq->qcnt;
1883 int rtw_build_tdls_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
1887 switch (ptxmgmt->action_code) {
1888 case TDLS_SETUP_REQUEST:
1889 rtw_build_tdls_setup_req_ies(padapter, pxmitframe, pframe, ptxmgmt);
1891 case TDLS_SETUP_RESPONSE:
1892 rtw_build_tdls_setup_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt);
1894 case TDLS_SETUP_CONFIRM:
1895 rtw_build_tdls_setup_cfm_ies(padapter, pxmitframe, pframe, ptxmgmt);
1898 rtw_build_tdls_teardown_ies(padapter, pxmitframe, pframe, ptxmgmt);
1900 case TDLS_DISCOVERY_REQUEST:
1901 rtw_build_tdls_dis_req_ies(padapter, pxmitframe, pframe, ptxmgmt);
1903 case TDLS_PEER_TRAFFIC_INDICATION:
1904 rtw_build_tdls_peer_traffic_indication_ies(padapter, pxmitframe, pframe, ptxmgmt);
1906 #ifdef CONFIG_TDLS_CH_SW
1907 case TDLS_CHANNEL_SWITCH_REQUEST:
1908 rtw_build_tdls_ch_switch_req_ies(padapter, pxmitframe, pframe, ptxmgmt);
1910 case TDLS_CHANNEL_SWITCH_RESPONSE:
1911 rtw_build_tdls_ch_switch_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt);
1914 case TDLS_PEER_TRAFFIC_RESPONSE:
1915 rtw_build_tdls_peer_traffic_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt);
1918 case TUNNELED_PROBE_REQ:
1919 rtw_build_tunneled_probe_req_ies(padapter, pxmitframe, pframe);
1921 case TUNNELED_PROBE_RSP:
1922 rtw_build_tunneled_probe_rsp_ies(padapter, pxmitframe, pframe);
1924 #endif /* CONFIG_WFD */
1933 s32 rtw_make_tdls_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt)
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 };
1943 sint res = _SUCCESS;
1944 u16 *fctrl = &pwlanhdr->frame_ctl;
1947 _rtw_memset(hdr, 0, WLANHDR_OFFSET);
1949 set_frame_sub_type(fctrl, pattrib->subtype);
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:
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);
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);
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);
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);
1989 if (pattrib->encrypt)
1992 if (ptxmgmt->action_code == TDLS_PEER_TRAFFIC_RESPONSE)
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);
2002 psta = pattrib->psta;
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);
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);
2014 if (pattrib->encrypt) {
2015 pattrib->encrypt = _AES_;
2016 pattrib->iv_len = 8;
2017 pattrib->icv_len = 8;
2018 pattrib->bswenc = _FALSE;
2020 pattrib->mac_id = ptdls_sta->mac_id;
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);
2039 s32 rtw_xmit_tdls_coalesce(_adapter *padapter, struct xmit_frame *pxmitframe, struct tdls_txmgmt *ptxmgmt)
2043 u8 *pframe, *mem_start;
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;
2050 s32 bmcst = IS_MCAST(pattrib->ra);
2055 psta = pattrib->psta;
2058 psta = rtw_get_bcmc_stainfo(padapter);
2060 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2068 if (pxmitframe->buf_addr == NULL) {
2073 pbuf_start = pxmitframe->buf_addr;
2074 mem_start = pbuf_start + TXDESC_OFFSET;
2076 if (rtw_make_tdls_wlanhdr(padapter, mem_start, pattrib, ptxmgmt) == _FAIL) {
2082 pframe += pattrib->hdrlen;
2084 /* adding icv, if necessary... */
2085 if (pattrib->iv_len) {
2087 switch (pattrib->encrypt) {
2090 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2094 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2096 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
2100 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2102 AES_IV(pattrib->iv, psta->dot11txpn, 0);
2107 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
2108 pframe += pattrib->iv_len;
2112 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
2115 /* pattrib->pktlen will be counted in rtw_build_tdls_ies */
2116 pattrib->pktlen = 0;
2118 rtw_build_tdls_ies(padapter, pxmitframe, pframe, ptxmgmt);
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;
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;
2130 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
2135 xmitframe_swencrypt(padapter, pxmitframe);
2137 update_attrib_vcs_info(padapter, pxmitframe);
2144 #endif /* CONFIG_TDLS */
2147 * Calculate wlan 802.11 packet MAX size from pkt_attrib
2148 * This function doesn't consider fragment case
2150 u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib)
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_)
2159 len += ((pattrib->bswenc) ? pattrib->icv_len : 0); /* ICV */
2164 #ifdef CONFIG_TX_AMSDU
2165 s32 check_amsdu(struct xmit_frame *pxmitframe)
2167 struct pkt_attrib *pattrib;
2173 pattrib = &pxmitframe->attrib;
2175 if (IS_MCAST(pattrib->ra))
2178 if ((pattrib->ether_type == 0x888e) ||
2179 (pattrib->ether_type == 0x0806) ||
2180 (pattrib->ether_type == 0x88b4) ||
2181 (pattrib->dhcp_pkt == 1))
2184 if ((pattrib->encrypt == _WEP40_) ||
2185 (pattrib->encrypt == _WEP104_) ||
2186 (pattrib->encrypt == _TKIP_))
2189 if (!pattrib->qos_en)
2196 s32 rtw_xmitframe_coalesce_amsdu(_adapter *padapter, struct xmit_frame *pxmitframe, struct xmit_frame *pxmitframe_queue)
2199 struct pkt_file pktfile;
2200 struct pkt_attrib *pattrib;
2203 struct pkt_file pktfile_queue;
2204 struct pkt_attrib *pattrib_queue;
2211 u8 *pframe, *mem_start;
2218 if (pxmitframe->buf_addr == NULL) {
2219 RTW_INFO("==> %s buf_addr==NULL\n", __FUNCTION__);
2224 pbuf_start = pxmitframe->buf_addr;
2226 #ifdef CONFIG_USB_TX_AGGREGATION
2227 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
2229 #ifdef CONFIG_TX_EARLY_MODE /* for SDIO && Tx Agg */
2230 hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
2232 hw_hdr_offset = TXDESC_OFFSET;
2236 mem_start = pbuf_start + hw_hdr_offset; //for DMA
2238 pattrib = &pxmitframe->attrib;
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");
2253 //SetMFrag(mem_start);
2254 ClearMFrag(mem_start);
2256 pframe += pattrib->hdrlen;
2258 /* adding icv, if necessary... */
2259 if (pattrib->iv_len) {
2260 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len); // queue or new?
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)));
2266 pframe += pattrib->iv_len;
2269 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len;
2271 if(pxmitframe_queue)
2273 pattrib_queue = &pxmitframe_queue->attrib;
2274 pkt_queue = pxmitframe_queue->pkt;
2276 _rtw_open_pktfile(pkt_queue, &pktfile_queue);
2277 _rtw_pktfile_read(&pktfile_queue, NULL, pattrib_queue->pkt_hdrlen);
2279 /* 802.3 MAC Header DA(6) SA(6) Len(2)*/
2281 _rtw_memcpy(pframe, pattrib_queue->dst, ETH_ALEN);
2284 _rtw_memcpy(pframe, pattrib_queue->src, ETH_ALEN);
2287 len = (u16*) pframe;
2290 llc_sz = rtw_put_snap(pframe, pattrib_queue->ether_type);
2293 mem_sz = _rtw_pktfile_read(&pktfile_queue, pframe, pattrib_queue->pktlen);
2296 *len = htons(llc_sz + mem_sz);
2299 padding = 4 - ((ETH_HLEN + llc_sz + mem_sz) & (4-1));
2303 //_rtw_memset(pframe,0xaa, padding);
2306 pattrib->last_txcmdsz += ETH_HLEN + llc_sz + mem_sz + padding ;
2311 pkt = pxmitframe->pkt;
2312 _rtw_open_pktfile(pkt, &pktfile);
2313 _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
2315 /* 802.3 MAC Header DA(6) SA(6) Len(2) */
2317 _rtw_memcpy(pframe, pattrib->dst, ETH_ALEN);
2320 _rtw_memcpy(pframe, pattrib->src, ETH_ALEN);
2323 len = (u16*) pframe;
2326 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
2329 mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
2333 *len = htons(llc_sz + mem_sz);
2335 //the last ampdu has no padding
2338 pattrib->nr_frags = 1;
2340 pattrib->last_txcmdsz += ETH_HLEN + llc_sz + mem_sz + padding +
2341 ((pattrib->bswenc) ? pattrib->icv_len : 0) ;
2343 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2344 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2345 pframe += pattrib->icv_len;
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");
2355 xmitframe_swencrypt(padapter, pxmitframe);
2357 pattrib->vcs_mode = NONE_VCS;
2362 #endif /* CONFIG_TX_AMSDU */
2366 This sub-routine will perform all the following:
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
2372 5. move frag chunk from pframe to pxmitframe->mem
2373 6. apply sw-encrypt, if necessary.
2376 s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
2378 struct pkt_file pktfile;
2380 s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
2384 u8 *pframe, *mem_start;
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;
2392 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2396 s32 bmcst = IS_MCAST(pattrib->ra);
2403 psta = pattrib->psta;
2406 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
2407 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2413 RTW_INFO("%s, psta==NUL\n", __func__);
2418 if(!(psta->state &_FW_LINKED))
2420 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
2424 if (pxmitframe->buf_addr == NULL) {
2425 RTW_INFO("==> %s buf_addr==NULL\n", __FUNCTION__);
2429 pbuf_start = pxmitframe->buf_addr;
2431 #ifdef CONFIG_USB_TX_AGGREGATION
2432 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
2434 #ifdef CONFIG_TX_EARLY_MODE /* for SDIO && Tx Agg */
2435 hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE;
2437 hw_hdr_offset = TXDESC_OFFSET;
2441 mem_start = pbuf_start + hw_hdr_offset;
2443 if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
2444 RTW_INFO("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n");
2449 _rtw_open_pktfile(pkt, &pktfile);
2450 _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
2453 frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
2462 SetMFrag(mem_start);
2464 pframe += pattrib->hdrlen;
2465 mpdu_len -= pattrib->hdrlen;
2467 /* adding icv, if necessary... */
2468 if (pattrib->iv_len) {
2470 /* if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) */
2471 /* psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); */
2473 /* psta = rtw_get_stainfo(pstapriv, pattrib->ra); */
2476 switch (pattrib->encrypt) {
2479 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2483 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2485 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
2489 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
2491 AES_IV(pattrib->iv, psta->dot11txpn, 0);
2493 #ifdef CONFIG_WAPI_SUPPORT
2495 rtw_wapi_get_iv(padapter, pattrib->ra, pattrib->iv);
2501 _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
2504 pframe += pattrib->iv_len;
2506 mpdu_len -= pattrib->iv_len;
2510 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
2515 if ((pattrib->icv_len > 0) && (pattrib->bswenc))
2516 mpdu_len -= pattrib->icv_len;
2520 /* don't do fragment to broadcat/multicast packets */
2521 mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
2523 mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len);
2527 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2528 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2529 pframe += pattrib->icv_len;
2534 if (bmcst || (rtw_endofpktfile(&pktfile) == _TRUE)) {
2535 pattrib->nr_frags = frg_inx;
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;
2540 ClearMFrag(mem_start);
2545 addr = (SIZE_PTR)(pframe);
2547 mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset;
2548 _rtw_memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
2552 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
2553 RTW_INFO("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n");
2558 xmitframe_swencrypt(padapter, pxmitframe);
2560 if (bmcst == _FALSE)
2561 update_attrib_vcs_info(padapter, pxmitframe);
2563 pattrib->vcs_mode = NONE_VCS;
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)
2575 struct pkt_file pktfile;
2576 s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
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;
2584 s32 bmcst = IS_MCAST(pattrib->ra);
2587 u8 *MGMT_body = NULL;
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_];
2596 mem_start = pframe = (u8 *)(pxmitframe->buf_addr) + TXDESC_OFFSET;
2597 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
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) */
2603 if (BIP_AAD == NULL)
2606 _enter_critical_bh(&padapter->security_key_mutex, &irqL);
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;
2614 /* station mode doesn't need TX BIP, just ready the code */
2619 _rtw_memset(MME, 0, _MME_IE_LENGTH_);
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;
2625 MGMT_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
2626 pframe += pattrib->pktlen;
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++;
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);
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);
2651 /* dump total packet include MME with zero MIC */
2654 printk("Total packet: ");
2655 for (i = 0; i < BIP_AAD_SIZE + frame_body_len; i++)
2656 printk(" %02x ", BIP_AAD[i]);
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;
2666 /* dump calculated mic result */
2669 printk("Calculated mic result: ");
2670 for (i = 0; i < 16; i++)
2671 printk(" %02x ", mic[i]);
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
2680 printk("pattrib->pktlen = %d\n", pattrib->pktlen);
2681 for(pp=0;pp< pattrib->pktlen; pp++)
2682 printk(" %02x ", mem_start[pp]);
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) {
2690 psta = pattrib->psta;
2692 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2696 RTW_INFO("%s, psta==NUL\n", __func__);
2697 goto xmitframe_coalesce_fail;
2700 if (pxmitframe->buf_addr == NULL) {
2701 RTW_INFO("%s, pxmitframe->buf_addr\n", __func__);
2702 goto xmitframe_coalesce_fail;
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 */
2717 printk("Management pkt: ");
2718 for(i=0; i<pattrib->pktlen; i++)
2719 printk(" %02x ", pframe[i]);
2720 printk("=======\n");
2722 if (pattrib->encrypt > 0)
2723 _rtw_memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16);
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;
2731 /* bakeup original management packet */
2732 _rtw_memcpy(tmp_buf, pframe, pattrib->pktlen);
2733 /* move to data portion */
2734 pframe += pattrib->hdrlen;
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;
2741 switch (pattrib->encrypt) {
2743 /* set AES IV header */
2744 AES_IV(pattrib->iv, psta->dot11wtxpn, 0);
2747 goto xmitframe_coalesce_fail;
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;
2759 /* dump management packet include AES IV header */
2762 printk("Management pkt + IV: ");
2763 /* for(i=0; i<pattrib->pktlen; i++) */
2765 printk("@@@@@@@@@@@@@\n");
2769 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
2770 _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
2771 pframe += pattrib->icv_len;
2773 /* add 8 bytes MIC */
2774 pattrib->pktlen += pattrib->icv_len;
2775 /* set final tx command size */
2776 pattrib->last_txcmdsz = pattrib->pktlen;
2778 /* set protected bit must be beofre SW encrypt */
2779 SetPrivacy(mem_start);
2781 /* dump management packet include AES header */
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");
2790 /* software encrypt */
2791 xmitframe_swencrypt(padapter, pxmitframe);
2795 xmitframe_coalesce_success:
2796 _exit_critical_bh(&padapter->security_key_mutex, &irqL);
2797 rtw_mfree(BIP_AAD, ori_len);
2800 xmitframe_coalesce_fail:
2801 _exit_critical_bh(&padapter->security_key_mutex, &irqL);
2802 rtw_mfree(BIP_AAD, ori_len);
2806 #endif /* CONFIG_IEEE80211W */
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.
2815 s32 rtw_put_snap(u8 *data, u16 h_proto)
2817 struct ieee80211_snap_hdr *snap;
2821 snap = (struct ieee80211_snap_hdr *)data;
2826 if (h_proto == 0x8137 || h_proto == 0x80f3)
2831 snap->oui[0] = oui[0];
2832 snap->oui[1] = oui[1];
2833 snap->oui[2] = oui[2];
2835 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
2838 return SNAP_SIZE + sizeof(u16);
2841 void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len)
2847 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2848 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2851 switch (pxmitpriv->vcs_setting) {
2853 pxmitpriv->vcs = NONE_VCS;
2861 perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
2863 pxmitpriv->vcs = NONE_VCS;
2865 protection = (*(perp + 2)) & BIT(1);
2867 if (pregistrypriv->vcs_type == RTS_CTS)
2868 pxmitpriv->vcs = RTS_CTS;
2870 pxmitpriv->vcs = CTS_TO_SELF;
2872 pxmitpriv->vcs = NONE_VCS;
2882 void rtw_count_tx_stats(PADAPTER padapter, struct xmit_frame *pxmitframe, int sz)
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;
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;
2894 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pkt_num;
2896 pxmitpriv->tx_pkts += pkt_num;
2898 pxmitpriv->tx_bytes += sz;
2900 psta = pxmitframe->attrib.psta;
2902 pstats = &psta->sta_stats;
2904 pstats->tx_pkts += pkt_num;
2906 pstats->tx_bytes += sz;
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;
2913 #endif /* CONFIG_TDLS */
2916 #ifdef CONFIG_CHECK_LEAVE_LPS
2917 /* traffic_check_for_leave_lps(padapter, _TRUE); */
2918 #endif /* CONFIG_LPS */
2923 static struct xmit_buf *__rtw_alloc_cmd_xmitbuf(struct xmit_priv *pxmitpriv,
2924 enum cmdbuf_type buf_type)
2926 struct xmit_buf *pxmitbuf = NULL;
2929 pxmitbuf = &pxmitpriv->pcmd_xmitbuf[buf_type];
2930 if (pxmitbuf != NULL) {
2931 pxmitbuf->priv_data = NULL;
2933 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2935 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
2936 pxmitbuf->agg_num = 0;
2937 pxmitbuf->pg_num = 0;
2939 #ifdef CONFIG_PCI_HCI
2941 #ifdef CONFIG_TRX_BD_ARCH
2942 /*pxmitbuf->buf_desc = NULL;*/
2944 pxmitbuf->desc = NULL;
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);
2953 RTW_INFO("%s fail, no xmitbuf available !!!\n", __func__);
2961 struct xmit_frame *__rtw_alloc_cmdxmitframe(struct xmit_priv *pxmitpriv,
2962 enum cmdbuf_type buf_type)
2964 struct xmit_frame *pcmdframe;
2965 struct xmit_buf *pxmitbuf;
2967 pcmdframe = rtw_alloc_xmitframe(pxmitpriv);
2968 if (pcmdframe == NULL) {
2969 RTW_INFO("%s, alloc xmitframe fail\n", __FUNCTION__);
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);
2980 pcmdframe->frame_tag = MGNT_FRAMETAG;
2982 pcmdframe->pxmitbuf = pxmitbuf;
2984 pcmdframe->buf_addr = pxmitbuf->pbuf;
2986 /* initial memory to zero */
2987 _rtw_memset(pcmdframe->buf_addr, 0, pxmitbuf->alloc_sz);
2989 pxmitbuf->priv_data = pcmdframe;
2995 struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
2998 struct xmit_buf *pxmitbuf = NULL;
2999 _list *plist, *phead;
3000 _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
3003 _enter_critical(&pfree_queue->lock, &irqL);
3005 if (_rtw_queue_empty(pfree_queue) == _TRUE)
3009 phead = get_list_head(pfree_queue);
3011 plist = get_next(phead);
3013 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
3015 rtw_list_delete(&(pxmitbuf->list));
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);
3025 pxmitbuf->priv_data = NULL;
3027 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3029 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
3030 pxmitbuf->agg_num = 1;
3032 #ifdef CONFIG_PCI_HCI
3034 #ifdef CONFIG_TRX_BD_ARCH
3035 /*pxmitbuf->buf_desc = NULL;*/
3037 pxmitbuf->desc = NULL;
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);
3048 _exit_critical(&pfree_queue->lock, &irqL);
3054 s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
3057 _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
3060 if (pxmitbuf == NULL)
3063 _enter_critical(&pfree_queue->lock, &irqL);
3065 rtw_list_delete(&pxmitbuf->list);
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);
3073 _exit_critical(&pfree_queue->lock, &irqL);
3079 struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
3082 struct xmit_buf *pxmitbuf = NULL;
3083 _list *plist, *phead;
3084 _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
3087 /* RTW_INFO("+rtw_alloc_xmitbuf\n"); */
3089 _enter_critical(&pfree_xmitbuf_queue->lock, &irqL);
3091 if (_rtw_queue_empty(pfree_xmitbuf_queue) == _TRUE)
3095 phead = get_list_head(pfree_xmitbuf_queue);
3097 plist = get_next(phead);
3099 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
3101 rtw_list_delete(&(pxmitbuf->list));
3104 if (pxmitbuf != NULL) {
3105 pxmitpriv->free_xmitbuf_cnt--;
3107 RTW_INFO("DBG_XMIT_BUF ALLOC no=%d, free_xmitbuf_cnt=%d\n", pxmitbuf->no, pxmitpriv->free_xmitbuf_cnt);
3109 /* RTW_INFO("alloc, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); */
3111 pxmitbuf->priv_data = NULL;
3113 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3115 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
3116 pxmitbuf->agg_num = 0;
3117 pxmitbuf->pg_num = 0;
3119 #ifdef CONFIG_PCI_HCI
3121 #ifdef CONFIG_TRX_BD_ARCH
3122 /*pxmitbuf->buf_desc = NULL;*/
3124 pxmitbuf->desc = NULL;
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);
3135 RTW_INFO("DBG_XMIT_BUF rtw_alloc_xmitbuf return NULL\n");
3138 _exit_critical(&pfree_xmitbuf_queue->lock, &irqL);
3144 s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
3147 _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
3150 /* RTW_INFO("+rtw_free_xmitbuf\n"); */
3152 if (pxmitbuf == NULL)
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);
3160 if (pxmitbuf->buf_tag == XMITBUF_CMD) {
3161 } else if (pxmitbuf->buf_tag == XMITBUF_MGNT)
3162 rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf);
3164 _enter_critical(&pfree_xmitbuf_queue->lock, &irqL);
3166 rtw_list_delete(&pxmitbuf->list);
3168 rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
3170 pxmitpriv->free_xmitbuf_cnt++;
3171 /* RTW_INFO("FREE, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); */
3173 RTW_INFO("DBG_XMIT_BUF FREE no=%d, free_xmitbuf_cnt=%d\n", pxmitbuf->no , pxmitpriv->free_xmitbuf_cnt);
3175 _exit_critical(&pfree_xmitbuf_queue->lock, &irqL);
3182 void rtw_init_xmitframe(struct xmit_frame *pxframe)
3184 if (pxframe != NULL) { /* default value setting */
3185 pxframe->buf_addr = NULL;
3186 pxframe->pxmitbuf = NULL;
3188 _rtw_memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
3189 /* pxframe->attrib.psta = NULL; */
3191 pxframe->frame_tag = DATA_FRAMETAG;
3193 #ifdef CONFIG_USB_HCI
3194 pxframe->pkt = NULL;
3195 #ifdef USB_PACKET_OFFSET_SZ
3196 pxframe->pkt_offset = (PACKET_OFFSET_SZ / 8);
3198 pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */
3201 #ifdef CONFIG_USB_TX_AGGREGATION
3202 pxframe->agg_num = 1;
3205 #endif /* #ifdef CONFIG_USB_HCI */
3207 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3208 pxframe->pg_num = 1;
3209 pxframe->agg_num = 1;
3212 #ifdef CONFIG_XMIT_ACK
3213 pxframe->ack_report = 0;
3222 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
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...
3227 Must be very very cautious...
3230 struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* (_queue *pfree_xmit_queue) */
3233 Please remember to use all the osdep_service api,
3234 and lock/unlock or _enter/_exit critical to protect
3239 struct xmit_frame *pxframe = NULL;
3240 _list *plist, *phead;
3241 _queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
3244 _enter_critical_bh(&pfree_xmit_queue->lock, &irqL);
3246 if (_rtw_queue_empty(pfree_xmit_queue) == _TRUE) {
3249 phead = get_list_head(pfree_xmit_queue);
3251 plist = get_next(phead);
3253 pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3255 rtw_list_delete(&(pxframe->list));
3256 pxmitpriv->free_xmitframe_cnt--;
3259 _exit_critical_bh(&pfree_xmit_queue->lock, &irqL);
3261 rtw_init_xmitframe(pxframe);
3267 struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv)
3270 struct xmit_frame *pxframe = NULL;
3271 _list *plist, *phead;
3272 _queue *queue = &pxmitpriv->free_xframe_ext_queue;
3275 _enter_critical_bh(&queue->lock, &irqL);
3277 if (_rtw_queue_empty(queue) == _TRUE) {
3280 phead = get_list_head(queue);
3281 plist = get_next(phead);
3282 pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3284 rtw_list_delete(&(pxframe->list));
3285 pxmitpriv->free_xframe_ext_cnt--;
3288 _exit_critical_bh(&queue->lock, &irqL);
3290 rtw_init_xmitframe(pxframe);
3296 struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv)
3298 struct xmit_frame *pxframe = NULL;
3301 alloc_addr = rtw_zmalloc(sizeof(struct xmit_frame) + 4);
3303 if (alloc_addr == NULL)
3306 pxframe = (struct xmit_frame *)N_BYTE_ALIGMENT((SIZE_PTR)(alloc_addr), 4);
3307 pxframe->alloc_addr = alloc_addr;
3309 pxframe->padapter = pxmitpriv->adapter;
3310 pxframe->frame_tag = NULL_FRAMETAG;
3312 pxframe->pkt = NULL;
3314 pxframe->buf_addr = NULL;
3315 pxframe->pxmitbuf = NULL;
3317 rtw_init_xmitframe(pxframe);
3319 RTW_INFO("################## %s ##################\n", __func__);
3325 s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
3328 _queue *queue = NULL;
3329 _adapter *padapter = pxmitpriv->adapter;
3330 _pkt *pndis_pkt = NULL;
3333 if (pxmitframe == NULL) {
3337 if (pxmitframe->pkt) {
3338 pndis_pkt = pxmitframe->pkt;
3339 pxmitframe->pkt = NULL;
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;
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;
3355 _enter_critical_bh(&queue->lock, &irqL);
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++;
3366 _exit_critical_bh(&queue->lock, &irqL);
3371 rtw_os_pkt_complete(padapter, pndis_pkt);
3379 void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue)
3382 _list *plist, *phead;
3383 struct xmit_frame *pxmitframe;
3386 _enter_critical_bh(&(pframequeue->lock), &irqL);
3388 phead = get_list_head(pframequeue);
3389 plist = get_next(phead);
3391 while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
3393 pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
3395 plist = get_next(plist);
3397 rtw_free_xmitframe(pxmitpriv, pxmitframe);
3400 _exit_critical_bh(&(pframequeue->lock), &irqL);
3404 s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
3406 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue);
3407 if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) {
3408 /* pxmitframe->pkt = NULL; */
3415 static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue)
3417 _list *xmitframe_plist, *xmitframe_phead;
3418 struct xmit_frame *pxmitframe = NULL;
3420 xmitframe_phead = get_list_head(pframe_queue);
3421 xmitframe_plist = get_next(xmitframe_phead);
3423 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
3424 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
3426 /* xmitframe_plist = get_next(xmitframe_plist); */
3428 /*#ifdef RTK_DMP_PLATFORM
3429 #ifdef CONFIG_USB_TX_AGGREGATION
3430 if((ptxservq->qcnt>0) && (ptxservq->qcnt<=2))
3434 tasklet_schedule(&pxmitpriv->xmit_tasklet);
3440 rtw_list_delete(&pxmitframe->list);
3444 /* rtw_list_insert_tail(&pxmitframe->list, &phwxmit->pending); */
3446 /* ptxservq->qcnt--; */
3450 /* pxmitframe = NULL; */
3457 static struct xmit_frame *get_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue)
3459 _list *xmitframe_plist, *xmitframe_phead;
3460 struct xmit_frame *pxmitframe = NULL;
3462 xmitframe_phead = get_list_head(pframe_queue);
3463 xmitframe_plist = get_next(xmitframe_phead);
3465 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
3466 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
3473 struct xmit_frame *rtw_get_xframe(struct xmit_priv *pxmitpriv, int *num_frame)
3476 _list *sta_plist, *sta_phead;
3477 struct hw_xmit *phwxmit_i = pxmitpriv->hwxmits;
3478 sint entry = pxmitpriv->hwxmit_entry;
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;
3488 #ifdef CONFIG_USB_HCI
3489 /* int j, tmp, acirp_cnt[4]; */
3499 /*No amsdu when wifi_spec on*/
3500 if (pregpriv->wifi_spec == 1) {
3504 _enter_critical_bh(&pxmitpriv->lock, &irqL0);
3506 for (i = 0; i < entry; i++) {
3507 phwxmit = phwxmit_i + inx[i];
3509 sta_phead = get_list_head(phwxmit->sta_queue);
3510 sta_plist = get_next(sta_phead);
3512 while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) {
3514 ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
3515 pframe_queue = &ptxservq->sta_pending;
3519 *num_frame = ptxservq->qcnt;
3520 pxmitframe = get_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
3523 sta_plist = get_next(sta_plist);
3529 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
3535 struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry)
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;
3546 #ifdef CONFIG_USB_HCI
3547 /* int j, tmp, acirp_cnt[4]; */
3556 if (pregpriv->wifi_spec == 1) {
3557 int j, tmp, acirp_cnt[4];
3559 if (flags < XMIT_QUEUE_ENTRY) {
3560 /* priority exchange according to the completed xmitbuf flags. */
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];
3572 _enter_critical_bh(&pxmitpriv->lock, &irqL0);
3574 for (i = 0; i < entry; i++) {
3575 phwxmit = phwxmit_i + inx[i];
3577 /* _enter_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
3579 sta_phead = get_list_head(phwxmit->sta_queue);
3580 sta_plist = get_next(sta_phead);
3582 while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) {
3584 ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
3586 pframe_queue = &ptxservq->sta_pending;
3588 pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
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);
3597 /* _exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
3602 sta_plist = get_next(sta_plist);
3606 /* _exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); */
3612 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
3618 struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac)
3620 struct tx_servq *ptxservq = NULL;
3626 ptxservq = &(psta->sta_xmitpriv.bk_q);
3632 ptxservq = &(psta->sta_xmitpriv.vi_q);
3638 ptxservq = &(psta->sta_xmitpriv.vo_q);
3645 ptxservq = &(psta->sta_xmitpriv.be_q);
3655 __inline static struct tx_servq *rtw_get_sta_pending
3656 (_adapter *padapter, _queue **ppstapending, struct sta_info *psta, sint up)
3658 struct tx_servq *ptxservq;
3659 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
3662 #ifdef CONFIG_RTL8711
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;
3673 ptxservq = &(psta->sta_xmitpriv.bk_q);
3674 *ppstapending = &padapter->xmitpriv.bk_pending;
3675 (phwxmits + 3)->accnt++;
3680 ptxservq = &(psta->sta_xmitpriv.vi_q);
3681 *ppstapending = &padapter->xmitpriv.vi_pending;
3682 (phwxmits + 1)->accnt++;
3687 ptxservq = &(psta->sta_xmitpriv.vo_q);
3688 *ppstapending = &padapter->xmitpriv.vo_pending;
3689 (phwxmits + 0)->accnt++;
3695 ptxservq = &(psta->sta_xmitpriv.be_q);
3696 *ppstapending = &padapter->xmitpriv.be_pending;
3697 (phwxmits + 2)->accnt++;
3710 * Will enqueue pxmitframe to the proper queue,
3711 * and indicate it to xx_pending list.....
3713 s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe)
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;
3725 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class);
3728 if (pattrib->psta) {
3729 psta = pattrib->psta;
3731 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
3732 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
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);
3744 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_nosta);
3746 RTW_INFO("rtw_xmit_classifier: psta == NULL\n");
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);
3756 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
3758 /* _enter_critical(&pstapending->lock, &irqL0); */
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));
3763 /* _enter_critical(&ptxservq->sta_pending.lock, &irqL1); */
3765 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
3767 phwxmits[ac_index].accnt++;
3769 /* _exit_critical(&ptxservq->sta_pending.lock, &irqL1); */
3771 /* _exit_critical(&pstapending->lock, &irqL0); */
3779 void rtw_alloc_hwxmits(_adapter *padapter)
3781 struct hw_xmit *hwxmits;
3782 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3784 pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
3786 pxmitpriv->hwxmits = NULL;
3788 pxmitpriv->hwxmits = (struct hw_xmit *)rtw_zmalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry);
3790 if (pxmitpriv->hwxmits == NULL) {
3791 RTW_INFO("alloc hwxmits fail!...\n");
3795 hwxmits = pxmitpriv->hwxmits;
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;
3802 /* pxmitpriv->vo_txqueue.head = 0; */
3803 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; */
3804 hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
3806 /* pxmitpriv->vi_txqueue.head = 0; */
3807 /* hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; */
3808 hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
3810 /* pxmitpriv->bk_txqueue.head = 0; */
3811 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
3812 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
3814 /* pxmitpriv->be_txqueue.head = 0; */
3815 /* hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; */
3816 hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
3818 } else if (pxmitpriv->hwxmit_entry == 4) {
3820 /* pxmitpriv->vo_txqueue.head = 0; */
3821 /* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */
3822 hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
3824 /* pxmitpriv->vi_txqueue.head = 0; */
3825 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */
3826 hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
3828 /* pxmitpriv->be_txqueue.head = 0; */
3829 /* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */
3830 hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
3832 /* pxmitpriv->bk_txqueue.head = 0; */
3833 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
3834 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
3843 void rtw_free_hwxmits(_adapter *padapter)
3845 struct hw_xmit *hwxmits;
3846 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3848 hwxmits = pxmitpriv->hwxmits;
3850 rtw_mfree((u8 *)hwxmits, (sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry));
3853 void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry)
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; */
3864 #ifdef CONFIG_BR_EXT
3865 int rtw_br_client_tx(_adapter *padapter, struct sk_buff **pskb)
3867 struct sk_buff *skb = *pskb;
3868 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3870 /* if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) */
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;
3877 /* mac_clone_handle_frame(priv, skb); */
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)) */
3883 br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
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) &&
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);
3897 /* if (!priv->pmib->ethBrExtInfo.nat25_disable) */
3899 /* if (priv->dev->br_port &&
3900 * !memcmp(skb->data+MACADDRLEN, priv->br_mac, MACADDRLEN)) { */
3902 if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q)) {
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));
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);
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);
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;
3927 if (padapter->scdb_entry) {
3928 padapter->scdb_entry->ageing_timer = jiffies;
3931 memset(padapter->scdb_mac, 0, MACADDRLEN);
3932 memset(padapter->scdb_ip, 0, 4);
3936 _exit_critical_bh(&padapter->br_ext_lock, &irqL);
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;
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;
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; */
3960 *pskb = skb = newskb;
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));
3969 if (skb_is_nonlinear(skb))
3970 DEBUG_ERR("%s(): skb_is_nonlinear!!\n", __FUNCTION__);
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)) */
3979 DEBUG_ERR("TX DROP: skb_linearize fail!\n");
3980 /* goto free_and_stop; */
3984 res = nat25_db_handle(padapter, skb, NAT25_INSERT);
3987 /* priv->ext_stats.tx_drops++; */
3988 DEBUG_ERR("TX DROP: nat25_db_handle fail!\n");
3989 /* goto free_and_stop; */
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! */
4000 memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
4002 dhcp_flag_bcast(padapter, skb);
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;
4014 if (*((unsigned short *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q))
4018 if (ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A_VALN(skb->data))
4019 memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
4021 if (ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A(skb->data))
4022 memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
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; */
4038 #endif /* CONFIG_BR_EXT */
4040 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
4043 struct pkt_attrib *pattrib = &pxmitframe->attrib;
4045 switch (pattrib->qsel) {
4048 addr = BE_QUEUE_INX;
4052 addr = BK_QUEUE_INX;
4056 addr = VI_QUEUE_INX;
4060 addr = VO_QUEUE_INX;
4063 addr = BCN_QUEUE_INX;
4065 case 0x11: /* BC/MC in PS (HIQ) */
4066 addr = HIGH_QUEUE_INX;
4069 addr = TXCMD_QUEUE_INX;
4073 addr = MGT_QUEUE_INX;
4082 static void do_queue_select(_adapter *padapter, struct pkt_attrib *pattrib)
4086 qsel = pattrib->priority;
4088 #ifdef CONFIG_CONCURRENT_MODE
4089 /* if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
4093 #ifdef CONFIG_MCC_MODE
4094 if (MCC_EN(padapter)) {
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 */
4101 pattrib->qsel = QSLT_BE; /* STA interface BE queue */
4105 pattrib->qsel = qsel;
4107 /* Not enable MCC */
4108 pattrib->qsel = qsel;
4109 #else /* !CONFIG_MCC_MODE */
4110 pattrib->qsel = qsel;
4111 #endif /* CONFIG_MCC_MODE */
4115 * The main transmit(tx) entry
4119 * 0 success, hardware will handle this xmit frame(packet)
4122 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
4123 s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
4128 int dot11_hdr_len = 24;
4130 unsigned char *pdata;
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);
4139 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
4141 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
4144 rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
4145 if (unlikely(rtap_hdr->it_version))
4148 rtap_len = ieee80211_get_radiotap_len(skb->data);
4149 if (unlikely(skb->len < rtap_len))
4152 if (rtap_len != 12) {
4153 RTW_INFO("radiotap len (should be 14): %d\n", rtap_len);
4157 /* Skip the ratio tap header */
4158 skb_pull(skb, rtap_len);
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 */
4164 if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
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;
4174 u8 category, action;
4177 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4178 if (pmgntframe == NULL) {
4182 pattrib = &pmgntframe->attrib;
4184 update_monitor_frame_attrib(padapter, pattrib);
4186 pattrib->retry_ctrl = _FALSE;
4188 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4190 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4192 _rtw_memcpy(pframe, (void *)buf, len);
4194 pattrib->pktlen = len;
4196 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4198 if (is_broadcast_mac_addr(pwlanhdr->addr3) || is_broadcast_mac_addr(pwlanhdr->addr1))
4199 pattrib->rate = MGN_24M;
4201 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4202 pattrib->seqnum = pmlmeext->mgnt_seq;
4203 pmlmeext->mgnt_seq++;
4205 pattrib->last_txcmdsz = pattrib->pktlen;
4207 dump_mgntframe(padapter, pmgntframe);
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;
4218 u8 category, action;
4221 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4222 if (pmgntframe == NULL)
4225 pattrib = &pmgntframe->attrib;
4226 update_mgntframe_attrib(padapter, pattrib);
4227 pattrib->retry_ctrl = _FALSE;
4229 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4231 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4233 _rtw_memcpy(pframe, (void *)buf, len);
4235 pattrib->pktlen = len;
4237 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4239 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4240 pattrib->seqnum = pmlmeext->mgnt_seq;
4241 pmlmeext->mgnt_seq++;
4243 pattrib->last_txcmdsz = pattrib->pktlen;
4245 dump_mgntframe(padapter, pmgntframe);
4257 * The main transmit(tx) entry
4261 * 0 success, hardware will handle this xmit frame(packet)
4264 s32 rtw_xmit(_adapter *padapter, _pkt **ppkt)
4266 static u32 start = 0;
4267 static u32 drop_cnt = 0;
4268 #ifdef CONFIG_AP_MODE
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 */
4280 DBG_COUNTER(padapter->tx_logs.core_tx);
4283 start = rtw_get_current_time();
4285 pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
4287 if (rtw_get_passing_time_ms(start) > 2000) {
4289 RTW_INFO("DBG_TX_DROP_FRAME %s no more pxmitframe, drop_cnt:%u\n", __FUNCTION__, drop_cnt);
4290 start = rtw_get_current_time();
4294 if (pxmitframe == NULL) {
4296 /*RTW_INFO("%s-"ADPT_FMT" no more xmitframe\n", __func__, ADPT_ARG(padapter));*/
4297 DBG_COUNTER(padapter->tx_logs.core_tx_err_pxmitframe);
4301 #ifdef CONFIG_BR_EXT
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)) */
4307 br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
4309 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
4311 if (br_port && check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) {
4312 res = rtw_br_client_tx(padapter, ppkt);
4314 rtw_free_xmitframe(pxmitpriv, pxmitframe);
4315 DBG_COUNTER(padapter->tx_logs.core_tx_err_brtx);
4320 #endif /* CONFIG_BR_EXT */
4322 res = update_attrib(padapter, *ppkt, &pxmitframe->attrib);
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 */
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");
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__);
4342 rtw_free_xmitframe(pxmitpriv, pxmitframe);
4345 pxmitframe->pkt = *ppkt;
4347 rtw_led_control(padapter, LED_CTL_TX);
4349 do_queue_select(padapter, &pxmitframe->attrib);
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);
4358 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
4362 if (rtw_hal_xmit(padapter, pxmitframe) == _FALSE)
4369 sint xmitframe_enqueue_for_tdls_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
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);
4380 ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
4381 if (ptdls_sta == NULL)
4383 else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
4385 if (pattrib->triggered == 1) {
4390 _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
4392 if (ptdls_sta->state & WIFI_SLEEP_STATE) {
4393 rtw_list_delete(&pxmitframe->list);
4395 /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
4397 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptdls_sta->sleep_q));
4399 ptdls_sta->sleepq_len++;
4400 ptdls_sta->sleepq_ac_len++;
4402 /* indicate 4-AC queue bit in TDLS peer traffic indication */
4403 switch (pattrib->priority) {
4406 ptdls_sta->uapsd_bk |= BIT(1);
4410 ptdls_sta->uapsd_vi |= BIT(1);
4414 ptdls_sta->uapsd_vo |= BIT(1);
4419 ptdls_sta->uapsd_be |= BIT(1);
4423 /* Transmit TDLS PTI via AP */
4424 if (ptdls_sta->sleepq_len == 1)
4425 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ISSUE_PTI);
4430 _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
4436 #endif /* CONFIG_TDLS */
4438 #define RTW_HIQ_FILTER_ALLOW_ALL 0
4439 #define RTW_HIQ_FILTER_ALLOW_SPECIAL 1
4440 #define RTW_HIQ_FILTER_DENY_ALL 2
4442 inline bool xmitframe_hiq_filter(struct xmit_frame *xmitframe)
4444 bool allow = _FALSE;
4445 _adapter *adapter = xmitframe->padapter;
4446 struct registry_priv *registry = &adapter->registrypriv;
4448 if (rtw_get_intf_type(adapter) != RTW_PCIE) {
4450 if (adapter->registrypriv.wifi_spec == 1)
4452 else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_SPECIAL) {
4454 struct pkt_attrib *attrib = &xmitframe->attrib;
4456 if (attrib->ether_type == 0x0806
4457 || attrib->ether_type == 0x888e
4458 #ifdef CONFIG_WAPI_SUPPORT
4459 || attrib->ether_type == 0x88B4
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" : "");
4468 } else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_ALL)
4470 else if (registry->hiq_filter == RTW_HIQ_FILTER_DENY_ALL) {
4477 #if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS)
4479 sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe)
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;
4491 if (padapter->tdlsinfo.link_established == _TRUE)
4492 ret = xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pxmitframe);
4493 #endif /* CONFIG_TDLS */
4495 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _FALSE) {
4496 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_fwstate);
4502 psta = pattrib->psta;
4506 RTW_INFO("%s, call rtw_get_stainfo()\n", __func__);
4507 psta=rtw_get_stainfo(pstapriv, pattrib->ra);
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);
4518 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_nosta);
4519 RTW_INFO("%s, psta==NUL\n", __func__);
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);
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"); */
4533 /* pattrib->triggered=0; */
4534 if (bmcst && xmitframe_hiq_filter(pxmitframe) == _TRUE)
4535 pattrib->qsel = QSLT_HIGH;/* HIQ */
4542 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
4544 if (pstapriv->sta_dz_bitmap) { /* if anyone sta is in ps mode */
4545 /* pattrib->qsel = QSLT_HIGH; */ /* HIQ */
4547 rtw_list_delete(&pxmitframe->list);
4549 /*_enter_critical_bh(&psta->sleep_q.lock, &irqL);*/
4551 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
4555 if (!(pstapriv->tim_bitmap & BIT(0)))
4558 pstapriv->tim_bitmap |= BIT(0);
4559 pstapriv->sta_dz_bitmap |= BIT(0);
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");
4566 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer MC");
4568 chk_bmc_sleepq_cmd(padapter);
4570 /*_exit_critical_bh(&psta->sleep_q.lock, &irqL);*/
4574 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_mcast);
4578 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
4585 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
4587 if (psta->state & WIFI_SLEEP_STATE) {
4590 if (pstapriv->sta_dz_bitmap & BIT(psta->aid)) {
4591 rtw_list_delete(&pxmitframe->list);
4593 /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
4595 rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
4599 switch (pattrib->priority) {
4602 wmmps_ac = psta->uapsd_bk & BIT(0);
4606 wmmps_ac = psta->uapsd_vi & BIT(0);
4610 wmmps_ac = psta->uapsd_vo & BIT(0);
4615 wmmps_ac = psta->uapsd_be & BIT(0);
4620 psta->sleepq_ac_len++;
4622 if (((psta->has_legacy_ac) && (!wmmps_ac)) || ((!psta->has_legacy_ac) && (wmmps_ac))) {
4623 if (!(pstapriv->tim_bitmap & BIT(psta->aid)))
4626 pstapriv->tim_bitmap |= BIT(psta->aid);
4628 /* RTW_INFO("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
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");
4637 /* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
4639 /* if(psta->sleepq_len > (NR_XMITFRAME>>3)) */
4641 /* wakeup_sta_to_xmit(padapter, psta); */
4646 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_ucast);
4651 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
4657 static void dequeue_xmitframes_to_sleeping_queue(_adapter *padapter, struct sta_info *psta, _queue *pframequeue)
4660 _list *plist, *phead;
4662 struct tx_servq *ptxservq;
4663 struct pkt_attrib *pattrib;
4664 struct xmit_frame *pxmitframe;
4665 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
4667 phead = get_list_head(pframequeue);
4668 plist = get_next(phead);
4670 while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
4671 pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
4673 plist = get_next(plist);
4675 pattrib = &pxmitframe->attrib;
4677 pattrib->triggered = 0;
4679 ret = xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
4682 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
4685 phwxmits[ac_index].accnt--;
4687 /* RTW_INFO("xmitframe_enqueue_for_sleeping_sta return _FALSE\n"); */
4694 void stop_sta_xmit(_adapter *padapter, struct sta_info *psta)
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;
4702 pstaxmitpriv = &psta->sta_xmitpriv;
4704 /* for BC/MC Frames */
4705 psta_bmc = rtw_get_bcmc_stainfo(padapter);
4708 _enter_critical_bh(&pxmitpriv->lock, &irqL0);
4710 psta->state |= WIFI_SLEEP_STATE;
4713 if (!(psta->tdls_sta_state & TDLS_LINKED_STATE))
4714 #endif /* CONFIG_TDLS */
4715 pstapriv->sta_dz_bitmap |= BIT(psta->aid);
4719 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
4720 rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));
4723 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
4724 rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));
4727 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
4728 rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
4731 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
4732 rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));
4735 if (!(psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta_bmc != NULL)) {
4736 #endif /* CONFIG_TDLS */
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));
4747 #endif /* CONFIG_TDLS */
4748 _exit_critical_bh(&pxmitpriv->lock, &irqL0);
4753 void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta)
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;
4763 psta_bmc = rtw_get_bcmc_stainfo(padapter);
4766 /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
4767 _enter_critical_bh(&pxmitpriv->lock, &irqL);
4769 xmitframe_phead = get_list_head(&psta->sleep_q);
4770 xmitframe_plist = get_next(xmitframe_phead);
4772 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
4773 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4775 xmitframe_plist = get_next(xmitframe_plist);
4777 rtw_list_delete(&pxmitframe->list);
4779 switch (pxmitframe->attrib.priority) {
4782 wmmps_ac = psta->uapsd_bk & BIT(1);
4786 wmmps_ac = psta->uapsd_vi & BIT(1);
4790 wmmps_ac = psta->uapsd_vo & BIT(1);
4795 wmmps_ac = psta->uapsd_be & BIT(1);
4800 if (psta->sleepq_len > 0)
4801 pxmitframe->attrib.mdata = 1;
4803 pxmitframe->attrib.mdata = 0;
4806 psta->sleepq_ac_len--;
4807 if (psta->sleepq_ac_len > 0) {
4808 pxmitframe->attrib.mdata = 1;
4809 pxmitframe->attrib.eosp = 0;
4811 pxmitframe->attrib.mdata = 0;
4812 pxmitframe->attrib.eosp = 1;
4816 pxmitframe->attrib.triggered = 1;
4819 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
4820 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
4822 rtw_os_xmit_complete(padapter, pxmitframe);
4824 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
4826 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
4831 if (psta->sleepq_len == 0) {
4833 if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
4834 if (psta->state & WIFI_SLEEP_STATE)
4835 psta->state ^= WIFI_SLEEP_STATE;
4837 _exit_critical_bh(&pxmitpriv->lock, &irqL);
4840 #endif /* CONFIG_TDLS */
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);
4849 pstapriv->tim_bitmap &= ~BIT(psta->aid);
4851 if (psta->state & WIFI_SLEEP_STATE)
4852 psta->state ^= WIFI_SLEEP_STATE;
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;
4860 pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
4863 /* for BC/MC Frames */
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);
4871 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
4872 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4874 xmitframe_plist = get_next(xmitframe_plist);
4876 rtw_list_delete(&pxmitframe->list);
4878 psta_bmc->sleepq_len--;
4879 if (psta_bmc->sleepq_len > 0)
4880 pxmitframe->attrib.mdata = 1;
4882 pxmitframe->attrib.mdata = 0;
4885 pxmitframe->attrib.triggered = 1;
4887 _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
4888 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
4890 rtw_os_xmit_complete(padapter, pxmitframe);
4892 _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
4895 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
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);
4906 pstapriv->tim_bitmap &= ~BIT(0);
4907 pstapriv->sta_dz_bitmap &= ~BIT(0);
4914 /* _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); */
4915 _exit_critical_bh(&pxmitpriv->lock, &irqL);
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");
4924 _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "clear UC");
4929 void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta)
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;
4939 /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
4940 _enter_critical_bh(&pxmitpriv->lock, &irqL);
4942 xmitframe_phead = get_list_head(&psta->sleep_q);
4943 xmitframe_plist = get_next(xmitframe_phead);
4945 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
4946 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
4948 xmitframe_plist = get_next(xmitframe_plist);
4950 switch (pxmitframe->attrib.priority) {
4953 wmmps_ac = psta->uapsd_bk & BIT(1);
4957 wmmps_ac = psta->uapsd_vi & BIT(1);
4961 wmmps_ac = psta->uapsd_vo & BIT(1);
4966 wmmps_ac = psta->uapsd_be & BIT(1);
4973 rtw_list_delete(&pxmitframe->list);
4976 psta->sleepq_ac_len--;
4978 if (psta->sleepq_ac_len > 0) {
4979 pxmitframe->attrib.mdata = 1;
4980 pxmitframe->attrib.eosp = 0;
4982 pxmitframe->attrib.mdata = 0;
4983 pxmitframe->attrib.eosp = 1;
4986 pxmitframe->attrib.triggered = 1;
4987 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
4989 if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) {
4991 if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
4992 /* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
4995 #endif /* CONFIG_TDLS */
4996 pstapriv->tim_bitmap &= ~BIT(psta->aid);
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); */
5008 /* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
5009 _exit_critical_bh(&pxmitpriv->lock, &irqL);
5014 #endif /* defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) */
5016 #ifdef CONFIG_XMIT_THREAD_MODE
5017 void enqueue_pending_xmitbuf(
5018 struct xmit_priv *pxmitpriv,
5019 struct xmit_buf *pxmitbuf)
5023 _adapter *pri_adapter = pxmitpriv->adapter;
5025 pqueue = &pxmitpriv->pending_xmitbuf_queue;
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);
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));
5038 void enqueue_pending_xmitbuf_to_head(
5039 struct xmit_priv *pxmitpriv,
5040 struct xmit_buf *pxmitbuf)
5043 _queue *pqueue = &pxmitpriv->pending_xmitbuf_queue;
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);
5051 struct xmit_buf *dequeue_pending_xmitbuf(
5052 struct xmit_priv *pxmitpriv)
5055 struct xmit_buf *pxmitbuf;
5060 pqueue = &pxmitpriv->pending_xmitbuf_queue;
5062 _enter_critical_bh(&pqueue->lock, &irql);
5064 if (_rtw_queue_empty(pqueue) == _FALSE) {
5065 _list *plist, *phead;
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);
5073 _exit_critical_bh(&pqueue->lock, &irql);
5078 static struct xmit_buf *dequeue_pending_xmitbuf_under_survey(
5079 struct xmit_priv *pxmitpriv)
5082 struct xmit_buf *pxmitbuf;
5083 #ifdef CONFIG_USB_HCI
5084 struct xmit_frame *pxmitframe;
5090 pqueue = &pxmitpriv->pending_xmitbuf_queue;
5092 _enter_critical_bh(&pqueue->lock, &irql);
5094 if (_rtw_queue_empty(pqueue) == _FALSE) {
5095 _list *plist, *phead;
5098 phead = get_list_head(pqueue);
5101 plist = get_next(plist);
5105 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
5107 #ifdef CONFIG_USB_HCI
5108 pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
5110 type = get_frame_sub_type(pxmitbuf->pbuf + TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
5112 RTW_INFO("%s, !!!ERROR!!! For USB, TODO ITEM\n", __FUNCTION__);
5114 type = get_frame_sub_type(pxmitbuf->pbuf + TXDESC_OFFSET);
5117 if ((type == WIFI_PROBEREQ) ||
5118 (type == WIFI_DATA_NULL) ||
5119 (type == WIFI_QOS_DATA_NULL)) {
5120 rtw_list_delete(&pxmitbuf->list);
5127 _exit_critical_bh(&pqueue->lock, &irql);
5132 static struct xmit_buf *dequeue_pending_xmitbuf_ext(
5133 struct xmit_priv *pxmitpriv)
5136 struct xmit_buf *pxmitbuf;
5140 pqueue = &pxmitpriv->pending_xmitbuf_queue;
5142 _enter_critical_bh(&pqueue->lock, &irql);
5144 if (_rtw_queue_empty(pqueue) == _FALSE) {
5145 _list *plist, *phead;
5148 phead = get_list_head(pqueue);
5151 plist = get_next(plist);
5155 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
5157 if (pxmitbuf->buf_tag == XMITBUF_MGNT) {
5158 rtw_list_delete(&pxmitbuf->list);
5165 _exit_critical_bh(&pqueue->lock, &irql);
5170 struct xmit_buf *select_and_dequeue_pending_xmitbuf(_adapter *padapter)
5172 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5173 struct xmit_buf *pxmitbuf = NULL;
5175 if (rtw_xmit_ac_blocked(padapter) == _TRUE)
5176 pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv);
5178 pxmitbuf = dequeue_pending_xmitbuf_ext(pxmitpriv);
5179 if (pxmitbuf == NULL)
5180 pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
5186 sint check_pending_xmitbuf(
5187 struct xmit_priv *pxmitpriv)
5193 pqueue = &pxmitpriv->pending_xmitbuf_queue;
5195 _enter_critical_bh(&pqueue->lock, &irql);
5197 if (_rtw_queue_empty(pqueue) == _FALSE)
5200 _exit_critical_bh(&pqueue->lock, &irql);
5205 thread_return rtw_xmit_thread(thread_context context)
5212 padapter = (PADAPTER)context;
5214 thread_enter("RTW_XMIT_THREAD");
5217 err = rtw_hal_xmit_thread_handler(padapter);
5218 flush_signals_thread();
5219 } while (_SUCCESS == err);
5221 _rtw_up_sema(&padapter->xmitpriv.terminate_xmitthread_sema);
5227 bool rtw_xmit_ac_blocked(_adapter *adapter)
5229 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5231 struct mlme_ext_priv *mlmeext;
5232 struct mlme_ext_info *mlmeextinfo;
5233 bool blocked = _FALSE;
5236 for (i = 0; i < dvobj->iface_nums; i++) {
5237 iface = dvobj->padapters[i];
5238 mlmeext = &iface->mlmeextpriv;
5240 /* check scan state */
5241 if (mlmeext_scan_state(mlmeext) != SCAN_DISABLE
5242 && mlmeext_scan_state(mlmeext) != SCAN_BACK_OP
5248 if (mlmeext_scan_state(mlmeext) == SCAN_BACK_OP
5249 && !mlmeext_chk_scan_backop_flags(mlmeext, SS_BACKOP_TX_RESUME)
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)) {
5265 #endif /* CONFIG_MCC_MODE */
5271 #ifdef CONFIG_TX_AMSDU
5272 void rtw_amsdu_vo_timeout_handler(void *FunctionContext)
5274 _adapter *adapter = (_adapter *)FunctionContext;
5276 adapter->xmitpriv.amsdu_vo_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5278 tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5281 void rtw_amsdu_vi_timeout_handler(void *FunctionContext)
5283 _adapter *adapter = (_adapter *)FunctionContext;
5285 adapter->xmitpriv.amsdu_vi_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5287 tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5290 void rtw_amsdu_be_timeout_handler(void *FunctionContext)
5292 _adapter *adapter = (_adapter *)FunctionContext;
5294 adapter->xmitpriv.amsdu_be_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5296 if (printk_ratelimit())
5297 RTW_INFO("%s Timeout!\n",__FUNCTION__);
5299 tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5302 void rtw_amsdu_bk_timeout_handler(void *FunctionContext)
5304 _adapter *adapter = (_adapter *)FunctionContext;
5306 adapter->xmitpriv.amsdu_bk_timeout = RTW_AMSDU_TIMER_TIMEOUT;
5308 tasklet_hi_schedule(&adapter->xmitpriv.xmit_tasklet);
5311 u8 rtw_amsdu_get_timer_status(_adapter *padapter, u8 priority)
5313 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5315 u8 status = RTW_AMSDU_TIMER_UNSET;
5321 status = pxmitpriv->amsdu_bk_timeout;
5325 status = pxmitpriv->amsdu_vi_timeout;
5329 status = pxmitpriv->amsdu_vo_timeout;
5334 status = pxmitpriv->amsdu_be_timeout;
5340 void rtw_amsdu_set_timer_status(_adapter *padapter, u8 priority, u8 status)
5342 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5348 pxmitpriv->amsdu_bk_timeout = status;
5352 pxmitpriv->amsdu_vi_timeout = status;
5356 pxmitpriv->amsdu_vo_timeout = status;
5361 pxmitpriv->amsdu_be_timeout = status;
5366 void rtw_amsdu_set_timer(_adapter *padapter, u8 priority)
5368 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5370 _timer* amsdu_timer = NULL;
5376 amsdu_timer = &pxmitpriv->amsdu_bk_timer;
5380 amsdu_timer = &pxmitpriv->amsdu_vi_timer;
5384 amsdu_timer = &pxmitpriv->amsdu_vo_timer;
5389 amsdu_timer = &pxmitpriv->amsdu_be_timer;
5392 _set_timer(amsdu_timer, 1);
5395 void rtw_amsdu_cancel_timer(_adapter *padapter, u8 priority)
5397 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5398 _timer* amsdu_timer = NULL;
5405 amsdu_timer = &pxmitpriv->amsdu_bk_timer;
5409 amsdu_timer = &pxmitpriv->amsdu_vi_timer;
5413 amsdu_timer = &pxmitpriv->amsdu_vo_timer;
5418 amsdu_timer = &pxmitpriv->amsdu_be_timer;
5421 _cancel_timer(amsdu_timer, &cancel);
5423 #endif /* CONFIG_TX_AMSDU */
5425 void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms)
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);
5432 sctx->status = RTW_SCTX_SUBMITTED;
5435 int rtw_sctx_wait(struct submit_ctx *sctx, const char *msg)
5438 unsigned long expire;
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);
5448 status = sctx->status;
5451 if (status == RTW_SCTX_DONE_SUCCESS)
5457 bool rtw_sctx_chk_waring_status(int status)
5460 case RTW_SCTX_DONE_UNKNOWN:
5461 case RTW_SCTX_DONE_BUF_ALLOC:
5462 case RTW_SCTX_DONE_BUF_FREE:
5464 case RTW_SCTX_DONE_DRV_STOP:
5465 case RTW_SCTX_DONE_DEV_REMOVE:
5472 void rtw_sctx_done_err(struct submit_ctx **sctx, int status)
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));
5485 void rtw_sctx_done(struct submit_ctx **sctx)
5487 rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS);
5490 #ifdef CONFIG_XMIT_ACK
5491 int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
5493 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
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;
5499 return rtw_sctx_wait(pack_tx_ops, __func__);
5502 void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)
5504 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
5506 if (pxmitpriv->ack_tx)
5507 rtw_sctx_done_err(&pack_tx_ops, status);
5509 RTW_INFO("%s ack_tx not set\n", __func__);
5511 #endif /* CONFIG_XMIT_ACK */