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