xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/phl/test/phl_ps_dbg_cmd.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2019 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _PHL_PS_DBG_CMD_C_
16 #include "../phl_headers.h"
17 #ifdef CONFIG_POWER_SAVE
18 struct phl_ps_cmd_info {
19 	char name[16];
20 	u8 id;
21 };
22 
23 enum PHL_PS_CMD_ID {
24 	PHL_PS_HELP,
25 	PHL_PS_SHOW,
26 	PHL_PS_TEST,
27 	PHL_PS_STOP_PS
28 };
29 
30 struct phl_ps_cmd_info phl_ps_cmd_i[] = {
31 	{"-h", PHL_PS_HELP},
32 	{"show", PHL_PS_SHOW},
33 	{"test", PHL_PS_TEST},
34 	{"stop_ps", PHL_PS_STOP_PS}
35 };
36 
37 /* echo phl ps show */
_phl_ps_cmd_show(struct phl_info_t * phl_info,u32 * used,char input[][MAX_ARGV],u32 input_num,char * output,u32 out_len)38 static void _phl_ps_cmd_show(struct phl_info_t *phl_info, u32 *used, char input[][MAX_ARGV],
39 			u32 input_num, char *output, u32 out_len)
40 {
41 	if (phl_info == NULL)
42 		return;
43 
44 	phl_ps_dbg_dump(phl_info, used, input, input_num, output, out_len);
45 }
46 
47 /* debug to disable power saving */
_phl_ps_cmd_stop_ps(struct phl_info_t * phl_info,u32 * used,char input[][MAX_ARGV],u32 input_num,char * output,u32 out_len)48 static void _phl_ps_cmd_stop_ps(struct phl_info_t *phl_info, u32 *used, char input[][MAX_ARGV],
49 			u32 input_num, char *output, u32 out_len)
50 {
51 	if (phl_info == NULL)
52 		return;
53 
54 	phl_ps_dbg_stop_ps(phl_info, used, input, input_num, output, out_len);
55 }
56 
_phl_ps_cmd_test_ps(struct phl_info_t * phl_info,u32 * used,char input[][MAX_ARGV],u32 input_num,char * output,u32 out_len)57 static void _phl_ps_cmd_test_ps(struct phl_info_t *phl_info, u32 *used, char input[][MAX_ARGV],
58 			u32 input_num, char *output, u32 out_len)
59 {
60 	if (phl_info == NULL)
61 		return;
62 
63 	phl_ps_dbg_test_ps(phl_info, used, input, input_num, output, out_len);
64 }
65 
phl_ps_cmd_parser(struct phl_info_t * phl_info,char input[][MAX_ARGV],u32 input_num,char * output,u32 out_len)66 void phl_ps_cmd_parser(struct phl_info_t *phl_info, char input[][MAX_ARGV],
67 			u32 input_num, char *output, u32 out_len)
68 {
69 	u32 used = 0;
70 	u8 id = 0;
71 	u32 i;
72 	u32 array_size = sizeof(phl_ps_cmd_i) / sizeof(struct phl_ps_cmd_info);
73 
74 	PS_CNSL(out_len, used, output + used, out_len - used, "\n");
75 
76 	/* Parsing Cmd ID */
77 	if (input_num) {
78 		for (i = 0; i < array_size; i++) {
79 			if (!_os_strcmp(phl_ps_cmd_i[i].name, input[1])) {
80 				id = phl_ps_cmd_i[i].id;
81 				break;
82 			}
83 		}
84 	}
85 
86 	switch (id) {
87 	case PHL_PS_TEST:
88 		_phl_ps_cmd_test_ps(phl_info, &used, input, input_num,
89 					output, out_len);
90 		break;
91 	case PHL_PS_SHOW:
92 		_phl_ps_cmd_show(phl_info, &used, input, input_num,
93 					output, out_len);
94 		break;
95 	case PHL_PS_STOP_PS:
96 		_phl_ps_cmd_stop_ps(phl_info, &used, input, input_num,
97 					output, out_len);
98 		break;
99 	default:
100 		PS_CNSL(out_len, used, output + used, out_len - used,
101 			 "command not supported !!\n");
102 
103 		/* fall through */
104 	case PHL_PS_HELP:
105 		PS_CNSL(out_len, used, output + used, out_len - used,
106 			 "PS cmd ==>\n");
107 
108 		for (i = 0; i < array_size - 1; i++)
109 			PS_CNSL(out_len, used, output + used, out_len - used,
110 				 " %s\n", phl_ps_cmd_i[i + 1].name);
111 		break;
112 	}
113 }
114 
phl_ps_dbg_dump(struct phl_info_t * phl_info,u32 * used,char input[][MAX_ARGV],u32 input_num,char * output,u32 out_len)115 void phl_ps_dbg_dump(struct phl_info_t *phl_info, u32 *used,
116 	char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len)
117 {
118 	struct phl_module_op_info op_info = {0};
119 	struct phl_cmd_ps_basic_info info = {0};
120 	struct rtw_ps_cap_t *ps_cap = NULL;
121 
122 	PS_CNSL(out_len, *used, output + *used, out_len - *used,
123 		"========== Basic Info ==========\n");
124 
125 	op_info.op_code = PS_MDL_OP_BASIC_INFO;
126 	op_info.inbuf = (u8 *)&info;
127 #ifdef CONFIG_CMD_DISP
128 	if (phl_disp_eng_query_bk_module_info(phl_info, HW_BAND_0,
129 			PHL_MDL_POWER_MGNT, &op_info) != RTW_PHL_STATUS_SUCCESS)
130 		return;
131 
132 	PS_CNSL(out_len, *used, output + *used, out_len - *used,
133 		"ps_mode: %s, cur_pwr_lvl: %s\
134 		\nap_active: %s, gc_active: %s\
135 		\ntx traffic lvl: %s, rx traffic lvl: %s\n",
136 		phl_ps_ps_mode_to_str(info.ps_mode), phl_ps_pwr_lvl_to_str(info.cur_pwr_lvl),
137 		(info.ap_active == true ? "yes" : "no"), (info.gc_active == true ? "yes" : "no"),
138 		phl_tfc_lvl_to_str(phl_info->phl_com->phl_stats.tx_traffic.lvl), phl_tfc_lvl_to_str(phl_info->phl_com->phl_stats.rx_traffic.lvl));
139 
140 	if (info.sta != NULL) {
141 		PS_CNSL(out_len, *used, output + *used, out_len - *used,
142 				"chnl: %d, rssi: %d, rssi_bcn: %d\n",
143 				info.sta->chandef.chan, rtw_hal_get_sta_rssi(info.sta), phl_get_min_rssi_bcn(phl_info));
144 	}
145 
146 	PS_CNSL(out_len, *used, output + *used, out_len - *used,
147 		"========== Advanced Info ==========\n");
148 
149 	PS_CNSL(out_len, *used, output + *used, out_len - *used,
150 		"last enter reason: %s\
151 		\nlast leave reason: %s\
152 		\nreject all pwr req: %s\
153 		\nbtc req pwr: %s\
154 		\nruntime stop reason: %d\n",
155 		info.enter_rson,
156 		info.leave_rson,
157 		(info.rej_pwr_req == true ? "yes" : "no"),
158 		(info.btc_req_pwr == true ? "yes" : "no"),
159 		info.rt_stop_rson);
160 
161 	PS_CNSL(out_len, *used, output + *used, out_len - *used,
162 		"========== Capability ==========\n");
163 
164 	ps_cap = _get_ps_cap(phl_info);
165 
166 	PS_CNSL(out_len, *used, output + *used, out_len - *used,
167 		"init_rf_state: %s, init_rt_stop_rson: 0x%x, leave_fail_act: 0x%x\
168 		\nlps: %s, lps_cap: %s, lps_pause_tx: %d\
169 		\nawake_interval: %d, listen_bcn_mode: %d, smart_ps_mode: %d\
170 		\nrssi_enter_threshold: %d, rssi_leave_threshold: %d, rssi_diff_threshold: %d\
171 		\nips: %s, ips_cap: %s\n",
172 		(ps_cap->init_rf_state ? "off" : "on"), ps_cap->init_rt_stop_rson, ps_cap->leave_fail_act,
173 		phl_ps_op_mode_to_str(ps_cap->lps_en), phl_ps_pwr_lvl_to_str(phl_ps_judge_pwr_lvl(ps_cap->lps_cap, PS_MODE_LPS, true)), ps_cap->lps_pause_tx,
174 		ps_cap->lps_awake_interval, ps_cap->lps_listen_bcn_mode, ps_cap->lps_smart_ps_mode,
175 		ps_cap->lps_rssi_enter_threshold, ps_cap->lps_rssi_leave_threshold, ps_cap->lps_rssi_diff_threshold,
176 		phl_ps_op_mode_to_str(ps_cap->ips_en), phl_ps_pwr_lvl_to_str(phl_ps_judge_pwr_lvl(ps_cap->ips_cap, PS_MODE_IPS, true)));
177 
178 #else
179 	PS_CNSL(out_len, *used, output + *used, out_len - *used,
180 		"Not support.\n");
181 #endif
182 }
183 
phl_ps_dbg_stop_ps(struct phl_info_t * phl_info,u32 * used,char input[][MAX_ARGV],u32 input_num,char * output,u32 out_len)184 void phl_ps_dbg_stop_ps(struct phl_info_t *phl_info, u32 *used,
185 	char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len)
186 {
187 	u32 stop = 0;
188 	bool ps_en = false;
189 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
190 
191 	do {
192 		if (input_num < 3){
193 			PS_CNSL(out_len, *used, output + *used, out_len - *used,
194 					 "[DBG] echo phl ps stop_ps <0/1>\n");
195 			break;
196 		}
197 
198 		if (!_get_hex_from_string(input[2], &stop))
199 			break;
200 
201 		if ((phl_com->dev_sw_cap.ps_cap.ips_en != PS_OP_MODE_AUTO)&&
202 			(phl_com->dev_sw_cap.ps_cap.lps_en != PS_OP_MODE_AUTO)){
203 				PS_CNSL(out_len, *used, output + *used, out_len - *used,
204 					 "One of ips or lps should set PS_OP_MODE_AUTO\n");
205 				break;
206 		}
207 
208 		if (stop)
209 			ps_en = false;
210 		else
211 			ps_en = true;
212 
213 		rtw_phl_ps_set_rt_cap((void*)phl_info, HW_BAND_0, ps_en, PS_RT_DEBUG);
214 
215 	} while (0);
216 }
217 
phl_ps_dbg_test_ps(struct phl_info_t * phl_info,u32 * used,char input[][MAX_ARGV],u32 input_num,char * output,u32 out_len)218 void phl_ps_dbg_test_ps(struct phl_info_t *phl_info, u32 *used,
219 	char input[][MAX_ARGV], u32 input_num, char *output, u32 out_len)
220 {
221 	u32 enter = 0;
222 	u8 ps_mode = PS_MODE_NONE;
223 
224 	do {
225 		if (input_num < 4){
226 			PS_CNSL(out_len, *used, output + *used, out_len - *used,
227 					 "[DBG] echo phl ps test <ips/lps> <0/1>\n");
228 			break;
229 		}
230 
231 		if (!_os_strcmp(input[2], "lps")) {
232 			ps_mode = PS_MODE_LPS;
233 		} else if (!_os_strcmp(input[2], "ips")) {
234 			ps_mode = PS_MODE_IPS;
235 		} else {
236 			break;
237 		}
238 
239 		if (!_get_hex_from_string(input[3], &enter))
240 			break;
241 
242 		phl_ps_dbg_set_ps(phl_info, ps_mode, (enter ? true : false));
243 
244 	} while (0);
245 }
246 
247 #endif /* CONFIG_POWER_SAVE */
248