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