1 /* SPDX-License-Identifier: GPL-2.0 */
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2017 Realtek Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 *****************************************************************************/
16 #define _RTL8188E_XMIT_C_
17
18 #include <drv_types.h>
19 #include <rtl8188e_hal.h>
20
21
rtl8188eu_init_xmit_priv(_adapter * padapter)22 s32 rtl8188eu_init_xmit_priv(_adapter *padapter)
23 {
24 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
25 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
26
27 #ifdef PLATFORM_LINUX
28 tasklet_init(&pxmitpriv->xmit_tasklet,
29 (void(*)(unsigned long))rtl8188eu_xmit_tasklet,
30 (unsigned long)padapter);
31 #endif
32 #ifdef CONFIG_TX_EARLY_MODE
33 pHalData->bEarlyModeEnable = padapter->registrypriv.early_mode;
34 #endif
35
36 return _SUCCESS;
37 }
38
rtl8188eu_free_xmit_priv(_adapter * padapter)39 void rtl8188eu_free_xmit_priv(_adapter *padapter)
40 {
41 }
42
urb_zero_packet_chk(_adapter * padapter,int sz)43 u8 urb_zero_packet_chk(_adapter *padapter, int sz)
44 {
45 u8 blnSetTxDescOffset;
46 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
47 blnSetTxDescOffset = (((sz + TXDESC_SIZE) % pHalData->UsbBulkOutSize) == 0) ? 1 : 0;
48
49 return blnSetTxDescOffset;
50 }
51
rtl8188eu_cal_txdesc_chksum(struct tx_desc * ptxdesc)52 void rtl8188eu_cal_txdesc_chksum(struct tx_desc *ptxdesc)
53 {
54 u16 *usPtr = (u16 *)ptxdesc;
55 u32 count = 16; /* (32 bytes / 2 bytes per XOR) => 16 times */
56 u32 index;
57 u16 checksum = 0;
58
59 /* Clear first */
60 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
61
62 for (index = 0 ; index < count ; index++)
63 checksum = checksum ^ le16_to_cpu(*(usPtr + index));
64
65 ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff & checksum);
66
67 }
68 /*
69 * Description: In normal chip, we should send some packet to Hw which will be used by Fw
70 * in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
71 * Fw can tell Hw to send these packet derectly.
72 * */
rtl8188e_fill_fake_txdesc(PADAPTER padapter,u8 * pDesc,u32 BufferLen,u8 IsPsPoll,u8 IsBTQosNull,u8 bDataFrame)73 void rtl8188e_fill_fake_txdesc(
74 PADAPTER padapter,
75 u8 *pDesc,
76 u32 BufferLen,
77 u8 IsPsPoll,
78 u8 IsBTQosNull,
79 u8 bDataFrame)
80 {
81 struct tx_desc *ptxdesc;
82
83
84 /* Clear all status */
85 ptxdesc = (struct tx_desc *)pDesc;
86 _rtw_memset(pDesc, 0, TXDESC_SIZE);
87
88 /* offset 0 */
89 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); /* own, bFirstSeg, bLastSeg; */
90
91 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); /* 32 bytes for TX Desc */
92
93 ptxdesc->txdw0 |= cpu_to_le32(BufferLen & 0x0000ffff); /* Buffer size + command header */
94
95 /* offset 4 */
96 ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT << QSEL_SHT) & 0x00001f00); /* Fixed queue of Mgnt queue */
97
98 /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. */
99 if (IsPsPoll)
100 ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
101 else {
102 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); /* Hw set sequence number */
103 ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
104 }
105
106 if (_TRUE == IsBTQosNull) {
107 ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); /* BT NULL */
108 }
109
110 /* offset 16 */
111 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */
112
113 /* */
114 /* Encrypt the data frame if under security mode excepct null data. Suggested by CCW. */
115 /* */
116 if (_TRUE == bDataFrame) {
117 u32 EncAlg;
118
119 EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
120 switch (EncAlg) {
121 case _NO_PRIVACY_:
122 SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x0);
123 break;
124 case _WEP40_:
125 case _WEP104_:
126 case _TKIP_:
127 SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x1);
128 break;
129 case _SMS4_:
130 SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x2);
131 break;
132 case _AES_:
133 SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x3);
134 break;
135 default:
136 SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x0);
137 break;
138 }
139 }
140
141 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
142 /* USB interface drop packet if the checksum of descriptor isn't correct. */
143 /* Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.). */
144 rtl8188eu_cal_txdesc_chksum(ptxdesc);
145 #endif
146 }
147
fill_txdesc_sectype(struct pkt_attrib * pattrib,struct tx_desc * ptxdesc)148 void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
149 {
150 if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
151 switch (pattrib->encrypt) {
152 /* SEC_TYPE : 0:NO_ENC,1:WEP40/TKIP,2:WAPI,3:AES */
153 case _WEP40_:
154 case _WEP104_:
155 ptxdesc->txdw1 |= cpu_to_le32((0x01 << SEC_TYPE_SHT) & 0x00c00000);
156 ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
157 break;
158 case _TKIP_:
159 case _TKIP_WTMIC_:
160 ptxdesc->txdw1 |= cpu_to_le32((0x01 << SEC_TYPE_SHT) & 0x00c00000);
161 ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
162 break;
163 #ifdef CONFIG_WAPI_SUPPORT
164 case _SMS4_:
165 ptxdesc->txdw1 |= cpu_to_le32((0x02 << SEC_TYPE_SHT) & 0x00c00000);
166 ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
167 break;
168 #endif
169 case _AES_:
170 ptxdesc->txdw1 |= cpu_to_le32((0x03 << SEC_TYPE_SHT) & 0x00c00000);
171 ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
172 break;
173 case _NO_PRIVACY_:
174 default:
175 break;
176
177 }
178
179 }
180
181 }
182
fill_txdesc_vcs(struct pkt_attrib * pattrib,u32 * pdw)183 void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
184 {
185 /* RTW_INFO("cvs_mode=%d\n", pattrib->vcs_mode); */
186
187 switch (pattrib->vcs_mode) {
188 case RTS_CTS:
189 *pdw |= cpu_to_le32(RTS_EN);
190 break;
191 case CTS_TO_SELF:
192 *pdw |= cpu_to_le32(CTS_2_SELF);
193 break;
194 case NONE_VCS:
195 default:
196 break;
197 }
198
199 if (pattrib->vcs_mode) {
200 *pdw |= cpu_to_le32(HW_RTS_EN);
201
202 /* Set RTS BW */
203 if (pattrib->ht_en) {
204 *pdw |= (pattrib->bwmode & CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(27)) : 0;
205
206 if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
207 *pdw |= cpu_to_le32((0x01 << 28) & 0x30000000);
208 else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
209 *pdw |= cpu_to_le32((0x02 << 28) & 0x30000000);
210 else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
211 *pdw |= 0;
212 else
213 *pdw |= cpu_to_le32((0x03 << 28) & 0x30000000);
214 }
215 }
216 }
217
fill_txdesc_phy(struct pkt_attrib * pattrib,u32 * pdw)218 void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw)
219 {
220 /* RTW_INFO("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset); */
221
222 if (pattrib->ht_en) {
223 *pdw |= (pattrib->bwmode & CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0;
224
225 if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
226 *pdw |= cpu_to_le32((0x01 << DATA_SC_SHT) & 0x003f0000);
227 else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
228 *pdw |= cpu_to_le32((0x02 << DATA_SC_SHT) & 0x003f0000);
229 else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
230 *pdw |= 0;
231 else
232 *pdw |= cpu_to_le32((0x03 << DATA_SC_SHT) & 0x003f0000);
233 }
234 }
235
236
update_txdesc(struct xmit_frame * pxmitframe,u8 * pmem,s32 sz,u8 bagg_pkt)237 static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz , u8 bagg_pkt)
238 {
239 int pull = 0;
240 uint qsel;
241 bool sgi = 0;
242 u8 data_rate = 0, pwr_status, offset;
243 _adapter *padapter = pxmitframe->padapter;
244 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
245 struct pkt_attrib *pattrib = &pxmitframe->attrib;
246 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
247
248 struct tx_desc *ptxdesc = (struct tx_desc *)pmem;
249 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
250 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
251 sint bmcst = IS_MCAST(pattrib->ra);
252 #ifdef CONFIG_P2P
253 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
254 #endif /* CONFIG_P2P */
255
256 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
257 if (padapter->registrypriv.mp_mode == 0) {
258 /* if((!bagg_pkt) &&(urb_zero_packet_chk(padapter, sz)==0)) */ /* (sz %512) != 0 */
259 if ((PACKET_OFFSET_SZ != 0) && (!bagg_pkt) && (rtw_usb_bulk_size_boundary(padapter, TXDESC_SIZE + sz) == _FALSE)) {
260 ptxdesc = (struct tx_desc *)(pmem + PACKET_OFFSET_SZ);
261 /* RTW_INFO("==> non-agg-pkt,shift pointer...\n"); */
262 pull = 1;
263 }
264 }
265 #endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
266
267 _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
268
269 /* 4 offset 0 */
270 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
271 /* RTW_INFO("%s==> pkt_len=%d,bagg_pkt=%02x\n",__FUNCTION__,sz,bagg_pkt); */
272 ptxdesc->txdw0 |= cpu_to_le32(sz & 0x0000ffff);/* update TXPKTSIZE */
273
274 offset = TXDESC_SIZE + OFFSET_SZ;
275
276 #ifdef CONFIG_TX_EARLY_MODE
277 if (bagg_pkt) {
278 offset += EARLY_MODE_INFO_SIZE ;/* 0x28 */
279 }
280 #endif
281 /* RTW_INFO("%s==>offset(0x%02x)\n",__FUNCTION__,offset); */
282 ptxdesc->txdw0 |= cpu_to_le32(((offset) << OFFSET_SHT) & 0x00ff0000);/* 32 bytes for TX Desc */
283
284 if (bmcst)
285 ptxdesc->txdw0 |= cpu_to_le32(BMC);
286
287 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
288 if (padapter->registrypriv.mp_mode == 0) {
289 if ((PACKET_OFFSET_SZ != 0) && (!bagg_pkt)) {
290 if ((pull) && (pxmitframe->pkt_offset > 0))
291 pxmitframe->pkt_offset = pxmitframe->pkt_offset - 1;
292 }
293 }
294 #endif
295 /* RTW_INFO("%s, pkt_offset=0x%02x\n",__FUNCTION__,pxmitframe->pkt_offset); */
296
297 /* pkt_offset, unit:8 bytes padding */
298 if (pxmitframe->pkt_offset > 0)
299 ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000);
300
301 if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
302 /* RTW_INFO("pxmitframe->frame_tag == DATA_FRAMETAG\n"); */
303
304 /* offset 4 */
305 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3F);
306
307 qsel = (uint)(pattrib->qsel & 0x0000001f);
308 /* RTW_INFO("==> macid(%d) qsel:0x%02x\n",pattrib->mac_id,qsel); */
309 ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
310
311 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000);
312
313 fill_txdesc_sectype(pattrib, ptxdesc);
314
315 #if defined(CONFIG_CONCURRENT_MODE)
316 if (bmcst)
317 fill_txdesc_force_bmc_camid(pattrib, ptxdesc);
318 #endif
319
320 if (pattrib->ampdu_en == _TRUE) {
321 ptxdesc->txdw2 |= cpu_to_le32(AGG_EN);/* AGG EN */
322 ptxdesc->txdw2 |= (pattrib->ampdu_spacing << AMPDU_DENSITY_SHT) & 0x00700000;
323
324 /* SET_TX_DESC_MAX_AGG_NUM_88E(pDesc, 0x1F); */
325 /* SET_TX_DESC_MCSG1_MAX_LEN_88E(pDesc, 0x6); */
326 /* SET_TX_DESC_MCSG2_MAX_LEN_88E(pDesc, 0x6); */
327 /* SET_TX_DESC_MCSG3_MAX_LEN_88E(pDesc, 0x6); */
328 /* SET_TX_DESC_MCS7_SGI_MAX_LEN_88E(pDesc, 0x6); */
329 ptxdesc->txdw6 = 0x6666f800;
330 } else {
331 ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */
332 }
333
334 /* offset 8 */
335
336
337 /* offset 12 */
338 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000);
339
340
341 /* offset 16 , offset 20 */
342 if (pattrib->qos_en)
343 ptxdesc->txdw4 |= cpu_to_le32(QOS);/* QoS */
344
345 /* offset 20 */
346 #ifdef CONFIG_USB_TX_AGGREGATION
347 if (pxmitframe->agg_num > 1) {
348 /* RTW_INFO("%s agg_num:%d\n",__FUNCTION__,pxmitframe->agg_num ); */
349 ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << USB_TXAGG_NUM_SHT) & 0xFF000000);
350 }
351 #endif
352
353 if ((pattrib->ether_type != 0x888e) &&
354 (pattrib->ether_type != 0x0806) &&
355 (pattrib->ether_type != 0x88b4) &&
356 (pattrib->dhcp_pkt != 1)) {
357 /* Non EAP & ARP & DHCP type data packet */
358
359 fill_txdesc_vcs(pattrib, &ptxdesc->txdw4);
360 fill_txdesc_phy(pattrib, &ptxdesc->txdw4);
361
362 ptxdesc->txdw4 |= cpu_to_le32(0x00000008);/* RTS Rate=24M */
363 ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);/* DATA/RTS Rate FB LMT */
364
365 #if (RATE_ADAPTIVE_SUPPORT == 1)
366 if (pHalData->fw_ractrl == _FALSE) {
367 /* driver-based RA*/
368 /* driver uses rate */
369 ptxdesc->txdw4 |= cpu_to_le32(USERATE);/* rate control always by driver */
370 if (pattrib->ht_en)
371 sgi = odm_ra_get_sgi_8188e(&pHalData->odmpriv, pattrib->mac_id);
372
373 data_rate = odm_ra_get_decision_rate_8188e(&pHalData->odmpriv, pattrib->mac_id);
374
375 #if (POWER_TRAINING_ACTIVE == 1)
376 pwr_status = odm_ra_get_hw_pwr_status_8188e(&pHalData->odmpriv, pattrib->mac_id);
377 ptxdesc->txdw4 |= cpu_to_le32((pwr_status & 0x7) << PWR_STATUS_SHT);
378 #endif
379 } else
380 #endif/* if (RATE_ADAPTIVE_SUPPORT == 1) */
381 {
382 /* FW-based RA, TODO */
383 if (pattrib->ht_en)
384 sgi = 1;
385
386 data_rate = DESC_RATEMCS7; /* default rate: MCS7 */
387 }
388 if (bmcst) {
389 data_rate = MRateToHwRate(pattrib->rate);
390 ptxdesc->txdw4 |= cpu_to_le32(USERATE);
391 ptxdesc->txdw4 |= cpu_to_le32(DISDATAFB);
392 }
393
394 if (padapter->fix_rate != 0xFF) {
395 data_rate = padapter->fix_rate;
396 ptxdesc->txdw4 |= cpu_to_le32(USERATE);
397 if (!padapter->data_fb)
398 ptxdesc->txdw4 |= cpu_to_le32(DISDATAFB);
399 sgi = (padapter->fix_rate & BIT(7)) ? 1 : 0;
400 }
401
402 if (sgi)
403 ptxdesc->txdw5 |= cpu_to_le32(SGI);
404
405 ptxdesc->txdw5 |= cpu_to_le32(data_rate & 0x3F);
406 } else {
407 /* EAP data packet and ARP packet and DHCP. */
408 /* Use the 1M data rate to send the EAP/ARP packet. */
409 /* This will maybe make the handshake smooth. */
410
411 /* driver uses rate */
412 ptxdesc->txdw4 |= cpu_to_le32(USERATE);/* rate control always by driver */
413 ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */
414
415 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
416 ptxdesc->txdw4 |= cpu_to_le32(BIT(24));/* DATA_SHORT */
417 #ifdef CONFIG_IP_R_MONITOR
418 if((pattrib->ether_type == ETH_P_ARP) &&
419 (IsSupportedTxOFDM(padapter->registrypriv.wireless_mode))) {
420 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(IEEE80211_OFDM_RATE_6MB));
421 #ifdef DBG_IP_R_MONITOR
422 RTW_INFO(FUNC_ADPT_FMT ": SP Packet(0x%04X) rate=0x%x SeqNum = %d\n",
423 FUNC_ADPT_ARG(padapter), pattrib->ether_type, MRateToHwRate(pmlmeext->tx_rate), pattrib->seqnum);
424 #endif/*DBG_IP_R_MONITOR*/
425 } else
426 #endif/*CONFIG_IP_R_MONITOR*/
427 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
428 }
429
430 #ifdef CONFIG_TDLS
431 #ifdef CONFIG_XMIT_ACK
432 /* CCX-TXRPT ack for xmit mgmt frames. */
433 if (pxmitframe->ack_report) {
434 #ifdef DBG_CCX
435 static u16 ccx_sw = 0x123;
436
437 ptxdesc->txdw7 |= cpu_to_le32(((ccx_sw) << 16) & 0x0fff0000);
438 RTW_INFO("%s set ccx, sw:0x%03x\n", __func__, ccx_sw);
439 ccx_sw = (ccx_sw + 1) % 0xfff;
440 #endif
441 ptxdesc->txdw2 |= cpu_to_le32(BIT(19));
442 }
443 #endif /* CONFIG_XMIT_ACK */
444 #endif
445 } else if ((pxmitframe->frame_tag & 0x0f) == MGNT_FRAMETAG) {
446 /* RTW_INFO("pxmitframe->frame_tag == MGNT_FRAMETAG\n"); */
447 /* driver uses rate */
448 ptxdesc->txdw4 |= cpu_to_le32(USERATE);/* rate control always by driver */
449
450 /* offset 4 */
451 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3f);
452
453 qsel = (uint)(pattrib->qsel & 0x0000001f);
454 ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
455
456 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000f0000);
457
458 /* fill_txdesc_sectype(pattrib, ptxdesc); */
459
460 /* offset 8 */
461 #ifdef CONFIG_XMIT_ACK
462 /* CCX-TXRPT ack for xmit mgmt frames. */
463 if (pxmitframe->ack_report) {
464 #ifdef DBG_CCX
465 static u16 ccx_sw = 0x123;
466 ptxdesc->txdw7 |= cpu_to_le32(((ccx_sw) << 16) & 0x0fff0000);
467 RTW_INFO("%s set ccx, sw:0x%03x\n", __func__, ccx_sw);
468 ccx_sw = (ccx_sw + 1) % 0xfff;
469 #endif
470 ptxdesc->txdw2 |= cpu_to_le32(BIT(19));
471 }
472 #endif /* CONFIG_XMIT_ACK */
473
474 /* offset 12 */
475 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000);
476
477 /* offset 20 */
478 ptxdesc->txdw5 |= cpu_to_le32(RTY_LMT_EN);/* retry limit enable */
479 if (pattrib->retry_ctrl == _TRUE)
480 ptxdesc->txdw5 |= cpu_to_le32(0x00180000);/* retry limit = 6 */
481 else
482 ptxdesc->txdw5 |= cpu_to_le32(0x00300000);/* retry limit = 12 */
483
484 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pattrib->rate));
485
486 } else if ((pxmitframe->frame_tag & 0x0f) == TXAGG_FRAMETAG)
487 RTW_INFO("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
488 #ifdef CONFIG_MP_INCLUDED
489 else if (((pxmitframe->frame_tag & 0x0f) == MP_FRAMETAG) &&
490 (padapter->registrypriv.mp_mode == 1))
491 fill_txdesc_for_mp(padapter, (u8 *)ptxdesc);
492 #endif
493 else {
494 RTW_INFO("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);
495
496 /* offset 4 */
497 ptxdesc->txdw1 |= cpu_to_le32((4) & 0x3f); /* CAM_ID(MAC_ID) */
498
499 ptxdesc->txdw1 |= cpu_to_le32((6 << RATE_ID_SHT) & 0x000f0000); /* raid */
500
501 /* offset 8 */
502
503 /* offset 12 */
504 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0fff0000);
505
506 /* offset 20 */
507 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
508 }
509
510 /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */
511 /* (1) The sequence number of each non-Qos frame / broadcast / multicast / */
512 /* mgnt frame should be controled by Hw because Fw will also send null data */
513 /* which we cannot control when Fw LPS enable. */
514 /* --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */
515 /* (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */
516 /* (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */
517 /* 2010.06.23. Added by tynli. */
518 if (!pattrib->qos_en) {
519 /* ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); */ /* Hw set sequence number */
520 /* ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); */ /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
521
522 ptxdesc->txdw3 |= cpu_to_le32(EN_HWSEQ); /* Hw set sequence number */
523 ptxdesc->txdw4 |= cpu_to_le32(HW_SSN); /* Hw set sequence number */
524
525 }
526
527 #ifdef CONFIG_ANTENNA_DIVERSITY
528 if (!bmcst && pattrib->psta)
529 odm_set_tx_ant_by_tx_info(adapter_to_phydm(padapter), pmem, pattrib->psta->cmn.mac_id);
530 #endif
531
532 rtl8188eu_cal_txdesc_chksum(ptxdesc);
533 _dbg_dump_tx_info(padapter, pxmitframe->frame_tag, ptxdesc);
534 return pull;
535
536 }
537
538
539 #ifdef CONFIG_XMIT_THREAD_MODE
540 /*
541 * Description
542 * Transmit xmitbuf to hardware tx fifo
543 *
544 * Return
545 * _SUCCESS ok
546 * _FAIL something error
547 */
rtl8188eu_xmit_buf_handler(PADAPTER padapter)548 s32 rtl8188eu_xmit_buf_handler(PADAPTER padapter)
549 {
550 /* PHAL_DATA_TYPE phal; */
551 struct xmit_priv *pxmitpriv;
552 struct xmit_buf *pxmitbuf;
553 struct xmit_frame *pxmitframe;
554 s32 ret;
555
556
557 /* phal = GET_HAL_DATA(padapter); */
558 pxmitpriv = &padapter->xmitpriv;
559
560 ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
561 if (_FAIL == ret) {
562 return _FAIL;
563 }
564 if (RTW_CANNOT_RUN(padapter)) {
565 RTW_DBG(FUNC_ADPT_FMT "- bDriverStopped(%s) bSurpriseRemoved(%s)\n",
566 FUNC_ADPT_ARG(padapter),
567 rtw_is_drv_stopped(padapter) ? "True" : "False",
568 rtw_is_surprise_removed(padapter) ? "True" : "False");
569 return _FAIL;
570 }
571
572 if (rtw_mi_check_pending_xmitbuf(padapter) == 0)
573 return _SUCCESS;
574
575 #ifdef CONFIG_LPS_LCLK
576 ret = rtw_register_tx_alive(padapter);
577 if (ret != _SUCCESS) {
578 return _SUCCESS;
579 }
580 #endif
581
582 do {
583 pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
584 if (pxmitbuf == NULL)
585 break;
586 pxmitframe = (struct xmit_frame *) pxmitbuf->priv_data;
587 rtw_write_port(padapter, pxmitbuf->ff_hwaddr, pxmitbuf->len, (unsigned char *)pxmitbuf);
588 rtw_free_xmitframe(pxmitpriv, pxmitframe);
589
590 } while (1);
591
592 #ifdef CONFIG_LPS_LCLK
593 rtw_unregister_tx_alive(padapter);
594 #endif
595
596 return _SUCCESS;
597 }
598 #endif
599
600 #ifdef CONFIG_IOL_IOREG_CFG_DBG
601 #include <rtw_iol.h>
602 #endif
603 /* for non-agg data frame or management frame */
rtw_dump_xframe(_adapter * padapter,struct xmit_frame * pxmitframe)604 static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
605 {
606 s32 ret = _SUCCESS;
607 s32 inner_ret = _SUCCESS;
608 int t, sz, w_sz, pull = 0;
609 u8 *mem_addr;
610 u32 ff_hwaddr;
611 struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
612 struct pkt_attrib *pattrib = &pxmitframe->attrib;
613 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
614 struct security_priv *psecuritypriv = &padapter->securitypriv;
615 #ifdef CONFIG_80211N_HT
616 if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
617 (pxmitframe->attrib.ether_type != 0x0806) &&
618 (pxmitframe->attrib.ether_type != 0x888e) &&
619 (pxmitframe->attrib.ether_type != 0x88b4) &&
620 (pxmitframe->attrib.dhcp_pkt != 1))
621 rtw_issue_addbareq_cmd(padapter, pxmitframe);
622 #endif /* CONFIG_80211N_HT */
623 mem_addr = pxmitframe->buf_addr;
624
625
626 for (t = 0; t < pattrib->nr_frags; t++) {
627 if (inner_ret != _SUCCESS && ret == _SUCCESS)
628 ret = _FAIL;
629
630 if (t != (pattrib->nr_frags - 1)) {
631
632 sz = pxmitpriv->frag_len;
633 sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
634 } else /* no frag */
635 sz = pattrib->last_txcmdsz;
636
637 pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
638
639 if (pull) {
640 mem_addr += PACKET_OFFSET_SZ; /* pull txdesc head */
641
642 /* pxmitbuf->pbuf = mem_addr; */
643 pxmitframe->buf_addr = mem_addr;
644
645 w_sz = sz + TXDESC_SIZE;
646 } else
647 w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
648 #ifdef CONFIG_IOL_IOREG_CFG_DBG
649 rtw_IOL_cmd_buf_dump(padapter, w_sz, pxmitframe->buf_addr);
650 #endif
651 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
652
653 #ifdef CONFIG_XMIT_THREAD_MODE
654 pxmitbuf->len = w_sz;
655 pxmitbuf->ff_hwaddr = ff_hwaddr;
656
657 if (pxmitframe->attrib.qsel == QSLT_BEACON)
658 /* download rsvd page*/
659 rtw_write_port(padapter, ff_hwaddr, w_sz, (u8 *)pxmitbuf);
660 else
661 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
662 #else
663 /* RTW_INFO("%s: rtw_write_port size =%d\n", __func__,w_sz); */
664 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf);
665 #endif
666
667 rtw_count_tx_stats(padapter, pxmitframe, sz);
668
669 /* RTW_INFO("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority); */
670
671 mem_addr += w_sz;
672
673 mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
674
675 }
676
677 #ifdef CONFIG_XMIT_THREAD_MODE
678 if (pxmitframe->attrib.qsel == QSLT_BEACON)
679 #endif
680 rtw_free_xmitframe(pxmitpriv, pxmitframe);
681
682 if (ret != _SUCCESS)
683 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
684
685 return ret;
686 }
687
688 #ifdef CONFIG_USB_TX_AGGREGATION
689 #define IDEA_CONDITION 1 /* check all packets before enqueue */
rtl8188eu_xmitframe_complete(_adapter * padapter,struct xmit_priv * pxmitpriv,struct xmit_buf * pxmitbuf)690 s32 rtl8188eu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
691 {
692 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
693 struct xmit_frame *pxmitframe = NULL;
694 struct xmit_frame *pfirstframe = NULL;
695
696 /* aggregate variable */
697 struct hw_xmit *phwxmit;
698 struct sta_info *psta = NULL;
699 struct tx_servq *ptxservq = NULL;
700
701 _irqL irqL;
702 _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
703
704 u32 pbuf; /* next pkt address */
705 u32 pbuf_tail; /* last pkt tail */
706 u32 len; /* packet length, except TXDESC_SIZE and PKT_OFFSET */
707
708 u32 bulkSize = pHalData->UsbBulkOutSize;
709 u8 descCount;
710 u32 bulkPtr;
711
712 /* dump frame variable */
713 u32 ff_hwaddr;
714
715 _list *sta_plist, *sta_phead;
716 u8 single_sta_in_queue = _FALSE;
717
718 #ifndef IDEA_CONDITION
719 int res = _SUCCESS;
720 #endif
721
722
723
724 /* check xmitbuffer is ok */
725 if (pxmitbuf == NULL) {
726 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
727 if (pxmitbuf == NULL) {
728 /* RTW_INFO("%s #1, connot alloc xmitbuf!!!!\n",__FUNCTION__); */
729 return _FALSE;
730 }
731 }
732
733 /* RTW_INFO("%s =====================================\n",__FUNCTION__); */
734 /* 3 1. pick up first frame */
735 do {
736 rtw_free_xmitframe(pxmitpriv, pxmitframe);
737
738 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
739 if (pxmitframe == NULL) {
740 /* no more xmit frame, release xmit buffer */
741 /* RTW_INFO("no more xmit frame ,return\n"); */
742 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
743 return _FALSE;
744 }
745
746 #ifndef IDEA_CONDITION
747 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
748 /* rtw_free_xmitframe(pxmitpriv, pxmitframe); */
749 continue;
750 }
751
752 /* TID 0~15 */
753 if ((pxmitframe->attrib.priority < 0) ||
754 (pxmitframe->attrib.priority > 15)) {
755 /* rtw_free_xmitframe(pxmitpriv, pxmitframe); */
756 continue;
757 }
758 #endif
759 /* RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority); */
760 pxmitframe->pxmitbuf = pxmitbuf;
761 pxmitframe->buf_addr = pxmitbuf->pbuf;
762 pxmitbuf->priv_data = pxmitframe;
763
764 pxmitframe->agg_num = 1; /* alloc xmitframe should assign to 1. */
765 #ifdef CONFIG_TX_EARLY_MODE
766 pxmitframe->pkt_offset = (PACKET_OFFSET_SZ / 8) + 1; /* 2; */ /* first frame of aggregation, reserve one offset for EM info ,another for usb bulk-out block check */
767 #else
768 pxmitframe->pkt_offset = (PACKET_OFFSET_SZ / 8); /* 1; */ /* first frame of aggregation, reserve offset */
769 #endif
770
771 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
772 RTW_INFO("%s coalesce 1st xmitframe failed\n", __FUNCTION__);
773 continue;
774 }
775
776 /* always return ndis_packet after rtw_xmitframe_coalesce */
777 rtw_os_xmit_complete(padapter, pxmitframe);
778
779 break;
780 } while (1);
781
782 /* 3 2. aggregate same priority and same DA(AP or STA) frames */
783 pfirstframe = pxmitframe;
784 len = rtw_wlan_pkt_size(pfirstframe) + TXDESC_SIZE + (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);
785 pbuf_tail = len;
786 pbuf = _RND8(pbuf_tail);
787
788 /* check pkt amount in one bulk */
789 descCount = 0;
790 bulkPtr = bulkSize;
791 if (pbuf < bulkPtr) {
792 descCount++;
793 if (descCount == pHalData->UsbTxAggDescNum)
794 goto agg_end;
795 } else {
796 descCount = 0;
797 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; /* round to next bulkSize */
798 }
799
800 /* dequeue same priority packet from station tx queue */
801 /* psta = pfirstframe->attrib.psta; */
802 psta = rtw_get_stainfo(&padapter->stapriv, pfirstframe->attrib.ra);
803 if (pfirstframe->attrib.psta != psta)
804 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pfirstframe->attrib.psta, psta);
805 if (psta == NULL)
806 RTW_INFO("rtw_xmit_classifier: psta == NULL\n");
807 if (!(psta->state & _FW_LINKED))
808 RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
809
810 switch (pfirstframe->attrib.priority) {
811 case 1:
812 case 2:
813 ptxservq = &(psta->sta_xmitpriv.bk_q);
814 phwxmit = pxmitpriv->hwxmits + 3;
815 break;
816
817 case 4:
818 case 5:
819 ptxservq = &(psta->sta_xmitpriv.vi_q);
820 phwxmit = pxmitpriv->hwxmits + 1;
821 break;
822
823 case 6:
824 case 7:
825 ptxservq = &(psta->sta_xmitpriv.vo_q);
826 phwxmit = pxmitpriv->hwxmits;
827 break;
828
829 case 0:
830 case 3:
831 default:
832 ptxservq = &(psta->sta_xmitpriv.be_q);
833 phwxmit = pxmitpriv->hwxmits + 2;
834 break;
835 }
836 /* RTW_INFO("==> pkt_no=%d,pkt_len=%d,len=%d,RND8_LEN=%d,pkt_offset=0x%02x\n", */
837 /* pxmitframe->agg_num,pxmitframe->attrib.last_txcmdsz,len,pbuf,pxmitframe->pkt_offset ); */
838
839 _enter_critical_bh(&pxmitpriv->lock, &irqL);
840
841 sta_phead = get_list_head(phwxmit->sta_queue);
842 sta_plist = get_next(sta_phead);
843 single_sta_in_queue = rtw_end_of_queue_search(sta_phead, get_next(sta_plist));
844
845 xmitframe_phead = get_list_head(&ptxservq->sta_pending);
846 xmitframe_plist = get_next(xmitframe_phead);
847
848 while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE) {
849 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
850 xmitframe_plist = get_next(xmitframe_plist);
851
852 if (_FAIL == rtw_hal_busagg_qsel_check(padapter, pfirstframe->attrib.qsel, pxmitframe->attrib.qsel))
853 break;
854
855 pxmitframe->agg_num = 0; /* not first frame of aggregation */
856 #ifdef CONFIG_TX_EARLY_MODE
857 pxmitframe->pkt_offset = 1;/* not first frame of aggregation,reserve offset for EM Info */
858 #else
859 pxmitframe->pkt_offset = 0; /* not first frame of aggregation, no need to reserve offset */
860 #endif
861
862 len = rtw_wlan_pkt_size(pxmitframe) + TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
863
864 if (_RND8(pbuf + len) > MAX_XMITBUF_SZ) {
865 /* RTW_INFO("%s....len> MAX_XMITBUF_SZ\n",__FUNCTION__); */
866 pxmitframe->agg_num = 1;
867 pxmitframe->pkt_offset = 1;
868 break;
869 }
870 rtw_list_delete(&pxmitframe->list);
871 ptxservq->qcnt--;
872 phwxmit->accnt--;
873
874 #ifndef IDEA_CONDITION
875 /* suppose only data frames would be in queue */
876 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
877 rtw_free_xmitframe(pxmitpriv, pxmitframe);
878 continue;
879 }
880
881 /* TID 0~15 */
882 if ((pxmitframe->attrib.priority < 0) ||
883 (pxmitframe->attrib.priority > 15)) {
884 rtw_free_xmitframe(pxmitpriv, pxmitframe);
885 continue;
886 }
887 #endif
888
889 /* pxmitframe->pxmitbuf = pxmitbuf; */
890 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
891
892 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
893 RTW_INFO("%s coalesce failed\n", __FUNCTION__);
894 rtw_free_xmitframe(pxmitpriv, pxmitframe);
895 continue;
896 }
897
898 /* RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority); */
899 /* always return ndis_packet after rtw_xmitframe_coalesce */
900 rtw_os_xmit_complete(padapter, pxmitframe);
901
902 /* (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz */
903 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
904
905 /* don't need xmitframe any more */
906 rtw_free_xmitframe(pxmitpriv, pxmitframe);
907
908 /* handle pointer and stop condition */
909 pbuf_tail = pbuf + len;
910 pbuf = _RND8(pbuf_tail);
911
912
913 pfirstframe->agg_num++;
914 #ifdef CONFIG_TX_EARLY_MODE
915 pxmitpriv->agg_pkt[pfirstframe->agg_num - 1].offset = _RND8(len);
916 pxmitpriv->agg_pkt[pfirstframe->agg_num - 1].pkt_len = pxmitframe->attrib.last_txcmdsz;
917 #endif
918 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
919 break;
920
921 if (pbuf < bulkPtr) {
922 descCount++;
923 if (descCount == pHalData->UsbTxAggDescNum)
924 break;
925 } else {
926 descCount = 0;
927 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
928 }
929 } /* end while( aggregate same priority and same DA(AP or STA) frames) */
930 if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
931 rtw_list_delete(&ptxservq->tx_pending);
932 else if (single_sta_in_queue == _FALSE) {
933 /* Re-arrange the order of stations in this ac queue to balance the service for these stations */
934 rtw_list_delete(&ptxservq->tx_pending);
935 rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmit->sta_queue));
936 }
937
938 _exit_critical_bh(&pxmitpriv->lock, &irqL);
939
940 agg_end:
941
942 #ifdef CONFIG_80211N_HT
943 if ((pfirstframe->attrib.ether_type != 0x0806) &&
944 (pfirstframe->attrib.ether_type != 0x888e) &&
945 (pfirstframe->attrib.ether_type != 0x88b4) &&
946 (pfirstframe->attrib.dhcp_pkt != 1))
947 rtw_issue_addbareq_cmd(padapter, pfirstframe);
948 #endif /* CONFIG_80211N_HT */
949 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
950 /* 3 3. update first frame txdesc */
951 if ((PACKET_OFFSET_SZ != 0) && ((pbuf_tail % bulkSize) == 0)) {
952 /* remove pkt_offset */
953 pbuf_tail -= PACKET_OFFSET_SZ;
954 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
955 pfirstframe->pkt_offset--;
956 /* RTW_INFO("$$$$$ buf size equal to USB block size $$$$$$\n"); */
957 }
958 #endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
959
960 update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
961
962 #ifdef CONFIG_TX_EARLY_MODE
963 /* prepare EM info for first frame, agg_num value start from 1 */
964 pxmitpriv->agg_pkt[0].offset = _RND8(pfirstframe->attrib.last_txcmdsz + TXDESC_SIZE + (pfirstframe->pkt_offset * PACKET_OFFSET_SZ));
965 pxmitpriv->agg_pkt[0].pkt_len = pfirstframe->attrib.last_txcmdsz;/* get from rtw_xmitframe_coalesce */
966
967 UpdateEarlyModeInfo8188E(pxmitpriv, pxmitbuf);
968 #endif
969
970 /* 3 4. write xmit buffer to USB FIFO */
971 ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
972 /* RTW_INFO("%s ===================================== write port,buf_size(%d)\n",__FUNCTION__,pbuf_tail); */
973 /* xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr */
974
975 #ifdef CONFIG_XMIT_THREAD_MODE
976 pxmitbuf->len = pbuf_tail;
977 pxmitbuf->ff_hwaddr = ff_hwaddr;
978
979 if (pfirstframe->attrib.qsel == QSLT_BEACON)
980 /* download rsvd page*/
981 rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
982 else
983 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
984 #else
985 rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
986 #endif
987
988
989 /* 3 5. update statisitc */
990 pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
991 pbuf_tail -= (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);
992
993
994 rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
995
996 #ifdef CONFIG_XMIT_THREAD_MODE
997 if (pfirstframe->attrib.qsel == QSLT_BEACON)
998 #endif
999 rtw_free_xmitframe(pxmitpriv, pfirstframe);
1000
1001 return _TRUE;
1002 }
1003
1004 #else
1005
rtl8188eu_xmitframe_complete(_adapter * padapter,struct xmit_priv * pxmitpriv,struct xmit_buf * pxmitbuf)1006 s32 rtl8188eu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
1007 {
1008
1009 struct hw_xmit *phwxmits;
1010 sint hwentry;
1011 struct xmit_frame *pxmitframe = NULL;
1012 int res = _SUCCESS, xcnt = 0;
1013
1014 phwxmits = pxmitpriv->hwxmits;
1015 hwentry = pxmitpriv->hwxmit_entry;
1016
1017
1018 if (pxmitbuf == NULL) {
1019 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
1020 if (!pxmitbuf)
1021 return _FALSE;
1022 }
1023
1024
1025 do {
1026 pxmitframe = rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
1027
1028 if (pxmitframe) {
1029 pxmitframe->pxmitbuf = pxmitbuf;
1030
1031 pxmitframe->buf_addr = pxmitbuf->pbuf;
1032
1033 pxmitbuf->priv_data = pxmitframe;
1034
1035 if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
1036 if (pxmitframe->attrib.priority <= 15) /* TID0~15 */
1037 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
1038 /* RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority); */
1039 rtw_os_xmit_complete(padapter, pxmitframe);/* always return ndis_packet after rtw_xmitframe_coalesce */
1040 }
1041
1042
1043
1044
1045 if (res == _SUCCESS)
1046 rtw_dump_xframe(padapter, pxmitframe);
1047 else {
1048 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
1049 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1050 }
1051
1052 xcnt++;
1053
1054 } else {
1055 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
1056 return _FALSE;
1057 }
1058
1059 break;
1060
1061 } while (0/*xcnt < (NR_XMITFRAME >> 3)*/);
1062
1063 return _TRUE;
1064
1065 }
1066 #endif
1067
1068
1069
xmitframe_direct(_adapter * padapter,struct xmit_frame * pxmitframe)1070 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
1071 {
1072 s32 res = _SUCCESS;
1073 /* RTW_INFO("==> %s\n",__FUNCTION__); */
1074
1075 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
1076 if (res == _SUCCESS)
1077 rtw_dump_xframe(padapter, pxmitframe);
1078 else
1079 RTW_INFO("==> %s xmitframe_coalsece failed\n", __FUNCTION__);
1080
1081 return res;
1082 }
1083
1084 /*
1085 * Return
1086 * _TRUE dump packet directly
1087 * _FALSE enqueue packet
1088 */
pre_xmitframe(_adapter * padapter,struct xmit_frame * pxmitframe)1089 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
1090 {
1091 _irqL irqL;
1092 s32 res;
1093 struct xmit_buf *pxmitbuf = NULL;
1094 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1095 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1096 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1097
1098 _enter_critical_bh(&pxmitpriv->lock, &irqL);
1099
1100 /* RTW_INFO("==> %s\n",__FUNCTION__); */
1101
1102 if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0) {
1103 /* RTW_INFO("enqueue AC(%d)\n",pattrib->priority); */
1104 goto enqueue;
1105 }
1106
1107 if (rtw_xmit_ac_blocked(padapter) == _TRUE)
1108 goto enqueue;
1109
1110 if (DEV_STA_LG_NUM(padapter->dvobj))
1111 goto enqueue;
1112
1113 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
1114 if (pxmitbuf == NULL)
1115 goto enqueue;
1116
1117 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1118
1119 pxmitframe->pxmitbuf = pxmitbuf;
1120 pxmitframe->buf_addr = pxmitbuf->pbuf;
1121 pxmitbuf->priv_data = pxmitframe;
1122
1123 if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
1124 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
1125 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1126 }
1127
1128 return _TRUE;
1129
1130 enqueue:
1131 res = rtw_xmitframe_enqueue(padapter, pxmitframe);
1132 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1133
1134 if (res != _SUCCESS) {
1135 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1136
1137 pxmitpriv->tx_drop++;
1138 return _TRUE;
1139 }
1140
1141 return _FALSE;
1142 }
1143
rtl8188eu_mgnt_xmit(_adapter * padapter,struct xmit_frame * pmgntframe)1144 s32 rtl8188eu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
1145 {
1146 return rtw_dump_xframe(padapter, pmgntframe);
1147 }
1148
1149 /*
1150 * Return
1151 * _TRUE dump packet directly ok
1152 * _FALSE temporary can't transmit packets to hardware
1153 */
rtl8188eu_hal_xmit(_adapter * padapter,struct xmit_frame * pxmitframe)1154 s32 rtl8188eu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
1155 {
1156 return pre_xmitframe(padapter, pxmitframe);
1157 }
1158
rtl8188eu_hal_xmitframe_enqueue(_adapter * padapter,struct xmit_frame * pxmitframe)1159 s32 rtl8188eu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
1160 {
1161 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1162 s32 err;
1163
1164 err = rtw_xmitframe_enqueue(padapter, pxmitframe);
1165 if (err != _SUCCESS) {
1166 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1167
1168 pxmitpriv->tx_drop++;
1169 } else {
1170 #ifdef PLATFORM_LINUX
1171 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
1172 #endif
1173 }
1174
1175 return err;
1176
1177 }
1178
1179
1180 #ifdef CONFIG_HOSTAPD_MLME
1181
rtl8188eu_hostap_mgnt_xmit_cb(struct urb * urb)1182 static void rtl8188eu_hostap_mgnt_xmit_cb(struct urb *urb)
1183 {
1184 #ifdef PLATFORM_LINUX
1185 struct sk_buff *skb = (struct sk_buff *)urb->context;
1186
1187 /* RTW_INFO("%s\n", __FUNCTION__); */
1188
1189 rtw_skb_free(skb);
1190 #endif
1191 }
1192
rtl8188eu_hostap_mgnt_xmit_entry(_adapter * padapter,_pkt * pkt)1193 s32 rtl8188eu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
1194 {
1195 #ifdef PLATFORM_LINUX
1196 u16 fc;
1197 int rc, len, pipe;
1198 unsigned int bmcst, tid, qsel;
1199 struct sk_buff *skb, *pxmit_skb;
1200 struct urb *urb;
1201 unsigned char *pxmitbuf;
1202 struct tx_desc *ptxdesc;
1203 struct rtw_ieee80211_hdr *tx_hdr;
1204 struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
1205 struct net_device *pnetdev = padapter->pnetdev;
1206 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1207 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
1208
1209
1210 /* RTW_INFO("%s\n", __FUNCTION__); */
1211
1212 skb = pkt;
1213
1214 len = skb->len;
1215 tx_hdr = (struct rtw_ieee80211_hdr *)(skb->data);
1216 fc = le16_to_cpu(tx_hdr->frame_ctl);
1217 bmcst = IS_MCAST(tx_hdr->addr1);
1218
1219 if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT)
1220 goto _exit;
1221
1222 pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
1223
1224 if (!pxmit_skb)
1225 goto _exit;
1226
1227 pxmitbuf = pxmit_skb->data;
1228
1229 urb = usb_alloc_urb(0, GFP_ATOMIC);
1230 if (!urb)
1231 goto _exit;
1232
1233 /* ----- fill tx desc ----- */
1234 ptxdesc = (struct tx_desc *)pxmitbuf;
1235 _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
1236
1237 /* offset 0 */
1238 ptxdesc->txdw0 |= cpu_to_le32(len & 0x0000ffff);
1239 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); /* default = 32 bytes for TX Desc */
1240 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
1241
1242 if (bmcst)
1243 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
1244
1245 /* offset 4 */
1246 ptxdesc->txdw1 |= cpu_to_le32(0x00);/* MAC_ID */
1247
1248 ptxdesc->txdw1 |= cpu_to_le32((0x12 << QSEL_SHT) & 0x00001f00);
1249
1250 ptxdesc->txdw1 |= cpu_to_le32((0x06 << 16) & 0x000f0000); /* b mode */
1251
1252 /* offset 8 */
1253
1254 /* offset 12 */
1255 ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl) << 16) & 0xffff0000);
1256
1257 /* offset 16 */
1258 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */
1259
1260 /* offset 20 */
1261
1262
1263 /* HW append seq */
1264 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); /* Hw set sequence number */
1265 ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
1266
1267
1268 rtl8188eu_cal_txdesc_chksum(ptxdesc);
1269 /* ----- end of fill tx desc ----- */
1270
1271 /* */
1272 skb_put(pxmit_skb, len + TXDESC_SIZE);
1273 pxmitbuf = pxmitbuf + TXDESC_SIZE;
1274 _rtw_memcpy(pxmitbuf, skb->data, len);
1275
1276 /* RTW_INFO("mgnt_xmit, len=%x\n", pxmit_skb->len); */
1277
1278
1279 /* ----- prepare urb for submit ----- */
1280
1281 /* translate DMA FIFO addr to pipehandle */
1282 /* pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX); */
1283 pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX] & 0x0f);
1284
1285 usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
1286 pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
1287
1288 urb->transfer_flags |= URB_ZERO_PACKET;
1289 usb_anchor_urb(urb, &phostapdpriv->anchored);
1290 rc = usb_submit_urb(urb, GFP_ATOMIC);
1291 if (rc < 0) {
1292 usb_unanchor_urb(urb);
1293 kfree_skb(skb);
1294 }
1295 usb_free_urb(urb);
1296
1297
1298 _exit:
1299
1300 rtw_skb_free(skb);
1301
1302 #endif
1303
1304 return 0;
1305
1306 }
1307 #endif
1308