1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 *
19 ******************************************************************************/
20 #define _RTL8189ES_XMIT_C_
21
22 #include <drv_types.h>
23 #include <rtl8188e_hal.h>
24
fill_txdesc_sectype(struct pkt_attrib * pattrib,PTXDESC_8188E ptxdesc)25 static void fill_txdesc_sectype(struct pkt_attrib *pattrib, PTXDESC_8188E ptxdesc)
26 {
27 if ((pattrib->encrypt > 0) && !pattrib->bswenc)
28 {
29 switch (pattrib->encrypt)
30 {
31 // SEC_TYPE
32 case _WEP40_:
33 case _WEP104_:
34 case _TKIP_:
35 case _TKIP_WTMIC_:
36 ptxdesc->sectype = 1;
37 break;
38 #ifdef CONFIG_WAPI_SUPPORT
39 case _SMS4_:
40 ptxdesc->sectype = 2;
41 break;
42 #endif
43 case _AES_:
44 ptxdesc->sectype = 3;
45 break;
46
47 case _NO_PRIVACY_:
48 default:
49 break;
50 }
51 }
52 }
53
54
fill_txdesc_vcs(struct pkt_attrib * pattrib,PTXDESC_8188E ptxdesc)55 static void fill_txdesc_vcs(struct pkt_attrib *pattrib, PTXDESC_8188E ptxdesc)
56 {
57 //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
58
59 switch (pattrib->vcs_mode)
60 {
61 case RTS_CTS:
62 ptxdesc->rtsen = 1;
63 break;
64
65 case CTS_TO_SELF:
66 ptxdesc->cts2self = 1;
67 break;
68
69 case NONE_VCS:
70 default:
71 break;
72 }
73
74 if(pattrib->vcs_mode) {
75 ptxdesc->hw_rts_en = 1; // ENABLE HW RTS
76
77 // Set RTS BW
78 if(pattrib->ht_en)
79 {
80 if (pattrib->bwmode & CHANNEL_WIDTH_40)
81 ptxdesc->rts_bw = 1;
82
83 switch (pattrib->ch_offset)
84 {
85 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
86 ptxdesc->rts_sc = 0;
87 break;
88
89 case HAL_PRIME_CHNL_OFFSET_LOWER:
90 ptxdesc->rts_sc = 1;
91 break;
92
93 case HAL_PRIME_CHNL_OFFSET_UPPER:
94 ptxdesc->rts_sc = 2;
95 break;
96
97 default:
98 ptxdesc->rts_sc = 3; // Duplicate
99 break;
100 }
101 }
102 }
103 }
104
fill_txdesc_phy(struct pkt_attrib * pattrib,PTXDESC_8188E ptxdesc)105 static void fill_txdesc_phy(struct pkt_attrib *pattrib, PTXDESC_8188E ptxdesc)
106 {
107 //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
108
109 if (pattrib->ht_en)
110 {
111 if (pattrib->bwmode & CHANNEL_WIDTH_40)
112 ptxdesc->data_bw = 1;
113
114 switch (pattrib->ch_offset)
115 {
116 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
117 ptxdesc->data_sc = 0;
118 break;
119
120 case HAL_PRIME_CHNL_OFFSET_LOWER:
121 ptxdesc->data_sc = 1;
122 break;
123
124 case HAL_PRIME_CHNL_OFFSET_UPPER:
125 ptxdesc->data_sc = 2;
126 break;
127
128 default:
129 ptxdesc->data_sc = 3; // Duplicate
130 break;
131 }
132 }
133 }
134
135 //
136 // Description: In normal chip, we should send some packet to Hw which will be used by Fw
137 // in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
138 // Fw can tell Hw to send these packet derectly.
139 //
rtl8188e_fill_fake_txdesc(PADAPTER padapter,u8 * pDesc,u32 BufferLen,u8 IsPsPoll,u8 IsBTQosNull,u8 bDataFrame)140 void rtl8188e_fill_fake_txdesc(
141 PADAPTER padapter,
142 u8* pDesc,
143 u32 BufferLen,
144 u8 IsPsPoll,
145 u8 IsBTQosNull,
146 u8 bDataFrame)
147 {
148 struct tx_desc *ptxdesc;
149
150
151 // Clear all status
152 ptxdesc = (struct tx_desc*)pDesc;
153 _rtw_memset(pDesc, 0, TXDESC_SIZE);
154
155 //offset 0
156 ptxdesc->txdw0 |= cpu_to_le32( OWN | FSG | LSG); //own, bFirstSeg, bLastSeg;
157
158 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000); //32 bytes for TX Desc
159
160 ptxdesc->txdw0 |= cpu_to_le32(BufferLen&0x0000ffff); // Buffer size + command header
161
162 //offset 4
163 ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT<<QSEL_SHT)&0x00001f00); // Fixed queue of Mgnt queue
164
165 //Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
166 if (IsPsPoll)
167 {
168 ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
169 }
170 else
171 {
172 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
173 ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
174 }
175
176 if (_TRUE == IsBTQosNull)
177 {
178 ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); // BT NULL
179 }
180
181 //offset 16
182 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
183
184 //
185 // Encrypt the data frame if under security mode excepct null data. Suggested by CCW.
186 //
187 if (_TRUE ==bDataFrame)
188 {
189 u32 EncAlg;
190
191 EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
192 switch (EncAlg)
193 {
194 case _NO_PRIVACY_:
195 SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x0);
196 break;
197 case _WEP40_:
198 case _WEP104_:
199 case _TKIP_:
200 SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x1);
201 break;
202 case _SMS4_:
203 SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x2);
204 break;
205 case _AES_:
206 SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x3);
207 break;
208 default:
209 SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x0);
210 break;
211 }
212 }
213
214 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
215 // USB interface drop packet if the checksum of descriptor isn't correct.
216 // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
217 rtl8188e_cal_txdesc_chksum(ptxdesc);
218 #endif
219 }
220
221
222 //#define CONFIG_FIX_CORE_DUMP ==> have bug
223 //#define DBG_EMINFO
224
rtl8188es_fill_default_txdesc(struct xmit_frame * pxmitframe,u8 * pbuf)225 void rtl8188es_fill_default_txdesc(
226 struct xmit_frame *pxmitframe,
227 u8 *pbuf)
228 {
229 PADAPTER padapter;
230 HAL_DATA_TYPE *pHalData;
231 struct mlme_ext_priv *pmlmeext;
232 struct mlme_ext_info *pmlmeinfo;
233 struct pkt_attrib *pattrib;
234 PTXDESC_8188E ptxdesc;
235 s32 bmcst;
236
237
238 padapter = pxmitframe->padapter;
239 pHalData = GET_HAL_DATA(padapter);
240 pmlmeext = &padapter->mlmeextpriv;
241 pmlmeinfo = &(pmlmeext->mlmext_info);
242
243 pattrib = &pxmitframe->attrib;
244 bmcst = IS_MCAST(pattrib->ra);
245
246 ptxdesc = (PTXDESC_8188E)pbuf;
247
248
249 if (pxmitframe->frame_tag == DATA_FRAMETAG)
250 {
251 ptxdesc->macid = pattrib->mac_id; // CAM_ID(MAC_ID)
252
253 if (pattrib->ampdu_en == _TRUE){
254 ptxdesc->agg_en = 1; // AGG EN
255 ptxdesc->ampdu_density = pattrib->ampdu_spacing;
256 }
257 else{
258 ptxdesc->bk = 1; // AGG BK
259 }
260
261 ptxdesc->qsel = pattrib->qsel;
262 ptxdesc->rate_id = pattrib->raid;
263
264 fill_txdesc_sectype(pattrib, ptxdesc);
265
266 ptxdesc->seq = pattrib->seqnum;
267
268 //todo: qos_en
269
270 if ((pattrib->ether_type != 0x888e) &&
271 (pattrib->ether_type != 0x0806) &&
272 (pattrib->dhcp_pkt != 1))
273 {
274 // Non EAP & ARP & DHCP type data packet
275
276 fill_txdesc_vcs(pattrib, ptxdesc);
277 fill_txdesc_phy(pattrib, ptxdesc);
278
279 ptxdesc->rtsrate = 8; // RTS Rate=24M
280 ptxdesc->data_ratefb_lmt = 0x1F;
281 ptxdesc->rts_ratefb_lmt = 0xF;
282
283 #if (RATE_ADAPTIVE_SUPPORT == 1)
284 if(pHalData->fw_ractrl == _FALSE){
285 /* driver-based RA*/
286 ptxdesc->userate = 1; // driver uses rate
287 if (pattrib->ht_en)
288 ptxdesc->sgi = ODM_RA_GetShortGI_8188E(&pHalData->odmpriv,pattrib->mac_id);
289 ptxdesc->datarate = ODM_RA_GetDecisionRate_8188E(&pHalData->odmpriv,pattrib->mac_id);
290
291 #if (POWER_TRAINING_ACTIVE==1)
292 ptxdesc->pwr_status = ODM_RA_GetHwPwrStatus_8188E(&pHalData->odmpriv,pattrib->mac_id);
293 #endif
294 }
295 else
296 #endif /* (RATE_ADAPTIVE_SUPPORT == 1) */
297 {
298 /* FW-based RA, TODO */
299 if(pattrib->ht_en)
300 ptxdesc->sgi = 1;
301
302 ptxdesc->datarate = 0x13; //MCS7
303 }
304
305 if (padapter->fix_rate != 0xFF) {
306 ptxdesc->userate = 1;
307 ptxdesc->datarate = padapter->fix_rate;
308 if (!padapter->data_fb)
309 ptxdesc->disdatafb = 1;
310 ptxdesc->sgi = (padapter->fix_rate & BIT(7))?1:0;
311 }
312 }
313 else
314 {
315 // EAP data packet and ARP and DHCP packet.
316 // Use the 1M or 6M data rate to send the EAP/ARP packet.
317 // This will maybe make the handshake smooth.
318 ptxdesc->userate = 1; // driver uses rate
319 ptxdesc->bk = 1; // AGG BK
320
321 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
322 ptxdesc->data_short = 1;// DATA_SHORT
323
324 ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
325 }
326
327 ptxdesc->usb_txagg_num = pxmitframe->agg_num;
328
329 #ifdef CONFIG_TDLS
330 #ifdef CONFIG_XMIT_ACK
331 /* CCX-TXRPT ack for xmit mgmt frames. */
332 if (pxmitframe->ack_report) {
333 #ifdef DBG_CCX
334 static u16 ccx_sw = 0x123;
335
336 txdesc_set_ccx_sw_88e(ptxdesc, ccx_sw);
337 DBG_871X("%s set ccx, sw:0x%03x\n", __func__, ccx_sw);
338 ccx_sw = (ccx_sw+1)%0xfff;
339 #endif
340 ptxdesc->ccx = 1;
341 }
342 #endif /* CONFIG_XMIT_ACK */
343 #endif
344 }
345 else if (pxmitframe->frame_tag == MGNT_FRAMETAG)
346 {
347 // RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MGNT_FRAMETAG\n", __FUNCTION__));
348 ptxdesc->userate = 1; // driver uses rate
349 ptxdesc->macid = pattrib->mac_id; // CAM_ID(MAC_ID)
350 ptxdesc->qsel = pattrib->qsel;
351 ptxdesc->rate_id = pattrib->raid; // Rate ID
352 ptxdesc->seq = pattrib->seqnum;
353 ptxdesc->userate = 1; // driver uses rate, 1M
354 ptxdesc->rty_lmt_en = 1; // retry limit enable
355 ptxdesc->data_rt_lmt = 6; // retry limit = 6
356
357 #ifdef CONFIG_XMIT_ACK
358 //CCX-TXRPT ack for xmit mgmt frames.
359 if (pxmitframe->ack_report) {
360 #ifdef DBG_CCX
361 static u16 ccx_sw = 0x123;
362 txdesc_set_ccx_sw_88e(ptxdesc, ccx_sw);
363 DBG_871X("%s set ccx, sw:0x%03x\n", __func__, ccx_sw);
364 ccx_sw = (ccx_sw+1)%0xfff;
365 #endif
366 ptxdesc->ccx = 1;
367 }
368 #endif //CONFIG_XMIT_ACK
369
370 #ifdef CONFIG_INTEL_PROXIM
371 if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
372 DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
373 ptxdesc->datarate = pattrib->rate;
374 }
375 else
376 #endif
377 {
378 ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
379 }
380 }
381 else if (pxmitframe->frame_tag == TXAGG_FRAMETAG)
382 {
383 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: TXAGG_FRAMETAG\n", __FUNCTION__));
384 }
385 #ifdef CONFIG_MP_INCLUDED
386 else if (pxmitframe->frame_tag == MP_FRAMETAG)
387 {
388 struct tx_desc *pdesc;
389
390 pdesc = (struct tx_desc*)ptxdesc;
391 RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MP_FRAMETAG\n", __FUNCTION__));
392 fill_txdesc_for_mp(padapter, (u8 *)pdesc);
393
394 pdesc->txdw0 = le32_to_cpu(pdesc->txdw0);
395 pdesc->txdw1 = le32_to_cpu(pdesc->txdw1);
396 pdesc->txdw2 = le32_to_cpu(pdesc->txdw2);
397 pdesc->txdw3 = le32_to_cpu(pdesc->txdw3);
398 pdesc->txdw4 = le32_to_cpu(pdesc->txdw4);
399 pdesc->txdw5 = le32_to_cpu(pdesc->txdw5);
400 pdesc->txdw6 = le32_to_cpu(pdesc->txdw6);
401 pdesc->txdw7 = le32_to_cpu(pdesc->txdw7);
402 }
403 #endif // CONFIG_MP_INCLUDED
404 else
405 {
406 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: frame_tag=0x%x\n", __FUNCTION__, pxmitframe->frame_tag));
407
408 ptxdesc->macid = 4; // CAM_ID(MAC_ID)
409 ptxdesc->rate_id = 6; // Rate ID
410 ptxdesc->seq = pattrib->seqnum;
411 ptxdesc->userate = 1; // driver uses rate
412 ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
413 }
414
415 ptxdesc->pktlen = pattrib->last_txcmdsz;
416 if (pxmitframe->frame_tag == DATA_FRAMETAG){
417 #ifdef CONFIG_TX_EARLY_MODE
418 ptxdesc->offset = TXDESC_SIZE +EARLY_MODE_INFO_SIZE ;
419 ptxdesc->pkt_offset = 0x01;
420 #else
421 ptxdesc->offset = TXDESC_SIZE ;
422 ptxdesc->pkt_offset = 0;
423 #endif
424 }
425 else{
426 ptxdesc->offset = TXDESC_SIZE ;
427 }
428
429 if (bmcst) ptxdesc->bmc = 1;
430 ptxdesc->ls = 1;
431 ptxdesc->fs = 1;
432 ptxdesc->own = 1;
433
434 // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
435 // (1) The sequence number of each non-Qos frame / broadcast / multicast /
436 // mgnt frame should be controled by Hw because Fw will also send null data
437 // which we cannot control when Fw LPS enable.
438 // --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
439 // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
440 // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
441 // 2010.06.23. Added by tynli.
442 if (!pattrib->qos_en)
443 {
444 // Hw set sequence number
445 ptxdesc->hwseq_en = 1; // HWSEQ_EN
446 ptxdesc->hwseq_sel = 0; // HWSEQ_SEL
447 }
448
449 }
450
451 /*
452 * Description:
453 *
454 * Parameters:
455 * pxmitframe xmitframe
456 * pbuf where to fill tx desc
457 */
rtl8188es_update_txdesc(struct xmit_frame * pxmitframe,u8 * pbuf)458 void rtl8188es_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
459 {
460 struct tx_desc *pdesc;
461
462
463 pdesc = (struct tx_desc*)pbuf;
464 _rtw_memset(pdesc, 0, sizeof(struct tx_desc));
465
466 rtl8188es_fill_default_txdesc(pxmitframe, pbuf);
467
468 pdesc->txdw0 = cpu_to_le32(pdesc->txdw0);
469 pdesc->txdw1 = cpu_to_le32(pdesc->txdw1);
470 pdesc->txdw2 = cpu_to_le32(pdesc->txdw2);
471 pdesc->txdw3 = cpu_to_le32(pdesc->txdw3);
472 pdesc->txdw4 = cpu_to_le32(pdesc->txdw4);
473 pdesc->txdw5 = cpu_to_le32(pdesc->txdw5);
474 pdesc->txdw6 = cpu_to_le32(pdesc->txdw6);
475 pdesc->txdw7 = cpu_to_le32(pdesc->txdw7);
476
477 rtl8188e_cal_txdesc_chksum(pdesc);
478 }
479
rtw_sdio_wait_enough_TxOQT_space(PADAPTER padapter,u8 agg_num)480 static u8 rtw_sdio_wait_enough_TxOQT_space(PADAPTER padapter, u8 agg_num)
481 {
482 u32 n = 0;
483 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
484
485 while (pHalData->SdioTxOQTFreeSpace < agg_num)
486 {
487 if (RTW_CANNOT_RUN(padapter)) {
488 DBG_871X("%s: bSurpriseRemoved or bDriverStopped (wait TxOQT)\n", __func__);
489 return _FALSE;
490 }
491
492 HalQueryTxOQTBufferStatus8189ESdio(padapter);
493
494 if ((++n % 60) == 0) {
495 if ((n % 300) == 0) {
496 DBG_871X("%s(%d): QOT free space(%d), agg_num: %d\n",
497 __func__, n, pHalData->SdioTxOQTFreeSpace, agg_num);
498 }
499 rtw_msleep_os(1);
500 //yield();
501 }
502 }
503
504 pHalData->SdioTxOQTFreeSpace -= agg_num;
505
506 //if (n > 1)
507 // ++priv->pshare->nr_out_of_txoqt_space;
508
509 return _TRUE;
510 }
511
512 //todo: static
rtl8188es_dequeue_writeport(PADAPTER padapter)513 s32 rtl8188es_dequeue_writeport(PADAPTER padapter)
514 {
515 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
516 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
517 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
518 struct xmit_buf *pxmitbuf;
519 u8 PageIdx = 0;
520 u32 deviceId;
521 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
522 u8 bUpdatePageNum = _FALSE;
523 #else
524 u32 polling_num = 0;
525 #endif
526
527 if (rtw_xmit_ac_blocked(padapter) == _TRUE)
528 pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv);
529 else
530 pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
531
532 if (pxmitbuf == NULL) {
533 return _TRUE;
534 }
535
536 deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr);
537
538 // translate fifo addr to queue index
539 switch (deviceId) {
540 case WLAN_TX_HIQ_DEVICE_ID:
541 PageIdx = HI_QUEUE_IDX;
542 break;
543
544 case WLAN_TX_MIQ_DEVICE_ID:
545 PageIdx = MID_QUEUE_IDX;
546 break;
547
548 case WLAN_TX_LOQ_DEVICE_ID:
549 PageIdx = LOW_QUEUE_IDX;
550 break;
551 }
552
553 query_free_page:
554 /* check if hardware tx fifo page is enough */
555 if (_FALSE == rtw_hal_sdio_query_tx_freepage(padapter, PageIdx, pxmitbuf->pg_num)) {
556 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
557 if (!bUpdatePageNum) {
558 // Total number of page is NOT available, so update current FIFO status
559 HalQueryTxBufferStatus8189ESdio(padapter);
560 bUpdatePageNum = _TRUE;
561 goto query_free_page;
562 } else {
563 bUpdatePageNum = _FALSE;
564 enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf);
565 return _TRUE;
566 }
567 #else //CONFIG_SDIO_TX_ENABLE_AVAL_INT
568 polling_num++;
569 if ((polling_num % 10) == 0) {//or 80
570 //DBG_871X("%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n",
571 // __func__, n, pxmitbuf->len, pxmitbuf->agg_num, pframe->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]);
572 enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf);
573 rtw_usleep_os(50);
574 return _FALSE;
575
576 }
577
578 // Total number of page is NOT available, so update current FIFO status
579 HalQueryTxBufferStatus8189ESdio(padapter);
580 goto query_free_page;
581 #endif //CONFIG_SDIO_TX_ENABLE_AVAL_INT
582 }
583
584 if (RTW_CANNOT_RUN(padapter)) {
585 RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
586 ("%s: bSurpriseRemoved(wirte port)\n", __FUNCTION__));
587 goto free_xmitbuf;
588 }
589
590 if (rtw_sdio_wait_enough_TxOQT_space(padapter, pxmitbuf->agg_num) == _FALSE)
591 {
592 goto free_xmitbuf;
593 }
594
595 rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8 *)pxmitbuf);
596
597 rtw_hal_sdio_update_tx_freepage(padapter, PageIdx, pxmitbuf->pg_num);
598
599 free_xmitbuf:
600 //rtw_free_xmitframe(pxmitpriv, pframe);
601 //pxmitbuf->priv_data = NULL;
602 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
603
604 #ifdef CONFIG_SDIO_TX_TASKLET
605 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
606 #endif
607
608 return _FAIL;
609 }
610
611 /*
612 * Description
613 * Transmit xmitbuf to hardware tx fifo
614 *
615 * Return
616 * _SUCCESS ok
617 * _FAIL something error
618 */
rtl8188es_xmit_buf_handler(PADAPTER padapter)619 s32 rtl8188es_xmit_buf_handler(PADAPTER padapter)
620 {
621 struct dvobj_priv *psdpriv = padapter->dvobj;
622 struct xmit_priv *pxmitpriv;
623 u8 queue_empty, queue_pending;
624 s32 ret;
625 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
626
627
628 pxmitpriv = &padapter->xmitpriv;
629
630 ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
631 if (ret == _FAIL) {
632 RT_TRACE(_module_hal_xmit_c_, _drv_emerg_, ("down SdioXmitBufSema fail!\n"));
633 return _FAIL;
634 }
635
636 if (RTW_CANNOT_RUN(padapter)) {
637 RT_TRACE(_module_hal_xmit_c_, _drv_notice_
638 , ("%s: bDriverStopped(%s) bSurpriseRemoved(%s)\n"
639 , __func__
640 , rtw_is_drv_stopped(padapter)?"True":"False"
641 , rtw_is_surprise_removed(padapter)?"True":"False"));
642 return _FAIL;
643 }
644
645 queue_pending = check_pending_xmitbuf(pxmitpriv);
646
647 #ifdef CONFIG_CONCURRENT_MODE
648 if(rtw_buddy_adapter_up(padapter))
649 queue_pending |= check_pending_xmitbuf(&padapter->pbuddy_adapter->xmitpriv);
650 #endif
651
652 if(queue_pending == _FALSE)
653 return _SUCCESS;
654
655 #ifdef CONFIG_LPS_LCLK
656 ret = rtw_register_tx_alive(padapter);
657 if (ret != _SUCCESS) return _SUCCESS;
658 #endif
659
660 do {
661 if (psdpriv->processing_dev_remove == _TRUE)
662 break;
663
664 queue_empty = rtl8188es_dequeue_writeport(padapter);
665 // dump secondary adapter xmitbuf
666 #ifdef CONFIG_CONCURRENT_MODE
667 if(rtw_buddy_adapter_up(padapter))
668 queue_empty &= rtl8188es_dequeue_writeport(padapter->pbuddy_adapter);
669 #endif
670
671 } while (!queue_empty);
672
673 #ifdef CONFIG_LPS_LCLK
674 rtw_unregister_tx_alive(padapter);
675 #endif
676 return _SUCCESS;
677 }
678
679 #if 0
680 /*
681 * Description:
682 * Aggregation packets and send to hardware
683 *
684 * Return:
685 * 0 Success
686 * -1 Hardware resource(TX FIFO) not ready
687 * -2 Software resource(xmitbuf) not ready
688 */
689 #ifdef CONFIG_TX_EARLY_MODE
690 #if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
691 #define EARLY_MODE_MAX_PKT_NUM 10
692 #else
693 #define EARLY_MODE_MAX_PKT_NUM 5
694 #endif
695
696
697 struct EMInfo{
698 u8 EMPktNum;
699 u16 EMPktLen[EARLY_MODE_MAX_PKT_NUM];
700 };
701
702
703 void
704 InsertEMContent_8188E(
705 struct EMInfo *pEMInfo,
706 IN pu1Byte VirtualAddress)
707 {
708
709 #if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
710 u1Byte index=0;
711 u4Byte dwtmp=0;
712 #endif
713
714 _rtw_memset(VirtualAddress, 0, EARLY_MODE_INFO_SIZE);
715 if(pEMInfo->EMPktNum==0)
716 return;
717
718 #ifdef DBG_EMINFO
719 {
720 int i;
721 DBG_8192C("\n%s ==> pEMInfo->EMPktNum =%d\n",__FUNCTION__,pEMInfo->EMPktNum);
722 for(i=0;i< EARLY_MODE_MAX_PKT_NUM;i++){
723 DBG_8192C("%s ==> pEMInfo->EMPktLen[%d] =%d\n",__FUNCTION__,i,pEMInfo->EMPktLen[i]);
724 }
725
726 }
727 #endif
728
729 #if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
730 SET_EARLYMODE_PKTNUM(VirtualAddress, pEMInfo->EMPktNum);
731
732 if(pEMInfo->EMPktNum == 1){
733 dwtmp = pEMInfo->EMPktLen[0];
734 }else{
735 dwtmp = pEMInfo->EMPktLen[0];
736 dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
737 dwtmp += pEMInfo->EMPktLen[1];
738 }
739 SET_EARLYMODE_LEN0(VirtualAddress, dwtmp);
740 if(pEMInfo->EMPktNum <= 3){
741 dwtmp = pEMInfo->EMPktLen[2];
742 }else{
743 dwtmp = pEMInfo->EMPktLen[2];
744 dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
745 dwtmp += pEMInfo->EMPktLen[3];
746 }
747 SET_EARLYMODE_LEN1(VirtualAddress, dwtmp);
748 if(pEMInfo->EMPktNum <= 5){
749 dwtmp = pEMInfo->EMPktLen[4];
750 }else{
751 dwtmp = pEMInfo->EMPktLen[4];
752 dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
753 dwtmp += pEMInfo->EMPktLen[5];
754 }
755 SET_EARLYMODE_LEN2_1(VirtualAddress, dwtmp&0xF);
756 SET_EARLYMODE_LEN2_2(VirtualAddress, dwtmp>>4);
757 if(pEMInfo->EMPktNum <= 7){
758 dwtmp = pEMInfo->EMPktLen[6];
759 }else{
760 dwtmp = pEMInfo->EMPktLen[6];
761 dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
762 dwtmp += pEMInfo->EMPktLen[7];
763 }
764 SET_EARLYMODE_LEN3(VirtualAddress, dwtmp);
765 if(pEMInfo->EMPktNum <= 9){
766 dwtmp = pEMInfo->EMPktLen[8];
767 }else{
768 dwtmp = pEMInfo->EMPktLen[8];
769 dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
770 dwtmp += pEMInfo->EMPktLen[9];
771 }
772 SET_EARLYMODE_LEN4(VirtualAddress, dwtmp);
773 #else
774 SET_EARLYMODE_PKTNUM(VirtualAddress, pEMInfo->EMPktNum);
775 SET_EARLYMODE_LEN0(VirtualAddress, pEMInfo->EMPktLen[0]);
776 SET_EARLYMODE_LEN1(VirtualAddress, pEMInfo->EMPktLen[1]);
777 SET_EARLYMODE_LEN2_1(VirtualAddress, pEMInfo->EMPktLen[2]&0xF);
778 SET_EARLYMODE_LEN2_2(VirtualAddress, pEMInfo->EMPktLen[2]>>4);
779 SET_EARLYMODE_LEN3(VirtualAddress, pEMInfo->EMPktLen[3]);
780 SET_EARLYMODE_LEN4(VirtualAddress, pEMInfo->EMPktLen[4]);
781 #endif
782 //RT_PRINT_DATA(COMP_SEND, DBG_LOUD, "EMHdr:", VirtualAddress, 8);
783
784 }
785
786
787
788 void UpdateEarlyModeInfo8188E(struct xmit_priv *pxmitpriv,struct xmit_buf *pxmitbuf )
789 {
790 //_adapter *padapter, struct xmit_frame *pxmitframe,struct tx_servq *ptxservq
791 int index,j;
792 u16 offset,pktlen;
793 PTXDESC_8188E ptxdesc;
794
795 u8 *pmem,*pEMInfo_mem;
796 s8 node_num_0=0,node_num_1=0;
797 struct EMInfo eminfo;
798 struct agg_pkt_info *paggpkt;
799 struct xmit_frame *pframe = (struct xmit_frame*)pxmitbuf->priv_data;
800 pmem= pframe->buf_addr;
801
802 #ifdef DBG_EMINFO
803 DBG_8192C("\n%s ==> agg_num:%d\n",__FUNCTION__, pframe->agg_num);
804 for(index=0;index<pframe->agg_num;index++){
805 offset = pxmitpriv->agg_pkt[index].offset;
806 pktlen = pxmitpriv->agg_pkt[index].pkt_len;
807 DBG_8192C("%s ==> agg_pkt[%d].offset=%d\n",__FUNCTION__,index,offset);
808 DBG_8192C("%s ==> agg_pkt[%d].pkt_len=%d\n",__FUNCTION__,index,pktlen);
809 }
810 #endif
811
812 if( pframe->agg_num > EARLY_MODE_MAX_PKT_NUM)
813 {
814 node_num_0 = pframe->agg_num;
815 node_num_1= EARLY_MODE_MAX_PKT_NUM-1;
816 }
817
818 for(index=0;index<pframe->agg_num;index++){
819 offset = pxmitpriv->agg_pkt[index].offset;
820 pktlen = pxmitpriv->agg_pkt[index].pkt_len;
821
822 _rtw_memset(&eminfo,0,sizeof(struct EMInfo));
823 if( pframe->agg_num > EARLY_MODE_MAX_PKT_NUM){
824 if(node_num_0 > EARLY_MODE_MAX_PKT_NUM){
825 eminfo.EMPktNum = EARLY_MODE_MAX_PKT_NUM;
826 node_num_0--;
827 }
828 else{
829 eminfo.EMPktNum = node_num_1;
830 node_num_1--;
831 }
832 }
833 else{
834 eminfo.EMPktNum = pframe->agg_num-(index+1);
835 }
836 for(j=0;j< eminfo.EMPktNum ;j++){
837 eminfo.EMPktLen[j] = pxmitpriv->agg_pkt[index+1+j].pkt_len+4;//CRC
838 }
839
840 if(pmem){
841 ptxdesc = (PTXDESC_8188E)(pmem+offset);
842 pEMInfo_mem = pmem+offset+TXDESC_SIZE;
843 #ifdef DBG_EMINFO
844 DBG_8192C("%s ==> desc.pkt_len=%d\n",__FUNCTION__,ptxdesc->pktlen);
845 #endif
846 InsertEMContent_8188E(&eminfo,pEMInfo_mem);
847 }
848
849
850 }
851 _rtw_memset(pxmitpriv->agg_pkt,0,sizeof(struct agg_pkt_info)*MAX_AGG_PKT_NUM);
852
853 }
854 #endif
855
856 #endif
857
858 #ifdef CONFIG_SDIO_TX_TASKLET
xmit_xmitframes(PADAPTER padapter,struct xmit_priv * pxmitpriv)859 static s32 xmit_xmitframes(PADAPTER padapter, struct xmit_priv *pxmitpriv)
860 {
861 s32 ret;
862 _irqL irqL;
863 struct xmit_buf *pxmitbuf;
864 struct hw_xmit *phwxmit = pxmitpriv->hwxmits;
865 struct tx_servq *ptxservq = NULL;
866 _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
867 struct xmit_frame *pxmitframe = NULL, *pfirstframe = NULL;
868 u32 pbuf = 0; // next pkt address
869 u32 pbuf_tail = 0; // last pkt tail
870 u32 txlen = 0; //packet length, except TXDESC_SIZE and PKT_OFFSET
871 u32 total_len = 0, max_xmit_len = 0;
872 u8 ac_index = 0;
873 u8 bfirst = _TRUE;//first aggregation xmitframe
874 u8 bulkstart = _FALSE;
875 #ifdef CONFIG_TX_EARLY_MODE
876 u8 pkt_index=0;
877 #endif
878
879 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
880 if (pxmitbuf == NULL) {
881 RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: xmit_buf is not enough!\n", __FUNCTION__));
882 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
883 #ifdef CONFIG_CONCURRENT_MODE
884 if (padapter->adapter_type > PRIMARY_ADAPTER)
885 _rtw_up_sema(&(padapter->pbuddy_adapter->xmitpriv.xmit_sema));
886 else
887 #endif
888 _rtw_up_sema(&(pxmitpriv->xmit_sema));
889 #endif
890 return _FALSE;
891 }
892
893 do {
894 //3 1. pick up first frame
895 if(bfirst)
896 {
897 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
898 if (pxmitframe == NULL) {
899 // no more xmit frame, release xmit buffer
900 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
901 return _FALSE;
902 }
903
904 pxmitframe->pxmitbuf = pxmitbuf;
905 pxmitframe->buf_addr = pxmitbuf->pbuf;
906 pxmitbuf->priv_data = pxmitframe;
907 pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
908
909 pfirstframe = pxmitframe;
910
911 max_xmit_len = rtw_hal_get_sdio_tx_max_length(padapter, pxmitbuf->ff_hwaddr);
912
913 _enter_critical_bh(&pxmitpriv->lock, &irqL);
914 ptxservq = rtw_get_sta_pending(padapter, pfirstframe->attrib.psta, pfirstframe->attrib.priority, (u8 *)(&ac_index));
915 _exit_critical_bh(&pxmitpriv->lock, &irqL);
916 }
917 //3 2. aggregate same priority and same DA(AP or STA) frames
918 else
919 {
920 // dequeue same priority packet from station tx queue
921 _enter_critical_bh(&pxmitpriv->lock, &irqL);
922
923 if (_rtw_queue_empty(&ptxservq->sta_pending) == _FALSE)
924 {
925 xmitframe_phead = get_list_head(&ptxservq->sta_pending);
926 xmitframe_plist = get_next(xmitframe_phead);
927
928 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
929
930 if(_FAIL == rtw_hal_busagg_qsel_check(padapter,pfirstframe->attrib.qsel,pxmitframe->attrib.qsel)){
931 bulkstart = _TRUE;
932 }
933 else{
934 // check xmit_buf size enough or not
935 txlen = TXDESC_SIZE +
936 #ifdef CONFIG_TX_EARLY_MODE
937 EARLY_MODE_INFO_SIZE +
938 #endif
939 rtw_wlan_pkt_size(pxmitframe);
940
941 if ((pbuf + txlen) > max_xmit_len)
942 {
943 bulkstart = _TRUE;
944 }
945 else
946 {
947 rtw_list_delete(&pxmitframe->list);
948 ptxservq->qcnt--;
949 phwxmit[ac_index].accnt--;
950
951 //Remove sta node when there is no pending packets.
952 if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
953 rtw_list_delete(&ptxservq->tx_pending);
954 }
955 }
956 }
957 else
958 {
959 bulkstart = _TRUE;
960 }
961
962 _exit_critical_bh(&pxmitpriv->lock, &irqL);
963
964 if(bulkstart)
965 {
966 break;
967 }
968
969 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
970
971 pxmitframe->agg_num = 0; // not first frame of aggregation
972 }
973
974 ret = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
975 if (ret == _FAIL) {
976 DBG_871X("%s: coalesce FAIL!", __FUNCTION__);
977 rtw_free_xmitframe(pxmitpriv, pxmitframe);
978 continue;
979 }
980
981 // always return ndis_packet after rtw_xmitframe_coalesce
982 //rtw_os_xmit_complete(padapter, pxmitframe);
983
984 #ifdef CONFIG_TX_EARLY_MODE
985 pxmitpriv->agg_pkt[pkt_index].pkt_len = pxmitframe->attrib.last_txcmdsz; //get from rtw_xmitframe_coalesce
986 pxmitpriv->agg_pkt[pkt_index].offset = _RND8(pxmitframe->attrib.last_txcmdsz+ TXDESC_SIZE+EARLY_MODE_INFO_SIZE);
987 pkt_index++;
988 #endif
989
990 if(bfirst)
991 {
992 txlen = TXDESC_SIZE +
993 #ifdef CONFIG_TX_EARLY_MODE
994 EARLY_MODE_INFO_SIZE +
995 #endif
996 pxmitframe->attrib.last_txcmdsz;
997
998 total_len = txlen;
999
1000 pxmitframe->pg_num = (txlen + 127)/128;
1001 pxmitbuf->pg_num = (txlen + 127)/128;
1002 pbuf_tail = txlen;
1003 pbuf = _RND8(pbuf_tail);
1004 bfirst = _FALSE;
1005 }
1006 else
1007 {
1008 rtl8188es_update_txdesc(pxmitframe, pxmitframe->buf_addr);
1009
1010 // don't need xmitframe any more
1011 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1012
1013 pxmitframe->pg_num = (txlen + 127)/128;
1014 //pfirstframe->pg_num += pxmitframe->pg_num;
1015 pxmitbuf->pg_num += (txlen + 127)/128;
1016
1017 total_len += txlen;
1018
1019 // handle pointer and stop condition
1020 pbuf_tail = pbuf + txlen;
1021 pbuf = _RND8(pbuf_tail);
1022
1023 pfirstframe->agg_num++;
1024 if(pfirstframe->agg_num >= (rtw_hal_sdio_max_txoqt_free_space(padapter)-1))
1025 break;
1026
1027 }
1028 }while(1);
1029
1030 //3 3. update first frame txdesc
1031 rtl8188es_update_txdesc(pfirstframe, pfirstframe->buf_addr);
1032 #ifdef CONFIG_TX_EARLY_MODE
1033 UpdateEarlyModeInfo8188E(pxmitpriv,pxmitbuf );
1034 #endif
1035
1036 //
1037 pxmitbuf->agg_num = pfirstframe->agg_num;
1038 pxmitbuf->priv_data = NULL;
1039
1040 //3 4. write xmit buffer to USB FIFO
1041 pxmitbuf->len = pbuf_tail;
1042 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
1043
1044 //3 5. update statisitc
1045 rtw_count_tx_stats(padapter, pfirstframe, total_len);
1046
1047 rtw_free_xmitframe(pxmitpriv, pfirstframe);
1048
1049 //rtw_yield_os();
1050
1051 return _TRUE;
1052 }
1053
rtl8188es_xmit_tasklet(void * priv)1054 void rtl8188es_xmit_tasklet(void *priv)
1055 {
1056 int ret = _FALSE;
1057 _adapter *padapter = (_adapter*)priv;
1058 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1059
1060 while(1)
1061 {
1062 if (RTW_CANNOT_TX(padapter))
1063 {
1064 DBG_871X("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n");
1065 break;
1066 }
1067
1068 ret = xmit_xmitframes(padapter, pxmitpriv);
1069 if(ret==_FALSE)
1070 break;
1071
1072 }
1073 }
1074 #else
xmit_xmitframes(PADAPTER padapter,struct xmit_priv * pxmitpriv)1075 static s32 xmit_xmitframes(PADAPTER padapter, struct xmit_priv *pxmitpriv)
1076 {
1077 s32 err, agg_num = 0;
1078 u8 pkt_index=0;
1079 struct hw_xmit *hwxmits, *phwxmit;
1080 u8 idx, hwentry;
1081 _irqL irql;
1082 struct tx_servq *ptxservq;
1083 _list *sta_plist, *sta_phead, *frame_plist, *frame_phead;
1084 struct xmit_frame *pxmitframe;
1085 _queue *pframe_queue;
1086 struct xmit_buf *pxmitbuf;
1087 u32 txlen, max_xmit_len, page_size;
1088 s32 ret;
1089 int inx[4];
1090 u8 pre_qsel=0xFF,next_qsel=0xFF;
1091 u8 single_sta_in_queue = _FALSE;
1092
1093 err = 0;
1094 hwxmits = pxmitpriv->hwxmits;
1095 hwentry = pxmitpriv->hwxmit_entry;
1096 ptxservq = NULL;
1097 pxmitframe = NULL;
1098 pframe_queue = NULL;
1099 pxmitbuf = NULL;
1100
1101 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
1102
1103 if (padapter->registrypriv.wifi_spec == 1) {
1104 for(idx=0; idx<4; idx++)
1105 inx[idx] = pxmitpriv->wmm_para_seq[idx];
1106 } else {
1107 inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
1108 }
1109
1110 // 0(VO), 1(VI), 2(BE), 3(BK)
1111 for (idx = 0; idx < hwentry; idx++)
1112 {
1113 phwxmit = hwxmits + inx[idx];
1114
1115 if((check_pending_xmitbuf(pxmitpriv) == _TRUE) && (padapter->mlmepriv.LinkDetectInfo.bHigherBusyTxTraffic == _TRUE)) {
1116 if ((phwxmit->accnt > 0) && (phwxmit->accnt < 5)) {
1117 err = -2;
1118 break;
1119 }
1120 }
1121
1122 max_xmit_len = rtw_hal_get_sdio_tx_max_length(padapter, inx[idx]);
1123
1124 // _enter_critical(&hwxmits->sta_queue->lock, &irqL0);
1125 _enter_critical_bh(&pxmitpriv->lock, &irql);
1126
1127 sta_phead = get_list_head(phwxmit->sta_queue);
1128 sta_plist = get_next(sta_phead);
1129
1130 single_sta_in_queue = rtw_end_of_queue_search(sta_phead, get_next(sta_plist));
1131
1132 while (rtw_end_of_queue_search(sta_phead, sta_plist) == _FALSE)
1133 {
1134 ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
1135
1136 sta_plist = get_next(sta_plist);
1137
1138 pframe_queue = &ptxservq->sta_pending;
1139
1140 // _enter_critical(&pframe_queue->lock, &irqL1);
1141 //_enter_critical_bh(&pxmitpriv->lock, &irql);
1142
1143 frame_phead = get_list_head(pframe_queue);
1144
1145 while (rtw_is_list_empty(frame_phead) == _FALSE)
1146 {
1147 frame_plist = get_next(frame_phead);
1148 pxmitframe = LIST_CONTAINOR(frame_plist, struct xmit_frame, list);
1149
1150 // check xmit_buf size enough or not
1151 #ifdef CONFIG_TX_EARLY_MODE
1152 txlen = TXDESC_SIZE +EARLY_MODE_INFO_SIZE+ rtw_wlan_pkt_size(pxmitframe);
1153 #else
1154 txlen = TXDESC_SIZE + rtw_wlan_pkt_size(pxmitframe);
1155 #endif
1156
1157 next_qsel = pxmitframe->attrib.qsel;
1158
1159 if ((NULL == pxmitbuf) ||
1160 (pxmitbuf->pg_num + PageNum(txlen, page_size) > PageNum(max_xmit_len, page_size))
1161 || (agg_num>= (rtw_hal_sdio_max_txoqt_free_space(padapter)-1))
1162 || ((agg_num!=0) && (_FAIL == rtw_hal_busagg_qsel_check(padapter,pre_qsel,next_qsel)))
1163 )
1164 {
1165 if (pxmitbuf) {
1166 //pxmitbuf->priv_data will be NULL, and will crash here
1167 if (pxmitbuf->len > 0 && pxmitbuf->priv_data)
1168 {
1169 struct xmit_frame *pframe;
1170 pframe = (struct xmit_frame*)pxmitbuf->priv_data;
1171 pframe->agg_num = agg_num;
1172 pxmitbuf->agg_num = agg_num;
1173 //DBG_8192C("==> agg_num:%d\n",agg_num);
1174 rtl8188es_update_txdesc(pframe, pframe->buf_addr);
1175 #ifdef CONFIG_TX_EARLY_MODE
1176 UpdateEarlyModeInfo8188E(pxmitpriv, pxmitbuf);
1177 #endif
1178 rtw_free_xmitframe(pxmitpriv, pframe);
1179 pxmitbuf->priv_data = NULL;
1180 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
1181
1182 //rtw_yield_os();
1183 if (single_sta_in_queue == _FALSE) {
1184 /* break the loop in case there is more than one sta in this ac queue */
1185 pxmitbuf = NULL;
1186 err = -3;
1187 break;
1188 }
1189
1190 } else {
1191 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
1192 }
1193 }
1194
1195 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
1196 if (pxmitbuf == NULL) {
1197 RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: xmit_buf is not enough!\n", __FUNCTION__));
1198 err = -2;
1199 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
1200 #ifdef CONFIG_CONCURRENT_MODE
1201 if (padapter->adapter_type > PRIMARY_ADAPTER)
1202 _rtw_up_sema(&(padapter->pbuddy_adapter->xmitpriv.xmit_sema));
1203 else
1204 #endif
1205 _rtw_up_sema(&(pxmitpriv->xmit_sema));
1206 #endif
1207 break;
1208 }
1209 agg_num = 0;
1210 pkt_index =0;
1211 }
1212
1213 // ok to send, remove frame from queue
1214 rtw_list_delete(&pxmitframe->list);
1215 ptxservq->qcnt--;
1216 phwxmit->accnt--;
1217
1218 if (agg_num == 0) {
1219 pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
1220 pxmitbuf->priv_data = (u8*)pxmitframe;
1221 }
1222
1223 // coalesce the xmitframe to xmitbuf
1224 pxmitframe->pxmitbuf = pxmitbuf;
1225 pxmitframe->buf_addr = pxmitbuf->ptail;
1226
1227 ret = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
1228 if (ret == _FAIL) {
1229 DBG_871X("%s: coalesce FAIL!", __FUNCTION__);
1230 // Todo: error handler
1231 //rtw_free_xmitframe(pxmitpriv, pxmitframe);
1232 } else {
1233 agg_num++;
1234 if (agg_num != 1)
1235 rtl8188es_update_txdesc(pxmitframe, pxmitframe->buf_addr);
1236 pre_qsel = pxmitframe->attrib.qsel;
1237 rtw_count_tx_stats(padapter, pxmitframe, pxmitframe->attrib.last_txcmdsz);
1238 #ifdef CONFIG_TX_EARLY_MODE
1239 txlen = TXDESC_SIZE+ EARLY_MODE_INFO_SIZE+ pxmitframe->attrib.last_txcmdsz;
1240 #else
1241 txlen = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
1242 #endif
1243 pxmitframe->pg_num = (txlen + 127)/128;
1244 pxmitbuf->pg_num += (txlen + 127)/128;
1245 //if (agg_num != 1)
1246 //((struct xmit_frame*)pxmitbuf->priv_data)->pg_num += pxmitframe->pg_num;
1247
1248 #ifdef CONFIG_TX_EARLY_MODE
1249 pxmitpriv->agg_pkt[pkt_index].pkt_len = pxmitframe->attrib.last_txcmdsz; //get from rtw_xmitframe_coalesce
1250 pxmitpriv->agg_pkt[pkt_index].offset = _RND8(pxmitframe->attrib.last_txcmdsz+ TXDESC_SIZE+EARLY_MODE_INFO_SIZE);
1251 #endif
1252
1253 pkt_index++;
1254 pxmitbuf->ptail += _RND(txlen, 8); // round to 8 bytes alignment
1255 pxmitbuf->len = _RND(pxmitbuf->len, 8) + txlen;
1256 }
1257
1258 if (agg_num != 1)
1259 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1260 pxmitframe = NULL;
1261 }
1262
1263 if (_rtw_queue_empty(pframe_queue) == _TRUE)
1264 rtw_list_delete(&ptxservq->tx_pending);
1265 else if (err == -3) {
1266 /* Re-arrange the order of stations in this ac queue to balance the service for these stations */
1267 rtw_list_delete(&ptxservq->tx_pending);
1268 rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmit->sta_queue));
1269 }
1270
1271 if (err) break;
1272 }
1273 _exit_critical_bh(&pxmitpriv->lock, &irql);
1274
1275 // dump xmit_buf to hw tx fifo
1276 if (pxmitbuf)
1277 {
1278 RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("pxmitbuf->len=%d enqueue\n",pxmitbuf->len));
1279
1280 if (pxmitbuf->len > 0) {
1281 struct xmit_frame *pframe;
1282 pframe = (struct xmit_frame*)pxmitbuf->priv_data;
1283 pframe->agg_num = agg_num;
1284 pxmitbuf->agg_num = agg_num;
1285 rtl8188es_update_txdesc(pframe, pframe->buf_addr);
1286 #ifdef CONFIG_TX_EARLY_MODE
1287 UpdateEarlyModeInfo8188E(pxmitpriv,pxmitbuf );
1288 #endif
1289 rtw_free_xmitframe(pxmitpriv, pframe);
1290 pxmitbuf->priv_data = NULL;
1291 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
1292 rtw_yield_os();
1293 }
1294 else
1295 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
1296
1297 pxmitbuf = NULL;
1298 }
1299
1300 if (err == -2)
1301 break;
1302 }
1303
1304 return err;
1305
1306 }
1307
1308 /*
1309 * Description
1310 * Transmit xmitframe from queue
1311 *
1312 * Return
1313 * _SUCCESS ok
1314 * _FAIL something error
1315 */
rtl8188es_xmit_handler(PADAPTER padapter)1316 s32 rtl8188es_xmit_handler(PADAPTER padapter)
1317 {
1318 struct xmit_priv *pxmitpriv = &padapter->xmitpriv ;
1319 s32 ret;
1320 _irqL irql;
1321
1322 wait:
1323 ret = _rtw_down_sema(&pxmitpriv->SdioXmitSema);
1324 if (_FAIL == ret) {
1325 RT_TRACE(_module_hal_xmit_c_, _drv_emerg_, ("%s: down sema fail!\n", __FUNCTION__));
1326 return _FAIL;
1327 }
1328
1329 next:
1330
1331 if (RTW_CANNOT_RUN(padapter)) {
1332 RT_TRACE(_module_hal_xmit_c_, _drv_notice_
1333 , ("%s: bDriverStopped(%s) bSurpriseRemoved(%s)\n"
1334 , __func__
1335 , rtw_is_drv_stopped(padapter)?"True":"False"
1336 , rtw_is_surprise_removed(padapter)?"True":"False"));
1337 return _FAIL;
1338 }
1339 _enter_critical_bh(&pxmitpriv->lock, &irql);
1340 ret = rtw_txframes_pending(padapter);
1341 _exit_critical_bh(&pxmitpriv->lock, &irql);
1342 if (ret == 0) {
1343 return _SUCCESS;
1344 }
1345 // dequeue frame and write to hardware
1346
1347 ret = xmit_xmitframes(padapter, pxmitpriv);
1348 if (ret == -2) {
1349 #ifdef CONFIG_REDUCE_TX_CPU_LOADING
1350 rtw_msleep_os(1);
1351 #else
1352 rtw_yield_os();
1353 #endif
1354 goto next;
1355 }
1356 _enter_critical_bh(&pxmitpriv->lock, &irql);
1357 ret = rtw_txframes_pending(padapter);
1358 _exit_critical_bh(&pxmitpriv->lock, &irql);
1359 if (ret == 1) {
1360 #ifdef CONFIG_REDUCE_TX_CPU_LOADING
1361 rtw_msleep_os(1);
1362 #endif
1363 goto next;
1364 }
1365
1366 return _SUCCESS;
1367 }
1368
rtl8188es_xmit_thread(thread_context context)1369 thread_return rtl8188es_xmit_thread(thread_context context)
1370 {
1371 s32 ret;
1372 PADAPTER padapter= (PADAPTER)context;
1373 struct xmit_priv *pxmitpriv= &padapter->xmitpriv;
1374
1375 ret = _SUCCESS;
1376
1377 thread_enter("RTWHALXT");
1378
1379 DBG_871X("start %s\n", __FUNCTION__);
1380
1381 do {
1382 ret = rtl8188es_xmit_handler(padapter);
1383 flush_signals(current);
1384 } while (_SUCCESS == ret);
1385
1386 RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("-%s\n", __FUNCTION__));
1387 DBG_871X("exit %s\n", __FUNCTION__);
1388
1389 /*_rtw_up_sema(&pxmitpriv->SdioXmitTerminateSema);*/
1390 thread_exit(&pxmitpriv->sdio_xmit_thread_comp);
1391 return 0;
1392 }
1393 #endif
1394
1395 #ifdef CONFIG_IOL_IOREG_CFG_DBG
1396 #include <rtw_iol.h>
1397 #endif
rtl8188es_mgnt_xmit(PADAPTER padapter,struct xmit_frame * pmgntframe)1398 s32 rtl8188es_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe)
1399 {
1400 s32 ret = _SUCCESS;
1401 struct pkt_attrib *pattrib;
1402 struct xmit_buf *pxmitbuf;
1403 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1404 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
1405 u8 *pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1406 u8 pattrib_subtype;
1407
1408 RT_TRACE(_module_hal_xmit_c_, _drv_info_, ("+%s\n", __FUNCTION__));
1409
1410 pattrib = &pmgntframe->attrib;
1411 pxmitbuf = pmgntframe->pxmitbuf;
1412
1413 rtl8188es_update_txdesc(pmgntframe, pmgntframe->buf_addr);
1414
1415 pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
1416 //pmgntframe->pg_num = (pxmitbuf->len + 127)/128; // 128 is tx page size
1417 pxmitbuf->pg_num = (pxmitbuf->len + 127)/128; // 128 is tx page size
1418 pxmitbuf->ptail = pmgntframe->buf_addr + pxmitbuf->len;
1419 pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pmgntframe);
1420
1421 rtw_count_tx_stats(padapter, pmgntframe, pattrib->last_txcmdsz);
1422 pattrib_subtype = pattrib->subtype;
1423 rtw_free_xmitframe(pxmitpriv, pmgntframe);
1424
1425 pxmitbuf->priv_data = NULL;
1426
1427 if((pattrib_subtype == WIFI_BEACON) || (GetFrameSubType(pframe)==WIFI_BEACON)) //dump beacon directly
1428 {
1429 #ifdef CONFIG_IOL_IOREG_CFG_DBG
1430 rtw_IOL_cmd_buf_dump(padapter,pxmitbuf->len,pxmitbuf->pdata);
1431 #endif
1432
1433 ret = rtw_write_port(padapter, ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr), pxmitbuf->len, (u8 *)pxmitbuf);
1434 if (ret != _SUCCESS)
1435 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
1436
1437 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
1438 }
1439 else
1440 {
1441 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
1442 }
1443
1444 return ret;
1445 }
1446
1447 /*
1448 * Description:
1449 * Handle xmitframe(packet) come from rtw_xmit()
1450 *
1451 * Return:
1452 * _TRUE dump packet directly ok
1453 * _FALSE enqueue, temporary can't transmit packets to hardware
1454 */
rtl8188es_hal_xmit(PADAPTER padapter,struct xmit_frame * pxmitframe)1455 s32 rtl8188es_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe)
1456 {
1457 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1458 _irqL irql;
1459 s32 err;
1460
1461 //pxmitframe->attrib.qsel = pxmitframe->attrib.priority;
1462
1463 #ifdef CONFIG_80211N_HT
1464 if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
1465 (pxmitframe->attrib.ether_type != 0x0806) &&
1466 (pxmitframe->attrib.ether_type != 0x888e) &&
1467 (pxmitframe->attrib.dhcp_pkt != 1))
1468 {
1469 if (padapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)
1470 rtw_issue_addbareq_cmd(padapter, pxmitframe);
1471 }
1472 #endif
1473
1474 _enter_critical_bh(&pxmitpriv->lock, &irql);
1475 err = rtw_xmitframe_enqueue(padapter, pxmitframe);
1476 _exit_critical_bh(&pxmitpriv->lock, &irql);
1477 if (err != _SUCCESS) {
1478 RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: enqueue xmitframe fail\n",__FUNCTION__));
1479 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1480
1481 pxmitpriv->tx_drop++;
1482 return _TRUE;
1483 }
1484
1485 #ifdef CONFIG_SDIO_TX_TASKLET
1486 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
1487 #else
1488 _rtw_up_sema(&pxmitpriv->SdioXmitSema);
1489 #endif
1490
1491 return _FALSE;
1492 }
1493
rtl8188es_hal_xmitframe_enqueue(_adapter * padapter,struct xmit_frame * pxmitframe)1494 s32 rtl8188es_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
1495 {
1496 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1497 s32 err;
1498
1499 if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS)
1500 {
1501 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1502
1503 pxmitpriv->tx_drop++;
1504 }
1505 else
1506 {
1507 #ifdef CONFIG_SDIO_TX_TASKLET
1508 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
1509 #else
1510 _rtw_up_sema(&pxmitpriv->SdioXmitSema);
1511 #endif
1512 }
1513
1514 return err;
1515
1516 }
1517
1518
1519 /*
1520 * Return
1521 * _SUCCESS start thread ok
1522 * _FAIL start thread fail
1523 *
1524 */
rtl8188es_init_xmit_priv(PADAPTER padapter)1525 s32 rtl8188es_init_xmit_priv(PADAPTER padapter)
1526 {
1527 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1528 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1529
1530 #ifdef CONFIG_SDIO_TX_TASKLET
1531 #ifdef PLATFORM_LINUX
1532 tasklet_init(&pxmitpriv->xmit_tasklet,
1533 (void(*)(unsigned long))rtl8188es_xmit_tasklet,
1534 (unsigned long)padapter);
1535 #endif
1536 #else //CONFIG_SDIO_TX_TASKLET
1537
1538 _rtw_init_sema(&pxmitpriv->SdioXmitSema, 0);
1539 /*_rtw_init_sema(&pxmitpriv->SdioXmitTerminateSema, 0);*/
1540 _rtw_init_completion(&pxmitpriv->sdio_xmit_thread_comp);
1541 #endif //CONFIG_SDIO_TX_TASKLET
1542
1543 _rtw_spinlock_init(&pHalData->SdioTxFIFOFreePageLock);
1544
1545 #ifdef CONFIG_TX_EARLY_MODE
1546 pHalData->bEarlyModeEnable = padapter->registrypriv.early_mode;
1547 #endif
1548
1549 return _SUCCESS;
1550 }
1551
rtl8188es_free_xmit_priv(PADAPTER padapter)1552 void rtl8188es_free_xmit_priv(PADAPTER padapter)
1553 {
1554 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1555
1556 _rtw_spinlock_free(&pHalData->SdioTxFIFOFreePageLock);
1557 }
1558
1559