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