Commit 61d73095 authored by Yan-Hsuan Chuang's avatar Yan-Hsuan Chuang Committed by Kalle Valo
Browse files

rtw88: not to enter or leave PS under IRQ



Remove PS related *_irqsafe functions to avoid entering/leaving PS
under interrupt context. Instead, make PS decision in watch_dog.
This could simplify the logic and make the code look clean.

But it could have a little side-effect that if the driver is having
heavy traffic before the every-2-second watch_dog detect the traffic
and decide to leave PS, the thoughput will be lower. Once traffic is
detected by watch_dog and left PS state, the throughput will resume
to the peak the hardware ought to have again.

Signed-off-by: default avatarYan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 6f0b0d28
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -182,6 +182,8 @@ static void rtw_watch_dog_work(struct work_struct *work)
	if (rtw_fw_support_lps &&
	    data.rtwvif && !data.active && data.assoc_cnt == 1)
		rtw_enter_lps(rtwdev, data.rtwvif);
	else
		rtw_leave_lps(rtwdev, rtwdev->lps_conf.rtwvif);

	if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
		return;
@@ -1152,7 +1154,6 @@ int rtw_core_init(struct rtw_dev *rtwdev)
		    rtw_tx_report_purge_timer, 0);

	INIT_DELAYED_WORK(&rtwdev->watch_dog_work, rtw_watch_dog_work);
	INIT_DELAYED_WORK(&rtwdev->lps_work, rtw_lps_work);
	INIT_DELAYED_WORK(&coex->bt_relink_work, rtw_coex_bt_relink_work);
	INIT_DELAYED_WORK(&coex->bt_reenable_work, rtw_coex_bt_reenable_work);
	INIT_DELAYED_WORK(&coex->defreeze_work, rtw_coex_defreeze_work);
+0 −1
Original line number Diff line number Diff line
@@ -1361,7 +1361,6 @@ struct rtw_dev {

	/* lps power state & handler work */
	struct rtw_lps_conf lps_conf;
	struct delayed_work lps_work;

	struct dentry *debugfs;

+0 −44
Original line number Diff line number Diff line
@@ -91,50 +91,6 @@ static void rtw_enter_lps_core(struct rtw_dev *rtwdev)
	set_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags);
}

void rtw_lps_work(struct work_struct *work)
{
	struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
					      lps_work.work);
	struct rtw_lps_conf *conf = &rtwdev->lps_conf;
	struct rtw_vif *rtwvif = conf->rtwvif;

	if (WARN_ON(!rtwvif))
		return;

	if (conf->mode == RTW_MODE_LPS)
		rtw_enter_lps_core(rtwdev);
	else
		rtw_leave_lps_core(rtwdev);
}

void rtw_enter_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
{
	struct rtw_lps_conf *conf = &rtwdev->lps_conf;

	if (rtwvif->in_lps)
		return;

	conf->mode = RTW_MODE_LPS;
	conf->rtwvif = rtwvif;
	rtwvif->in_lps = true;

	ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->lps_work, 0);
}

void rtw_leave_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
{
	struct rtw_lps_conf *conf = &rtwdev->lps_conf;

	if (!rtwvif->in_lps)
		return;

	conf->mode = RTW_MODE_ACTIVE;
	conf->rtwvif = rtwvif;
	rtwvif->in_lps = false;

	ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->lps_work, 0);
}

bool rtw_in_lps(struct rtw_dev *rtwdev)
{
	return test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags);
+0 −3
Original line number Diff line number Diff line
@@ -10,9 +10,6 @@
int rtw_enter_ips(struct rtw_dev *rtwdev);
int rtw_leave_ips(struct rtw_dev *rtwdev);

void rtw_lps_work(struct work_struct *work);
void rtw_enter_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif);
void rtw_leave_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif);
void rtw_enter_lps(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif);
void rtw_leave_lps(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif);
bool rtw_in_lps(struct rtw_dev *rtwdev);
+0 −2
Original line number Diff line number Diff line
@@ -25,8 +25,6 @@ void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
			rtwvif = (struct rtw_vif *)vif->drv_priv;
			rtwvif->stats.rx_unicast += skb->len;
			rtwvif->stats.rx_cnt++;
			if (rtwvif->stats.rx_cnt > RTW_LPS_THRESHOLD)
				rtw_leave_lps_irqsafe(rtwdev, rtwvif);
		}
	}
}
Loading