xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8188eu/hal/rtl8188e/usb/rtl8188eu_xmit.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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