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