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