1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#define _RTW_XMIT_C_
16
17#include <drv_types.h>
18#include <rtw_debug.h>
19
20static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
21static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
22
23static void _init_txservq(struct tx_servq *ptxservq)
24{
25 INIT_LIST_HEAD(&ptxservq->tx_pending);
26 _rtw_init_queue(&ptxservq->sta_pending);
27 ptxservq->qcnt = 0;
28}
29
30void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
31{
32 memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv));
33
34 spin_lock_init(&psta_xmitpriv->lock);
35
36
37
38
39 _init_txservq(&psta_xmitpriv->be_q);
40 _init_txservq(&psta_xmitpriv->bk_q);
41 _init_txservq(&psta_xmitpriv->vi_q);
42 _init_txservq(&psta_xmitpriv->vo_q);
43 INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
44 INIT_LIST_HEAD(&psta_xmitpriv->apsd);
45}
46
47s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
48{
49 int i;
50 struct xmit_buf *pxmitbuf;
51 struct xmit_frame *pxframe;
52 sint res = _SUCCESS;
53
54
55
56
57 spin_lock_init(&pxmitpriv->lock);
58 spin_lock_init(&pxmitpriv->lock_sctx);
59 sema_init(&pxmitpriv->xmit_sema, 0);
60 sema_init(&pxmitpriv->terminate_xmitthread_sema, 0);
61
62
63
64
65
66 pxmitpriv->adapter = padapter;
67
68
69
70
71 _rtw_init_queue(&pxmitpriv->be_pending);
72 _rtw_init_queue(&pxmitpriv->bk_pending);
73 _rtw_init_queue(&pxmitpriv->vi_pending);
74 _rtw_init_queue(&pxmitpriv->vo_pending);
75 _rtw_init_queue(&pxmitpriv->bm_pending);
76
77
78
79
80 _rtw_init_queue(&pxmitpriv->free_xmit_queue);
81
82
83
84
85
86
87
88 pxmitpriv->pallocated_frame_buf = vzalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
89
90 if (pxmitpriv->pallocated_frame_buf == NULL) {
91 pxmitpriv->pxmit_frame_buf = NULL;
92 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_frame fail!\n"));
93 res = _FAIL;
94 goto exit;
95 }
96 pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_frame_buf), 4);
97
98
99
100 pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
101
102 for (i = 0; i < NR_XMITFRAME; i++) {
103 INIT_LIST_HEAD(&(pxframe->list));
104
105 pxframe->padapter = padapter;
106 pxframe->frame_tag = NULL_FRAMETAG;
107
108 pxframe->pkt = NULL;
109
110 pxframe->buf_addr = NULL;
111 pxframe->pxmitbuf = NULL;
112
113 list_add_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue));
114
115 pxframe++;
116 }
117
118 pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
119
120 pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
121
122
123
124 _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue);
125 _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue);
126
127 pxmitpriv->pallocated_xmitbuf = vzalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
128
129 if (pxmitpriv->pallocated_xmitbuf == NULL) {
130 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_buf fail!\n"));
131 res = _FAIL;
132 goto exit;
133 }
134
135 pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmitbuf), 4);
136
137
138
139 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
140
141 for (i = 0; i < NR_XMITBUFF; i++) {
142 INIT_LIST_HEAD(&pxmitbuf->list);
143
144 pxmitbuf->priv_data = NULL;
145 pxmitbuf->padapter = padapter;
146 pxmitbuf->buf_tag = XMITBUF_DATA;
147
148
149 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), true);
150 if (res == _FAIL) {
151 msleep(10);
152 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), true);
153 if (res == _FAIL)
154 goto exit;
155 }
156
157 pxmitbuf->phead = pxmitbuf->pbuf;
158 pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMITBUF_SZ;
159 pxmitbuf->len = 0;
160 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
161
162 pxmitbuf->flags = XMIT_VO_QUEUE;
163
164 list_add_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue));
165 #ifdef DBG_XMIT_BUF
166 pxmitbuf->no = i;
167 #endif
168
169 pxmitbuf++;
170
171 }
172
173 pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
174
175
176 _rtw_init_queue(&pxmitpriv->free_xframe_ext_queue);
177
178 pxmitpriv->xframe_ext_alloc_addr = vzalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4);
179
180 if (pxmitpriv->xframe_ext_alloc_addr == NULL) {
181 pxmitpriv->xframe_ext = NULL;
182 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xframe_ext fail!\n"));
183 res = _FAIL;
184 goto exit;
185 }
186 pxmitpriv->xframe_ext = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->xframe_ext_alloc_addr), 4);
187 pxframe = (struct xmit_frame *)pxmitpriv->xframe_ext;
188
189 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
190 INIT_LIST_HEAD(&(pxframe->list));
191
192 pxframe->padapter = padapter;
193 pxframe->frame_tag = NULL_FRAMETAG;
194
195 pxframe->pkt = NULL;
196
197 pxframe->buf_addr = NULL;
198 pxframe->pxmitbuf = NULL;
199
200 pxframe->ext_tag = 1;
201
202 list_add_tail(&(pxframe->list), &(pxmitpriv->free_xframe_ext_queue.queue));
203
204 pxframe++;
205 }
206 pxmitpriv->free_xframe_ext_cnt = NR_XMIT_EXTBUFF;
207
208
209 _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
210
211 pxmitpriv->pallocated_xmit_extbuf = vzalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4);
212
213 if (pxmitpriv->pallocated_xmit_extbuf == NULL) {
214 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_extbuf fail!\n"));
215 res = _FAIL;
216 goto exit;
217 }
218
219 pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmit_extbuf), 4);
220
221 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
222
223 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
224 INIT_LIST_HEAD(&pxmitbuf->list);
225
226 pxmitbuf->priv_data = NULL;
227 pxmitbuf->padapter = padapter;
228 pxmitbuf->buf_tag = XMITBUF_MGNT;
229
230 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ, true);
231 if (res == _FAIL) {
232 res = _FAIL;
233 goto exit;
234 }
235
236 pxmitbuf->phead = pxmitbuf->pbuf;
237 pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMIT_EXTBUF_SZ;
238 pxmitbuf->len = 0;
239 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
240
241 list_add_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue));
242 #ifdef DBG_XMIT_BUF_EXT
243 pxmitbuf->no = i;
244 #endif
245 pxmitbuf++;
246
247 }
248
249 pxmitpriv->free_xmit_extbuf_cnt = NR_XMIT_EXTBUFF;
250
251 for (i = 0; i < CMDBUF_MAX; i++) {
252 pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i];
253 if (pxmitbuf) {
254 INIT_LIST_HEAD(&pxmitbuf->list);
255
256 pxmitbuf->priv_data = NULL;
257 pxmitbuf->padapter = padapter;
258 pxmitbuf->buf_tag = XMITBUF_CMD;
259
260 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ, true);
261 if (res == _FAIL) {
262 res = _FAIL;
263 goto exit;
264 }
265
266 pxmitbuf->phead = pxmitbuf->pbuf;
267 pxmitbuf->pend = pxmitbuf->pbuf + MAX_CMDBUF_SZ;
268 pxmitbuf->len = 0;
269 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
270 pxmitbuf->alloc_sz = MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ;
271 }
272 }
273
274 rtw_alloc_hwxmits(padapter);
275 rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
276
277 for (i = 0; i < 4; i++) {
278 pxmitpriv->wmm_para_seq[i] = i;
279 }
280
281 pxmitpriv->ack_tx = false;
282 mutex_init(&pxmitpriv->ack_tx_mutex);
283 rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0);
284
285 rtw_hal_init_xmit_priv(padapter);
286
287exit:
288 return res;
289}
290
291void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv)
292{
293 int i;
294 struct adapter *padapter = pxmitpriv->adapter;
295 struct xmit_frame *pxmitframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
296 struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
297
298 rtw_hal_free_xmit_priv(padapter);
299
300 if (pxmitpriv->pxmit_frame_buf == NULL)
301 return;
302
303 for (i = 0; i < NR_XMITFRAME; i++) {
304 rtw_os_xmit_complete(padapter, pxmitframe);
305
306 pxmitframe++;
307 }
308
309 for (i = 0; i < NR_XMITBUFF; i++) {
310 rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), true);
311
312 pxmitbuf++;
313 }
314
315 if (pxmitpriv->pallocated_frame_buf)
316 vfree(pxmitpriv->pallocated_frame_buf);
317
318
319 if (pxmitpriv->pallocated_xmitbuf)
320 vfree(pxmitpriv->pallocated_xmitbuf);
321
322
323 pxmitframe = (struct xmit_frame *)pxmitpriv->xframe_ext;
324 if (pxmitframe) {
325 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
326 rtw_os_xmit_complete(padapter, pxmitframe);
327 pxmitframe++;
328 }
329 }
330 if (pxmitpriv->xframe_ext_alloc_addr)
331 vfree(pxmitpriv->xframe_ext_alloc_addr);
332
333
334 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
335 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
336 rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ), true);
337
338 pxmitbuf++;
339 }
340
341 if (pxmitpriv->pallocated_xmit_extbuf) {
342 vfree(pxmitpriv->pallocated_xmit_extbuf);
343 }
344
345 for (i = 0; i < CMDBUF_MAX; i++) {
346 pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i];
347 if (pxmitbuf != NULL)
348 rtw_os_xmit_resource_free(padapter, pxmitbuf, MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ, true);
349 }
350
351 rtw_free_hwxmits(padapter);
352
353 mutex_destroy(&pxmitpriv->ack_tx_mutex);
354}
355
356u8 query_ra_short_GI(struct sta_info *psta)
357{
358 u8 sgi = false, sgi_20m = false, sgi_40m = false, sgi_80m = false;
359
360 sgi_20m = psta->htpriv.sgi_20m;
361 sgi_40m = psta->htpriv.sgi_40m;
362
363 switch (psta->bw_mode) {
364 case CHANNEL_WIDTH_80:
365 sgi = sgi_80m;
366 break;
367 case CHANNEL_WIDTH_40:
368 sgi = sgi_40m;
369 break;
370 case CHANNEL_WIDTH_20:
371 default:
372 sgi = sgi_20m;
373 break;
374 }
375
376 return sgi;
377}
378
379static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame *pxmitframe)
380{
381 u32 sz;
382 struct pkt_attrib *pattrib = &pxmitframe->attrib;
383
384 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
385 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
386
387 if (pattrib->nr_frags != 1)
388 sz = padapter->xmitpriv.frag_len;
389 else
390 sz = pattrib->last_txcmdsz;
391
392
393
394
395
396 if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N || padapter->registrypriv.wifi_spec) {
397 if (sz > padapter->registrypriv.rts_thresh)
398 pattrib->vcs_mode = RTS_CTS;
399 else{
400 if (pattrib->rtsen)
401 pattrib->vcs_mode = RTS_CTS;
402 else if (pattrib->cts2self)
403 pattrib->vcs_mode = CTS_TO_SELF;
404 else
405 pattrib->vcs_mode = NONE_VCS;
406 }
407 } else{
408 while (true) {
409
410 if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && (pattrib->ampdu_en == true) &&
411 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
412 pattrib->vcs_mode = CTS_TO_SELF;
413 break;
414 }
415
416
417
418 if (pattrib->rtsen || pattrib->cts2self) {
419 if (pattrib->rtsen)
420 pattrib->vcs_mode = RTS_CTS;
421 else if (pattrib->cts2self)
422 pattrib->vcs_mode = CTS_TO_SELF;
423
424 break;
425 }
426
427
428 if (pattrib->ht_en) {
429 u8 HTOpMode = pmlmeinfo->HT_protection;
430 if ((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) ||
431 (!pmlmeext->cur_bwmode && HTOpMode == 3)) {
432 pattrib->vcs_mode = RTS_CTS;
433 break;
434 }
435 }
436
437
438 if (sz > padapter->registrypriv.rts_thresh) {
439 pattrib->vcs_mode = RTS_CTS;
440 break;
441 }
442
443
444
445
446 if (pattrib->ampdu_en == true) {
447 pattrib->vcs_mode = RTS_CTS;
448 break;
449 }
450
451 pattrib->vcs_mode = NONE_VCS;
452 break;
453 }
454 }
455
456
457 if (padapter->driver_vcs_en == 1)
458 pattrib->vcs_mode = padapter->driver_vcs_type;
459}
460
461static void update_attrib_phy_info(struct adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
462{
463 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
464
465 pattrib->rtsen = psta->rtsen;
466 pattrib->cts2self = psta->cts2self;
467
468 pattrib->mdata = 0;
469 pattrib->eosp = 0;
470 pattrib->triggered = 0;
471 pattrib->ampdu_spacing = 0;
472
473
474 pattrib->qos_en = psta->qos_option;
475
476 pattrib->raid = psta->raid;
477
478 if (mlmeext->cur_bwmode < psta->bw_mode)
479 pattrib->bwmode = mlmeext->cur_bwmode;
480 else
481 pattrib->bwmode = psta->bw_mode;
482
483 pattrib->sgi = query_ra_short_GI(psta);
484
485 pattrib->ldpc = psta->ldpc;
486 pattrib->stbc = psta->stbc;
487
488 pattrib->ht_en = psta->htpriv.ht_option;
489 pattrib->ch_offset = psta->htpriv.ch_offset;
490 pattrib->ampdu_en = false;
491
492 if (padapter->driver_ampdu_spacing != 0xFF)
493 pattrib->ampdu_spacing = padapter->driver_ampdu_spacing;
494 else
495 pattrib->ampdu_spacing = psta->htpriv.rx_ampdu_min_spacing;
496
497
498
499
500
501
502
503
504 pattrib->retry_ctrl = false;
505
506#ifdef CONFIG_AUTO_AP_MODE
507 if (psta->isrc && psta->pid > 0)
508 pattrib->pctrl = true;
509#endif
510
511}
512
513static s32 update_attrib_sec_info(struct adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
514{
515 sint res = _SUCCESS;
516 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
517 struct security_priv *psecuritypriv = &padapter->securitypriv;
518 sint bmcast = IS_MCAST(pattrib->ra);
519
520 memset(pattrib->dot118021x_UncstKey.skey, 0, 16);
521 memset(pattrib->dot11tkiptxmickey.skey, 0, 16);
522 pattrib->mac_id = psta->mac_id;
523
524 if (psta->ieee8021x_blocked == true) {
525 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\n psta->ieee8021x_blocked == true\n"));
526
527 pattrib->encrypt = 0;
528
529 if ((pattrib->ether_type != 0x888e) && (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)) {
530 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\npsta->ieee8021x_blocked == true, pattrib->ether_type(%.4x) != 0x888e\n", pattrib->ether_type));
531 #ifdef DBG_TX_DROP_FRAME
532 DBG_871X("DBG_TX_DROP_FRAME %s psta->ieee8021x_blocked == true, pattrib->ether_type(%04x) != 0x888e\n", __func__, pattrib->ether_type);
533 #endif
534 res = _FAIL;
535 goto exit;
536 }
537 } else{
538 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
539
540 switch (psecuritypriv->dot11AuthAlgrthm) {
541 case dot11AuthAlgrthm_Open:
542 case dot11AuthAlgrthm_Shared:
543 case dot11AuthAlgrthm_Auto:
544 pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
545 break;
546 case dot11AuthAlgrthm_8021X:
547 if (bmcast)
548 pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
549 else
550 pattrib->key_idx = 0;
551 break;
552 default:
553 pattrib->key_idx = 0;
554 break;
555 }
556
557
558 if (((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) && (pattrib->ether_type == 0x888e))
559 pattrib->encrypt = _NO_PRIVACY_;
560
561 }
562
563 switch (pattrib->encrypt) {
564 case _WEP40_:
565 case _WEP104_:
566 pattrib->iv_len = 4;
567 pattrib->icv_len = 4;
568 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
569 break;
570
571 case _TKIP_:
572 pattrib->iv_len = 8;
573 pattrib->icv_len = 4;
574
575 if (psecuritypriv->busetkipkey == _FAIL) {
576 #ifdef DBG_TX_DROP_FRAME
577 DBG_871X("DBG_TX_DROP_FRAME %s psecuritypriv->busetkipkey(%d) == _FAIL drop packet\n", __func__, psecuritypriv->busetkipkey);
578 #endif
579 res = _FAIL;
580 goto exit;
581 }
582
583 if (bmcast)
584 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
585 else
586 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
587
588
589 memcpy(pattrib->dot11tkiptxmickey.skey, psta->dot11tkiptxmickey.skey, 16);
590
591 break;
592
593 case _AES_:
594
595 pattrib->iv_len = 8;
596 pattrib->icv_len = 8;
597
598 if (bmcast)
599 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
600 else
601 AES_IV(pattrib->iv, psta->dot11txpn, 0);
602
603 break;
604
605 default:
606 pattrib->iv_len = 0;
607 pattrib->icv_len = 0;
608 break;
609 }
610
611 if (pattrib->encrypt > 0)
612 memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16);
613
614 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
615 ("update_attrib: encrypt =%d securitypriv.sw_encrypt =%d\n",
616 pattrib->encrypt, padapter->securitypriv.sw_encrypt));
617
618 if (pattrib->encrypt &&
619 ((padapter->securitypriv.sw_encrypt == true) || (psecuritypriv->hw_decrypted == false))) {
620 pattrib->bswenc = true;
621 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
622 ("update_attrib: encrypt =%d securitypriv.hw_decrypted =%d bswenc =true\n",
623 pattrib->encrypt, padapter->securitypriv.sw_encrypt));
624 } else {
625 pattrib->bswenc = false;
626 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("update_attrib: bswenc =false\n"));
627 }
628
629exit:
630
631 return res;
632
633}
634
635u8 qos_acm(u8 acm_mask, u8 priority)
636{
637 u8 change_priority = priority;
638
639 switch (priority) {
640 case 0:
641 case 3:
642 if (acm_mask & BIT(1))
643 change_priority = 1;
644 break;
645 case 1:
646 case 2:
647 break;
648 case 4:
649 case 5:
650 if (acm_mask & BIT(2))
651 change_priority = 0;
652 break;
653 case 6:
654 case 7:
655 if (acm_mask & BIT(3))
656 change_priority = 5;
657 break;
658 default:
659 DBG_871X("qos_acm(): invalid pattrib->priority: %d!!!\n", priority);
660 break;
661 }
662
663 return change_priority;
664}
665
666static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
667{
668 struct ethhdr etherhdr;
669 struct iphdr ip_hdr;
670 s32 UserPriority = 0;
671
672
673 _rtw_open_pktfile(ppktfile->pkt, ppktfile);
674 _rtw_pktfile_read(ppktfile, (unsigned char *)ðerhdr, ETH_HLEN);
675
676
677 if (pattrib->ether_type == 0x0800) {
678 _rtw_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr));
679
680 UserPriority = ip_hdr.tos >> 5;
681 }
682 pattrib->priority = UserPriority;
683 pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
684 pattrib->subtype = WIFI_QOS_DATA_TYPE;
685}
686
687static s32 update_attrib(struct adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib)
688{
689 uint i;
690 struct pkt_file pktfile;
691 struct sta_info *psta = NULL;
692 struct ethhdr etherhdr;
693
694 sint bmcast;
695 struct sta_priv *pstapriv = &padapter->stapriv;
696 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
697 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
698 sint res = _SUCCESS;
699
700 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib);
701
702 _rtw_open_pktfile(pkt, &pktfile);
703 i = _rtw_pktfile_read(&pktfile, (u8 *)ðerhdr, ETH_HLEN);
704
705 pattrib->ether_type = ntohs(etherhdr.h_proto);
706
707
708 memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN);
709 memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN);
710
711
712 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) ||
713 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
714 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
715 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
716 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_adhoc);
717 } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
718 memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
719 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
720 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_sta);
721 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
722 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
723 memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
724 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_ap);
725 } else
726 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_unknown);
727
728 pattrib->pktlen = pktfile.pkt_len;
729
730 if (ETH_P_IP == pattrib->ether_type) {
731
732
733
734 u8 tmp[24];
735
736 _rtw_pktfile_read(&pktfile, &tmp[0], 24);
737
738 pattrib->dhcp_pkt = 0;
739 if (pktfile.pkt_len > 282) {
740 if (ETH_P_IP == pattrib->ether_type) {
741 if (((tmp[21] == 68) && (tmp[23] == 67)) ||
742 ((tmp[21] == 67) && (tmp[23] == 68))) {
743
744
745 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("======================update_attrib: get DHCP Packet\n"));
746 pattrib->dhcp_pkt = 1;
747 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_dhcp);
748 }
749 }
750 }
751
752
753 {
754 struct iphdr *piphdr = (struct iphdr *)tmp;
755
756 pattrib->icmp_pkt = 0;
757 if (piphdr->protocol == 0x1) {
758 pattrib->icmp_pkt = 1;
759 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_icmp);
760 }
761 }
762
763
764 } else if (0x888e == pattrib->ether_type) {
765 DBG_871X_LEVEL(_drv_always_, "send eapol packet\n");
766 }
767
768 if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
769 rtw_set_scan_deny(padapter, 3000);
770
771
772 if (pattrib->icmp_pkt == 1)
773 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1);
774 else if (pattrib->dhcp_pkt == 1) {
775 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_active);
776 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
777 }
778
779 bmcast = IS_MCAST(pattrib->ra);
780
781
782 if (bmcast) {
783 psta = rtw_get_bcmc_stainfo(padapter);
784 } else {
785 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
786 if (psta == NULL) {
787 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_sta);
788 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT"\n", MAC_ARG(pattrib->ra)));
789 #ifdef DBG_TX_DROP_FRAME
790 DBG_871X("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __func__, MAC_ARG(pattrib->ra));
791 #endif
792 res = _FAIL;
793 goto exit;
794 } else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) && (!(psta->state & _FW_LINKED))) {
795 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_ap_link);
796 res = _FAIL;
797 goto exit;
798 }
799 }
800
801 if (psta == NULL) {
802
803 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sta);
804 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT "\n", MAC_ARG(pattrib->ra)));
805 #ifdef DBG_TX_DROP_FRAME
806 DBG_871X("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __func__, MAC_ARG(pattrib->ra));
807 #endif
808 res = _FAIL;
809 goto exit;
810 }
811
812 if (!(psta->state & _FW_LINKED)) {
813 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_link);
814 DBG_871X("%s, psta("MAC_FMT")->state(0x%x) != _FW_LINKED\n", __func__, MAC_ARG(psta->hwaddr), psta->state);
815 return _FAIL;
816 }
817
818
819
820
821 if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) {
822 DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sec);
823 res = _FAIL;
824 goto exit;
825 }
826
827 update_attrib_phy_info(padapter, pattrib, psta);
828
829
830
831 pattrib->psta = psta;
832
833
834 pattrib->pctrl = 0;
835
836 pattrib->ack_policy = 0;
837
838 pattrib->pkt_hdrlen = ETH_HLEN;
839
840 pattrib->hdrlen = WLAN_HDR_A3_LEN;
841 pattrib->subtype = WIFI_DATA_TYPE;
842 pattrib->priority = 0;
843
844 if (check_fwstate(pmlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) {
845 if (pattrib->qos_en)
846 set_qos(&pktfile, pattrib);
847 } else{
848 if (pqospriv->qos_option) {
849 set_qos(&pktfile, pattrib);
850
851 if (pmlmepriv->acm_mask != 0)
852 pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority);
853
854 }
855 }
856
857
858
859 rtw_set_tx_chksum_offload(pkt, pattrib);
860
861exit:
862 return res;
863}
864
865static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitframe)
866{
867 sint curfragnum, length;
868 u8 *pframe, *payload, mic[8];
869 struct mic_data micdata;
870
871 struct pkt_attrib *pattrib = &pxmitframe->attrib;
872 struct security_priv *psecuritypriv = &padapter->securitypriv;
873 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
874 u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
875 u8 hw_hdr_offset = 0;
876 sint bmcst = IS_MCAST(pattrib->ra);
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902 hw_hdr_offset = TXDESC_OFFSET;
903
904 if (pattrib->encrypt == _TKIP_) {
905
906
907 {
908 u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
909
910 pframe = pxmitframe->buf_addr + hw_hdr_offset;
911
912 if (bmcst) {
913 if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16)) {
914
915
916 return _FAIL;
917 }
918
919 rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
920 } else {
921 if (!memcmp(&pattrib->dot11tkiptxmickey.skey[0], null_key, 16)) {
922
923
924 return _FAIL;
925 }
926
927 rtw_secmicsetkey(&micdata, &pattrib->dot11tkiptxmickey.skey[0]);
928 }
929
930 if (pframe[1]&1) {
931 rtw_secmicappend(&micdata, &pframe[16], 6);
932 if (pframe[1]&2)
933 rtw_secmicappend(&micdata, &pframe[24], 6);
934 else
935 rtw_secmicappend(&micdata, &pframe[10], 6);
936 } else {
937 rtw_secmicappend(&micdata, &pframe[4], 6);
938 if (pframe[1]&2)
939 rtw_secmicappend(&micdata, &pframe[16], 6);
940 else
941 rtw_secmicappend(&micdata, &pframe[10], 6);
942
943 }
944
945
946 if (pattrib->qos_en)
947 priority[0] = (u8)pxmitframe->attrib.priority;
948
949
950 rtw_secmicappend(&micdata, &priority[0], 4);
951
952 payload = pframe;
953
954 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
955 payload = (u8 *)RND4((SIZE_PTR)(payload));
956 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("===curfragnum =%d, pframe = 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n",
957 curfragnum, *payload, *(payload+1), *(payload+2), *(payload+3), *(payload+4), *(payload+5), *(payload+6), *(payload+7)));
958
959 payload = payload+pattrib->hdrlen+pattrib->iv_len;
960 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("curfragnum =%d pattrib->hdrlen =%d pattrib->iv_len =%d", curfragnum, pattrib->hdrlen, pattrib->iv_len));
961 if ((curfragnum+1) == pattrib->nr_frags) {
962 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-((pattrib->bswenc) ? pattrib->icv_len : 0);
963 rtw_secmicappend(&micdata, payload, length);
964 payload = payload+length;
965 } else{
966 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-((pattrib->bswenc) ? pattrib->icv_len : 0);
967 rtw_secmicappend(&micdata, payload, length);
968 payload = payload+length+pattrib->icv_len;
969 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("curfragnum =%d length =%d pattrib->icv_len =%d", curfragnum, length, pattrib->icv_len));
970 }
971 }
972 rtw_secgetmic(&micdata, &(mic[0]));
973 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic: before add mic code!!!\n"));
974 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic: pattrib->last_txcmdsz =%d!!!\n", pattrib->last_txcmdsz));
975 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic: mic[0]= 0x%.2x , mic[1]= 0x%.2x , mic[2]= 0x%.2x , mic[3]= 0x%.2x\n\
976 mic[4]= 0x%.2x , mic[5]= 0x%.2x , mic[6]= 0x%.2x , mic[7]= 0x%.2x !!!!\n",
977 mic[0], mic[1], mic[2], mic[3], mic[4], mic[5], mic[6], mic[7]));
978
979
980 memcpy(payload, &(mic[0]), 8);
981 pattrib->last_txcmdsz += 8;
982
983 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("\n ========last pkt ========\n"));
984 payload = payload-pattrib->last_txcmdsz+8;
985 for (curfragnum = 0; curfragnum < pattrib->last_txcmdsz; curfragnum = curfragnum+8)
986 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, (" %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x ",
987 *(payload+curfragnum), *(payload+curfragnum+1), *(payload+curfragnum+2), *(payload+curfragnum+3),
988 *(payload+curfragnum+4), *(payload+curfragnum+5), *(payload+curfragnum+6), *(payload+curfragnum+7)));
989 }
990
991
992
993
994
995 }
996 return _SUCCESS;
997}
998
999static s32 xmitframe_swencrypt(struct adapter *padapter, struct xmit_frame *pxmitframe)
1000{
1001
1002 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1003
1004
1005
1006 if (pattrib->bswenc) {
1007
1008 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("### xmitframe_swencrypt\n"));
1009 switch (pattrib->encrypt) {
1010 case _WEP40_:
1011 case _WEP104_:
1012 rtw_wep_encrypt(padapter, (u8 *)pxmitframe);
1013 break;
1014 case _TKIP_:
1015 rtw_tkip_encrypt(padapter, (u8 *)pxmitframe);
1016 break;
1017 case _AES_:
1018 rtw_aes_encrypt(padapter, (u8 *)pxmitframe);
1019 break;
1020 default:
1021 break;
1022 }
1023
1024 } else
1025 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_, ("### xmitframe_hwencrypt\n"));
1026
1027 return _SUCCESS;
1028}
1029
1030s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib)
1031{
1032 u16 *qc;
1033
1034 struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
1035 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1036 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1037 u8 qos_option = false;
1038 sint res = _SUCCESS;
1039 __le16 *fctrl = &pwlanhdr->frame_control;
1040
1041 memset(hdr, 0, WLANHDR_OFFSET);
1042
1043 SetFrameSubType(fctrl, pattrib->subtype);
1044
1045 if (pattrib->subtype & WIFI_DATA_TYPE) {
1046 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)) {
1047
1048
1049 {
1050
1051
1052 SetToDs(fctrl);
1053 memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
1054 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1055 memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
1056 }
1057
1058 if (pqospriv->qos_option)
1059 qos_option = true;
1060
1061 } else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)) {
1062
1063 SetFrDs(fctrl);
1064 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1065 memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN);
1066 memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
1067
1068 if (pattrib->qos_en)
1069 qos_option = true;
1070 } else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) ||
1071 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
1072 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
1073 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
1074 memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
1075
1076 if (pattrib->qos_en)
1077 qos_option = true;
1078 } else {
1079 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("fw_state:%x is not allowed to xmit frame\n", get_fwstate(pmlmepriv)));
1080 res = _FAIL;
1081 goto exit;
1082 }
1083
1084 if (pattrib->mdata)
1085 SetMData(fctrl);
1086
1087 if (pattrib->encrypt)
1088 SetPrivacy(fctrl);
1089
1090 if (qos_option) {
1091 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
1092
1093 if (pattrib->priority)
1094 SetPriority(qc, pattrib->priority);
1095
1096 SetEOSP(qc, pattrib->eosp);
1097
1098 SetAckpolicy(qc, pattrib->ack_policy);
1099 }
1100
1101
1102
1103
1104 {
1105 struct sta_info *psta;
1106 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1107 if (pattrib->psta != psta) {
1108 DBG_871X("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
1109 return _FAIL;
1110 }
1111
1112 if (psta == NULL) {
1113 DBG_871X("%s, psta ==NUL\n", __func__);
1114 return _FAIL;
1115 }
1116
1117 if (!(psta->state & _FW_LINKED)) {
1118 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
1119 return _FAIL;
1120 }
1121
1122
1123 if (psta) {
1124 psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
1125 psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
1126 pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
1127
1128 SetSeqNum(hdr, pattrib->seqnum);
1129
1130
1131 if (pattrib->ht_en && psta->htpriv.ampdu_enable)
1132 if (psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
1133 pattrib->ampdu_en = true;
1134
1135
1136
1137 if (pattrib->ampdu_en == true) {
1138 u16 tx_seq;
1139
1140 tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
1141
1142
1143 if (SN_LESS(pattrib->seqnum, tx_seq)) {
1144
1145 pattrib->ampdu_en = false;
1146 } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) {
1147 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff;
1148
1149 pattrib->ampdu_en = true;
1150 } else{
1151
1152 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff;
1153 pattrib->ampdu_en = true;
1154 }
1155
1156 }
1157 }
1158 }
1159
1160 } else{
1161
1162 }
1163
1164exit:
1165 return res;
1166}
1167
1168s32 rtw_txframes_pending(struct adapter *padapter)
1169{
1170 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1171
1172 return ((!list_empty(&pxmitpriv->be_pending.queue)) ||
1173 (!list_empty(&pxmitpriv->bk_pending.queue)) ||
1174 (!list_empty(&pxmitpriv->vi_pending.queue)) ||
1175 (!list_empty(&pxmitpriv->vo_pending.queue)));
1176}
1177
1178
1179
1180
1181
1182u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib)
1183{
1184 u32 len = 0;
1185
1186 len = pattrib->hdrlen + pattrib->iv_len;
1187 len += SNAP_SIZE + sizeof(u16);
1188 len += pattrib->pktlen;
1189 if (pattrib->encrypt == _TKIP_)
1190 len += 8;
1191 len += ((pattrib->bswenc) ? pattrib->icv_len : 0);
1192
1193 return len;
1194}
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208s32 rtw_xmitframe_coalesce(struct adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
1209{
1210 struct pkt_file pktfile;
1211
1212 s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
1213
1214 SIZE_PTR addr;
1215
1216 u8 *pframe, *mem_start;
1217 u8 hw_hdr_offset;
1218
1219
1220
1221
1222 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1223
1224 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1225
1226 u8 *pbuf_start;
1227
1228 s32 bmcst = IS_MCAST(pattrib->ra);
1229 s32 res = _SUCCESS;
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255 if (pxmitframe->buf_addr == NULL) {
1256 DBG_8192C("==> %s buf_addr == NULL\n", __func__);
1257 return _FAIL;
1258 }
1259
1260 pbuf_start = pxmitframe->buf_addr;
1261
1262 hw_hdr_offset = TXDESC_OFFSET;
1263 mem_start = pbuf_start + hw_hdr_offset;
1264
1265 if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
1266 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n"));
1267 DBG_8192C("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n");
1268 res = _FAIL;
1269 goto exit;
1270 }
1271
1272 _rtw_open_pktfile(pkt, &pktfile);
1273 _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
1274
1275 frg_inx = 0;
1276 frg_len = pxmitpriv->frag_len - 4;
1277
1278 while (1) {
1279 llc_sz = 0;
1280
1281 mpdu_len = frg_len;
1282
1283 pframe = mem_start;
1284
1285 SetMFrag(mem_start);
1286
1287 pframe += pattrib->hdrlen;
1288 mpdu_len -= pattrib->hdrlen;
1289
1290
1291 if (pattrib->iv_len) {
1292 memcpy(pframe, pattrib->iv, pattrib->iv_len);
1293
1294 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
1295 ("rtw_xmitframe_coalesce: keyid =%d pattrib->iv[3]=%.2x pframe =%.2x %.2x %.2x %.2x\n",
1296 padapter->securitypriv.dot11PrivacyKeyIndex, pattrib->iv[3], *pframe, *(pframe+1), *(pframe+2), *(pframe+3)));
1297
1298 pframe += pattrib->iv_len;
1299
1300 mpdu_len -= pattrib->iv_len;
1301 }
1302
1303 if (frg_inx == 0) {
1304 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
1305 pframe += llc_sz;
1306 mpdu_len -= llc_sz;
1307 }
1308
1309 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
1310 mpdu_len -= pattrib->icv_len;
1311 }
1312
1313
1314 if (bmcst) {
1315
1316 mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
1317 } else {
1318 mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len);
1319 }
1320
1321 pframe += mem_sz;
1322
1323 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
1324 memcpy(pframe, pattrib->icv, pattrib->icv_len);
1325 pframe += pattrib->icv_len;
1326 }
1327
1328 frg_inx++;
1329
1330 if (bmcst || (rtw_endofpktfile(&pktfile) == true)) {
1331 pattrib->nr_frags = frg_inx;
1332
1333 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags == 1) ? llc_sz:0) +
1334 ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz;
1335
1336 ClearMFrag(mem_start);
1337
1338 break;
1339 } else
1340 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: There're still something in packet!\n", __func__));
1341
1342 addr = (SIZE_PTR)(pframe);
1343
1344 mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset;
1345 memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
1346
1347 }
1348
1349 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
1350 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n"));
1351 DBG_8192C("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n");
1352 res = _FAIL;
1353 goto exit;
1354 }
1355
1356 xmitframe_swencrypt(padapter, pxmitframe);
1357
1358 if (bmcst == false)
1359 update_attrib_vcs_info(padapter, pxmitframe);
1360 else
1361 pattrib->vcs_mode = NONE_VCS;
1362
1363exit:
1364 return res;
1365}
1366
1367
1368s32 rtw_mgmt_xmitframe_coalesce(struct adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
1369{
1370 u8 *pframe, *mem_start = NULL, *tmp_buf = NULL;
1371 u8 subtype;
1372 struct sta_info *psta = NULL;
1373 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1374 s32 bmcst = IS_MCAST(pattrib->ra);
1375 u8 *BIP_AAD = NULL;
1376 u8 *MGMT_body = NULL;
1377
1378 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1379 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1380 struct ieee80211_hdr *pwlanhdr;
1381 u8 MME[_MME_IE_LENGTH_];
1382 u32 ori_len;
1383 mem_start = pframe = (u8 *)(pxmitframe->buf_addr) + TXDESC_OFFSET;
1384 pwlanhdr = (struct ieee80211_hdr *)pframe;
1385
1386 ori_len = BIP_AAD_SIZE+pattrib->pktlen;
1387 tmp_buf = BIP_AAD = rtw_zmalloc(ori_len);
1388 subtype = GetFrameSubType(pframe);
1389
1390 if (BIP_AAD == NULL)
1391 return _FAIL;
1392
1393 spin_lock_bh(&padapter->security_key_mutex);
1394
1395
1396 if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE) || !check_fwstate(pmlmepriv, _FW_LINKED))
1397 goto xmitframe_coalesce_success;
1398
1399
1400 if (padapter->securitypriv.binstallBIPkey != true) {
1401 DBG_871X("no instll BIP key\n");
1402 goto xmitframe_coalesce_success;
1403 }
1404
1405 if (bmcst) {
1406 int frame_body_len;
1407 u8 mic[16];
1408
1409 memset(MME, 0, 18);
1410
1411
1412 if (GetFrameSubType(pframe) != WIFI_DEAUTH && GetFrameSubType(pframe) != WIFI_DISASSOC)
1413 goto xmitframe_coalesce_fail;
1414
1415 MGMT_body = pframe + sizeof(struct ieee80211_hdr_3addr);
1416 pframe += pattrib->pktlen;
1417
1418
1419 MME[0] = padapter->securitypriv.dot11wBIPKeyid;
1420
1421 memcpy(&MME[2], &pmlmeext->mgnt_80211w_IPN, 6);
1422
1423 pmlmeext->mgnt_80211w_IPN++;
1424
1425
1426 pframe = rtw_set_ie(pframe, _MME_IE_, 16, MME, &(pattrib->pktlen));
1427 pattrib->last_txcmdsz = pattrib->pktlen;
1428
1429 frame_body_len = pattrib->pktlen - sizeof(struct ieee80211_hdr_3addr);
1430
1431
1432 memcpy(BIP_AAD, &pwlanhdr->frame_control, 2);
1433 ClearRetry(BIP_AAD);
1434 ClearPwrMgt(BIP_AAD);
1435 ClearMData(BIP_AAD);
1436
1437 memcpy(BIP_AAD+2, pwlanhdr->addr1, 18);
1438
1439 memcpy(BIP_AAD+BIP_AAD_SIZE, MGMT_body, frame_body_len);
1440
1441 if (omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey
1442 , BIP_AAD, BIP_AAD_SIZE+frame_body_len, mic))
1443 goto xmitframe_coalesce_fail;
1444
1445
1446 memcpy(pframe-8, mic, 8);
1447 } else {
1448
1449 if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC ||
1450 subtype == WIFI_REASSOCREQ || subtype == WIFI_ACTION) {
1451 if (pattrib->psta)
1452 psta = pattrib->psta;
1453 else
1454 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1455
1456 if (psta == NULL) {
1457
1458 DBG_871X("%s, psta ==NUL\n", __func__);
1459 goto xmitframe_coalesce_fail;
1460 }
1461
1462 if (!(psta->state & _FW_LINKED) || pxmitframe->buf_addr == NULL) {
1463 DBG_871X("%s, not _FW_LINKED or addr null\n", __func__);
1464 goto xmitframe_coalesce_fail;
1465 }
1466
1467
1468
1469 if (subtype == WIFI_ACTION &&
1470 (pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_PUBLIC ||
1471 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_HT ||
1472 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_UNPROTECTED_WNM ||
1473 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_SELF_PROTECTED ||
1474 pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_P2P))
1475 goto xmitframe_coalesce_fail;
1476
1477 if (pattrib->encrypt > 0)
1478 memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16);
1479
1480 memcpy(tmp_buf, pframe, pattrib->pktlen);
1481
1482 pframe += pattrib->hdrlen;
1483
1484
1485 pattrib->iv_len = 8;
1486
1487 pattrib->icv_len = 8;
1488
1489 switch (pattrib->encrypt) {
1490 case _AES_:
1491
1492 AES_IV(pattrib->iv, psta->dot11wtxpn, 0);
1493 break;
1494 default:
1495 goto xmitframe_coalesce_fail;
1496 }
1497
1498 memcpy(pframe, pattrib->iv, pattrib->iv_len);
1499 pframe += pattrib->iv_len;
1500
1501 memcpy(pframe, tmp_buf+pattrib->hdrlen, pattrib->pktlen-pattrib->hdrlen);
1502
1503 pframe += pattrib->pktlen-pattrib->hdrlen;
1504
1505 pattrib->pktlen += pattrib->iv_len;
1506 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
1507 memcpy(pframe, pattrib->icv, pattrib->icv_len);
1508 pframe += pattrib->icv_len;
1509 }
1510
1511 pattrib->pktlen += pattrib->icv_len;
1512
1513 pattrib->last_txcmdsz = pattrib->pktlen;
1514
1515
1516 SetPrivacy(mem_start);
1517
1518 xmitframe_swencrypt(padapter, pxmitframe);
1519 }
1520 }
1521
1522xmitframe_coalesce_success:
1523 spin_unlock_bh(&padapter->security_key_mutex);
1524 kfree(BIP_AAD);
1525 return _SUCCESS;
1526
1527xmitframe_coalesce_fail:
1528 spin_unlock_bh(&padapter->security_key_mutex);
1529 kfree(BIP_AAD);
1530 return _FAIL;
1531}
1532
1533
1534
1535
1536
1537
1538
1539
1540s32 rtw_put_snap(u8 *data, u16 h_proto)
1541{
1542 struct ieee80211_snap_hdr *snap;
1543 u8 *oui;
1544
1545 snap = (struct ieee80211_snap_hdr *)data;
1546 snap->dsap = 0xaa;
1547 snap->ssap = 0xaa;
1548 snap->ctrl = 0x03;
1549
1550 if (h_proto == 0x8137 || h_proto == 0x80f3)
1551 oui = P802_1H_OUI;
1552 else
1553 oui = RFC1042_OUI;
1554
1555 snap->oui[0] = oui[0];
1556 snap->oui[1] = oui[1];
1557 snap->oui[2] = oui[2];
1558
1559 *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
1560
1561 return SNAP_SIZE + sizeof(u16);
1562}
1563
1564void rtw_update_protection(struct adapter *padapter, u8 *ie, uint ie_len)
1565{
1566
1567 uint protection;
1568 u8 *perp;
1569 sint erp_len;
1570 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1571 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1572
1573 switch (pxmitpriv->vcs_setting) {
1574 case DISABLE_VCS:
1575 pxmitpriv->vcs = NONE_VCS;
1576 break;
1577
1578 case ENABLE_VCS:
1579 break;
1580
1581 case AUTO_VCS:
1582 default:
1583 perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
1584 if (perp == NULL)
1585 pxmitpriv->vcs = NONE_VCS;
1586 else{
1587 protection = (*(perp + 2)) & BIT(1);
1588 if (protection) {
1589 if (pregistrypriv->vcs_type == RTS_CTS)
1590 pxmitpriv->vcs = RTS_CTS;
1591 else
1592 pxmitpriv->vcs = CTS_TO_SELF;
1593 } else
1594 pxmitpriv->vcs = NONE_VCS;
1595 }
1596
1597 break;
1598
1599 }
1600}
1601
1602void rtw_count_tx_stats(struct adapter *padapter, struct xmit_frame *pxmitframe, int sz)
1603{
1604 struct sta_info *psta = NULL;
1605 struct stainfo_stats *pstats = NULL;
1606 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1607 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1608 u8 pkt_num = 1;
1609
1610 if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) {
1611 pkt_num = pxmitframe->agg_num;
1612
1613 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pkt_num;
1614
1615 pxmitpriv->tx_pkts += pkt_num;
1616
1617 pxmitpriv->tx_bytes += sz;
1618
1619 psta = pxmitframe->attrib.psta;
1620 if (psta) {
1621 pstats = &psta->sta_stats;
1622
1623 pstats->tx_pkts += pkt_num;
1624
1625 pstats->tx_bytes += sz;
1626 }
1627 }
1628}
1629
1630static struct xmit_buf *__rtw_alloc_cmd_xmitbuf(struct xmit_priv *pxmitpriv,
1631 enum cmdbuf_type buf_type)
1632{
1633 struct xmit_buf *pxmitbuf = NULL;
1634
1635 pxmitbuf = &pxmitpriv->pcmd_xmitbuf[buf_type];
1636 if (pxmitbuf != NULL) {
1637 pxmitbuf->priv_data = NULL;
1638
1639 pxmitbuf->len = 0;
1640 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
1641 pxmitbuf->agg_num = 0;
1642 pxmitbuf->pg_num = 0;
1643
1644 if (pxmitbuf->sctx) {
1645 DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__);
1646 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1647 }
1648 } else
1649 DBG_871X("%s fail, no xmitbuf available !!!\n", __func__);
1650
1651 return pxmitbuf;
1652}
1653
1654struct xmit_frame *__rtw_alloc_cmdxmitframe(struct xmit_priv *pxmitpriv,
1655 enum cmdbuf_type buf_type)
1656{
1657 struct xmit_frame *pcmdframe;
1658 struct xmit_buf *pxmitbuf;
1659
1660 pcmdframe = rtw_alloc_xmitframe(pxmitpriv);
1661 if (pcmdframe == NULL) {
1662 DBG_871X("%s, alloc xmitframe fail\n", __func__);
1663 return NULL;
1664 }
1665
1666 pxmitbuf = __rtw_alloc_cmd_xmitbuf(pxmitpriv, buf_type);
1667 if (pxmitbuf == NULL) {
1668 DBG_871X("%s, alloc xmitbuf fail\n", __func__);
1669 rtw_free_xmitframe(pxmitpriv, pcmdframe);
1670 return NULL;
1671 }
1672
1673 pcmdframe->frame_tag = MGNT_FRAMETAG;
1674
1675 pcmdframe->pxmitbuf = pxmitbuf;
1676
1677 pcmdframe->buf_addr = pxmitbuf->pbuf;
1678
1679 pxmitbuf->priv_data = pcmdframe;
1680
1681 return pcmdframe;
1682
1683}
1684
1685struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
1686{
1687 _irqL irqL;
1688 struct xmit_buf *pxmitbuf = NULL;
1689 struct list_head *plist, *phead;
1690 struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1691
1692 spin_lock_irqsave(&pfree_queue->lock, irqL);
1693
1694 if (list_empty(&pfree_queue->queue)) {
1695 pxmitbuf = NULL;
1696 } else {
1697
1698 phead = get_list_head(pfree_queue);
1699
1700 plist = get_next(phead);
1701
1702 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
1703
1704 list_del_init(&(pxmitbuf->list));
1705 }
1706
1707 if (pxmitbuf != NULL) {
1708 pxmitpriv->free_xmit_extbuf_cnt--;
1709 #ifdef DBG_XMIT_BUF_EXT
1710 DBG_871X("DBG_XMIT_BUF_EXT ALLOC no =%d, free_xmit_extbuf_cnt =%d\n", pxmitbuf->no, pxmitpriv->free_xmit_extbuf_cnt);
1711 #endif
1712
1713
1714 pxmitbuf->priv_data = NULL;
1715
1716 pxmitbuf->len = 0;
1717 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
1718 pxmitbuf->agg_num = 1;
1719
1720 if (pxmitbuf->sctx) {
1721 DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__);
1722 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1723 }
1724
1725 }
1726
1727 spin_unlock_irqrestore(&pfree_queue->lock, irqL);
1728
1729 return pxmitbuf;
1730}
1731
1732s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
1733{
1734 _irqL irqL;
1735 struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1736
1737 if (pxmitbuf == NULL)
1738 return _FAIL;
1739
1740 spin_lock_irqsave(&pfree_queue->lock, irqL);
1741
1742 list_del_init(&pxmitbuf->list);
1743
1744 list_add_tail(&(pxmitbuf->list), get_list_head(pfree_queue));
1745 pxmitpriv->free_xmit_extbuf_cnt++;
1746 #ifdef DBG_XMIT_BUF_EXT
1747 DBG_871X("DBG_XMIT_BUF_EXT FREE no =%d, free_xmit_extbuf_cnt =%d\n", pxmitbuf->no, pxmitpriv->free_xmit_extbuf_cnt);
1748 #endif
1749
1750 spin_unlock_irqrestore(&pfree_queue->lock, irqL);
1751
1752 return _SUCCESS;
1753}
1754
1755struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
1756{
1757 _irqL irqL;
1758 struct xmit_buf *pxmitbuf = NULL;
1759 struct list_head *plist, *phead;
1760 struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
1761
1762
1763
1764 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
1765
1766 if (list_empty(&pfree_xmitbuf_queue->queue)) {
1767 pxmitbuf = NULL;
1768 } else {
1769
1770 phead = get_list_head(pfree_xmitbuf_queue);
1771
1772 plist = get_next(phead);
1773
1774 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
1775
1776 list_del_init(&(pxmitbuf->list));
1777 }
1778
1779 if (pxmitbuf != NULL) {
1780 pxmitpriv->free_xmitbuf_cnt--;
1781 #ifdef DBG_XMIT_BUF
1782 DBG_871X("DBG_XMIT_BUF ALLOC no =%d, free_xmitbuf_cnt =%d\n", pxmitbuf->no, pxmitpriv->free_xmitbuf_cnt);
1783 #endif
1784
1785
1786 pxmitbuf->priv_data = NULL;
1787
1788 pxmitbuf->len = 0;
1789 pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
1790 pxmitbuf->agg_num = 0;
1791 pxmitbuf->pg_num = 0;
1792
1793 if (pxmitbuf->sctx) {
1794 DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__);
1795 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1796 }
1797 }
1798 #ifdef DBG_XMIT_BUF
1799 else
1800 DBG_871X("DBG_XMIT_BUF rtw_alloc_xmitbuf return NULL\n");
1801 #endif
1802
1803 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
1804
1805 return pxmitbuf;
1806}
1807
1808s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
1809{
1810 _irqL irqL;
1811 struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
1812
1813
1814
1815 if (pxmitbuf == NULL)
1816 return _FAIL;
1817
1818 if (pxmitbuf->sctx) {
1819 DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__);
1820 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
1821 }
1822
1823 if (pxmitbuf->buf_tag == XMITBUF_CMD) {
1824 } else if (pxmitbuf->buf_tag == XMITBUF_MGNT) {
1825 rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf);
1826 } else{
1827 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
1828
1829 list_del_init(&pxmitbuf->list);
1830
1831 list_add_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
1832
1833 pxmitpriv->free_xmitbuf_cnt++;
1834
1835 #ifdef DBG_XMIT_BUF
1836 DBG_871X("DBG_XMIT_BUF FREE no =%d, free_xmitbuf_cnt =%d\n", pxmitbuf->no, pxmitpriv->free_xmitbuf_cnt);
1837 #endif
1838 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
1839 }
1840 return _SUCCESS;
1841}
1842
1843static void rtw_init_xmitframe(struct xmit_frame *pxframe)
1844{
1845 if (pxframe != NULL) {
1846 pxframe->buf_addr = NULL;
1847 pxframe->pxmitbuf = NULL;
1848
1849 memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
1850
1851
1852 pxframe->frame_tag = DATA_FRAMETAG;
1853
1854 pxframe->pg_num = 1;
1855 pxframe->agg_num = 1;
1856 pxframe->ack_report = 0;
1857 }
1858}
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)
1872{
1873
1874
1875
1876
1877
1878
1879 struct xmit_frame *pxframe = NULL;
1880 struct list_head *plist, *phead;
1881 struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
1882
1883 spin_lock_bh(&pfree_xmit_queue->lock);
1884
1885 if (list_empty(&pfree_xmit_queue->queue)) {
1886 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe:%d\n", pxmitpriv->free_xmitframe_cnt));
1887 pxframe = NULL;
1888 } else {
1889 phead = get_list_head(pfree_xmit_queue);
1890
1891 plist = get_next(phead);
1892
1893 pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
1894
1895 list_del_init(&(pxframe->list));
1896 pxmitpriv->free_xmitframe_cnt--;
1897 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe():free_xmitframe_cnt =%d\n", pxmitpriv->free_xmitframe_cnt));
1898 }
1899
1900 spin_unlock_bh(&pfree_xmit_queue->lock);
1901
1902 rtw_init_xmitframe(pxframe);
1903 return pxframe;
1904}
1905
1906struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv)
1907{
1908 struct xmit_frame *pxframe = NULL;
1909 struct list_head *plist, *phead;
1910 struct __queue *queue = &pxmitpriv->free_xframe_ext_queue;
1911
1912 spin_lock_bh(&queue->lock);
1913
1914 if (list_empty(&queue->queue)) {
1915 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe_ext:%d\n", pxmitpriv->free_xframe_ext_cnt));
1916 pxframe = NULL;
1917 } else {
1918 phead = get_list_head(queue);
1919 plist = get_next(phead);
1920 pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
1921
1922 list_del_init(&(pxframe->list));
1923 pxmitpriv->free_xframe_ext_cnt--;
1924 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe_ext():free_xmitframe_cnt =%d\n", pxmitpriv->free_xframe_ext_cnt));
1925 }
1926
1927 spin_unlock_bh(&queue->lock);
1928
1929 rtw_init_xmitframe(pxframe);
1930
1931 return pxframe;
1932}
1933
1934struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv)
1935{
1936 struct xmit_frame *pxframe = NULL;
1937 u8 *alloc_addr;
1938
1939 alloc_addr = rtw_zmalloc(sizeof(struct xmit_frame) + 4);
1940
1941 if (alloc_addr == NULL)
1942 goto exit;
1943
1944 pxframe = (struct xmit_frame *)N_BYTE_ALIGMENT((SIZE_PTR)(alloc_addr), 4);
1945 pxframe->alloc_addr = alloc_addr;
1946
1947 pxframe->padapter = pxmitpriv->adapter;
1948 pxframe->frame_tag = NULL_FRAMETAG;
1949
1950 pxframe->pkt = NULL;
1951
1952 pxframe->buf_addr = NULL;
1953 pxframe->pxmitbuf = NULL;
1954
1955 rtw_init_xmitframe(pxframe);
1956
1957 DBG_871X("################## %s ##################\n", __func__);
1958
1959exit:
1960 return pxframe;
1961}
1962
1963s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
1964{
1965 struct __queue *queue = NULL;
1966 struct adapter *padapter = pxmitpriv->adapter;
1967 _pkt *pndis_pkt = NULL;
1968
1969 if (pxmitframe == NULL) {
1970 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("======rtw_free_xmitframe():pxmitframe == NULL!!!!!!!!!!\n"));
1971 goto exit;
1972 }
1973
1974 if (pxmitframe->pkt) {
1975 pndis_pkt = pxmitframe->pkt;
1976 pxmitframe->pkt = NULL;
1977 }
1978
1979 if (pxmitframe->alloc_addr) {
1980 DBG_871X("################## %s with alloc_addr ##################\n", __func__);
1981 kfree(pxmitframe->alloc_addr);
1982 goto check_pkt_complete;
1983 }
1984
1985 if (pxmitframe->ext_tag == 0)
1986 queue = &pxmitpriv->free_xmit_queue;
1987 else if (pxmitframe->ext_tag == 1)
1988 queue = &pxmitpriv->free_xframe_ext_queue;
1989 else {
1990
1991 }
1992
1993 spin_lock_bh(&queue->lock);
1994
1995 list_del_init(&pxmitframe->list);
1996 list_add_tail(&pxmitframe->list, get_list_head(queue));
1997 if (pxmitframe->ext_tag == 0) {
1998 pxmitpriv->free_xmitframe_cnt++;
1999 RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xmitframe_cnt =%d\n", pxmitpriv->free_xmitframe_cnt));
2000 } else if (pxmitframe->ext_tag == 1) {
2001 pxmitpriv->free_xframe_ext_cnt++;
2002 RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xframe_ext_cnt =%d\n", pxmitpriv->free_xframe_ext_cnt));
2003 } else {
2004 }
2005
2006 spin_unlock_bh(&queue->lock);
2007
2008check_pkt_complete:
2009
2010 if (pndis_pkt)
2011 rtw_os_pkt_complete(padapter, pndis_pkt);
2012
2013exit:
2014 return _SUCCESS;
2015}
2016
2017void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pframequeue)
2018{
2019 struct list_head *plist, *phead;
2020 struct xmit_frame *pxmitframe;
2021
2022 spin_lock_bh(&(pframequeue->lock));
2023
2024 phead = get_list_head(pframequeue);
2025 plist = get_next(phead);
2026
2027 while (phead != plist) {
2028
2029 pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
2030
2031 plist = get_next(plist);
2032
2033 rtw_free_xmitframe(pxmitpriv, pxmitframe);
2034
2035 }
2036 spin_unlock_bh(&(pframequeue->lock));
2037}
2038
2039s32 rtw_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe)
2040{
2041 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue);
2042 if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) {
2043 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
2044 ("rtw_xmitframe_enqueue: drop xmit pkt for classifier fail\n"));
2045
2046 return _FAIL;
2047 }
2048
2049 return _SUCCESS;
2050}
2051
2052struct tx_servq *rtw_get_sta_pending(struct adapter *padapter, struct sta_info *psta, sint up, u8 *ac)
2053{
2054 struct tx_servq *ptxservq = NULL;
2055
2056 switch (up) {
2057 case 1:
2058 case 2:
2059 ptxservq = &(psta->sta_xmitpriv.bk_q);
2060 *(ac) = 3;
2061 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : BK\n"));
2062 break;
2063
2064 case 4:
2065 case 5:
2066 ptxservq = &(psta->sta_xmitpriv.vi_q);
2067 *(ac) = 1;
2068 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : VI\n"));
2069 break;
2070
2071 case 6:
2072 case 7:
2073 ptxservq = &(psta->sta_xmitpriv.vo_q);
2074 *(ac) = 0;
2075 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : VO\n"));
2076 break;
2077
2078 case 0:
2079 case 3:
2080 default:
2081 ptxservq = &(psta->sta_xmitpriv.be_q);
2082 *(ac) = 2;
2083 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : BE\n"));
2084 break;
2085
2086 }
2087
2088 return ptxservq;
2089}
2090
2091
2092
2093
2094
2095s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
2096{
2097
2098 u8 ac_index;
2099 struct sta_info *psta;
2100 struct tx_servq *ptxservq;
2101 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2102 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
2103 sint res = _SUCCESS;
2104
2105 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class);
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2117 if (pattrib->psta != psta) {
2118 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_sta);
2119 DBG_871X("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
2120 return _FAIL;
2121 }
2122
2123 if (psta == NULL) {
2124 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_nosta);
2125 res = _FAIL;
2126 DBG_8192C("rtw_xmit_classifier: psta == NULL\n");
2127 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmit_classifier: psta == NULL\n"));
2128 goto exit;
2129 }
2130
2131 if (!(psta->state & _FW_LINKED)) {
2132 DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_fwlink);
2133 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
2134 return _FAIL;
2135 }
2136
2137 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
2138
2139
2140
2141 if (list_empty(&ptxservq->tx_pending)) {
2142 list_add_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
2143 }
2144
2145
2146
2147 list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
2148 ptxservq->qcnt++;
2149 phwxmits[ac_index].accnt++;
2150
2151
2152
2153
2154
2155exit:
2156
2157 return res;
2158}
2159
2160void rtw_alloc_hwxmits(struct adapter *padapter)
2161{
2162 struct hw_xmit *hwxmits;
2163 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2164
2165 pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
2166
2167 pxmitpriv->hwxmits = NULL;
2168
2169 pxmitpriv->hwxmits = (struct hw_xmit *)rtw_zmalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry);
2170
2171 if (pxmitpriv->hwxmits == NULL) {
2172 DBG_871X("alloc hwxmits fail!...\n");
2173 return;
2174 }
2175
2176 hwxmits = pxmitpriv->hwxmits;
2177
2178 if (pxmitpriv->hwxmit_entry == 5) {
2179
2180
2181 hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
2182
2183
2184
2185 hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
2186
2187
2188
2189 hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
2190
2191
2192
2193 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
2194
2195
2196
2197 hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
2198
2199 } else if (pxmitpriv->hwxmit_entry == 4) {
2200
2201
2202
2203 hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
2204
2205
2206
2207 hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
2208
2209
2210
2211 hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
2212
2213
2214
2215 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
2216 } else {
2217
2218 }
2219
2220
2221}
2222
2223void rtw_free_hwxmits(struct adapter *padapter)
2224{
2225 struct hw_xmit *hwxmits;
2226 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2227
2228 hwxmits = pxmitpriv->hwxmits;
2229 if (hwxmits)
2230 kfree((u8 *)hwxmits);
2231}
2232
2233void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry)
2234{
2235 sint i;
2236
2237 for (i = 0; i < entry; i++, phwxmit++) {
2238
2239
2240
2241 phwxmit->accnt = 0;
2242 }
2243}
2244
2245u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
2246{
2247 u32 addr;
2248 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2249
2250 switch (pattrib->qsel) {
2251 case 0:
2252 case 3:
2253 addr = BE_QUEUE_INX;
2254 break;
2255 case 1:
2256 case 2:
2257 addr = BK_QUEUE_INX;
2258 break;
2259 case 4:
2260 case 5:
2261 addr = VI_QUEUE_INX;
2262 break;
2263 case 6:
2264 case 7:
2265 addr = VO_QUEUE_INX;
2266 break;
2267 case 0x10:
2268 addr = BCN_QUEUE_INX;
2269 break;
2270 case 0x11:
2271 addr = HIGH_QUEUE_INX;
2272 break;
2273 case 0x12:
2274 default:
2275 addr = MGT_QUEUE_INX;
2276 break;
2277
2278 }
2279
2280 return addr;
2281
2282}
2283
2284static void do_queue_select(struct adapter *padapter, struct pkt_attrib *pattrib)
2285{
2286 u8 qsel;
2287
2288 qsel = pattrib->priority;
2289 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("### do_queue_select priority =%d , qsel = %d\n", pattrib->priority, qsel));
2290
2291 pattrib->qsel = qsel;
2292}
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302s32 rtw_xmit(struct adapter *padapter, _pkt **ppkt)
2303{
2304 static unsigned long start = 0;
2305 static u32 drop_cnt = 0;
2306
2307 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2308 struct xmit_frame *pxmitframe = NULL;
2309
2310 s32 res;
2311
2312 DBG_COUNTER(padapter->tx_logs.core_tx);
2313
2314 if (start == 0)
2315 start = jiffies;
2316
2317 pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
2318
2319 if (jiffies_to_msecs(jiffies - start) > 2000) {
2320 if (drop_cnt)
2321 DBG_871X("DBG_TX_DROP_FRAME %s no more pxmitframe, drop_cnt:%u\n", __func__, drop_cnt);
2322 start = jiffies;
2323 drop_cnt = 0;
2324 }
2325
2326 if (pxmitframe == NULL) {
2327 drop_cnt++;
2328 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: no more pxmitframe\n"));
2329 DBG_COUNTER(padapter->tx_logs.core_tx_err_pxmitframe);
2330 return -1;
2331 }
2332
2333 res = update_attrib(padapter, *ppkt, &pxmitframe->attrib);
2334
2335 if (res == _FAIL) {
2336 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: update attrib fail\n"));
2337 #ifdef DBG_TX_DROP_FRAME
2338 DBG_871X("DBG_TX_DROP_FRAME %s update attrib fail\n", __func__);
2339 #endif
2340 rtw_free_xmitframe(pxmitpriv, pxmitframe);
2341 return -1;
2342 }
2343 pxmitframe->pkt = *ppkt;
2344
2345 do_queue_select(padapter, &pxmitframe->attrib);
2346
2347 spin_lock_bh(&pxmitpriv->lock);
2348 if (xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == true) {
2349 spin_unlock_bh(&pxmitpriv->lock);
2350 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue);
2351 return 1;
2352 }
2353 spin_unlock_bh(&pxmitpriv->lock);
2354
2355
2356 if (rtw_hal_xmit(padapter, pxmitframe) == false)
2357 return 1;
2358
2359 return 0;
2360}
2361
2362#define RTW_HIQ_FILTER_ALLOW_ALL 0
2363#define RTW_HIQ_FILTER_ALLOW_SPECIAL 1
2364#define RTW_HIQ_FILTER_DENY_ALL 2
2365
2366inline bool xmitframe_hiq_filter(struct xmit_frame *xmitframe)
2367{
2368 bool allow = false;
2369 struct adapter *adapter = xmitframe->padapter;
2370 struct registry_priv *registry = &adapter->registrypriv;
2371
2372 if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_SPECIAL) {
2373
2374 struct pkt_attrib *attrib = &xmitframe->attrib;
2375
2376 if (attrib->ether_type == 0x0806
2377 || attrib->ether_type == 0x888e
2378 || attrib->dhcp_pkt
2379 ) {
2380 DBG_871X(FUNC_ADPT_FMT" ether_type:0x%04x%s\n", FUNC_ADPT_ARG(xmitframe->padapter)
2381 , attrib->ether_type, attrib->dhcp_pkt?" DHCP":"");
2382 allow = true;
2383 }
2384 } else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_ALL)
2385 allow = true;
2386 else if (registry->hiq_filter == RTW_HIQ_FILTER_DENY_ALL) {
2387 } else
2388 rtw_warn_on(1);
2389
2390 return allow;
2391}
2392
2393sint xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_frame *pxmitframe)
2394{
2395 sint ret = false;
2396 struct sta_info *psta = NULL;
2397 struct sta_priv *pstapriv = &padapter->stapriv;
2398 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2399 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2400 sint bmcst = IS_MCAST(pattrib->ra);
2401 bool update_tim = false;
2402
2403 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == false) {
2404 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_fwstate);
2405 return ret;
2406 }
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2419 if (pattrib->psta != psta) {
2420 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_sta);
2421 DBG_871X("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
2422 return false;
2423 }
2424
2425 if (psta == NULL) {
2426 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_nosta);
2427 DBG_871X("%s, psta ==NUL\n", __func__);
2428 return false;
2429 }
2430
2431 if (!(psta->state & _FW_LINKED)) {
2432 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_link);
2433 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
2434 return false;
2435 }
2436
2437 if (pattrib->triggered == 1) {
2438 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_trigger);
2439
2440
2441
2442 if (bmcst && xmitframe_hiq_filter(pxmitframe) == true)
2443 pattrib->qsel = 0x11;
2444
2445 return ret;
2446 }
2447
2448
2449 if (bmcst) {
2450 spin_lock_bh(&psta->sleep_q.lock);
2451
2452 if (pstapriv->sta_dz_bitmap) {
2453
2454
2455 list_del_init(&pxmitframe->list);
2456
2457
2458
2459 list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
2460
2461 psta->sleepq_len++;
2462
2463 if (!(pstapriv->tim_bitmap & BIT(0)))
2464 update_tim = true;
2465
2466 pstapriv->tim_bitmap |= BIT(0);
2467 pstapriv->sta_dz_bitmap |= BIT(0);
2468
2469
2470
2471 if (update_tim == true) {
2472 update_beacon(padapter, _TIM_IE_, NULL, true);
2473 } else {
2474 chk_bmc_sleepq_cmd(padapter);
2475 }
2476
2477
2478
2479 ret = true;
2480
2481 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_mcast);
2482
2483 }
2484
2485 spin_unlock_bh(&psta->sleep_q.lock);
2486
2487 return ret;
2488
2489 }
2490
2491
2492 spin_lock_bh(&psta->sleep_q.lock);
2493
2494 if (psta->state&WIFI_SLEEP_STATE) {
2495 u8 wmmps_ac = 0;
2496
2497 if (pstapriv->sta_dz_bitmap & BIT(psta->aid)) {
2498 list_del_init(&pxmitframe->list);
2499
2500
2501
2502 list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
2503
2504 psta->sleepq_len++;
2505
2506 switch (pattrib->priority) {
2507 case 1:
2508 case 2:
2509 wmmps_ac = psta->uapsd_bk&BIT(0);
2510 break;
2511 case 4:
2512 case 5:
2513 wmmps_ac = psta->uapsd_vi&BIT(0);
2514 break;
2515 case 6:
2516 case 7:
2517 wmmps_ac = psta->uapsd_vo&BIT(0);
2518 break;
2519 case 0:
2520 case 3:
2521 default:
2522 wmmps_ac = psta->uapsd_be&BIT(0);
2523 break;
2524 }
2525
2526 if (wmmps_ac)
2527 psta->sleepq_ac_len++;
2528
2529 if (((psta->has_legacy_ac) && (!wmmps_ac)) || ((!psta->has_legacy_ac) && (wmmps_ac))) {
2530 if (!(pstapriv->tim_bitmap & BIT(psta->aid)))
2531 update_tim = true;
2532
2533 pstapriv->tim_bitmap |= BIT(psta->aid);
2534
2535
2536
2537 if (update_tim == true)
2538
2539
2540 update_beacon(padapter, _TIM_IE_, NULL, true);
2541 }
2542
2543
2544
2545
2546
2547
2548
2549
2550 ret = true;
2551
2552 DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_ucast);
2553 }
2554
2555 }
2556
2557 spin_unlock_bh(&psta->sleep_q.lock);
2558
2559 return ret;
2560
2561}
2562
2563static void dequeue_xmitframes_to_sleeping_queue(struct adapter *padapter, struct sta_info *psta, struct __queue *pframequeue)
2564{
2565 sint ret;
2566 struct list_head *plist, *phead;
2567 u8 ac_index;
2568 struct tx_servq *ptxservq;
2569 struct pkt_attrib *pattrib;
2570 struct xmit_frame *pxmitframe;
2571 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
2572
2573 phead = get_list_head(pframequeue);
2574 plist = get_next(phead);
2575
2576 while (phead != plist) {
2577 pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
2578
2579 plist = get_next(plist);
2580
2581 pattrib = &pxmitframe->attrib;
2582
2583 pattrib->triggered = 0;
2584
2585 ret = xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
2586
2587 if (true == ret) {
2588 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
2589
2590 ptxservq->qcnt--;
2591 phwxmits[ac_index].accnt--;
2592 } else {
2593
2594 }
2595
2596 }
2597
2598}
2599
2600void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta)
2601{
2602 struct sta_info *psta_bmc;
2603 struct sta_xmit_priv *pstaxmitpriv;
2604 struct sta_priv *pstapriv = &padapter->stapriv;
2605 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2606
2607 pstaxmitpriv = &psta->sta_xmitpriv;
2608
2609
2610 psta_bmc = rtw_get_bcmc_stainfo(padapter);
2611
2612
2613 spin_lock_bh(&pxmitpriv->lock);
2614
2615 psta->state |= WIFI_SLEEP_STATE;
2616
2617 pstapriv->sta_dz_bitmap |= BIT(psta->aid);
2618
2619
2620
2621 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
2622 list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
2623
2624
2625 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
2626 list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
2627
2628
2629 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
2630 list_del_init(&(pstaxmitpriv->be_q.tx_pending));
2631
2632
2633 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
2634 list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
2635
2636
2637 pstaxmitpriv = &psta_bmc->sta_xmitpriv;
2638 dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending);
2639 list_del_init(&(pstaxmitpriv->be_q.tx_pending));
2640
2641 spin_unlock_bh(&pxmitpriv->lock);
2642}
2643
2644void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
2645{
2646 u8 update_mask = 0, wmmps_ac = 0;
2647 struct sta_info *psta_bmc;
2648 struct list_head *xmitframe_plist, *xmitframe_phead;
2649 struct xmit_frame *pxmitframe = NULL;
2650 struct sta_priv *pstapriv = &padapter->stapriv;
2651 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2652
2653 psta_bmc = rtw_get_bcmc_stainfo(padapter);
2654
2655
2656
2657 spin_lock_bh(&pxmitpriv->lock);
2658
2659 xmitframe_phead = get_list_head(&psta->sleep_q);
2660 xmitframe_plist = get_next(xmitframe_phead);
2661
2662 while (xmitframe_phead != xmitframe_plist) {
2663 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
2664
2665 xmitframe_plist = get_next(xmitframe_plist);
2666
2667 list_del_init(&pxmitframe->list);
2668
2669 switch (pxmitframe->attrib.priority) {
2670 case 1:
2671 case 2:
2672 wmmps_ac = psta->uapsd_bk&BIT(1);
2673 break;
2674 case 4:
2675 case 5:
2676 wmmps_ac = psta->uapsd_vi&BIT(1);
2677 break;
2678 case 6:
2679 case 7:
2680 wmmps_ac = psta->uapsd_vo&BIT(1);
2681 break;
2682 case 0:
2683 case 3:
2684 default:
2685 wmmps_ac = psta->uapsd_be&BIT(1);
2686 break;
2687 }
2688
2689 psta->sleepq_len--;
2690 if (psta->sleepq_len > 0)
2691 pxmitframe->attrib.mdata = 1;
2692 else
2693 pxmitframe->attrib.mdata = 0;
2694
2695 if (wmmps_ac) {
2696 psta->sleepq_ac_len--;
2697 if (psta->sleepq_ac_len > 0) {
2698 pxmitframe->attrib.mdata = 1;
2699 pxmitframe->attrib.eosp = 0;
2700 } else{
2701 pxmitframe->attrib.mdata = 0;
2702 pxmitframe->attrib.eosp = 1;
2703 }
2704 }
2705
2706 pxmitframe->attrib.triggered = 1;
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
2717
2718
2719 }
2720
2721 if (psta->sleepq_len == 0) {
2722 if (pstapriv->tim_bitmap & BIT(psta->aid)) {
2723
2724
2725
2726 update_mask = BIT(0);
2727 }
2728
2729 pstapriv->tim_bitmap &= ~BIT(psta->aid);
2730
2731 if (psta->state&WIFI_SLEEP_STATE)
2732 psta->state ^= WIFI_SLEEP_STATE;
2733
2734 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
2735 DBG_871X("%s alive check\n", __func__);
2736 psta->expire_to = pstapriv->expire_to;
2737 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
2738 }
2739
2740 pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
2741 }
2742
2743
2744 if (!psta_bmc)
2745 goto _exit;
2746
2747 if ((pstapriv->sta_dz_bitmap&0xfffe) == 0x0) {
2748 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
2749 xmitframe_plist = get_next(xmitframe_phead);
2750
2751 while (xmitframe_phead != xmitframe_plist) {
2752 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
2753
2754 xmitframe_plist = get_next(xmitframe_plist);
2755
2756 list_del_init(&pxmitframe->list);
2757
2758 psta_bmc->sleepq_len--;
2759 if (psta_bmc->sleepq_len > 0)
2760 pxmitframe->attrib.mdata = 1;
2761 else
2762 pxmitframe->attrib.mdata = 0;
2763
2764
2765 pxmitframe->attrib.triggered = 1;
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
2776
2777 }
2778
2779 if (psta_bmc->sleepq_len == 0) {
2780 if (pstapriv->tim_bitmap & BIT(0)) {
2781
2782
2783
2784 update_mask |= BIT(1);
2785 }
2786 pstapriv->tim_bitmap &= ~BIT(0);
2787 pstapriv->sta_dz_bitmap &= ~BIT(0);
2788 }
2789
2790 }
2791
2792_exit:
2793
2794
2795 spin_unlock_bh(&pxmitpriv->lock);
2796
2797 if (update_mask)
2798
2799
2800 update_beacon(padapter, _TIM_IE_, NULL, true);
2801
2802}
2803
2804void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *psta)
2805{
2806 u8 wmmps_ac = 0;
2807 struct list_head *xmitframe_plist, *xmitframe_phead;
2808 struct xmit_frame *pxmitframe = NULL;
2809 struct sta_priv *pstapriv = &padapter->stapriv;
2810 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2811
2812
2813
2814 spin_lock_bh(&pxmitpriv->lock);
2815
2816 xmitframe_phead = get_list_head(&psta->sleep_q);
2817 xmitframe_plist = get_next(xmitframe_phead);
2818
2819 while (xmitframe_phead != xmitframe_plist) {
2820 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
2821
2822 xmitframe_plist = get_next(xmitframe_plist);
2823
2824 switch (pxmitframe->attrib.priority) {
2825 case 1:
2826 case 2:
2827 wmmps_ac = psta->uapsd_bk&BIT(1);
2828 break;
2829 case 4:
2830 case 5:
2831 wmmps_ac = psta->uapsd_vi&BIT(1);
2832 break;
2833 case 6:
2834 case 7:
2835 wmmps_ac = psta->uapsd_vo&BIT(1);
2836 break;
2837 case 0:
2838 case 3:
2839 default:
2840 wmmps_ac = psta->uapsd_be&BIT(1);
2841 break;
2842 }
2843
2844 if (!wmmps_ac)
2845 continue;
2846
2847 list_del_init(&pxmitframe->list);
2848
2849 psta->sleepq_len--;
2850 psta->sleepq_ac_len--;
2851
2852 if (psta->sleepq_ac_len > 0) {
2853 pxmitframe->attrib.mdata = 1;
2854 pxmitframe->attrib.eosp = 0;
2855 } else{
2856 pxmitframe->attrib.mdata = 0;
2857 pxmitframe->attrib.eosp = 1;
2858 }
2859
2860 pxmitframe->attrib.triggered = 1;
2861 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
2862
2863 if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) {
2864 pstapriv->tim_bitmap &= ~BIT(psta->aid);
2865
2866
2867
2868
2869 update_beacon(padapter, _TIM_IE_, NULL, true);
2870
2871 }
2872
2873 }
2874
2875
2876 spin_unlock_bh(&pxmitpriv->lock);
2877
2878 return;
2879}
2880
2881void enqueue_pending_xmitbuf(
2882 struct xmit_priv *pxmitpriv,
2883 struct xmit_buf *pxmitbuf)
2884{
2885 struct __queue *pqueue;
2886 struct adapter *pri_adapter = pxmitpriv->adapter;
2887
2888 pqueue = &pxmitpriv->pending_xmitbuf_queue;
2889
2890 spin_lock_bh(&pqueue->lock);
2891 list_del_init(&pxmitbuf->list);
2892 list_add_tail(&pxmitbuf->list, get_list_head(pqueue));
2893 spin_unlock_bh(&pqueue->lock);
2894
2895 up(&(pri_adapter->xmitpriv.xmit_sema));
2896}
2897
2898void enqueue_pending_xmitbuf_to_head(
2899 struct xmit_priv *pxmitpriv,
2900 struct xmit_buf *pxmitbuf)
2901{
2902 struct __queue *pqueue;
2903
2904 pqueue = &pxmitpriv->pending_xmitbuf_queue;
2905
2906 spin_lock_bh(&pqueue->lock);
2907 list_del_init(&pxmitbuf->list);
2908 list_add(&pxmitbuf->list, get_list_head(pqueue));
2909 spin_unlock_bh(&pqueue->lock);
2910}
2911
2912struct xmit_buf *dequeue_pending_xmitbuf(
2913 struct xmit_priv *pxmitpriv)
2914{
2915 struct xmit_buf *pxmitbuf;
2916 struct __queue *pqueue;
2917
2918
2919 pxmitbuf = NULL;
2920 pqueue = &pxmitpriv->pending_xmitbuf_queue;
2921
2922 spin_lock_bh(&pqueue->lock);
2923
2924 if (!list_empty(&pqueue->queue)) {
2925 struct list_head *plist, *phead;
2926
2927 phead = get_list_head(pqueue);
2928 plist = get_next(phead);
2929 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
2930 list_del_init(&pxmitbuf->list);
2931 }
2932
2933 spin_unlock_bh(&pqueue->lock);
2934
2935 return pxmitbuf;
2936}
2937
2938struct xmit_buf *dequeue_pending_xmitbuf_under_survey(
2939 struct xmit_priv *pxmitpriv)
2940{
2941 struct xmit_buf *pxmitbuf;
2942 struct __queue *pqueue;
2943
2944
2945 pxmitbuf = NULL;
2946 pqueue = &pxmitpriv->pending_xmitbuf_queue;
2947
2948 spin_lock_bh(&pqueue->lock);
2949
2950 if (!list_empty(&pqueue->queue)) {
2951 struct list_head *plist, *phead;
2952 u8 type;
2953
2954 phead = get_list_head(pqueue);
2955 plist = phead;
2956 do {
2957 plist = get_next(plist);
2958 if (plist == phead)
2959 break;
2960
2961 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
2962
2963 type = GetFrameSubType(pxmitbuf->pbuf + TXDESC_OFFSET);
2964
2965 if ((type == WIFI_PROBEREQ) ||
2966 (type == WIFI_DATA_NULL) ||
2967 (type == WIFI_QOS_DATA_NULL)) {
2968 list_del_init(&pxmitbuf->list);
2969 break;
2970 }
2971 pxmitbuf = NULL;
2972 } while (1);
2973 }
2974
2975 spin_unlock_bh(&pqueue->lock);
2976
2977 return pxmitbuf;
2978}
2979
2980sint check_pending_xmitbuf(
2981 struct xmit_priv *pxmitpriv)
2982{
2983 struct __queue *pqueue;
2984 sint ret = false;
2985
2986 pqueue = &pxmitpriv->pending_xmitbuf_queue;
2987
2988 spin_lock_bh(&pqueue->lock);
2989
2990 if (!list_empty(&pqueue->queue))
2991 ret = true;
2992
2993 spin_unlock_bh(&pqueue->lock);
2994
2995 return ret;
2996}
2997
2998int rtw_xmit_thread(void *context)
2999{
3000 s32 err;
3001 struct adapter *padapter;
3002
3003
3004 err = _SUCCESS;
3005 padapter = (struct adapter *)context;
3006
3007 thread_enter("RTW_XMIT_THREAD");
3008
3009 do {
3010 err = rtw_hal_xmit_thread_handler(padapter);
3011 flush_signals_thread();
3012 } while (_SUCCESS == err);
3013
3014 up(&padapter->xmitpriv.terminate_xmitthread_sema);
3015
3016 thread_exit();
3017}
3018
3019void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms)
3020{
3021 sctx->timeout_ms = timeout_ms;
3022 sctx->submit_time = jiffies;
3023 init_completion(&sctx->done);
3024 sctx->status = RTW_SCTX_SUBMITTED;
3025}
3026
3027int rtw_sctx_wait(struct submit_ctx *sctx, const char *msg)
3028{
3029 int ret = _FAIL;
3030 unsigned long expire;
3031 int status = 0;
3032
3033 expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT;
3034 if (!wait_for_completion_timeout(&sctx->done, expire)) {
3035
3036 status = RTW_SCTX_DONE_TIMEOUT;
3037 DBG_871X("%s timeout: %s\n", __func__, msg);
3038 } else {
3039 status = sctx->status;
3040 }
3041
3042 if (status == RTW_SCTX_DONE_SUCCESS) {
3043 ret = _SUCCESS;
3044 }
3045
3046 return ret;
3047}
3048
3049static bool rtw_sctx_chk_waring_status(int status)
3050{
3051 switch (status) {
3052 case RTW_SCTX_DONE_UNKNOWN:
3053 case RTW_SCTX_DONE_BUF_ALLOC:
3054 case RTW_SCTX_DONE_BUF_FREE:
3055
3056 case RTW_SCTX_DONE_DRV_STOP:
3057 case RTW_SCTX_DONE_DEV_REMOVE:
3058 return true;
3059 default:
3060 return false;
3061 }
3062}
3063
3064void rtw_sctx_done_err(struct submit_ctx **sctx, int status)
3065{
3066 if (*sctx) {
3067 if (rtw_sctx_chk_waring_status(status))
3068 DBG_871X("%s status:%d\n", __func__, status);
3069 (*sctx)->status = status;
3070 complete(&((*sctx)->done));
3071 *sctx = NULL;
3072 }
3073}
3074
3075void rtw_sctx_done(struct submit_ctx **sctx)
3076{
3077 rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS);
3078}
3079
3080int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
3081{
3082 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
3083
3084 pack_tx_ops->submit_time = jiffies;
3085 pack_tx_ops->timeout_ms = timeout_ms;
3086 pack_tx_ops->status = RTW_SCTX_SUBMITTED;
3087
3088 return rtw_sctx_wait(pack_tx_ops, __func__);
3089}
3090
3091void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)
3092{
3093 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
3094
3095 if (pxmitpriv->ack_tx) {
3096 rtw_sctx_done_err(&pack_tx_ops, status);
3097 } else {
3098 DBG_871X("%s ack_tx not set\n", __func__);
3099 }
3100}
3101