Esempio n. 1
0
//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;
}
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	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 = HalQueryTxBufferStatus8189ESdio(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;
}
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;
}
Esempio n. 4
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)

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