1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
20 #define _RTL8703BS_XMIT_C_
22 #include <rtl8703b_hal.h>
24 static u8 rtw_sdio_wait_enough_TxOQT_space(PADAPTER padapter, u8 agg_num)
27 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
29 while (pHalData->SdioTxOQTFreeSpace < agg_num) {
30 if (RTW_CANNOT_RUN(padapter)) {
31 RTW_INFO("%s: bSurpriseRemoved or bDriverStopped (wait TxOQT)\n", __func__);
35 HalQueryTxOQTBufferStatus8703BSdio(padapter);
37 if ((++n % 60) == 0) {
39 RTW_INFO("%s(%d): QOT free space(%d), agg_num: %d\n",
40 __func__, n, pHalData->SdioTxOQTFreeSpace, agg_num);
47 pHalData->SdioTxOQTFreeSpace -= agg_num;
50 /* ++priv->pshare->nr_out_of_txoqt_space; */
55 s32 _dequeue_writeport(PADAPTER padapter)
57 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
58 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
59 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
60 struct xmit_buf *pxmitbuf;
63 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
64 u8 bUpdatePageNum = _FALSE;
69 pxmitbuf = select_and_dequeue_pending_xmitbuf(padapter);
74 deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr);
76 /* translate fifo addr to queue index */
78 case WLAN_TX_HIQ_DEVICE_ID:
79 PageIdx = HI_QUEUE_IDX;
82 case WLAN_TX_MIQ_DEVICE_ID:
83 PageIdx = MID_QUEUE_IDX;
86 case WLAN_TX_LOQ_DEVICE_ID:
87 PageIdx = LOW_QUEUE_IDX;
92 /* check if hardware tx fifo page is enough */
93 if (_FALSE == rtw_hal_sdio_query_tx_freepage(padapter, PageIdx, pxmitbuf->pg_num)) {
94 if (RTW_CANNOT_RUN(padapter))
96 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
97 if (!bUpdatePageNum) {
98 /* Total number of page is NOT available, so update current FIFO status */
99 HalQueryTxBufferStatus8703BSdio(padapter);
100 bUpdatePageNum = _TRUE;
101 goto query_free_page;
103 bUpdatePageNum = _FALSE;
104 enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf);
107 #else /* CONFIG_SDIO_TX_ENABLE_AVAL_INT */
109 if ((polling_num % 10) == 0) {
110 /* RTW_INFO("%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n", */
111 /* __func__, polling_num, pxmitbuf->len, pxmitbuf->agg_num, pframe->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]); */
112 enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf);
117 /* Total number of page is NOT available, so update current FIFO status */
118 HalQueryTxBufferStatus8703BSdio(padapter);
119 goto query_free_page;
120 #endif /* CONFIG_SDIO_TX_ENABLE_AVAL_INT */
123 if (rtw_sdio_wait_enough_TxOQT_space(padapter, pxmitbuf->agg_num) == _FALSE)
126 #ifdef CONFIG_CHECK_LEAVE_LPS
127 traffic_check_for_leave_lps(padapter, _TRUE, pxmitbuf->agg_num);
130 rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8 *)pxmitbuf);
132 rtw_hal_sdio_update_tx_freepage(padapter, PageIdx, pxmitbuf->pg_num);
135 /* rtw_free_xmitframe(pxmitpriv, pframe); */
136 /* pxmitbuf->priv_data = NULL; */
137 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
139 #if 0 /* improve TX/RX throughput balance */
142 struct sdio_func *func;
147 psdio = &adapter_to_dvobj(padapter)->intf_data;
153 sdio_hisr = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR);
154 sdio_hisr &= GET_HAL_DATA(padapter)->sdio_himr;
155 if (sdio_hisr & SDIO_HISR_RX_REQUEST) {
156 sdio_claim_host(func);
157 sd_int_hdl(GET_PRIMARY_ADAPTER(padapter));
158 sdio_release_host(func);
169 #ifdef CONFIG_SDIO_TX_TASKLET
170 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
178 * Transmit xmitbuf to hardware tx fifo
182 * _FAIL something error
184 s32 rtl8703bs_xmit_buf_handler(PADAPTER padapter)
186 struct xmit_priv *pxmitpriv;
191 pxmitpriv = &padapter->xmitpriv;
193 ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
195 RTW_ERR("%s: down SdioXmitBufSema fail!\n", __FUNCTION__);
199 if (RTW_CANNOT_RUN(padapter)) {
203 if (rtw_mi_check_pending_xmitbuf(padapter) == 0)
206 #ifdef CONFIG_LPS_LCLK
207 ret = rtw_register_tx_alive(padapter);
213 queue_empty = rtw_mi_dequeue_writeport(padapter);
214 } while (!queue_empty);
216 #ifdef CONFIG_LPS_LCLK
217 rtw_unregister_tx_alive(padapter);
225 * Aggregation packets and send to hardware
229 * -1 Hardware resource(TX FIFO) not ready
230 * -2 Software resource(xmitbuf) not ready
232 static s32 xmit_xmitframes(PADAPTER padapter, struct xmit_priv *pxmitpriv)
236 struct hw_xmit *hwxmits, *phwxmit;
237 u8 no_res, idx, hwentry;
239 struct tx_servq *ptxservq;
240 _list *sta_plist, *sta_phead, *frame_plist, *frame_phead;
241 struct xmit_frame *pxmitframe;
242 _queue *pframe_queue;
243 struct xmit_buf *pxmitbuf;
244 u32 txlen, max_xmit_len, page_size;
245 u8 txdesc_size = TXDESC_SIZE;
247 u8 pre_qsel = 0xFF, next_qsel = 0xFF;
248 u8 single_sta_in_queue = _FALSE;
252 hwxmits = pxmitpriv->hwxmits;
253 hwentry = pxmitpriv->hwxmit_entry;
258 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
260 if (padapter->registrypriv.wifi_spec == 1) {
261 for (idx = 0; idx < 4; idx++)
262 inx[idx] = pxmitpriv->wmm_para_seq[idx];
270 /* 0(VO), 1(VI), 2(BE), 3(BK) */
271 for (idx = 0; idx < hwentry; idx++) {
272 phwxmit = hwxmits + inx[idx];
274 if ((check_pending_xmitbuf(pxmitpriv) == _TRUE) && (padapter->mlmepriv.LinkDetectInfo.bHigherBusyTxTraffic == _TRUE)) {
275 if ((phwxmit->accnt > 0) && (phwxmit->accnt < 5)) {
281 max_xmit_len = rtw_hal_get_sdio_tx_max_length(padapter, inx[idx]);
283 _enter_critical_bh(&pxmitpriv->lock, &irql);
285 sta_phead = get_list_head(phwxmit->sta_queue);
286 sta_plist = get_next(sta_phead);
287 /* because stop_sta_xmit may delete sta_plist at any time */
288 /* so we should add lock here, or while loop can not exit */
290 single_sta_in_queue = rtw_end_of_queue_search(sta_phead, get_next(sta_plist));
292 while (rtw_end_of_queue_search(sta_phead, sta_plist) == _FALSE) {
293 ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
294 sta_plist = get_next(sta_plist);
297 RTW_INFO("%s idx:%d hwxmit_pkt_num:%d ptxservq_pkt_num:%d\n", __func__, idx, phwxmit->accnt, ptxservq->qcnt);
298 RTW_INFO("%s free_xmit_extbuf_cnt=%d free_xmitbuf_cnt=%d free_xmitframe_cnt=%d\n",
299 __func__, pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xmitbuf_cnt,
300 pxmitpriv->free_xmitframe_cnt);
302 pframe_queue = &ptxservq->sta_pending;
304 frame_phead = get_list_head(pframe_queue);
306 while (rtw_is_list_empty(frame_phead) == _FALSE) {
307 frame_plist = get_next(frame_phead);
308 pxmitframe = LIST_CONTAINOR(frame_plist, struct xmit_frame, list);
310 /* check xmit_buf size enough or not */
311 txlen = txdesc_size + rtw_wlan_pkt_size(pxmitframe);
312 next_qsel = pxmitframe->attrib.qsel;
313 if ((NULL == pxmitbuf) ||
314 (pxmitbuf->pg_num + PageNum(txlen, page_size) > PageNum(max_xmit_len, page_size))
315 || (k >= (rtw_hal_sdio_max_txoqt_free_space(padapter) - 1))
316 || ((k != 0) && (_FAIL == rtw_hal_busagg_qsel_check(padapter, pre_qsel, next_qsel)))
319 /* pxmitbuf->priv_data will be NULL, and will crash here */
320 if (pxmitbuf->len > 0 && pxmitbuf->priv_data) {
321 struct xmit_frame *pframe;
322 pframe = (struct xmit_frame *)pxmitbuf->priv_data;
324 pxmitbuf->agg_num = k;
325 rtl8703b_update_txdesc(pframe, pframe->buf_addr);
326 rtw_free_xmitframe(pxmitpriv, pframe);
327 pxmitbuf->priv_data = NULL;
328 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
329 /* can not yield under lock */
331 /* rtw_yield_os(); */
332 if (single_sta_in_queue == _FALSE) {
333 /* break the loop in case there is more than one sta in this ac queue */
339 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
342 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
343 if (pxmitbuf == NULL) {
345 RTW_ERR("%s: xmit_buf is not enough!\n", __FUNCTION__);
348 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
349 _rtw_up_sema(&(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.xmit_sema));
356 /* ok to send, remove frame from queue */
357 #ifdef CONFIG_AP_MODE
358 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
359 if ((pxmitframe->attrib.psta->state & WIFI_SLEEP_STATE) &&
360 (pxmitframe->attrib.triggered == 0)) {
361 RTW_INFO("%s: one not triggered pkt in queue when this STA sleep,"
362 " break and goto next sta\n", __func__);
367 rtw_list_delete(&pxmitframe->list);
372 pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
373 pxmitbuf->priv_data = (u8 *)pxmitframe;
376 /* coalesce the xmitframe to xmitbuf */
377 pxmitframe->pxmitbuf = pxmitbuf;
378 pxmitframe->buf_addr = pxmitbuf->ptail;
380 ret = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
382 RTW_ERR("%s: coalesce FAIL!", __FUNCTION__);
383 /* Todo: error handler */
387 rtl8703b_update_txdesc(pxmitframe, pxmitframe->buf_addr);
388 rtw_count_tx_stats(padapter, pxmitframe, pxmitframe->attrib.last_txcmdsz);
389 pre_qsel = pxmitframe->attrib.qsel;
390 txlen = txdesc_size + pxmitframe->attrib.last_txcmdsz;
391 pxmitframe->pg_num = (txlen + 127) / 128;
392 pxmitbuf->pg_num += (txlen + 127) / 128;
394 /* ((struct xmit_frame*)pxmitbuf->priv_data)->pg_num += pxmitframe->pg_num; */
395 pxmitbuf->ptail += _RND(txlen, 8); /* round to 8 bytes alignment */
396 pxmitbuf->len = _RND(pxmitbuf->len, 8) + txlen;
400 rtw_free_xmitframe(pxmitpriv, pxmitframe);
404 if (_rtw_queue_empty(pframe_queue) == _TRUE)
405 rtw_list_delete(&ptxservq->tx_pending);
406 else if (err == -3) {
407 /* Re-arrange the order of stations in this ac queue to balance the service for these stations */
408 rtw_list_delete(&ptxservq->tx_pending);
409 rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmit->sta_queue));
415 _exit_critical_bh(&pxmitpriv->lock, &irql);
417 /* dump xmit_buf to hw tx fifo */
420 if (pxmitbuf->len > 0) {
421 struct xmit_frame *pframe;
422 pframe = (struct xmit_frame *)pxmitbuf->priv_data;
424 pxmitbuf->agg_num = k;
425 rtl8703b_update_txdesc(pframe, pframe->buf_addr);
426 rtw_free_xmitframe(pxmitpriv, pframe);
427 pxmitbuf->priv_data = NULL;
428 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
431 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
444 * Transmit xmitframe from queue
448 * _FAIL something error
450 s32 rtl8703bs_xmit_handler(PADAPTER padapter)
452 struct xmit_priv *pxmitpriv;
457 pxmitpriv = &padapter->xmitpriv;
460 ret = _rtw_down_sema(&pxmitpriv->SdioXmitSema);
462 RTW_ERR("%s: down sema fail!\n", __FUNCTION__);
467 if (RTW_CANNOT_RUN(padapter)) {
471 _enter_critical_bh(&pxmitpriv->lock, &irql);
472 ret = rtw_txframes_pending(padapter);
473 _exit_critical_bh(&pxmitpriv->lock, &irql);
477 /* dequeue frame and write to hardware */
479 ret = xmit_xmitframes(padapter, pxmitpriv);
481 /* here sleep 1ms will cause big TP loss of TX */
482 /* from 50+ to 40+ */
483 if (padapter->registrypriv.wifi_spec)
486 #ifdef CONFIG_REDUCE_TX_CPU_LOADING
494 _enter_critical_bh(&pxmitpriv->lock, &irql);
495 ret = rtw_txframes_pending(padapter);
496 _exit_critical_bh(&pxmitpriv->lock, &irql);
498 #ifdef CONFIG_REDUCE_TX_CPU_LOADING
507 thread_return rtl8703bs_xmit_thread(thread_context context)
511 struct xmit_priv *pxmitpriv;
512 u8 thread_name[20] = "RTWHALXT";
516 padapter = (PADAPTER)context;
517 pxmitpriv = &padapter->xmitpriv;
519 rtw_sprintf(thread_name, 20, "%s-"ADPT_FMT, thread_name, ADPT_ARG(padapter));
520 thread_enter(thread_name);
522 RTW_INFO("start "FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
524 /* For now, no one would down sema to check thread is running, */
525 /* so mark this temporary, Lucas@20130820
526 * _rtw_up_sema(&pxmitpriv->SdioXmitTerminateSema); */
529 ret = rtl8703bs_xmit_handler(padapter);
530 if (signal_pending(current))
531 flush_signals(current);
532 } while (_SUCCESS == ret);
534 _rtw_up_sema(&pxmitpriv->SdioXmitTerminateSema);
540 s32 rtl8703bs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe)
543 struct pkt_attrib *pattrib;
544 struct xmit_buf *pxmitbuf;
545 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
546 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
547 u8 *pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
548 u8 txdesc_size = TXDESC_SIZE;
551 pattrib = &pmgntframe->attrib;
552 pxmitbuf = pmgntframe->pxmitbuf;
554 rtl8703b_update_txdesc(pmgntframe, pmgntframe->buf_addr);
556 pxmitbuf->len = txdesc_size + pattrib->last_txcmdsz;
557 /* pmgntframe->pg_num = (pxmitbuf->len + 127)/128; // 128 is tx page size */
558 pxmitbuf->pg_num = (pxmitbuf->len + 127) / 128; /* 128 is tx page size */
559 pxmitbuf->ptail = pmgntframe->buf_addr + pxmitbuf->len;
560 pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pmgntframe);
562 rtw_count_tx_stats(padapter, pmgntframe, pattrib->last_txcmdsz);
564 rtw_free_xmitframe(pxmitpriv, pmgntframe);
566 pxmitbuf->priv_data = NULL;
568 if (get_frame_sub_type(pframe) == WIFI_BEACON) { /* dump beacon directly */
569 ret = rtw_write_port(padapter, pdvobjpriv->Queue2Pipe[pxmitbuf->ff_hwaddr], pxmitbuf->len, (u8 *)pxmitbuf);
571 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
573 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
575 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
582 * Handle xmitframe(packet) come from rtw_xmit()
585 * _TRUE dump packet directly ok
586 * _FALSE enqueue, temporary can't transmit packets to hardware
588 s32 rtl8703bs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe)
590 struct xmit_priv *pxmitpriv;
595 pxmitframe->attrib.qsel = pxmitframe->attrib.priority;
596 pxmitpriv = &padapter->xmitpriv;
598 #ifdef CONFIG_80211N_HT
599 if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
600 (pxmitframe->attrib.ether_type != 0x0806) &&
601 (pxmitframe->attrib.ether_type != 0x888e) &&
602 (pxmitframe->attrib.dhcp_pkt != 1)) {
603 if (padapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)
604 rtw_issue_addbareq_cmd(padapter, pxmitframe);
608 _enter_critical_bh(&pxmitpriv->lock, &irql);
609 err = rtw_xmitframe_enqueue(padapter, pxmitframe);
610 _exit_critical_bh(&pxmitpriv->lock, &irql);
611 if (err != _SUCCESS) {
612 rtw_free_xmitframe(pxmitpriv, pxmitframe);
614 pxmitpriv->tx_drop++;
618 _rtw_up_sema(&pxmitpriv->SdioXmitSema);
623 s32 rtl8703bs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
625 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
628 err = rtw_xmitframe_enqueue(padapter, pxmitframe);
629 if (err != _SUCCESS) {
630 rtw_free_xmitframe(pxmitpriv, pxmitframe);
632 pxmitpriv->tx_drop++;
634 #ifdef CONFIG_SDIO_TX_TASKLET
635 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
637 _rtw_up_sema(&pxmitpriv->SdioXmitSema);
647 * _SUCCESS start thread ok
648 * _FAIL start thread fail
651 s32 rtl8703bs_init_xmit_priv(PADAPTER padapter)
653 struct xmit_priv *xmitpriv = &padapter->xmitpriv;
657 phal = GET_HAL_DATA(padapter);
659 _rtw_spinlock_init(&phal->SdioTxFIFOFreePageLock);
660 _rtw_init_sema(&xmitpriv->SdioXmitSema, 0);
661 _rtw_init_sema(&xmitpriv->SdioXmitTerminateSema, 0);
666 void rtl8703bs_free_xmit_priv(PADAPTER padapter)
669 struct xmit_priv *pxmitpriv;
670 struct xmit_buf *pxmitbuf;
672 _list *plist, *phead;
677 phal = GET_HAL_DATA(padapter);
678 pxmitpriv = &padapter->xmitpriv;
679 pqueue = &pxmitpriv->pending_xmitbuf_queue;
680 phead = get_list_head(pqueue);
681 _rtw_init_listhead(&tmplist);
683 _enter_critical_bh(&pqueue->lock, &irql);
684 if (_rtw_queue_empty(pqueue) == _FALSE) {
685 /* Insert tmplist to end of queue, and delete phead */
686 /* then tmplist become head of queue. */
687 rtw_list_insert_tail(&tmplist, phead);
688 rtw_list_delete(phead);
690 _exit_critical_bh(&pqueue->lock, &irql);
693 while (rtw_is_list_empty(phead) == _FALSE) {
694 plist = get_next(phead);
695 rtw_list_delete(plist);
697 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
698 rtw_free_xmitframe(pxmitpriv, (struct xmit_frame *)pxmitbuf->priv_data);
699 pxmitbuf->priv_data = NULL;
700 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
703 _rtw_spinlock_free(&phal->SdioTxFIFOFreePageLock);