예제 #1
0
파일: sdio_ops.c 프로젝트: Lyude/linux
static s32 ReadInterrupt8723BSdio(struct adapter *adapter, u32 *phisr)
{
	u32 hisr, himr;
	u8 val8, hisr_len;


	if (!phisr)
		return false;

	himr = GET_HAL_DATA(adapter)->sdio_himr;

	/*  decide how many bytes need to be read */
	hisr_len = 0;
	while (himr) {
		hisr_len++;
		himr >>= 8;
	}

	hisr = 0;
	while (hisr_len != 0) {
		hisr_len--;
		val8 = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HISR+hisr_len);
		hisr |= (val8 << (8*hisr_len));
	}

	*phisr = hisr;

	return true;
}
예제 #2
0
static s32 ReadInterrupt8723BSdio(PADAPTER padapter, u32 *phisr)
{
	u32 hisr, himr;
	u8 val8, hisr_len;


	if (phisr == NULL)
		return _FALSE;

	himr = GET_HAL_DATA(padapter)->sdio_himr;

	// decide how many bytes need to be read
	hisr_len = 0;
	while (himr)
	{
		hisr_len++;
		himr >>= 8;
	}

	hisr = 0;
	while (hisr_len != 0)
	{
		hisr_len--;
		val8 = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR+hisr_len);
		hisr |= (val8 << (8*hisr_len));
	}

	*phisr = hisr;

	return _TRUE;
}
예제 #3
0
파일: sdio_ops.c 프로젝트: Lyude/linux
u8 HalQueryTxOQTBufferStatus8723BSdio(struct adapter *adapter)
{
	struct hal_com_data *haldata = GET_HAL_DATA(adapter);

	haldata->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_OQT_FREE_PG);
	return true;
}
예제 #4
0
파일: sdio_ops.c 프로젝트: Lyude/linux
void sd_int_dpc(struct adapter *adapter)
{
	struct hal_com_data *hal;
	struct dvobj_priv *dvobj;
	struct intf_hdl *intfhdl = &adapter->iopriv.intf;
	struct pwrctrl_priv *pwrctl;


	hal = GET_HAL_DATA(adapter);
	dvobj = adapter_to_dvobj(adapter);
	pwrctl = dvobj_to_pwrctl(dvobj);

	if (hal->sdio_hisr & SDIO_HISR_AVAL) {
		u8 freepage[4];

		_sdio_local_read(adapter, SDIO_REG_FREE_TXPG, 4, freepage);
		up(&(adapter->xmitpriv.xmit_sema));
	}

	if (hal->sdio_hisr & SDIO_HISR_CPWM1) {
		struct reportpwrstate_parm report;

		u8 bcancelled;
		_cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled);

		report.state = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HCPWM1_8723B);

		/* cpwm_int_hdl(adapter, &report); */
		_set_workitem(&(pwrctl->cpwm_event));
	}

	if (hal->sdio_hisr & SDIO_HISR_TXERR) {
		u8 *status;
		u32 addr;

		status = rtw_malloc(4);
		if (status) {
			addr = REG_TXDMA_STATUS;
			HalSdioGetCmdAddr8723BSdio(adapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
			_sd_read(intfhdl, addr, 4, status);
			_sd_write(intfhdl, addr, 4, status);
			DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32 *)status));
			kfree(status);
		} else {
			DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
		}
	}

	if (hal->sdio_hisr & SDIO_HISR_TXBCNOK) {
		DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
	}

	if (hal->sdio_hisr & SDIO_HISR_TXBCNERR) {
		DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
	}
#ifndef CONFIG_C2H_PACKET_EN
	if (hal->sdio_hisr & SDIO_HISR_C2HCMD) {
		struct c2h_evt_hdr_88xx *c2h_evt;

		DBG_8192C("%s: C2H Command\n", __func__);
		c2h_evt = rtw_zmalloc(16);
		if (c2h_evt != NULL) {
			if (rtw_hal_c2h_evt_read(adapter, (u8 *)c2h_evt) == _SUCCESS) {
				if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) {
					/* Handle CCX report here */
					rtw_hal_c2h_handler(adapter, (u8 *)c2h_evt);
					kfree((u8 *)c2h_evt);
				} else {
					rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt);
				}
			}
		} else {
			/* Error handling for malloc fail */
			if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, NULL) != _SUCCESS)
				DBG_871X("%s rtw_cbuf_push fail\n", __func__);
			_set_workitem(&adapter->evtpriv.c2h_wk);
		}
	}
#endif

	if (hal->sdio_hisr & SDIO_HISR_RXFOVW) {
		DBG_8192C("%s: Rx Overflow\n", __func__);
	}

	if (hal->sdio_hisr & SDIO_HISR_RXERR) {
		DBG_8192C("%s: Rx Error\n", __func__);
	}

	if (hal->sdio_hisr & SDIO_HISR_RX_REQUEST) {
		struct recv_buf *recvbuf;
		int alloc_fail_time = 0;
		u32 hisr;

/* 		DBG_8192C("%s: RX Request, size =%d\n", __func__, hal->SdioRxFIFOSize); */
		hal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
		do {
			hal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(adapter, SDIO_REG_RX0_REQ_LEN);
			if (hal->SdioRxFIFOSize != 0) {
				recvbuf = sd_recv_rxfifo(adapter, hal->SdioRxFIFOSize);
				if (recvbuf)
					sd_rxhandler(adapter, recvbuf);
				else {
					alloc_fail_time++;
					DBG_871X("recvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time);
					if (alloc_fail_time >= 10)
						break;
				}
				hal->SdioRxFIFOSize = 0;
			} else
				break;

			hisr = 0;
			ReadInterrupt8723BSdio(adapter, &hisr);
			hisr &= SDIO_HISR_RX_REQUEST;
			if (!hisr)
				break;
		} while (1);

		if (alloc_fail_time == 10)
			DBG_871X("exit because alloc memory failed more than 10 times\n");

	}
}
예제 #5
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;
}
예제 #6
0
//
//	Description:
//		Query SDIO Local register to get the current number of TX OQT Free Space.
//
u8 HalQueryTxOQTBufferStatus8723BSdio(PADAPTER padapter)
{
	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
	pHalData->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_OQT_FREE_PG);
	return _TRUE;
}
예제 #7
0
void sd_int_dpc(PADAPTER padapter)
{
	PHAL_DATA_TYPE phal;
	struct dvobj_priv *dvobj;
	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
	struct pwrctrl_priv *pwrctl;


	phal = GET_HAL_DATA(padapter);
	dvobj = adapter_to_dvobj(padapter);
	pwrctl = dvobj_to_pwrctl(dvobj);

#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
	if (phal->sdio_hisr & SDIO_HISR_AVAL)
	{
		//_irqL irql;
		u8	freepage[4];

		_sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 4, freepage);
		//_enter_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);
		//_rtw_memcpy(phal->SdioTxFIFOFreePage, freepage, 4);
		//_exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);
		//DBG_871X("SDIO_HISR_AVAL, Tx Free Page = 0x%x%x%x%x\n",
		//	freepage[0],
		//	freepage[1],
		//	freepage[2],
		//	freepage[3]);
		_rtw_up_sema(&(padapter->xmitpriv.xmit_sema));
	}
#endif
	if (phal->sdio_hisr & SDIO_HISR_CPWM1)
	{
		struct reportpwrstate_parm report;

#ifdef CONFIG_LPS_RPWM_TIMER
		u8 bcancelled;
		_cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled);
#endif // CONFIG_LPS_RPWM_TIMER

		report.state = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HCPWM1_8723B);

#ifdef CONFIG_LPS_LCLK
		//cpwm_int_hdl(padapter, &report);
		_set_workitem(&(pwrctl->cpwm_event));
#endif
	}

	if (phal->sdio_hisr & SDIO_HISR_TXERR)
	{
		u8 *status;
		u32 addr;

		status = rtw_malloc(4);
		if (status)
		{
			addr = REG_TXDMA_STATUS;
			HalSdioGetCmdAddr8723BSdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
			_sd_read(pintfhdl, addr, 4, status);
			_sd_write(pintfhdl, addr, 4, status);
			DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32*)status));
			rtw_mfree(status, 4);
		} else {
			DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
		}
	}

	if (phal->sdio_hisr & SDIO_HISR_TXBCNOK)
	{
		DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
	}

	if (phal->sdio_hisr & SDIO_HISR_TXBCNERR)
	{
		DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
	}
#ifndef CONFIG_C2H_PACKET_EN
	if (phal->sdio_hisr & SDIO_HISR_C2HCMD)
	{
		struct c2h_evt_hdr_88xx *c2h_evt;

		DBG_8192C("%s: C2H Command\n", __func__);
		if ((c2h_evt = (struct c2h_evt_hdr_88xx*)rtw_zmalloc(16)) != NULL) {
			if (rtw_hal_c2h_evt_read(padapter, (u8 *)c2h_evt) == _SUCCESS) {
				if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) {
					/* Handle CCX report here */
					rtw_hal_c2h_handler(padapter, (u8 *)c2h_evt);
					rtw_mfree((u8*)c2h_evt, 16);
				} else {
					rtw_c2h_wk_cmd(padapter, (u8 *)c2h_evt);
				}
			}
		} else {
			/* Error handling for malloc fail */
			if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, (void*)NULL) != _SUCCESS)
				DBG_871X("%s rtw_cbuf_push fail\n", __func__);
			_set_workitem(&padapter->evtpriv.c2h_wk);
		}
	}
#endif	

	if (phal->sdio_hisr & SDIO_HISR_RXFOVW)
	{
		DBG_8192C("%s: Rx Overflow\n", __func__);
	}
	if (phal->sdio_hisr & SDIO_HISR_RXERR)
	{
		DBG_8192C("%s: Rx Error\n", __func__);
	}

	if (phal->sdio_hisr & SDIO_HISR_RX_REQUEST)
	{
		struct recv_buf *precvbuf;
		int alloc_fail_time=0;
		u32 hisr;

//		DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize);
		phal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
		do {
			phal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(padapter, SDIO_REG_RX0_REQ_LEN);
			if (phal->SdioRxFIFOSize != 0)
			{
#ifdef CONFIG_MAC_LOOPBACK_DRIVER
				sd_recv_loopback(padapter, phal->SdioRxFIFOSize);
#else
				precvbuf = sd_recv_rxfifo(padapter, phal->SdioRxFIFOSize);
				if (precvbuf)
				     	sd_rxhandler(padapter, precvbuf);
				else
				{
					alloc_fail_time++;
					DBG_871X("precvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time);
					if (alloc_fail_time >= 10)
						break;
				}
				phal->SdioRxFIFOSize = 0;
#endif
			}
			else
				break;

			hisr = 0;
			ReadInterrupt8723BSdio(padapter, &hisr);
			hisr &= SDIO_HISR_RX_REQUEST;
			if (!hisr)
				break;
		} while (1);

		if(alloc_fail_time==10)
			DBG_871X("exit because alloc memory failed more than 10 times \n");

	}
}
예제 #8
0
//
//	Description:
//		This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC.
//
//	Assumption:
//		We should follow specific format which was released from HW SD.
//
//	2011.07.07, added by Roger.
//
u8 HalPwrSeqCmdParsing(
	PADAPTER		padapter,
	u8				CutVersion,
	u8				FabVersion,
	u8				InterfaceType,
	WLAN_PWR_CFG	PwrSeqCmd[])
{
	WLAN_PWR_CFG 	PwrCfgCmd = {0};
	u8				bPollingBit = _FALSE;
	u32				AryIdx = 0;
	u8				value = 0;
	u32				offset = 0;
	u32				pollingCount = 0; // polling autoload done.
	u32				maxPollingCnt = 5000;

	do {
		PwrCfgCmd = PwrSeqCmd[AryIdx];

		RT_TRACE(_module_hal_init_c_ , _drv_info_,
				 ("HalPwrSeqCmdParsing: offset(%#x) cut_msk(%#x) fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x) msk(%#x) value(%#x)\n",
					GET_PWR_CFG_OFFSET(PwrCfgCmd),
					GET_PWR_CFG_CUT_MASK(PwrCfgCmd),
					GET_PWR_CFG_FAB_MASK(PwrCfgCmd),
					GET_PWR_CFG_INTF_MASK(PwrCfgCmd),
					GET_PWR_CFG_BASE(PwrCfgCmd),
					GET_PWR_CFG_CMD(PwrCfgCmd),
					GET_PWR_CFG_MASK(PwrCfgCmd),
					GET_PWR_CFG_VALUE(PwrCfgCmd)));

		//2 Only Handle the command whose FAB, CUT, and Interface are matched
		if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) &&
			(GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) &&
			(GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType))
		{
			switch (GET_PWR_CFG_CMD(PwrCfgCmd))
			{
				case PWR_CMD_READ:
					RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_READ\n"));
					break;

				case PWR_CMD_WRITE:
					RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_WRITE\n"));
					offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);

#ifdef CONFIG_SDIO_HCI
					//
					// <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface
					// 2011.07.07.
					//
					if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
					{
						// Read Back SDIO Local value
						value = SdioLocalCmd52Read1Byte(padapter, offset);

						value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
						value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));

						// Write Back SDIO Local value
						SdioLocalCmd52Write1Byte(padapter, offset, value);
					}
					else
#endif
					{
#ifdef CONFIG_GSPI_HCI
						if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
							offset = SPI_LOCAL_OFFSET | offset;
#endif
						// Read the value from system register
						value = rtw_read8(padapter, offset);

						value=value&(~(GET_PWR_CFG_MASK(PwrCfgCmd)));
						value=value|(GET_PWR_CFG_VALUE(PwrCfgCmd)&GET_PWR_CFG_MASK(PwrCfgCmd));

						// Write the value back to sytem register
						rtw_write8(padapter, offset, value);
					}
					break;

				case PWR_CMD_POLLING:
					RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_POLLING\n"));

					bPollingBit = _FALSE;
					offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
#ifdef CONFIG_GSPI_HCI
					if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
						offset = SPI_LOCAL_OFFSET | offset;
#endif
					do {
#ifdef CONFIG_SDIO_HCI
						if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
							value = SdioLocalCmd52Read1Byte(padapter, offset);
						else
#endif
							value = rtw_read8(padapter, offset);

						value=value&GET_PWR_CFG_MASK(PwrCfgCmd);
						if (value == (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)))
							bPollingBit = _TRUE;
						else
							rtw_udelay_os(10);

						if (pollingCount++ > maxPollingCnt) {
							DBG_871X("Fail to polling Offset[%#x]=%02x\n", offset, value);
							return _FALSE;
						}
					} while (!bPollingBit);

					break;

				case PWR_CMD_DELAY:
					RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_DELAY\n"));
					if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
						rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd));
					else
						rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000);
					break;

				case PWR_CMD_END:
					// When this command is parsed, end the process
					RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_END\n"));
					return _TRUE;
					break;

				default:
					RT_TRACE(_module_hal_init_c_ , _drv_err_, ("HalPwrSeqCmdParsing: Unknown CMD!!\n"));
					break;
			}
		}

		AryIdx++;//Add Array Index
	}while(1);

	return _TRUE;
}
예제 #9
0
/*
 *	Description:
 *		This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC.
 *
 *	Assumption:
 *		We should follow specific format which was released from HW SD.
 *
 *	2011.07.07, added by Roger.
 *   */
u8 HalPwrSeqCmdParsing(
	PADAPTER		padapter,
	u8				CutVersion,
	u8				FabVersion,
	u8				InterfaceType,
	WLAN_PWR_CFG	PwrSeqCmd[])
{
	WLAN_PWR_CFG	PwrCfgCmd = {0};
	u8				bPollingBit = _FALSE;
	u32				AryIdx = 0;
	u8				value = 0;
	u32				offset = 0;
	u32				pollingCount = 0; /* polling autoload done. */
	u32				maxPollingCnt = 5000;

	do {
		PwrCfgCmd = PwrSeqCmd[AryIdx];


		/* 2 Only Handle the command whose FAB, CUT, and Interface are matched */
		if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) &&
		    (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) &&
		    (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)) {
			switch (GET_PWR_CFG_CMD(PwrCfgCmd)) {
			case PWR_CMD_READ:
				break;

			case PWR_CMD_WRITE:
				offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);

#ifdef CONFIG_SDIO_HCI
				/*  */
				/* <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface */
				/* 2011.07.07. */
				/*  */
				if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) {
					/* Read Back SDIO Local value */
					value = SdioLocalCmd52Read1Byte(padapter, offset);

					value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
					value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));

					/* Write Back SDIO Local value */
					SdioLocalCmd52Write1Byte(padapter, offset, value);
				} else
#endif
				{
#ifdef CONFIG_GSPI_HCI
					if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
						offset = SPI_LOCAL_OFFSET | offset;
#endif
					/* Read the value from system register */
					value = rtw_read8(padapter, offset);

					value = value & (~(GET_PWR_CFG_MASK(PwrCfgCmd)));
					value = value | (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));

					/* Write the value back to sytem register */
					rtw_write8(padapter, offset, value);
				}
				break;

			case PWR_CMD_POLLING:

				bPollingBit = _FALSE;
				offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
#ifdef CONFIG_GSPI_HCI
				if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
					offset = SPI_LOCAL_OFFSET | offset;
#endif
				do {
#ifdef CONFIG_SDIO_HCI
					if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
						value = SdioLocalCmd52Read1Byte(padapter, offset);
					else
#endif
						value = rtw_read8(padapter, offset);

					value = value & GET_PWR_CFG_MASK(PwrCfgCmd);
					if (value == (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)))
						bPollingBit = _TRUE;
					else
						rtw_udelay_os(10);

					if (pollingCount++ > maxPollingCnt) {
						RTW_ERR("HalPwrSeqCmdParsing: Fail to polling Offset[%#x]=%02x\n", offset, value);
						return _FALSE;
					}
				} while (!bPollingBit);

				break;

			case PWR_CMD_DELAY:
				if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
					rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd));
				else
					rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd) * 1000);
				break;

			case PWR_CMD_END:
				/* When this command is parsed, end the process */
				return _TRUE;
				break;

			default:
				break;
			}
		}

		AryIdx++;/* Add Array Index */
	} while (1);

	return _TRUE;
}
예제 #10
0
//
//	Description: 
//		This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC.
//
//	Assumption:
//		We should follow specific format which was released from HW SD. 
//
//	2011.07.07, added by Roger.
//
unsigned int HalPwrSeqCmdParsing(struct rtl8192cd_priv *priv, unsigned char CutVersion, unsigned char FabVersion, 
							 unsigned char InterfaceType, WLAN_PWR_CFG PwrSeqCmd[])
{
		
	WLAN_PWR_CFG 	PwrCfgCmd = {0};
	unsigned int 		bPollingBit = FALSE;
	unsigned int		AryIdx=0;
	unsigned char		value = 0;
	unsigned int		offset = 0;
	unsigned int 		pollingCount = 0; // polling autoload done.
	unsigned int		maxPollingCnt = 5000;
	
	do {
		PwrCfgCmd=PwrSeqCmd[AryIdx];

		DEBUG_INFO("%s %d, ENTRY, offset:0x%x, cut_msk:0x%x, fab_msk:0x%x, if_msk:0x%x, base:0x%x, cmd:0x%x, msk:0x%x, value:0x%x\n", 
			__FUNCTION__, __LINE__, GET_PWR_CFG_OFFSET(PwrCfgCmd), GET_PWR_CFG_CUT_MASK(PwrCfgCmd), 
			GET_PWR_CFG_FAB_MASK(PwrCfgCmd), GET_PWR_CFG_INTF_MASK(PwrCfgCmd), GET_PWR_CFG_BASE(PwrCfgCmd), 
			GET_PWR_CFG_CMD(PwrCfgCmd), GET_PWR_CFG_MASK(PwrCfgCmd), GET_PWR_CFG_VALUE(PwrCfgCmd));

		//2 Only Handle the command whose FAB, CUT, and Interface are matched
		if((GET_PWR_CFG_FAB_MASK(PwrCfgCmd)&FabVersion)&&
			(GET_PWR_CFG_CUT_MASK(PwrCfgCmd)&CutVersion)&&
			(GET_PWR_CFG_INTF_MASK(PwrCfgCmd)&InterfaceType)) {
			switch(GET_PWR_CFG_CMD(PwrCfgCmd))
			{
			case PWR_CMD_READ:
				DEBUG_INFO("%s %d, PWR_CMD_READ\n", __FUNCTION__, __LINE__);
				break;

			case PWR_CMD_WRITE:
				DEBUG_INFO("%s %d, PWR_CMD_WRITE\n", __FUNCTION__, __LINE__);
				offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);

#ifdef CONFIG_SDIO_HCI
				//
				// <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface
				// 2011.07.07.
				//
				if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
				{
					// Read Back SDIO Local value
					value = SdioLocalCmd52Read1Byte(priv, offset);

					value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
					value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));

					// Write Back SDIO Local value
					SdioLocalCmd52Write1Byte(priv, offset, value);
				}
				else
#endif
				{
					//Read the value from system register		
					value = RTL_R8(offset);
					value = value&(~(GET_PWR_CFG_MASK(PwrCfgCmd)));
					value = value|(GET_PWR_CFG_VALUE(PwrCfgCmd)&GET_PWR_CFG_MASK(PwrCfgCmd));

					//Write the value back to sytem register
					RTL_W8(offset, value);
				}
				break;

			case PWR_CMD_POLLING:
				DEBUG_INFO("%s %d, PWR_CMD_POLLING\n", __FUNCTION__, __LINE__);
				bPollingBit = FALSE;					
				offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);				

				do {
#ifdef CONFIG_SDIO_HCI
					if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
						value = SdioLocalCmd52Read1Byte(priv, offset);
					else
#endif
					value = RTL_R8(offset);
					value=value&GET_PWR_CFG_MASK(PwrCfgCmd);
					if(value==(GET_PWR_CFG_VALUE(PwrCfgCmd)&GET_PWR_CFG_MASK(PwrCfgCmd)))
						bPollingBit=TRUE;
					else	
						delay_us(10);
					
					if(pollingCount++ > maxPollingCnt){
						DEBUG_WARN("%s %d, PWR_CMD_POLLING, Fail to polling Offset[0x%x]\n", __FUNCTION__, __LINE__, offset);
						return FALSE;
					}
				}while(!bPollingBit);

				break;

			case PWR_CMD_DELAY:
				DEBUG_INFO("%s %d, PWR_CMD_DELAY\n", __FUNCTION__, __LINE__);
				if(GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
					delay_us(GET_PWR_CFG_OFFSET(PwrCfgCmd));
				else
					delay_us(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000);
				break; 

			case PWR_CMD_END:
				// When this command is parsed, end the process
				DEBUG_INFO("%s %d, PWR_CMD_END\n", __FUNCTION__, __LINE__);
				return TRUE;
				break;

			default:
				DEBUG_ERR("%s %d, Unknown CMD!!\n", __FUNCTION__, __LINE__);
				break;
			}

		}
		
		AryIdx++;//Add Array Index
	}while(1);

	return TRUE;
}
예제 #11
0
void sd_int_dpc(PADAPTER padapter)
{
	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
	if (pHalData->sdio_hisr & SDIO_HISR_CPWM1)
	{
		struct reportpwrstate_parm report;

#ifdef CONFIG_USING_CMD52_READ_INT
		report.state = SdioLocalCmd52Read1Byte(padapter,SDIO_REG_HCPWM1);
#else //CONFIG_USING_CMD52_READ_INT
		_sdio_local_read(padapter, SDIO_REG_HCPWM1, 1, &report.state);
#endif

#ifdef CONFIG_LPS_LCLK
		//88e's cpwm value only change BIT0, so driver need to add PS_STATE_S2 for LPS flow.
		//modify by Thomas. 2012/4/2.

#ifdef CONFIG_EXT_CLK //for sprd
		if(report.state & BIT(4)) //indicate FW entering 32k
		{
			u8 chk_cnt = 0;

			do{
				if(_sdio_read8(padapter, 0x90)&BIT(0))//FW in 32k already
				{
					struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);

					if(pwrpriv->rpwm < PS_STATE_S2)
					{
						//DBG_871X("disable ext clk when FW in LPS-32K already!\n");
						EnableGpio5ClockReq(padapter, _TRUE, 0);
					}

					break;
				}

				chk_cnt++;

			}while(chk_cnt<10);

			if(chk_cnt==10)
			{
				DBG_871X("polling fw in 32k already, fail!\n");
			}

		}
		else //indicate fw leaving 32K
#endif //CONFIG_EXT_CLK
		{
		report.state |= PS_STATE_S2;
		//cpwm_int_hdl(padapter, &report);
		_set_workitem(&(adapter_to_pwrctl(padapter)->cpwm_event));
		}
#endif
	}

#ifdef CONFIG_WOWLAN
	if (pHalData->sdio_hisr & SDIO_HISR_CPWM2) {
		u32	value;
		value = rtw_read32(padapter, SDIO_LOCAL_BASE+SDIO_REG_HISR);
		DBG_871X_LEVEL(_drv_always_, "Reset SDIO HISR(0x%08x) original:0x%08x\n",
			SDIO_LOCAL_BASE+SDIO_REG_HISR, value);
		value |= BIT19;
		rtw_write32(padapter, SDIO_LOCAL_BASE+SDIO_REG_HISR, value);

		value = rtw_read8(padapter, SDIO_LOCAL_BASE+SDIO_REG_HIMR+2);
		DBG_871X_LEVEL(_drv_always_, "Reset SDIO HIMR CPWM2(0x%08x) original:0x%02x\n",
			SDIO_LOCAL_BASE+SDIO_REG_HIMR + 2, value);
	}
#endif
	if (pHalData->sdio_hisr & SDIO_HISR_TXERR)
	{
		u8 *status;
		u32 addr;
	
		status = rtw_malloc(4);
		if (status)
		{
			addr = REG_TXDMA_STATUS;
			HalSdioGetCmdAddr8723ASdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
			_sd_read(pintfhdl, addr, 4, status);
			_sd_write(pintfhdl, addr, 4, status);
			DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32*)status));
			rtw_mfree(status, 4);
		} else {
			DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
		}		
	}

#ifdef CONFIG_INTERRUPT_BASED_TXBCN

	#ifdef  CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
	if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT)
	#endif
	#ifdef  CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
	if (pHalData->sdio_hisr & (SDIO_HISR_TXBCNOK|SDIO_HISR_TXBCNERR))
	#endif	
	{		
		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;

		#if 0 //for debug
		if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT)
			DBG_8192C("%s: SDIO_HISR_BCNERLY_INT\n", __func__);
		
		if (pHalData->sdio_hisr & SDIO_HISR_TXBCNOK)	
			DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
	
		if (pHalData->sdio_hisr & SDIO_HISR_TXBCNERR)	
			DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
		#endif

		
		if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
		{
			//send_beacon(padapter);
			if(pmlmepriv->update_bcn == _TRUE)
			{
				//tx_beacon_hdl(padapter, NULL);
				set_tx_beacon_cmd(padapter);
			}
		}
#ifdef CONFIG_CONCURRENT_MODE
		if(check_buddy_fwstate(padapter, WIFI_AP_STATE))
		{
			//send_beacon(padapter);
			if(padapter->pbuddy_adapter->mlmepriv.update_bcn == _TRUE)
			{
				//tx_beacon_hdl(padapter, NULL);
				set_tx_beacon_cmd(padapter->pbuddy_adapter);
			}
		}
#endif
	}
#endif //CONFIG_INTERRUPT_BASED_TXBCN

#ifdef CONFIG_EXT_CLK
	if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT)
	{
		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;

		if(check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE))
		{
			//DBG_8192C("BCNERLY_INT for enabling ext clk\n");
			EnableGpio5ClockReq(padapter, _TRUE, 1);
		}
	}
#endif //CONFIG_EXT_CLK

	if (pHalData->sdio_hisr & SDIO_HISR_C2HCMD)
	{
		DBG_8192C("%s: C2H Command\n", __func__);
	}

	if (pHalData->sdio_hisr & SDIO_HISR_RX_REQUEST)
	{
		struct recv_buf *precvbuf;
#ifdef CONFIG_USING_CMD52_READ_INT
		u32 hisr;

		//DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize);
		pHalData->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
#ifdef CONFIG_MAC_LOOPBACK_DRIVER
		sd_recv_loopback(padapter, pHalData->SdioRxFIFOSize);
#else
		do {
			pHalData->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(padapter, SDIO_REG_RX0_REQ_LEN);

			if(pHalData->SdioRxFIFOSize != 0)
			{
				precvbuf = sd_recv_rxfifo(padapter, pHalData->SdioRxFIFOSize);

				pHalData->SdioRxFIFOSize = 0;

				if (precvbuf)
					sd_rxhandler(padapter, precvbuf);
				else
					break;
			}
			else
			{
				DBG_871X("%s, WARNING!!, SdioRxFIFOSize = 0!!\n", __func__);
				break;
			}
			
			hisr = 0;
			ReadInterrupt8188ESdio(padapter, &hisr);
			hisr &= SDIO_HISR_RX_REQUEST;
			if (!hisr)
				break;
#ifdef CONFIG_SDIO_DISABLE_RXFIFO_POLLING_LOOP			
		} while (0);
#else
		} while (1);
	
#endif //CONFIG_SDIO_DISABLE_RXFIFO_POLLING_LOOP
#endif //CONFIG_MAC_LOOPBACK_DRIVER
#else  //!CONFIG_USING_CMD52_READ_INT

		//DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize);
		pHalData->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
#ifdef CONFIG_MAC_LOOPBACK_DRIVER
		sd_recv_loopback(padapter, pHalData->SdioRxFIFOSize);
#else
		do {
			//Sometimes rx length will be zero. driver need to use cmd53 read again.
			if(pHalData->SdioRxFIFOSize == 0)
			{
				u8 data[4];

				_sdio_local_read(padapter, SDIO_REG_RX0_REQ_LEN, 4, data);

				pHalData->SdioRxFIFOSize = le16_to_cpu(*(u16*)data);
			}

			if(pHalData->SdioRxFIFOSize)
			{
				precvbuf = sd_recv_rxfifo(padapter, pHalData->SdioRxFIFOSize);

				pHalData->SdioRxFIFOSize = 0;

				if (precvbuf)
					sd_rxhandler(padapter, precvbuf);
				else
					break;
			}
			else
				break;
#ifdef CONFIG_SDIO_DISABLE_RXFIFO_POLLING_LOOP			
		} while (0);
#else
		} while (1);
예제 #12
0
u8 HalPwrSeqCmdParsing(
	struct adapter *padapter,
	u8 CutVersion,
	u8 FabVersion,
	u8 InterfaceType,
	WLAN_PWR_CFG PwrSeqCmd[]
)
{
	WLAN_PWR_CFG PwrCfgCmd = {0};
	u8 bPollingBit = false;
	u32 AryIdx = 0;
	u8 value = 0;
	u32 offset = 0;
	u32 pollingCount = 0; /*  polling autoload done. */
	u32 maxPollingCnt = 5000;

	do {
		PwrCfgCmd = PwrSeqCmd[AryIdx];

		RT_TRACE(
			_module_hal_init_c_,
			_drv_info_,
			(
				"HalPwrSeqCmdParsing: offset(%#x) cut_msk(%#x) fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x) msk(%#x) value(%#x)\n",
				GET_PWR_CFG_OFFSET(PwrCfgCmd),
				GET_PWR_CFG_CUT_MASK(PwrCfgCmd),
				GET_PWR_CFG_FAB_MASK(PwrCfgCmd),
				GET_PWR_CFG_INTF_MASK(PwrCfgCmd),
				GET_PWR_CFG_BASE(PwrCfgCmd),
				GET_PWR_CFG_CMD(PwrCfgCmd),
				GET_PWR_CFG_MASK(PwrCfgCmd),
				GET_PWR_CFG_VALUE(PwrCfgCmd)
			)
		);

		/* 2 Only Handle the command whose FAB, CUT, and Interface are matched */
		if (
			(GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) &&
			(GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) &&
			(GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)
		) {
			switch (GET_PWR_CFG_CMD(PwrCfgCmd)) {
			case PWR_CMD_READ:
				RT_TRACE(
					_module_hal_init_c_,
					_drv_info_,
					("HalPwrSeqCmdParsing: PWR_CMD_READ\n")
				);
				break;

			case PWR_CMD_WRITE:
				RT_TRACE(
					_module_hal_init_c_,
					_drv_info_,
					("HalPwrSeqCmdParsing: PWR_CMD_WRITE\n")
				);
				offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);

				/*  */
				/*  <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface */
				/*  2011.07.07. */
				/*  */
				if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) {
					/*  Read Back SDIO Local value */
					value = SdioLocalCmd52Read1Byte(padapter, offset);

					value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
					value |= (
						GET_PWR_CFG_VALUE(PwrCfgCmd) &
						GET_PWR_CFG_MASK(PwrCfgCmd)
					);

					/*  Write Back SDIO Local value */
					SdioLocalCmd52Write1Byte(padapter, offset, value);
				} else {
					/*  Read the value from system register */
					value = rtw_read8(padapter, offset);

					value &= (~(GET_PWR_CFG_MASK(PwrCfgCmd)));
					value |= (
						GET_PWR_CFG_VALUE(PwrCfgCmd)
						&GET_PWR_CFG_MASK(PwrCfgCmd)
					);

					/*  Write the value back to sytem register */
					rtw_write8(padapter, offset, value);
				}
				break;

			case PWR_CMD_POLLING:
				RT_TRACE(
					_module_hal_init_c_,
					_drv_info_,
					("HalPwrSeqCmdParsing: PWR_CMD_POLLING\n")
				);

				bPollingBit = false;
				offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
				do {
					if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
						value = SdioLocalCmd52Read1Byte(padapter, offset);
					else
						value = rtw_read8(padapter, offset);

					value = value&GET_PWR_CFG_MASK(PwrCfgCmd);
					if (
						value == (GET_PWR_CFG_VALUE(PwrCfgCmd) &
						GET_PWR_CFG_MASK(PwrCfgCmd))
					)
						bPollingBit = true;
					else
						udelay(10);

					if (pollingCount++ > maxPollingCnt) {
						DBG_871X(
							"Fail to polling Offset[%#x]=%02x\n",
							offset,
							value
						);
						return false;
					}
				} while (!bPollingBit);

				break;

			case PWR_CMD_DELAY:
				RT_TRACE(
					_module_hal_init_c_,
					_drv_info_,
					("HalPwrSeqCmdParsing: PWR_CMD_DELAY\n")
				);
				if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
					udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd));
				else
					udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000);
				break;

			case PWR_CMD_END:
				/*  When this command is parsed, end the process */
				RT_TRACE(
					_module_hal_init_c_,
					_drv_info_,
					("HalPwrSeqCmdParsing: PWR_CMD_END\n")
				);
				return true;

			default:
				RT_TRACE(
					_module_hal_init_c_,
					_drv_err_,
					("HalPwrSeqCmdParsing: Unknown CMD!!\n")
				);
				break;
			}
		}

		AryIdx++;/* Add Array Index */
	} while (1);

	return true;
}