コード例 #1
0
//todo: static
s32 rtl8188es_dequeue_writeport(PADAPTER padapter, u8 *freePage)
{
	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;

#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 == rtl8188es_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;
	}

	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);

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

	return _FAIL;
}
コード例 #2
0
ファイル: rtl8189es_xmit.c プロジェクト: alex-deng/a33_linux
//todo: static 
s32 rtl8188es_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;
#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
	u8	bUpdatePageNum = _FALSE;
#else
	u32	polling_num = 0;
#endif

#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;
	}

	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))
	{
#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
		if (!bUpdatePageNum) {
			// Total number of page is NOT available, so update current FIFO status
			HalQueryTxBufferStatus8189ESdio(padapter);
			bUpdatePageNum = _TRUE;
			goto query_free_page;
		} else {
			bUpdatePageNum = _FALSE;
			enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf);
			return _TRUE;
		}
#else //CONFIG_SDIO_TX_ENABLE_AVAL_INT
		polling_num++;
		if ((polling_num % 60) == 0) {//or 80
			//DBG_871X("%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n",
			//	__func__, n, pxmitbuf->len, pxmitbuf->agg_num, pframe->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]);
			rtw_msleep_os(1);
		}

		// Total number of page is NOT available, so update current FIFO status
		HalQueryTxBufferStatus8189ESdio(padapter);
		goto query_free_page;
#endif //CONFIG_SDIO_TX_ENABLE_AVAL_INT
	}

	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;
	}

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

	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;
}
コード例 #3
0
static u8 rtl8723bs_query_tx_freepage(_adapter *padapter, struct xmit_buf *pxmitbuf)
{
    HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
    struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
    u8	TxRequiredPageNum = 0;
    u8	DedicatedPgNum = 0;
    u8	RequiredPublicFreePgNum = 0;
    u8	PageIdx = 0;
    u8	CheckStep = 0;
    u8	bResult = _TRUE;
    u8	bUpdatePageNum = _FALSE;
    u32	deviceId;


    TxRequiredPageNum = pxmitbuf->pg_num;

    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;
    }

    do {
        if ((padapter->bSurpriseRemoved == _TRUE) || (padapter->bDriverStopped == _TRUE)) {
            RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
                     ("%s: bSurpriseRemoved(update TX FIFO page)\n", __FUNCTION__));
            break;
        }

        // The number of page which public page is included is available .
        if ((pHalData->SdioTxFIFOFreePage[PageIdx]+pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]) > (TxRequiredPageNum+1)) {
            DedicatedPgNum = pHalData->SdioTxFIFOFreePage[PageIdx];
            if (TxRequiredPageNum <= DedicatedPgNum) {
                pHalData->SdioTxFIFOFreePage[PageIdx] -= TxRequiredPageNum;
                break;
            } else {
                pHalData->SdioTxFIFOFreePage[PageIdx] = 0;
                RequiredPublicFreePgNum = TxRequiredPageNum - DedicatedPgNum;
                pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= RequiredPublicFreePgNum;
                break;
            }
        } else { // Total number of page is NOT available, so update current FIFO status.
            if (!bUpdatePageNum) {
                bResult = HalQueryTxBufferStatus8723BSdio(padapter); // Set to default value.
                bUpdatePageNum = _TRUE;
            } else {
                bResult = _FALSE;
            }
        }
    } while(++CheckStep < 2); // step1: user page variables, step2: physical page number

    RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s(): HIQ(%#x), MIQ(%#x), LOQ(%#x), PUBQ(%#x)\n",
             __FUNCTION__,
             pHalData->SdioTxFIFOFreePage[HI_QUEUE_IDX],
             pHalData->SdioTxFIFOFreePage[MID_QUEUE_IDX],
             pHalData->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
             pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));

    RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s(): TxRequiredPageNum(%d) is available to send?(%d)\n",
             __FUNCTION__, TxRequiredPageNum, bResult));

    return bResult;
}
コード例 #4
0
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;
}
コード例 #5
0
static u8 rtl8723bs_query_tx_freepage(_adapter *padapter, struct xmit_buf *pxmitbuf)
{
    HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
    struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
    u8	TxRequiredPageNum = 0;
    u8	DedicatedPgNum = 0;
    u8	RequiredPublicFreePgNum = 0;
    u8	PageIdx = 0;
    u8	bResult = _TRUE;
    u32	n, deviceId;

    TxRequiredPageNum = pxmitbuf->pg_num;

    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;
    }

    // check if hardware tx fifo page is enough
    n = 0;
    do {
        if ((padapter->bSurpriseRemoved == _TRUE) || (padapter->bDriverStopped == _TRUE)) {
            RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
                     ("%s: bSurpriseRemoved(update TX FIFO page)\n", __FUNCTION__));
            break;
        }

        // The number of page which public page is included is available .
        if ((pHalData->SdioTxFIFOFreePage[PageIdx]+pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]) > (TxRequiredPageNum+1)) {
            DedicatedPgNum = pHalData->SdioTxFIFOFreePage[PageIdx];
            if (TxRequiredPageNum <= DedicatedPgNum) {
                pHalData->SdioTxFIFOFreePage[PageIdx] -= TxRequiredPageNum;
                break;
            } else {
                pHalData->SdioTxFIFOFreePage[PageIdx] = 0;
                RequiredPublicFreePgNum = TxRequiredPageNum - DedicatedPgNum;
                pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= RequiredPublicFreePgNum;
                break;
            }
        }

        n++;

#if 0
        if (n >= 5000)
        {
            u8 reg_value_1 = 0;
            u8 reg_value_2 = 0;
            u8 reg_value_3 = 0;

            //try to recover the transmission
            reg_value_1 = rtw_read8(padapter, REG_SYS_FUNC_EN);
            reg_value_2 = rtw_read8(padapter, REG_CR);
            reg_value_3 = rtw_read8(padapter, REG_TXPAUSE);
            DBG_871X("Before recovery: REG_SYS_FUNC_EN = 0x%X, REG_CR = 0x%X, REG_TXPAUSE = 0x%X\n", reg_value_1, reg_value_2, reg_value_3);

            rtw_write8(padapter, REG_SYS_FUNC_EN, reg_value_1 | 0x01);
            rtw_write8(padapter, REG_CR, reg_value_2 | 0xC0);
            rtw_write8(padapter, REG_TXPAUSE, 0);
            DBG_871X("After recovery: REG_SYS_FUNC_EN = 0x%X, REG_CR = 0x%X, REG_TXPAUSE = 0x%X\n",
                     rtw_read8(padapter, REG_SYS_FUNC_EN), rtw_read8(padapter, REG_CR), rtw_read8(padapter, REG_TXPAUSE));
        }
#endif

        if ((n % 0x7F) == 0) {//or 80
            //DBG_871X("%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n",
            //	__func__, n, pxmitbuf->len, pxmitbuf->agg_num, pframe->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]);
            rtw_msleep_os(1);
        }

        // Total number of page is NOT available, so update current FIFO status
        HalQueryTxBufferStatus8723BSdio(padapter);
    } while (1);

    return bResult;
}
コード例 #6
0
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;
}
コード例 #7
0
static u8 rtl8188es_query_tx_freepage(_adapter *padapter, struct xmit_buf *pxmitbuf)
{
	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
	u8	TxRequiredPageNum = 0;
	u8	DedicatedPgNum = 0;
	u8	RequiredPublicFreePgNum = 0;
	u8	PageIdx = 0;
	u8	bResult = _TRUE;
	u32	n, deviceId;

	TxRequiredPageNum = pxmitbuf->pg_num;

	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;
	}

	// check if hardware tx fifo page is enough
	n = 0;
	do {
		if ((padapter->bSurpriseRemoved == _TRUE) || (padapter->bDriverStopped == _TRUE)){
			RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
				 ("%s: bSurpriseRemoved(update TX FIFO page)\n", __FUNCTION__));
			break;
		}

		// The number of page which public page is included is available .
		if ((pHalData->SdioTxFIFOFreePage[PageIdx]+pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]) > (TxRequiredPageNum+1)) {
			DedicatedPgNum = pHalData->SdioTxFIFOFreePage[PageIdx];
			if (TxRequiredPageNum <= DedicatedPgNum) {
				pHalData->SdioTxFIFOFreePage[PageIdx] -= TxRequiredPageNum;
				break;
			} else {
				pHalData->SdioTxFIFOFreePage[PageIdx] = 0;
				RequiredPublicFreePgNum = TxRequiredPageNum - DedicatedPgNum;
				pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= RequiredPublicFreePgNum;
				break;
			}
		}

		n++;
		if ((n % 60) == 0) {//or 80
			//DBG_871X("%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n",
			//	__func__, n, pxmitbuf->len, pxmitbuf->agg_num, pframe->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]);
			rtw_msleep_os(10);
			rtw_yield_os();
		}

		// Total number of page is NOT available, so update current FIFO status
		HalQueryTxBufferStatus8189ESdio(padapter);
	} while (1);

	return bResult;
}