Пример #1
0
static void cpwm_event_callback(struct work_struct *work)
{
	struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, cpwm_event);
	struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
	_adapter *adapter = dvobj->if1;
	struct reportpwrstate_parm report;

	/* DBG_871X("%s\n", __FUNCTION__); */

	report.state = PS_STATE_S2;
	cpwm_int_hdl(adapter, &report);
}
Пример #2
0
static void rpwmtimeout_workitem_callback(struct work_struct *work)
{
	PADAPTER padapter;
	struct dvobj_priv *dvobj;
	struct pwrctrl_priv *pwrpriv;


	pwrpriv = container_of(work, struct pwrctrl_priv, rpwmtimeoutwi);
	dvobj = pwrctl_to_dvobj(pwrpriv);
	padapter = dvobj->if1;
/* 	DBG_871X("+%s: rpwm =0x%02X cpwm =0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); */

	down(&pwrpriv->lock);
	if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2))
	{
		DBG_871X("%s: rpwm =0x%02X cpwm =0x%02X CPWM done!\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
		goto exit;
	}
	up(&pwrpriv->lock);

	if (rtw_read8(padapter, 0x100) != 0xEA)
	{
		struct reportpwrstate_parm report;

		report.state = PS_STATE_S2;
		DBG_871X("\n%s: FW already leave 32K!\n\n", __func__);
		cpwm_int_hdl(padapter, &report);

		return;
	}

	down(&pwrpriv->lock);

	if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2))
	{
		DBG_871X("%s: cpwm =%d, nothing to do!\n", __func__, pwrpriv->cpwm);
		goto exit;
	}
	pwrpriv->brpwmtimeout = true;
	rtw_set_rpwm(padapter, pwrpriv->rpwm);
	pwrpriv->brpwmtimeout = false;

exit:
	up(&pwrpriv->lock);
}
Пример #3
0
void spi_int_dpc(PADAPTER padapter, u32 sdio_hisr)
{
	PHAL_DATA_TYPE phal;
	static u32 last_c2h;


	phal = GET_HAL_DATA(padapter);

	if (sdio_hisr & SPI_HISR_CPWM1)
	{
		struct reportpwrstate_parm report;

		report.state = spi_read8(padapter, SPI_LOCAL_OFFSET | SDIO_REG_HCPWM1, NULL);
#ifdef CONFIG_LPS_LCLK
		cpwm_int_hdl(padapter, &report);
#endif
	}

	if (sdio_hisr & SPI_HISR_TXERR)
	{
		u32 status;

		status = rtw_read32(padapter, REG_TXDMA_STATUS);
		rtw_write32(padapter, REG_TXDMA_STATUS, status);
		//DBG_8192C("%s: SPI_HISR_TXERR (0x%08x)\n", __func__, status);
	}

	if (sdio_hisr & SPI_HISR_TXBCNOK)
	{
		DBG_8192C("%s: SPI_HISR_TXBCNOK\n", __func__);
	}

	if (sdio_hisr & SPI_HISR_TXBCNERR)
	{
		DBG_8192C("%s: SPI_HISR_TXBCNERR\n", __func__);
	}

	if (sdio_hisr & SPI_HISR_C2HCMD)
	{
		DBG_8192C("%s: C2H Command\n", __func__);
		last_c2h = rtw_c2h_wk_cmd(padapter);
	} else if (last_c2h != _SUCCESS) {
		/* check C2H stuck */
		u8 have_c2h = 0;

		have_c2h = rtw_read8(padapter, REG_C2HEVT_CLEAR);

		if (have_c2h) {
			DBG_871X_LEVEL(_drv_err_, "%s: c2h stuck\n", __FUNCTION__);
			last_c2h = rtw_c2h_wk_cmd(padapter);
		} else {
			last_c2h = _SUCCESS;
		}
	}

	if (sdio_hisr & SPI_HISR_RX_REQUEST)// || sdio_hisr & SPI_HISR_RXFOVW)
	{
		struct dvobj_priv *dvobj = padapter->dvobj;
		PGSPI_DATA pgspi_data = &dvobj->intf_data;

		if (pgspi_data->priv_wq)
			queue_delayed_work(pgspi_data->priv_wq, &pgspi_data->recv_work, 0);
	}
}
Пример #4
0
/*
 *
 * Parameters
 *	padapter
 *	pslv			power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
 *
 */
void rtw_set_rpwm(PADAPTER padapter, u8 pslv)
{
	u8	rpwm;
	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;

_func_enter_;

	pslv = PS_STATE(pslv);


	if (_TRUE ==padapter->pwrctrlpriv.btcoex_rfon)
	{
		if (pslv < PS_STATE_S4)
			pslv = PS_STATE_S3;
		
		if (pwrpriv->rpwm == pslv) {
			struct reportpwrstate_parm report;
			report.state = PS_STATE_S3;
#ifdef CONFIG_LPS_LCLK
			cpwm_int_hdl(padapter, &report);
#endif
			return;
		}
	}
#ifdef CONFIG_LPS_RPWM_TIMER
	if (pwrpriv->brpwmtimeout == _TRUE)
	{
		DBG_871X("%s: RPWM timeout, force to set RPWM(0x%02X) again!\n", __FUNCTION__, pslv);
	}
	else
#endif // CONFIG_LPS_RPWM_TIMER
	{
	if ( (pwrpriv->rpwm == pslv)
#ifdef CONFIG_LPS_LCLK
		|| ((pwrpriv->rpwm >= PS_STATE_S2)&&(pslv >= PS_STATE_S2))
#endif
		)
	{
		RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,
			("%s: Already set rpwm[0x%02X], new=0x%02X!\n", __FUNCTION__, pwrpriv->rpwm, pslv));
		return;
	}
	}

	if ((padapter->bSurpriseRemoved == _TRUE) ||
		(padapter->hw_init_completed == _FALSE))
	{
		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
				 ("%s: SurpriseRemoved(%d) hw_init_completed(%d)\n",
				  __FUNCTION__, padapter->bSurpriseRemoved, padapter->hw_init_completed));

		pwrpriv->cpwm = PS_STATE_S4;

		return;
	}

	if (padapter->bDriverStopped == _TRUE)
	{
		RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
				 ("%s: change power state(0x%02X) when DriverStopped\n", __FUNCTION__, pslv));

		if (pslv < PS_STATE_S2) {
			RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
					 ("%s: Reject to enter PS_STATE(0x%02X) lower than S2 when DriverStopped!!\n", __FUNCTION__, pslv));
			return;
		}
	}

	rpwm = pslv | pwrpriv->tog;
#ifdef CONFIG_LPS_LCLK
	// only when from PS_STATE S0/S1 to S2 and higher needs ACK
	if ((pwrpriv->cpwm < PS_STATE_S2) && (pslv >= PS_STATE_S2))
		rpwm |= PS_ACK;
#endif
	RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
			 ("rtw_set_rpwm: rpwm=0x%02x cpwm=0x%02x\n", rpwm, pwrpriv->cpwm));

	pwrpriv->rpwm = pslv;

#ifdef CONFIG_LPS_RPWM_TIMER
	if (rpwm & PS_ACK)
		_set_timer(&pwrpriv->pwr_rpwm_timer, LPS_RPWM_WAIT_MS);
#endif // CONFIG_LPS_RPWM_TIMER
	rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));

	pwrpriv->tog += 0x80;


	if (_TRUE == padapter->pwrctrlpriv.btcoex_rfon)
	{
		struct reportpwrstate_parm report;
		report.state = pslv;
#ifdef CONFIG_LPS_LCLK
		cpwm_int_hdl(padapter, &report);
#endif
	}
	else
	{
#ifdef CONFIG_LPS_LCLK
	// No LPS 32K, No Ack
	if (!(rpwm & PS_ACK))
#endif
	{
		pwrpriv->cpwm = pslv;
	}
	}

_func_exit_;
}