1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /**
8  * @brief Header containing command specific declarations for the
9  * radio test mode in the FMAC IF Layer of the Wi-Fi driver.
10  */
11 
12 #include "radio_test/fmac_cmd.h"
13 #include "common/hal_api_common.h"
14 
umac_cmd_rt_init(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_phy_rf_params * rf_params,bool rf_params_valid,int sleep_type,unsigned int phy_calib,enum op_band op_band,bool beamforming,struct nrf_wifi_tx_pwr_ctrl_params * tx_pwr_ctrl_params,struct nrf_wifi_board_params * board_params,unsigned char * country_code)15 enum nrf_wifi_status umac_cmd_rt_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
16 				      struct nrf_wifi_phy_rf_params *rf_params,
17 				      bool rf_params_valid,
18 #ifdef NRF_WIFI_LOW_POWER
19 				      int sleep_type,
20 #endif /* NRF_WIFI_LOW_POWER */
21 				      unsigned int phy_calib,
22 				      enum op_band op_band,
23 				      bool beamforming,
24 				      struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params,
25 				      struct nrf_wifi_board_params *board_params,
26 				      unsigned char *country_code)
27 {
28 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
29 	struct host_rpu_msg *umac_cmd = NULL;
30 	struct nrf_wifi_cmd_sys_init *umac_cmd_data = NULL;
31 	unsigned int len = 0;
32 
33 	len = sizeof(*umac_cmd_data);
34 
35 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
36 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
37 				  len);
38 
39 	if (!umac_cmd) {
40 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
41 				      __func__);
42 		goto out;
43 	}
44 
45 	umac_cmd_data = (struct nrf_wifi_cmd_sys_init *)(umac_cmd->msg);
46 
47 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_INIT;
48 	umac_cmd_data->sys_head.len = len;
49 
50 
51 	umac_cmd_data->sys_params.rf_params_valid = rf_params_valid;
52 
53 	if (rf_params_valid) {
54 		nrf_wifi_osal_mem_cpy(umac_cmd_data->sys_params.rf_params,
55 				      rf_params,
56 				      NRF_WIFI_RF_PARAMS_SIZE);
57 	}
58 
59 
60 	umac_cmd_data->sys_params.phy_calib = phy_calib;
61 	umac_cmd_data->sys_params.hw_bringup_time = HW_DELAY;
62 	umac_cmd_data->sys_params.sw_bringup_time = SW_DELAY;
63 	umac_cmd_data->sys_params.bcn_time_out = BCN_TIMEOUT;
64 	umac_cmd_data->sys_params.calib_sleep_clk = CALIB_SLEEP_CLOCK_ENABLE;
65 #ifdef NRF_WIFI_LOW_POWER
66 	umac_cmd_data->sys_params.sleep_enable = sleep_type;
67 #endif /* NRF_WIFI_LOW_POWER */
68 #ifdef NRF70_TCP_IP_CHECKSUM_OFFLOAD
69 	umac_cmd_data->tcp_ip_checksum_offload = 1;
70 #endif /* NRF70_TCP_IP_CHECKSUM_OFFLOAD */
71 	umac_cmd_data->discon_timeout = NRF_WIFI_AP_DEAD_DETECT_TIMEOUT;
72 #ifdef NRF_WIFI_RPU_RECOVERY
73 	umac_cmd_data->watchdog_timer_val =
74 		(NRF_WIFI_RPU_RECOVERY_PS_ACTIVE_TIMEOUT_MS) / 1000;
75 #else
76 	/* Disable watchdog */
77 	umac_cmd_data->watchdog_timer_val = 0xFFFFFF;
78 #endif /* NRF_WIFI_RPU_RECOVERY */
79 
80 	nrf_wifi_osal_log_dbg("RPU LPM type: %s",
81 		umac_cmd_data->sys_params.sleep_enable == 2 ? "HW" :
82 		umac_cmd_data->sys_params.sleep_enable == 1 ? "SW" : "DISABLED");
83 
84 #ifdef NRF_WIFI_MGMT_BUFF_OFFLOAD
85 	umac_cmd_data->mgmt_buff_offload =  1;
86 	nrf_wifi_osal_log_info("Management buffer offload enabled\n");
87 #endif /* NRF_WIFI_MGMT_BUFF_OFFLOAD */
88 #ifdef NRF_WIFI_FEAT_KEEPALIVE
89 	umac_cmd_data->keep_alive_enable = KEEP_ALIVE_ENABLED;
90 	umac_cmd_data->keep_alive_period = NRF_WIFI_KEEPALIVE_PERIOD_S;
91 	nrf_wifi_osal_log_dbg("Keepalive enabled with period %d\n",
92 				   umac_cmd_data->keepalive_period);
93 #endif /* NRF_WIFI_FEAT_KEEPALIVE */
94 
95 	umac_cmd_data->op_band = op_band;
96 
97 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->sys_params.rf_params[PCB_LOSS_BYTE_2G_OFST],
98 			      &board_params->pcb_loss_2g,
99 			      NUM_PCB_LOSS_OFFSET);
100 
101 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->sys_params.rf_params[ANT_GAIN_2G_OFST],
102 			      &tx_pwr_ctrl_params->ant_gain_2g,
103 			      NUM_ANT_GAIN);
104 
105 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->sys_params.rf_params[BAND_2G_LW_ED_BKF_DSSS_OFST],
106 			      &tx_pwr_ctrl_params->band_edge_2g_lo_dss,
107 			      NUM_EDGE_BACKOFF);
108 
109 	nrf_wifi_osal_mem_cpy(umac_cmd_data->country_code,
110 			      country_code,
111 			      NRF_WIFI_COUNTRY_CODE_LEN);
112 
113 #ifdef NRF70_RPU_EXTEND_TWT_SP
114 	 umac_cmd_data->feature_flags |= TWT_EXTEND_SP_EDCA;
115 #endif
116 #ifdef CONFIG_WIFI_NRF70_SCAN_DISABLE_DFS_CHANNELS
117 	umac_cmd_data->feature_flags |= DISABLE_DFS_CHANNELS;
118 #endif /* NRF70_SCAN_DISABLE_DFS_CHANNELS */
119 
120 	if (!beamforming) {
121 		umac_cmd_data->disable_beamforming = 1;
122 	}
123 
124 #if defined(NRF_WIFI_PS_INT_PS)
125 	umac_cmd_data->ps_exit_strategy = INT_PS;
126 #else
127 	umac_cmd_data->ps_exit_strategy = EVERY_TIM;
128 #endif  /* NRF_WIFI_PS_INT_PS */
129 
130 	umac_cmd_data->display_scan_bss_limit = NRF_WIFI_DISPLAY_SCAN_BSS_LIMIT;
131 
132 #ifdef NRF_WIFI_COEX_DISABLE_PRIORITY_WINDOW_FOR_SCAN
133 	umac_cmd_data->coex_disable_ptiwin_for_wifi_scan = 1;
134 #else
135 	umac_cmd_data->coex_disable_ptiwin_for_wifi_scan = 0;
136 #endif /* NRF_WIFI_COEX_DISABLE_PRIORITY_WINDOW_FOR_SCAN */
137 
138 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
139 					    umac_cmd,
140 					    (sizeof(*umac_cmd) + len));
141 
142 out:
143 	return status;
144 }
145 
umac_cmd_rt_prog_stats_get(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,int op_mode)146 enum nrf_wifi_status umac_cmd_rt_prog_stats_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
147 						int op_mode)
148 {
149 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
150 	struct host_rpu_msg *umac_cmd = NULL;
151 	struct nrf_wifi_cmd_get_stats *umac_cmd_data = NULL;
152 	int len = 0;
153 
154 	len = sizeof(*umac_cmd_data);
155 
156 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
157 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
158 				  len);
159 
160 	if (!umac_cmd) {
161 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
162 				      __func__);
163 		goto out;
164 	}
165 
166 	umac_cmd_data = (struct nrf_wifi_cmd_get_stats *)(umac_cmd->msg);
167 
168 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_GET_STATS;
169 	umac_cmd_data->sys_head.len = len;
170 	umac_cmd_data->stats_type = RPU_STATS_TYPE_PHY;
171 	umac_cmd_data->op_mode = op_mode;
172 
173 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
174 					    umac_cmd,
175 					    (sizeof(*umac_cmd) + len));
176 
177 out:
178 	return status;
179 }
180 
181 
umac_cmd_rt_prog_init(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_radio_test_init_info * init_params)182 enum nrf_wifi_status umac_cmd_rt_prog_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
183 					   struct nrf_wifi_radio_test_init_info *init_params)
184 {
185 	struct host_rpu_msg *umac_cmd = NULL;
186 	struct nrf_wifi_cmd_radio_test_init *umac_cmd_data = NULL;
187 	int len = 0;
188 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
189 
190 	len = sizeof(*umac_cmd_data);
191 
192 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
193 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
194 				  len);
195 
196 	if (!umac_cmd) {
197 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
198 				      __func__);
199 		goto out;
200 	}
201 
202 	umac_cmd_data = (struct nrf_wifi_cmd_radio_test_init *)(umac_cmd->msg);
203 
204 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_RADIO_TEST_INIT;
205 	umac_cmd_data->sys_head.len = len;
206 
207 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->conf,
208 			      init_params,
209 			      sizeof(umac_cmd_data->conf));
210 
211 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
212 					    umac_cmd,
213 					    (sizeof(*umac_cmd) + len));
214 out:
215 	return status;
216 }
217 
218 
umac_cmd_rt_prog_tx(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct rpu_conf_params * params)219 enum nrf_wifi_status umac_cmd_rt_prog_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
220 					 struct rpu_conf_params *params)
221 {
222 	struct host_rpu_msg *umac_cmd = NULL;
223 	struct nrf_wifi_cmd_mode_params *umac_cmd_data = NULL;
224 	int len = 0;
225 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
226 
227 	len = sizeof(*umac_cmd_data);
228 
229 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
230 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
231 				  len);
232 
233 	if (!umac_cmd) {
234 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
235 				      __func__);
236 		goto out;
237 	}
238 
239 	umac_cmd_data = (struct nrf_wifi_cmd_mode_params *)(umac_cmd->msg);
240 
241 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_TX;
242 	umac_cmd_data->sys_head.len = len;
243 
244 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->conf,
245 			      params,
246 			      sizeof(umac_cmd_data->conf));
247 
248 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
249 					    umac_cmd,
250 					    (sizeof(*umac_cmd) + len));
251 
252 out:
253 	return status;
254 }
255 
256 
umac_cmd_rt_prog_rx(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct rpu_conf_rx_radio_test_params * rx_params)257 enum nrf_wifi_status umac_cmd_rt_prog_rx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
258 					 struct rpu_conf_rx_radio_test_params *rx_params)
259 {
260 	struct host_rpu_msg *umac_cmd = NULL;
261 	struct nrf_wifi_cmd_rx *umac_cmd_data = NULL;
262 	int len = 0;
263 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
264 
265 	len = sizeof(*umac_cmd_data);
266 
267 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
268 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
269 				  len);
270 
271 	if (!umac_cmd) {
272 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
273 				      __func__);
274 		goto out;
275 	}
276 
277 	umac_cmd_data = (struct nrf_wifi_cmd_rx *)(umac_cmd->msg);
278 
279 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_RX;
280 	umac_cmd_data->sys_head.len = len;
281 
282 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->conf,
283 			      rx_params,
284 			      sizeof(umac_cmd_data->conf));
285 
286 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
287 					    umac_cmd,
288 					    (sizeof(*umac_cmd) + len));
289 
290 out:
291 	return status;
292 }
293 
294 
umac_cmd_rt_prog_rf_test(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * rf_test_params,unsigned int rf_test_params_sz)295 enum nrf_wifi_status umac_cmd_rt_prog_rf_test(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
296 					      void *rf_test_params,
297 					      unsigned int rf_test_params_sz)
298 {
299 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
300 	struct host_rpu_msg *umac_cmd = NULL;
301 	struct nrf_wifi_cmd_rftest *umac_cmd_data = NULL;
302 	int len = 0;
303 
304 	len = (sizeof(*umac_cmd_data) + rf_test_params_sz);
305 
306 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
307 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
308 				  len);
309 
310 	if (!umac_cmd) {
311 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
312 				      __func__);
313 		goto out;
314 	}
315 
316 	umac_cmd_data = (struct nrf_wifi_cmd_rftest *)(umac_cmd->msg);
317 
318 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_RF_TEST;
319 	umac_cmd_data->sys_head.len = len;
320 
321 	nrf_wifi_osal_mem_cpy((void *)umac_cmd_data->rf_test_info.rfcmd,
322 			      rf_test_params,
323 			      rf_test_params_sz);
324 
325 	umac_cmd_data->rf_test_info.len = rf_test_params_sz;
326 
327 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
328 					    umac_cmd,
329 					    (sizeof(*umac_cmd) + len));
330 
331 out:
332 	return status;
333 }