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
16 #define _RTL8188FU_XMIT_C_
17
18 #include <rtl8188f_hal.h>
19
20
rtl8188fu_init_xmit_priv(_adapter * padapter)21 s32 rtl8188fu_init_xmit_priv(_adapter *padapter)
22 {
23 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
24
25 #ifdef PLATFORM_LINUX
26 tasklet_init(&pxmitpriv->xmit_tasklet,
27 (void(*)(unsigned long))rtl8188fu_xmit_tasklet,
28 (unsigned long)padapter);
29 #endif
30 return _SUCCESS;
31 }
32
rtl8188fu_free_xmit_priv(_adapter * padapter)33 void rtl8188fu_free_xmit_priv(_adapter *padapter)
34 {
35 }
36
_dbg_dump_tx_info(_adapter * padapter,int frame_tag,struct tx_desc * ptxdesc)37 void _dbg_dump_tx_info(_adapter *padapter, int frame_tag, struct tx_desc *ptxdesc)
38 {
39 u8 bDumpTxPkt;
40 u8 bDumpTxDesc = _FALSE;
41 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(bDumpTxPkt));
42
43 if (bDumpTxPkt == 1) { /*dump txdesc for data frame */
44 RTW_INFO("dump tx_desc for data frame\n");
45 if ((frame_tag & 0x0f) == DATA_FRAMETAG)
46 bDumpTxDesc = _TRUE;
47 } else if (bDumpTxPkt == 2) { /*dump txdesc for mgnt frame */
48 RTW_INFO("dump tx_desc for mgnt frame\n");
49 if ((frame_tag & 0x0f) == MGNT_FRAMETAG)
50 bDumpTxDesc = _TRUE;
51 } else if (bDumpTxPkt == 3) { /*dump early info */
52 }
53
54 if (bDumpTxDesc) {
55 RTW_INFO("=====================================\n");
56 RTW_INFO("txdw0(0x%08x)\n", ptxdesc->txdw0);
57 RTW_INFO("txdw1(0x%08x)\n", ptxdesc->txdw1);
58 RTW_INFO("txdw2(0x%08x)\n", ptxdesc->txdw2);
59 RTW_INFO("txdw3(0x%08x)\n", ptxdesc->txdw3);
60 RTW_INFO("txdw4(0x%08x)\n", ptxdesc->txdw4);
61 RTW_INFO("txdw5(0x%08x)\n", ptxdesc->txdw5);
62 RTW_INFO("txdw6(0x%08x)\n", ptxdesc->txdw6);
63 RTW_INFO("txdw7(0x%08x)\n", ptxdesc->txdw7);
64 RTW_INFO("txdw8(0x%08x)\n", ptxdesc->txdw8);
65 RTW_INFO("txdw9(0x%08x)\n", ptxdesc->txdw9);
66 RTW_INFO("=====================================\n");
67 }
68
69 }
70
urb_zero_packet_chk(_adapter * padapter,int sz)71 int urb_zero_packet_chk(_adapter *padapter, int sz)
72 {
73 u8 blnSetTxDescOffset;
74 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
75 blnSetTxDescOffset = (((sz + TXDESC_SIZE) % pHalData->UsbBulkOutSize) == 0) ? 1 : 0;
76
77 return blnSetTxDescOffset;
78 }
fill_txdesc_sectype(struct pkt_attrib * pattrib,struct tx_desc * ptxdesc)79 void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
80 {
81 if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
82 switch (pattrib->encrypt) {
83 /*SEC_TYPE */
84 case _WEP40_:
85 case _WEP104_:
86 ptxdesc->txdw1 |= cpu_to_le32((0x01 << 22) & 0x00c00000);
87 break;
88 case _TKIP_:
89 case _TKIP_WTMIC_:
90 /*ptxdesc->txdw1 |= cpu_to_le32((0x02<<22)&0x00c00000); */
91 ptxdesc->txdw1 |= cpu_to_le32((0x01 << 22) & 0x00c00000);
92 break;
93 case _AES_:
94 ptxdesc->txdw1 |= cpu_to_le32((0x03 << 22) & 0x00c00000);
95 break;
96 case _NO_PRIVACY_:
97 default:
98 break;
99
100 }
101
102 }
103
104 }
105
fill_txdesc_vcs(struct pkt_attrib * pattrib,u32 * pdw)106 void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
107 {
108 /*RTW_INFO("cvs_mode=%d\n", pattrib->vcs_mode); */
109
110 switch (pattrib->vcs_mode) {
111 case RTS_CTS:
112 *pdw |= cpu_to_le32(BIT(12));
113 break;
114 case CTS_TO_SELF:
115 *pdw |= cpu_to_le32(BIT(11));
116 break;
117 case NONE_VCS:
118 default:
119 break;
120 }
121
122 if (pattrib->vcs_mode) {
123 *pdw |= cpu_to_le32(BIT(13));
124
125 /* Set RTS BW */
126 if (pattrib->ht_en) {
127 *pdw |= (pattrib->bwmode & CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(27)) : 0;
128
129 if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
130 *pdw |= cpu_to_le32((0x01 << 28) & 0x30000000);
131 else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
132 *pdw |= cpu_to_le32((0x02 << 28) & 0x30000000);
133 else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
134 *pdw |= 0;
135 else
136 *pdw |= cpu_to_le32((0x03 << 28) & 0x30000000);
137 }
138 }
139 }
140
fill_txdesc_phy(struct pkt_attrib * pattrib,u32 * pdw)141 void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw)
142 {
143 /*RTW_INFO("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset); */
144
145 if (pattrib->ht_en) {
146 *pdw |= (pattrib->bwmode & CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0;
147
148 if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
149 *pdw |= cpu_to_le32((0x01 << 20) & 0x003f0000);
150 else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
151 *pdw |= cpu_to_le32((0x02 << 20) & 0x003f0000);
152 else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
153 *pdw |= 0;
154 else
155 *pdw |= cpu_to_le32((0x03 << 20) & 0x003f0000);
156 }
157 }
158
update_txdesc(struct xmit_frame * pxmitframe,u8 * pmem,s32 sz,u8 bagg_pkt)159 static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt)
160 {
161 int pull = 0;
162
163
164 _adapter *padapter = pxmitframe->padapter;
165 struct tx_desc *ptxdesc = (struct tx_desc *)pmem;
166 #if 0
167 uint qsel;
168 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
169 struct pkt_attrib *pattrib = &pxmitframe->attrib;
170 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
171 struct dm_priv *pdmpriv = &pHalData->dmpriv;
172
173 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
174 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
175 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
176 sint bmcst = IS_MCAST(pattrib->ra);
177 #ifdef CONFIG_P2P
178 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
179 #endif /*CONFIG_P2P */
180 #endif
181 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
182 if ((PACKET_OFFSET_SZ != 0)
183 && (_FALSE == bagg_pkt)
184 && (urb_zero_packet_chk(padapter, sz) == 0)) {
185 ptxdesc = (struct tx_desc *)(pmem + PACKET_OFFSET_SZ);
186 pull = 1;
187 pxmitframe->pkt_offset--;
188 }
189 #endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
190
191 _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
192
193 rtl8188f_update_txdesc(pxmitframe, (u8 *)ptxdesc);
194 _dbg_dump_tx_info(padapter, pxmitframe->frame_tag, ptxdesc);
195 return pull;
196
197 }
198
199 #ifdef CONFIG_XMIT_THREAD_MODE
200 /*
201 * Description
202 * Transmit xmitbuf to hardware tx fifo
203 *
204 * Return
205 * _SUCCESS ok
206 * _FAIL something error
207 */
rtl8188fu_xmit_buf_handler(PADAPTER padapter)208 s32 rtl8188fu_xmit_buf_handler(PADAPTER padapter)
209 {
210 /*PHAL_DATA_TYPE phal; */
211 struct xmit_priv *pxmitpriv;
212 struct xmit_buf *pxmitbuf;
213 struct xmit_frame *pxmitframe;
214 s32 ret;
215
216
217 /*phal = GET_HAL_DATA(padapter); */
218 pxmitpriv = &padapter->xmitpriv;
219
220 ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
221 if (ret == _FAIL)
222 return _FAIL;
223
224 if (RTW_CANNOT_RUN(padapter)) {
225 RTW_DBG(FUNC_ADPT_FMT "- bDriverStopped(%s) bSurpriseRemoved(%s)\n",
226 FUNC_ADPT_ARG(padapter),
227 rtw_is_drv_stopped(padapter) ? "True" : "False",
228 rtw_is_surprise_removed(padapter) ? "True" : "False");
229 return _FAIL;
230 }
231
232 if (rtw_mi_check_pending_xmitbuf(padapter) == 0)
233 return _SUCCESS;
234
235 #ifdef CONFIG_LPS_LCLK
236 ret = rtw_register_tx_alive(padapter);
237 if (ret != _SUCCESS) {
238 return _SUCCESS;
239 }
240 #endif
241
242 do {
243 pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
244 if (pxmitbuf == NULL)
245 break;
246 pxmitframe = (struct xmit_frame *) pxmitbuf->priv_data;
247 rtw_write_port_and_wait(padapter, pxmitbuf->ff_hwaddr, pxmitbuf->len, (unsigned char *)pxmitbuf, 500);
248 rtw_free_xmitframe(pxmitpriv, pxmitframe);
249
250 } while (1);
251
252 #ifdef CONFIG_LPS_LCLK
253 rtw_unregister_tx_alive(padapter);
254 #endif
255
256 return _SUCCESS;
257 }
258 #endif
259
260
rtw_dump_xframe(_adapter * padapter,struct xmit_frame * pxmitframe)261 static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
262 {
263 s32 ret = _SUCCESS;
264 s32 inner_ret = _SUCCESS;
265 int t, sz, w_sz, pull = 0;
266 u8 *mem_addr;
267 u32 ff_hwaddr;
268 struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
269 struct pkt_attrib *pattrib = &pxmitframe->attrib;
270 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
271 struct security_priv *psecuritypriv = &padapter->securitypriv;
272 #ifdef CONFIG_80211N_HT
273 if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
274 (pxmitframe->attrib.ether_type != 0x0806) &&
275 (pxmitframe->attrib.ether_type != 0x888e) &&
276 (pxmitframe->attrib.dhcp_pkt != 1))
277 rtw_issue_addbareq_cmd(padapter, pxmitframe, _FALSE);
278 #endif /* CONFIG_80211N_HT */
279 mem_addr = pxmitframe->buf_addr;
280
281
282 for (t = 0; t < pattrib->nr_frags; t++) {
283 if (inner_ret != _SUCCESS && ret == _SUCCESS)
284 ret = _FAIL;
285
286 if (t != (pattrib->nr_frags - 1)) {
287
288 sz = pxmitpriv->frag_len;
289 sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
290 } else /*no frag */
291 sz = pattrib->last_txcmdsz;
292
293 pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
294 /* rtl8188f_update_txdesc(pxmitframe, mem_addr+PACKET_OFFSET_SZ); */
295
296 if (pull) {
297 mem_addr += PACKET_OFFSET_SZ; /*pull txdesc head */
298
299 /*pxmitbuf->pbuf = mem_addr; */
300 pxmitframe->buf_addr = mem_addr;
301
302 w_sz = sz + TXDESC_SIZE;
303 } else
304 w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
305
306 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
307 #ifdef CONFIG_XMIT_THREAD_MODE
308 pxmitbuf->len = w_sz;
309 pxmitbuf->ff_hwaddr = ff_hwaddr;
310 if (pxmitframe->attrib.qsel == QSLT_BEACON)
311 /* download rsvd page or fw */
312 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf);
313 else
314 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
315 #else
316 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf);
317 #endif
318 rtw_count_tx_stats(padapter, pxmitframe, sz);
319
320
321 /*RTW_INFO("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority); */
322
323 mem_addr += w_sz;
324
325 mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
326
327 }
328
329 #ifdef CONFIG_XMIT_THREAD_MODE
330 if (pxmitframe->attrib.qsel == QSLT_BEACON)
331 #endif
332 rtw_free_xmitframe(pxmitpriv, pxmitframe);
333
334 if (ret != _SUCCESS)
335 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
336
337 return ret;
338 }
339
340 #ifdef CONFIG_USB_TX_AGGREGATION
341 #define IDEA_CONDITION 1 /* check all packets before enqueue */
rtl8188fu_xmitframe_complete(_adapter * padapter,struct xmit_priv * pxmitpriv,struct xmit_buf * pxmitbuf)342 s32 rtl8188fu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
343 {
344 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
345 struct xmit_frame *pxmitframe = NULL;
346 struct xmit_frame *pfirstframe = NULL;
347
348 /* aggregate variable */
349 struct hw_xmit *phwxmit;
350 struct sta_info *psta = NULL;
351 struct tx_servq *ptxservq = NULL;
352
353 _irqL irqL;
354 _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
355
356 u32 pbuf; /* next pkt address */
357 u32 pbuf_tail; /* last pkt tail */
358 u32 len; /* packet length, except TXDESC_SIZE and PKT_OFFSET */
359
360 u32 bulkSize = pHalData->UsbBulkOutSize;
361 u8 descCount;
362 u32 bulkPtr;
363
364 /* dump frame variable */
365 u32 ff_hwaddr;
366
367 _list *sta_plist, *sta_phead;
368 u8 single_sta_in_queue = _FALSE;
369
370 #ifndef IDEA_CONDITION
371 int res = _SUCCESS;
372 #endif
373
374
375
376 /* check xmitbuffer is ok */
377 if (pxmitbuf == NULL) {
378 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
379 if (pxmitbuf == NULL)
380 return _FALSE;
381 }
382
383
384 /*3 1. pick up first frame */
385 do {
386 rtw_free_xmitframe(pxmitpriv, pxmitframe);
387
388 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
389 if (pxmitframe == NULL) {
390 /* no more xmit frame, release xmit buffer */
391 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
392 return _FALSE;
393 }
394
395
396 #ifndef IDEA_CONDITION
397 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
398 /* rtw_free_xmitframe(pxmitpriv, pxmitframe); */
399 continue;
400 }
401
402 /* TID 0~15 */
403 if ((pxmitframe->attrib.priority < 0) ||
404 (pxmitframe->attrib.priority > 15)) {
405 /* rtw_free_xmitframe(pxmitpriv, pxmitframe); */
406 continue;
407 }
408 #endif
409
410 pxmitframe->pxmitbuf = pxmitbuf;
411 pxmitframe->buf_addr = pxmitbuf->pbuf;
412 pxmitbuf->priv_data = pxmitframe;
413
414 /* pxmitframe->agg_num = 1; */ /* alloc xmitframe should assign to 1. */
415 /* pxmitframe->pkt_offset = 1; */ /* first frame of aggregation, reserve offset */
416 pxmitframe->pkt_offset = (PACKET_OFFSET_SZ / 8);
417
418 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
419 RTW_INFO("%s coalesce 1st xmitframe failed\n", __func__);
420 continue;
421 }
422
423
424 /* always return ndis_packet after rtw_xmitframe_coalesce */
425 rtw_os_xmit_complete(padapter, pxmitframe);
426
427 break;
428 } while (1);
429
430 /*3 2. aggregate same priority and same DA(AP or STA) frames */
431 pfirstframe = pxmitframe;
432 len = rtw_wlan_pkt_size(pfirstframe) + TXDESC_OFFSET;
433 pbuf_tail = len;
434 pbuf = _RND8(pbuf_tail);
435
436 /* check pkt amount in one bluk */
437 descCount = 0;
438 bulkPtr = bulkSize;
439 if (pbuf < bulkPtr)
440 descCount++;
441 else {
442 descCount = 0;
443 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; /* round to next bulkSize */
444 }
445
446 /* dequeue same priority packet from station tx queue */
447 psta = pfirstframe->attrib.psta;
448 switch (pfirstframe->attrib.priority) {
449 case 1:
450 case 2:
451 ptxservq = &(psta->sta_xmitpriv.bk_q);
452 phwxmit = pxmitpriv->hwxmits + 3;
453 break;
454
455 case 4:
456 case 5:
457 ptxservq = &(psta->sta_xmitpriv.vi_q);
458 phwxmit = pxmitpriv->hwxmits + 1;
459 break;
460
461 case 6:
462 case 7:
463 ptxservq = &(psta->sta_xmitpriv.vo_q);
464 phwxmit = pxmitpriv->hwxmits;
465 break;
466
467 case 0:
468 case 3:
469 default:
470 ptxservq = &(psta->sta_xmitpriv.be_q);
471 phwxmit = pxmitpriv->hwxmits + 2;
472 break;
473 }
474
475 _enter_critical_bh(&pxmitpriv->lock, &irqL);
476
477 sta_phead = get_list_head(phwxmit->sta_queue);
478 sta_plist = get_next(sta_phead);
479 single_sta_in_queue = rtw_end_of_queue_search(sta_phead, get_next(sta_plist));
480
481 xmitframe_phead = get_list_head(&ptxservq->sta_pending);
482 xmitframe_plist = get_next(xmitframe_phead);
483 while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE) {
484 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
485 xmitframe_plist = get_next(xmitframe_plist);
486
487 if (_FAIL == rtw_hal_busagg_qsel_check(padapter, pfirstframe->attrib.qsel, pxmitframe->attrib.qsel))
488 break;
489
490 len = rtw_wlan_pkt_size(pxmitframe) + TXDESC_SIZE; /* no offset */
491 if (pbuf + len > MAX_XMITBUF_SZ)
492 break;
493
494 rtw_list_delete(&pxmitframe->list);
495 ptxservq->qcnt--;
496 phwxmit->accnt--;
497
498 #ifndef IDEA_CONDITION
499 /* suppose only data frames would be in queue */
500 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
501 rtw_free_xmitframe(pxmitpriv, pxmitframe);
502 continue;
503 }
504
505 /* TID 0~15 */
506 if ((pxmitframe->attrib.priority < 0) ||
507 (pxmitframe->attrib.priority > 15)) {
508 rtw_free_xmitframe(pxmitpriv, pxmitframe);
509 continue;
510 }
511 #endif
512
513 /* pxmitframe->pxmitbuf = pxmitbuf; */
514 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
515
516 pxmitframe->agg_num = 0; /* not first frame of aggregation */
517 pxmitframe->pkt_offset = 0; /* not first frame of aggregation, no need to reserve offset */
518
519 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
520 RTW_INFO("%s coalesce failed\n", __func__);
521 rtw_free_xmitframe(pxmitpriv, pxmitframe);
522 continue;
523 }
524
525
526 /* always return ndis_packet after rtw_xmitframe_coalesce */
527 rtw_os_xmit_complete(padapter, pxmitframe);
528
529 /* (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz */
530 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
531
532 /* don't need xmitframe any more */
533 rtw_free_xmitframe(pxmitpriv, pxmitframe);
534
535 /* handle pointer and stop condition */
536 pbuf_tail = pbuf + len;
537 pbuf = _RND8(pbuf_tail);
538
539 pfirstframe->agg_num++;
540 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
541 break;
542
543 if (pbuf < bulkPtr) {
544 descCount++;
545 if (descCount == pHalData->UsbTxAggDescNum)
546 break;
547 } else {
548 descCount = 0;
549 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
550 }
551 }
552 if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
553 rtw_list_delete(&ptxservq->tx_pending);
554 else if (single_sta_in_queue == _FALSE) {
555 /* Re-arrange the order of stations in this ac queue to balance the service for these stations */
556 rtw_list_delete(&ptxservq->tx_pending);
557 rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmit->sta_queue));
558 }
559
560 _exit_critical_bh(&pxmitpriv->lock, &irqL);
561 #ifdef CONFIG_80211N_HT
562 if ((pfirstframe->attrib.ether_type != 0x0806) &&
563 (pfirstframe->attrib.ether_type != 0x888e) &&
564 (pfirstframe->attrib.dhcp_pkt != 1))
565 rtw_issue_addbareq_cmd(padapter, pfirstframe, _FALSE);
566 #endif /* CONFIG_80211N_HT */
567 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
568 /*3 3. update first frame txdesc */
569 if ((PACKET_OFFSET_SZ != 0)
570 && (pbuf_tail % bulkSize) == 0) {
571 /* remove pkt_offset */
572 pbuf_tail -= PACKET_OFFSET_SZ;
573 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
574 pfirstframe->pkt_offset = 0;
575 }
576 #endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
577 update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
578
579 /*3 4. write xmit buffer to USB FIFO */
580 ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
581
582 /* xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr */
583 #ifdef CONFIG_XMIT_THREAD_MODE
584 pxmitbuf->len = pbuf_tail;
585 pxmitbuf->ff_hwaddr = ff_hwaddr;
586
587 if (pfirstframe->attrib.qsel == QSLT_BEACON)
588 /* download rsvd page or fw */
589 rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
590 else
591 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
592 #else
593 rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
594 #endif
595
596
597 /*3 5. update statisitc */
598 pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
599 if (pfirstframe->pkt_offset == 1)
600 pbuf_tail -= PACKET_OFFSET_SZ;
601
602 rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
603
604 #ifdef CONFIG_XMIT_THREAD_MODE
605 if (pfirstframe->attrib.qsel == QSLT_BEACON)
606 #endif
607 rtw_free_xmitframe(pxmitpriv, pfirstframe);
608
609 return _TRUE;
610 }
611
612 #else
613
rtl8188fu_xmitframe_complete(_adapter * padapter,struct xmit_priv * pxmitpriv,struct xmit_buf * pxmitbuf)614 s32 rtl8188fu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
615 {
616
617 struct hw_xmit *phwxmits;
618 sint hwentry;
619 struct xmit_frame *pxmitframe = NULL;
620 int res = _SUCCESS, xcnt = 0;
621
622 phwxmits = pxmitpriv->hwxmits;
623 hwentry = pxmitpriv->hwxmit_entry;
624
625
626 if (pxmitbuf == NULL) {
627 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
628 if (!pxmitbuf)
629 return _FALSE;
630 }
631
632
633 do {
634 pxmitframe = rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
635
636 if (pxmitframe) {
637 pxmitframe->pxmitbuf = pxmitbuf;
638
639 pxmitframe->buf_addr = pxmitbuf->pbuf;
640
641 pxmitbuf->priv_data = pxmitframe;
642
643 if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
644 if (pxmitframe->attrib.priority <= 15) /*TID0~15 */
645 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
646
647 rtw_os_xmit_complete(padapter, pxmitframe);/*always return ndis_packet after rtw_xmitframe_coalesce */
648 }
649
650
651
652
653 if (res == _SUCCESS)
654 rtw_dump_xframe(padapter, pxmitframe);
655 else {
656 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
657 rtw_free_xmitframe(pxmitpriv, pxmitframe);
658 }
659
660 xcnt++;
661
662 } else {
663 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
664 return _FALSE;
665 }
666
667 break;
668
669 } while (0/*xcnt < (NR_XMITFRAME >> 3)*/);
670
671 return _TRUE;
672
673 }
674 #endif
675
676
677
xmitframe_direct(_adapter * padapter,struct xmit_frame * pxmitframe)678 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
679 {
680 s32 res = _SUCCESS;
681
682
683 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
684 if (res == _SUCCESS)
685 rtw_dump_xframe(padapter, pxmitframe);
686
687 return res;
688 }
689
690 /*
691 * Return
692 * _TRUE dump packet directly
693 * _FALSE enqueue packet
694 */
pre_xmitframe(_adapter * padapter,struct xmit_frame * pxmitframe)695 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
696 {
697 _irqL irqL;
698 s32 res;
699 struct xmit_buf *pxmitbuf = NULL;
700 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
701 struct pkt_attrib *pattrib = &pxmitframe->attrib;
702 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
703
704 _enter_critical_bh(&pxmitpriv->lock, &irqL);
705
706 if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0)
707 goto enqueue;
708
709 if (rtw_xmit_ac_blocked(padapter) == _TRUE)
710 goto enqueue;
711
712 if (DEV_STA_LG_NUM(padapter->dvobj))
713 goto enqueue;
714
715 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
716 if (pxmitbuf == NULL)
717 goto enqueue;
718
719 _exit_critical_bh(&pxmitpriv->lock, &irqL);
720
721 pxmitframe->pxmitbuf = pxmitbuf;
722 pxmitframe->buf_addr = pxmitbuf->pbuf;
723 pxmitbuf->priv_data = pxmitframe;
724
725 if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
726 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
727 rtw_free_xmitframe(pxmitpriv, pxmitframe);
728 }
729
730 return _TRUE;
731
732 enqueue:
733 res = rtw_xmitframe_enqueue(padapter, pxmitframe);
734 _exit_critical_bh(&pxmitpriv->lock, &irqL);
735
736 if (res != _SUCCESS) {
737 rtw_free_xmitframe(pxmitpriv, pxmitframe);
738
739 pxmitpriv->tx_drop++;
740 return _TRUE;
741 }
742
743 return _FALSE;
744 }
745
rtl8188fu_mgnt_xmit(_adapter * padapter,struct xmit_frame * pmgntframe)746 s32 rtl8188fu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
747 {
748 return rtw_dump_xframe(padapter, pmgntframe);
749 }
750
751 /*
752 * Return
753 * _TRUE dump packet directly ok
754 * _FALSE temporary can't transmit packets to hardware
755 */
rtl8188fu_hal_xmit(_adapter * padapter,struct xmit_frame * pxmitframe)756 s32 rtl8188fu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
757 {
758 return pre_xmitframe(padapter, pxmitframe);
759 }
760
rtl8188fu_hal_xmitframe_enqueue(_adapter * padapter,struct xmit_frame * pxmitframe)761 s32 rtl8188fu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
762 {
763 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
764 s32 err;
765
766 err = rtw_xmitframe_enqueue(padapter, pxmitframe);
767 if (err != _SUCCESS) {
768 rtw_free_xmitframe(pxmitpriv, pxmitframe);
769
770 pxmitpriv->tx_drop++;
771 } else {
772 #ifdef PLATFORM_LINUX
773 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
774 #endif
775 }
776
777 return err;
778
779 }
780
781
782 #ifdef CONFIG_HOSTAPD_MLME
783
rtl8188fu_hostap_mgnt_xmit_cb(struct urb * urb)784 static void rtl8188fu_hostap_mgnt_xmit_cb(struct urb *urb)
785 {
786 #ifdef PLATFORM_LINUX
787 struct sk_buff *skb = (struct sk_buff *)urb->context;
788
789 /*RTW_INFO("%s\n", __func__); */
790
791 rtw_skb_free(skb);
792 #endif
793 }
794
rtl8188fu_hostap_mgnt_xmit_entry(_adapter * padapter,_pkt * pkt)795 s32 rtl8188fu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
796 {
797 #ifdef PLATFORM_LINUX
798 u16 fc;
799 int rc, len, pipe;
800 unsigned int bmcst, tid, qsel;
801 struct sk_buff *skb, *pxmit_skb;
802 struct urb *urb;
803 unsigned char *pxmitbuf;
804 struct tx_desc *ptxdesc;
805 struct ieee80211_hdr *tx_hdr;
806 struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
807 struct net_device *pnetdev = padapter->pnetdev;
808 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
809 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
810
811
812 /*RTW_INFO("%s\n", __func__); */
813
814 skb = pkt;
815
816 len = skb->len;
817 tx_hdr = (struct ieee80211_hdr *)(skb->data);
818 fc = le16_to_cpu(tx_hdr->frame_ctl);
819 bmcst = IS_MCAST(tx_hdr->addr1);
820
821 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
822 goto _exit;
823
824 pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
825
826 if (!pxmit_skb)
827 goto _exit;
828
829 pxmitbuf = pxmit_skb->data;
830
831 urb = usb_alloc_urb(0, GFP_ATOMIC);
832 if (!urb)
833 goto _exit;
834
835 /* ----- fill tx desc ----- */
836 ptxdesc = (struct tx_desc *)pxmitbuf;
837 _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
838
839 /*offset 0 */
840 ptxdesc->txdw0 |= cpu_to_le32(len & 0x0000ffff);
841 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); /*default = 32 bytes for TX Desc */
842 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
843
844 if (bmcst)
845 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
846
847 /*offset 4 */
848 ptxdesc->txdw1 |= cpu_to_le32(0x00);/*MAC_ID */
849
850 ptxdesc->txdw1 |= cpu_to_le32((0x12 << QSEL_SHT) & 0x00001f00);
851
852 ptxdesc->txdw1 |= cpu_to_le32((0x06 << 16) & 0x000f0000); /*b mode */
853
854 /*offset 8 */
855
856 /*offset 12 */
857 ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl) << 16) & 0xffff0000);
858
859 /*offset 16 */
860 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/*driver uses rate */
861
862 /*offset 20 */
863
864
865 /*HW append seq */
866 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); /* Hw set sequence number */
867 ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); /*set bit3 to 1. Suugested by TimChen. 2009.12.29. */
868
869
870 rtl8192cu_cal_txdesc_chksum(ptxdesc);
871 /* ----- end of fill tx desc ----- */
872
873 /* */
874 skb_put(pxmit_skb, len + TXDESC_SIZE);
875 pxmitbuf = pxmitbuf + TXDESC_SIZE;
876 _rtw_memcpy(pxmitbuf, skb->data, len);
877
878 /*RTW_INFO("mgnt_xmit, len=%x\n", pxmit_skb->len); */
879
880
881 /* ----- prepare urb for submit ----- */
882
883 /*translate DMA FIFO addr to pipehandle */
884 /*pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX); */
885 pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX] & 0x0f);
886
887 usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
888 pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
889
890 urb->transfer_flags |= URB_ZERO_PACKET;
891 usb_anchor_urb(urb, &phostapdpriv->anchored);
892 rc = usb_submit_urb(urb, GFP_ATOMIC);
893 if (rc < 0) {
894 usb_unanchor_urb(urb);
895 kfree_skb(skb);
896 }
897 usb_free_urb(urb);
898
899
900 _exit:
901
902 rtw_skb_free(skb);
903
904 #endif
905
906 return 0;
907
908 }
909 #endif
910