Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2/* Copyright(c) 2018-2019  Realtek Corporation
  3 */
  4
  5#include "main.h"
  6#include "fw.h"
  7#include "ps.h"
  8#include "mac.h"
  9#include "coex.h"
 10#include "debug.h"
 11
 12static int rtw_ips_pwr_up(struct rtw_dev *rtwdev)
 13{
 14	int ret;
 15
 16	ret = rtw_core_start(rtwdev);
 17	if (ret)
 18		rtw_err(rtwdev, "leave idle state failed\n");
 19
 20	rtw_set_channel(rtwdev);
 21	rtw_flag_clear(rtwdev, RTW_FLAG_INACTIVE_PS);
 22
 23	return ret;
 24}
 25
 26int rtw_enter_ips(struct rtw_dev *rtwdev)
 27{
 28	rtw_flag_set(rtwdev, RTW_FLAG_INACTIVE_PS);
 29
 30	rtw_coex_ips_notify(rtwdev, COEX_IPS_ENTER);
 31
 32	rtw_core_stop(rtwdev);
 33
 34	return 0;
 35}
 36
 37static void rtw_restore_port_cfg_iter(void *data, u8 *mac,
 38				      struct ieee80211_vif *vif)
 39{
 40	struct rtw_dev *rtwdev = data;
 41	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
 42	u32 config = ~0;
 43
 44	rtw_vif_port_config(rtwdev, rtwvif, config);
 45}
 46
 47int rtw_leave_ips(struct rtw_dev *rtwdev)
 48{
 49	int ret;
 50
 51	ret = rtw_ips_pwr_up(rtwdev);
 52	if (ret) {
 53		rtw_err(rtwdev, "failed to leave ips state\n");
 54		return ret;
 55	}
 56
 57	rtw_iterate_vifs_atomic(rtwdev, rtw_restore_port_cfg_iter, rtwdev);
 58
 59	rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE);
 60
 61	return 0;
 62}
 63
 64static void rtw_leave_lps_core(struct rtw_dev *rtwdev)
 65{
 66	struct rtw_lps_conf *conf = &rtwdev->lps_conf;
 67
 68	conf->state = RTW_ALL_ON;
 69	conf->awake_interval = 1;
 70	conf->rlbm = 0;
 71	conf->smart_ps = 0;
 72
 73	rtw_fw_set_pwr_mode(rtwdev);
 74	rtw_flag_clear(rtwdev, RTW_FLAG_LEISURE_PS);
 75
 76	rtw_coex_lps_notify(rtwdev, COEX_LPS_DISABLE);
 77}
 78
 79static void rtw_enter_lps_core(struct rtw_dev *rtwdev)
 80{
 81	struct rtw_lps_conf *conf = &rtwdev->lps_conf;
 82
 83	conf->state = RTW_RF_OFF;
 84	conf->awake_interval = 1;
 85	conf->rlbm = 1;
 86	conf->smart_ps = 2;
 87
 88	rtw_coex_lps_notify(rtwdev, COEX_LPS_ENABLE);
 89
 90	rtw_fw_set_pwr_mode(rtwdev);
 91	rtw_flag_set(rtwdev, RTW_FLAG_LEISURE_PS);
 92}
 93
 94void rtw_lps_work(struct work_struct *work)
 95{
 96	struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
 97					      lps_work.work);
 98	struct rtw_lps_conf *conf = &rtwdev->lps_conf;
 99	struct rtw_vif *rtwvif = conf->rtwvif;
100
101	if (WARN_ON(!rtwvif))
102		return;
103
104	if (conf->mode == RTW_MODE_LPS)
105		rtw_enter_lps_core(rtwdev);
106	else
107		rtw_leave_lps_core(rtwdev);
108}
109
110void rtw_enter_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
111{
112	struct rtw_lps_conf *conf = &rtwdev->lps_conf;
113
114	if (rtwvif->in_lps)
115		return;
116
117	conf->mode = RTW_MODE_LPS;
118	conf->rtwvif = rtwvif;
119	rtwvif->in_lps = true;
120
121	ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->lps_work, 0);
122}
123
124void rtw_leave_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
125{
126	struct rtw_lps_conf *conf = &rtwdev->lps_conf;
127
128	if (!rtwvif->in_lps)
129		return;
130
131	conf->mode = RTW_MODE_ACTIVE;
132	conf->rtwvif = rtwvif;
133	rtwvif->in_lps = false;
134
135	ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->lps_work, 0);
136}
137
138bool rtw_in_lps(struct rtw_dev *rtwdev)
139{
140	return rtw_flag_check(rtwdev, RTW_FLAG_LEISURE_PS);
141}
142
143void rtw_enter_lps(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
144{
145	struct rtw_lps_conf *conf = &rtwdev->lps_conf;
146
147	if (WARN_ON(!rtwvif))
148		return;
149
150	if (rtwvif->in_lps)
151		return;
152
153	conf->mode = RTW_MODE_LPS;
154	conf->rtwvif = rtwvif;
155	rtwvif->in_lps = true;
156
157	rtw_enter_lps_core(rtwdev);
158}
159
160void rtw_leave_lps(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
161{
162	struct rtw_lps_conf *conf = &rtwdev->lps_conf;
163
164	if (WARN_ON(!rtwvif))
165		return;
166
167	if (!rtwvif->in_lps)
168		return;
169
170	conf->mode = RTW_MODE_ACTIVE;
171	conf->rtwvif = rtwvif;
172	rtwvif->in_lps = false;
173
174	rtw_leave_lps_core(rtwdev);
175}