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