static s32 rtl8723_dequeue_writeport(PADAPTER padapter)
{
    struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
    struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
    struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
    struct xmit_buf *pxmitbuf;
    PADAPTER pri_padapter = padapter;
    u32 deviceId;
    u32 requiredPage;
    u8 PageIdx=0;
    u8 *freePage;
    _irqL irql;
    u32 n;
    s32 ret = 0;


#ifdef CONFIG_CONCURRENT_MODE
    if (padapter->adapter_type > 0)
        pri_padapter = padapter->pbuddy_adapter;

    if (rtw_buddy_adapter_up(padapter))
        ret = check_buddy_fwstate(padapter, _FW_UNDER_SURVEY);
#endif

    ret = ret || check_fwstate(pmlmepriv, _FW_UNDER_SURVEY);

    if (_TRUE == ret)
        pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv);
    else
        pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);

    if (pxmitbuf == NULL)
        return _TRUE;

query_free_page:
    // check if hardware tx fifo page is enough
    if( _FALSE == rtl8723bs_query_tx_freepage(pri_padapter, pxmitbuf))
    {
        rtw_msleep_os(1);
        goto query_free_page;
    }

    if ((padapter->bSurpriseRemoved == _TRUE)
            || (padapter->bDriverStopped == _TRUE)
#ifdef CONFIG_CONCURRENT_MODE
            ||((padapter->pbuddy_adapter)
               && ((padapter->pbuddy_adapter->bSurpriseRemoved) ||(padapter->pbuddy_adapter->bDriverStopped)))
#endif
       ) {
        RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
                 ("%s: bSurpriseRemoved(wirte port)\n", __FUNCTION__));
        goto free_xmitbuf;
    }


#ifdef CONFIG_CHECK_LEAVE_LPS
    traffic_check_for_leave_lps(padapter, _TRUE, pxmitbuf->agg_num);
#endif


    rtw_write_port(padapter, ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr), pxmitbuf->len, (u8 *)pxmitbuf);

free_xmitbuf:
    //rtw_free_xmitframe(pxmitpriv, pframe);
    //pxmitbuf->priv_data = NULL;
    rtw_free_xmitbuf(pxmitpriv, pxmitbuf);

#if 0 // improve TX/RX throughput balance
    {
        PSDIO_DATA psdio;
        struct sdio_func *func;
        static u8 i = 0;
        u32 sdio_hisr;
        u8 j;

        psdio = &adapter_to_dvobj(padapter)->intf_data;
        func = psdio->func;

        if (i == 2)
        {
            j = 0;
            while (j < 10)
            {
                sdio_hisr = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR);
                sdio_hisr &= GET_HAL_DATA(padapter)->sdio_himr;
                if (sdio_hisr & SDIO_HISR_RX_REQUEST)
                {
                    sdio_claim_host(func);
                    sd_int_hdl(pri_padapter);
                    sdio_release_host(func);
                }
                else
                {
                    break;
                }
                j++;
            }
            i = 0;
        }
        else
        {
            i++;
        }
    }
#endif

#ifdef CONFIG_SDIO_TX_TASKLET
    tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
#endif

    return _FAIL;
}
static s32 rtl8723_dequeue_writeport(PADAPTER padapter)
{
	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
	struct xmit_buf *pxmitbuf;
	PADAPTER pri_padapter = padapter;
	s32 ret = 0;
	u8	PageIdx = 0;
	u32	deviceId;
	u8	bUpdatePageNum = false;

	ret = ret || check_fwstate(pmlmepriv, _FW_UNDER_SURVEY);

	if (true == ret)
		pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv);
	else
		pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);

	if (pxmitbuf == NULL)
		return true;

	deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr);

	// translate fifo addr to queue index
	switch (deviceId) {
		case WLAN_TX_HIQ_DEVICE_ID:
				PageIdx = HI_QUEUE_IDX;
				break;

		case WLAN_TX_MIQ_DEVICE_ID:
				PageIdx = MID_QUEUE_IDX;
				break;

		case WLAN_TX_LOQ_DEVICE_ID:
				PageIdx = LOW_QUEUE_IDX;
				break;
	}

query_free_page:
	// check if hardware tx fifo page is enough
	if( false == rtw_hal_sdio_query_tx_freepage(pri_padapter, PageIdx, pxmitbuf->pg_num))
	{
		if (!bUpdatePageNum) {
			// Total number of page is NOT available, so update current FIFO status
			HalQueryTxBufferStatus8723BSdio(padapter);
			bUpdatePageNum = true;
			goto query_free_page;
		} else {
			bUpdatePageNum = false;
			enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf);
			return true;
		}
	}

	if ((padapter->bSurpriseRemoved == true)
		|| (padapter->bDriverStopped == true)){
		RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
			 ("%s: bSurpriseRemoved(wirte port)\n", __FUNCTION__));
		goto free_xmitbuf;
	}

	if (rtw_sdio_wait_enough_TxOQT_space(padapter, pxmitbuf->agg_num) == false)
	{
		goto free_xmitbuf;
	}

	traffic_check_for_leave_lps(padapter, true, pxmitbuf->agg_num);

	rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8 *)pxmitbuf);

	rtw_hal_sdio_update_tx_freepage(pri_padapter, PageIdx, pxmitbuf->pg_num);

free_xmitbuf:
	//rtw_free_xmitframe(pxmitpriv, pframe);
	//pxmitbuf->priv_data = NULL;
	rtw_free_xmitbuf(pxmitpriv, pxmitbuf);

#ifdef CONFIG_SDIO_TX_TASKLET
	tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
#endif

	return _FAIL;
}