drivers/staging/rtl8723bs/core/rtw_pwrctrl.c

Source file repositories/reference/linux-study-clean/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/rtl8723bs/core/rtw_pwrctrl.c
Extension
.c
Size
27129 bytes
Lines
1146
Domain
Driver Families
Bucket
drivers/staging
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (jiffies_to_msecs(jiffies - start_time) > 2000) { /*  2 sec == watch dog timer */
			if (xmit_cnt > 8) {
				if (adapter_to_pwrctl(padapter)->bLeisurePs &&
				    (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE) &&
				    !(hal_btcoex_IsBtControlLps(padapter))) {
					bLeaveLPS = true;
				}
			}

			start_time = jiffies;
			xmit_cnt = 0;
		}

	} else { /*  from rx path */
		if (pmlmepriv->link_detect_info.num_rx_unicast_ok_in_period > 4) {
			if (adapter_to_pwrctl(padapter)->bLeisurePs &&
			    (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE) &&
			    !(hal_btcoex_IsBtControlLps(padapter)))
				bLeaveLPS = true;
		}
	}

	if (bLeaveLPS)
		/* rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1); */
		rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, tx ? 0 : 1);
}

/*
 * Description:
 *This function MUST be called under power lock protect
 *
 * Parameters
 *padapter
 *pslv			power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
 *
 */
void rtw_set_rpwm(struct adapter *padapter, u8 pslv)
{
	u8 rpwm;
	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
	u8 cpwm_orig;

	pslv = PS_STATE(pslv);

	if (!pwrpriv->brpwmtimeout) {
		if (pwrpriv->rpwm == pslv ||
		    (pwrpriv->rpwm >= PS_STATE_S2 && pslv >= PS_STATE_S2))
			return;
	}

	if ((padapter->bSurpriseRemoved) || !(padapter->hw_init_completed)) {
		pwrpriv->cpwm = PS_STATE_S4;
		return;
	}

	if (padapter->bDriverStopped) {
		if (pslv < PS_STATE_S2)
			return;
	}

	rpwm = pslv | pwrpriv->tog;
	/*  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;

	pwrpriv->rpwm = pslv;

	cpwm_orig = 0;
	if (rpwm & PS_ACK)
		rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);

	if (rpwm & PS_ACK)
		_set_timer(&pwrpriv->pwr_rpwm_timer, LPS_RPWM_WAIT_MS);
	rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));

	pwrpriv->tog += 0x80;

	/*  No LPS 32K, No Ack */
	if (rpwm & PS_ACK) {
		unsigned long start_time;
		u8 cpwm_now;

		start_time = jiffies;

		/*  polling cpwm */
		do {
			mdelay(1);
			rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now);
			if ((cpwm_orig ^ cpwm_now) & 0x80) {
				pwrpriv->cpwm = PS_STATE_S4;

Annotation

Implementation Notes