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

source code of linux/drivers/staging/rtl8723bs/core/rtw_xmit.c