1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /**
8  * @brief File containing API definitions for the
9  * FMAC IF Layer of the Wi-Fi driver.
10  */
11 
12 #include "host_rpu_umac_if.h"
13 #include "system/phy_rf_params.h"
14 #include "system/fmac_api.h"
15 #include "system/hal_api.h"
16 #include "system/fmac_structs.h"
17 #include "common/fmac_util.h"
18 #include "system/fmac_peer.h"
19 #include "system/fmac_vif.h"
20 #include "system/fmac_tx.h"
21 #include "system/fmac_rx.h"
22 #include "system/fmac_cmd.h"
23 #include "system/fmac_event.h"
24 #include "system/fmac_bb.h"
25 #include "util.h"
26 
27 
nrf_wifi_fmac_vif_idx_get(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)28 static unsigned char nrf_wifi_fmac_vif_idx_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
29 {
30 	unsigned char i = 0;
31 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
32 
33 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
34 
35 	for (i = 0; i < MAX_NUM_VIFS; i++) {
36 		if (sys_dev_ctx->vif_ctx[i] == NULL) {
37 			break;
38 		}
39 	}
40 
41 	return i;
42 }
43 
44 
45 #ifdef NRF70_DATA_TX
nrf_wifi_sys_fmac_init_tx(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)46 static enum nrf_wifi_status nrf_wifi_sys_fmac_init_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
47 {
48 	struct nrf_wifi_fmac_priv *fpriv = NULL;
49 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
50 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
51 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
52 	unsigned int size = 0;
53 
54 	fpriv = fmac_dev_ctx->fpriv;
55 
56 	sys_fpriv = wifi_fmac_priv(fpriv);
57 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
58 
59 	size = (sys_fpriv->num_tx_tokens *
60 		sys_fpriv->data_config.max_tx_aggregation *
61 		sizeof(struct nrf_wifi_fmac_buf_map_info));
62 
63 	sys_dev_ctx->tx_buf_info = nrf_wifi_osal_mem_zalloc(size);
64 
65 	if (!sys_dev_ctx->tx_buf_info) {
66 		nrf_wifi_osal_log_err("%s: No space for TX buf info",
67 				      __func__);
68 		goto out;
69 	}
70 
71 	status = tx_init(fmac_dev_ctx);
72 
73 out:
74 	return status;
75 }
76 
77 
nrf_wifi_sys_fmac_deinit_tx(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)78 static void nrf_wifi_sys_fmac_deinit_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
79 {
80 	struct nrf_wifi_fmac_priv *fpriv = NULL;
81 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
82 
83 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
84 
85 	fpriv = fmac_dev_ctx->fpriv;
86 
87 	tx_deinit(fmac_dev_ctx);
88 
89 	nrf_wifi_osal_mem_free(sys_dev_ctx->tx_buf_info);
90 }
91 
92 #endif /* NRF70_DATA_TX */
93 
nrf_wifi_sys_fmac_init_rx(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)94 static enum nrf_wifi_status nrf_wifi_sys_fmac_init_rx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
95 {
96 	struct nrf_wifi_fmac_priv *fpriv = NULL;
97 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
98 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
99 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
100 	unsigned int size = 0;
101 	unsigned int desc_id = 0;
102 
103 	fpriv = fmac_dev_ctx->fpriv;
104 	sys_fpriv = wifi_fmac_priv(fpriv);
105 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
106 
107 	size = (sys_fpriv->num_rx_bufs * sizeof(struct nrf_wifi_fmac_buf_map_info));
108 
109 	sys_dev_ctx->rx_buf_info = nrf_wifi_osal_mem_zalloc(size);
110 
111 	if (!sys_dev_ctx->rx_buf_info) {
112 		nrf_wifi_osal_log_err("%s: No space for RX buf info",
113 				      __func__);
114 		goto out;
115 	}
116 
117 	for (desc_id = 0; desc_id < sys_fpriv->num_rx_bufs; desc_id++) {
118 		status = nrf_wifi_fmac_rx_cmd_send(fmac_dev_ctx,
119 						   NRF_WIFI_FMAC_RX_CMD_TYPE_INIT,
120 						   desc_id);
121 
122 		if (status != NRF_WIFI_STATUS_SUCCESS) {
123 			nrf_wifi_osal_log_err("%s: RX init failed for desc_id = %d",
124 					      __func__,
125 					      desc_id);
126 			goto out;
127 		}
128 	}
129 #ifdef NRF70_RX_WQ_ENABLED
130 	sys_dev_ctx->rx_tasklet = nrf_wifi_osal_tasklet_alloc(NRF_WIFI_TASKLET_TYPE_RX);
131 	if (!sys_dev_ctx->rx_tasklet) {
132 		nrf_wifi_osal_log_err("%s: No space for RX tasklet",
133 				      __func__);
134 		status = NRF_WIFI_STATUS_FAIL;
135 		goto out;
136 	}
137 
138 	sys_dev_ctx->rx_tasklet_event_q = nrf_wifi_utils_q_alloc();
139 	if (!sys_dev_ctx->rx_tasklet_event_q) {
140 		nrf_wifi_osal_log_err("%s: No space for RX tasklet event queue",
141 				      __func__);
142 		status = NRF_WIFI_STATUS_FAIL;
143 		goto out;
144 	}
145 
146 	nrf_wifi_osal_tasklet_init(sys_dev_ctx->rx_tasklet,
147 				   nrf_wifi_fmac_rx_tasklet,
148 				   (unsigned long)fmac_dev_ctx);
149 #endif /* NRF70_RX_WQ_ENABLED */
150 out:
151 	return status;
152 }
153 
154 
nrf_wifi_sys_fmac_deinit_rx(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)155 static enum nrf_wifi_status nrf_wifi_sys_fmac_deinit_rx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
156 {
157 	struct nrf_wifi_fmac_priv *fpriv = NULL;
158 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
159 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
160 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
161 	unsigned int desc_id = 0;
162 
163 	fpriv = fmac_dev_ctx->fpriv;
164 	sys_fpriv = wifi_fmac_priv(fpriv);
165 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
166 
167 #ifdef NRF70_RX_WQ_ENABLED
168 	nrf_wifi_osal_tasklet_free(sys_dev_ctx->rx_tasklet);
169 	nrf_wifi_utils_q_free(sys_dev_ctx->rx_tasklet_event_q);
170 #endif /* NRF70_RX_WQ_ENABLED */
171 
172 	for (desc_id = 0; desc_id < sys_fpriv->num_rx_bufs; desc_id++) {
173 		status = nrf_wifi_fmac_rx_cmd_send(fmac_dev_ctx,
174 						   NRF_WIFI_FMAC_RX_CMD_TYPE_DEINIT,
175 						   desc_id);
176 
177 		if (status != NRF_WIFI_STATUS_SUCCESS) {
178 			nrf_wifi_osal_log_err("%s: RX deinit failed for desc_id = %d",
179 					      __func__,
180 					      desc_id);
181 			goto out;
182 		}
183 	}
184 
185 	nrf_wifi_osal_mem_free(sys_dev_ctx->rx_buf_info);
186 
187 	sys_dev_ctx->rx_buf_info = NULL;
188 out:
189 	return status;
190 }
191 
192 
nrf_wifi_sys_fmac_fw_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,struct nrf_wifi_board_params * board_params,unsigned char * country_code)193 static enum nrf_wifi_status nrf_wifi_sys_fmac_fw_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
194 						      struct nrf_wifi_phy_rf_params *rf_params,
195 						      bool rf_params_valid,
196 #ifdef NRF_WIFI_LOW_POWER
197 						      int sleep_type,
198 #endif /* NRF_WIFI_LOW_POWER */
199 						      unsigned int phy_calib,
200 						      enum op_band op_band,
201 						      bool beamforming,
202 						      struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl,
203 						      struct nrf_wifi_board_params *board_params,
204 						      unsigned char *country_code)
205 {
206 	unsigned long start_time_us = 0;
207 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
208 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
209 
210 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
211 
212 #ifdef NRF70_DATA_TX
213 	status = nrf_wifi_sys_fmac_init_tx(fmac_dev_ctx);
214 
215 	if (status != NRF_WIFI_STATUS_SUCCESS) {
216 		nrf_wifi_osal_log_err("%s: Init TX failed",
217 				      __func__);
218 		goto out;
219 	}
220 #endif /* NRF70_DATA_TX */
221 
222 	status = nrf_wifi_sys_fmac_init_rx(fmac_dev_ctx);
223 
224 	if (status != NRF_WIFI_STATUS_SUCCESS) {
225 		nrf_wifi_osal_log_err("%s: Init RX failed",
226 				      __func__);
227 #ifdef NRF70_DATA_TX
228 		nrf_wifi_sys_fmac_deinit_tx(fmac_dev_ctx);
229 #endif
230 		goto out;
231 	}
232 
233 	status = umac_cmd_sys_init(fmac_dev_ctx,
234 				   rf_params,
235 				   rf_params_valid,
236 				   &sys_fpriv->data_config,
237 #ifdef NRF_WIFI_LOW_POWER
238 				   sleep_type,
239 #endif /* NRF_WIFI_LOW_POWER */
240 				   phy_calib,
241 				   op_band,
242 				   beamforming,
243 				   tx_pwr_ctrl,
244 				   board_params,
245 				   country_code);
246 
247 	if (status != NRF_WIFI_STATUS_SUCCESS) {
248 		nrf_wifi_osal_log_err("%s: UMAC init failed",
249 				      __func__);
250 		nrf_wifi_sys_fmac_deinit_rx(fmac_dev_ctx);
251 #ifdef NRF70_DATA_TX
252 		nrf_wifi_sys_fmac_deinit_tx(fmac_dev_ctx);
253 #endif /* NRF70_DATA_TX */
254 		goto out;
255 	}
256 	start_time_us = nrf_wifi_osal_time_get_curr_us();
257 	while (!fmac_dev_ctx->fw_init_done) {
258 		nrf_wifi_osal_sleep_ms(1);
259 #define MAX_INIT_WAIT (5 * 1000 * 1000)
260 		if (nrf_wifi_osal_time_elapsed_us(start_time_us) >= MAX_INIT_WAIT) {
261 			break;
262 		}
263 	}
264 
265 	if (!fmac_dev_ctx->fw_init_done) {
266 		nrf_wifi_osal_log_err("%s: UMAC init timed out",
267 				      __func__);
268 		nrf_wifi_sys_fmac_deinit_rx(fmac_dev_ctx);
269 #ifdef NRF70_DATA_TX
270 		nrf_wifi_sys_fmac_deinit_tx(fmac_dev_ctx);
271 #endif /* NRF70_DATA_TX */
272 		status = NRF_WIFI_STATUS_FAIL;
273 		goto out;
274 	}
275 
276 	status = NRF_WIFI_STATUS_SUCCESS;
277 
278 out:
279 	return status;
280 }
281 
nrf_wifi_sys_fmac_fw_deinit(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)282 static void nrf_wifi_sys_fmac_fw_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
283 {
284 	/* TODO: To be activated once UMAC supports deinit */
285 #ifdef NOTYET
286 	unsigned long start_time_us = 0;
287 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
288 
289 	status = umac_cmd_deinit(fmac_dev_ctx);
290 
291 	if (status != NRF_WIFI_STATUS_SUCCESS) {
292 		nrf_wifi_osal_log_err("%s: UMAC deinit failed",
293 				      __func__);
294 		goto out;
295 	}
296 
297 	start_time_us = nrf_wifi_osal_time_get_curr_us();
298 
299 	while (!fmac_dev_ctx->fw_deinit_done) {
300 #define MAX_DEINIT_WAIT (5 * 1000 * 1000)
301 		nrf_wifi_osal_sleep_ms(1);
302 		if (nrf_wifi_osal_time_elapsed_us(start_time_us) >= MAX_DEINIT_WAIT) {
303 			break;
304 		}
305 	}
306 
307 	if (!fmac_dev_ctx->fw_deinit_done) {
308 		nrf_wifi_osal_log_err("%s: UMAC deinit timed out",
309 				      __func__);
310 		status = NRF_WIFI_STATUS_FAIL;
311 		goto out;
312 	}
313 out:
314 #endif /* NOTYET */
315 	nrf_wifi_sys_fmac_deinit_rx(fmac_dev_ctx);
316 #ifdef NRF70_DATA_TX
317 	nrf_wifi_sys_fmac_deinit_tx(fmac_dev_ctx);
318 #endif /* NRF70_DATA_TX */
319 
320 }
321 
nrf_wifi_sys_fmac_dev_add(struct nrf_wifi_fmac_priv * fpriv,void * os_dev_ctx)322 struct nrf_wifi_fmac_dev_ctx *nrf_wifi_sys_fmac_dev_add(struct nrf_wifi_fmac_priv *fpriv,
323 							void *os_dev_ctx)
324 {
325 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
326 	struct nrf_wifi_sys_fmac_dev_ctx *sys_fmac_dev_ctx = NULL;
327 #ifdef NRF70_DATA_TX
328 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
329 #endif /* NRF70_DATA_TX */
330 
331 	if (!fpriv || !os_dev_ctx) {
332 		return NULL;
333 	}
334 
335 	if (fpriv->op_mode != NRF_WIFI_OP_MODE_SYS) {
336 		nrf_wifi_osal_log_err("%s: Invalid op mode",
337 				      __func__);
338 		goto out;
339 	}
340 
341 	fmac_dev_ctx = nrf_wifi_osal_mem_zalloc(sizeof(*fmac_dev_ctx) + sizeof(*sys_fmac_dev_ctx));
342 
343 	if (!fmac_dev_ctx) {
344 		nrf_wifi_osal_log_err("%s: Unable to allocate fmac_dev_ctx",
345 				      __func__);
346 		goto out;
347 	}
348 
349 	fmac_dev_ctx->fpriv = fpriv;
350 	fmac_dev_ctx->os_dev_ctx = os_dev_ctx;
351 
352 	fmac_dev_ctx->hal_dev_ctx = nrf_wifi_sys_hal_dev_add(fpriv->hpriv,
353 							     fmac_dev_ctx);
354 
355 	if (!fmac_dev_ctx->hal_dev_ctx) {
356 		nrf_wifi_osal_log_err("%s: nrf_wifi_sys_hal_dev_add failed",
357 				      __func__);
358 
359 		nrf_wifi_osal_mem_free(fmac_dev_ctx);
360 		fmac_dev_ctx = NULL;
361 		goto out;
362 	}
363 #ifdef NRF70_DATA_TX
364 
365 	sys_fpriv = wifi_fmac_priv(fpriv);
366 	fpriv->hpriv->cfg_params.max_ampdu_len_per_token = sys_fpriv->max_ampdu_len_per_token;
367 #endif /* NRF70_DATA_TX */
368 
369 	fmac_dev_ctx->op_mode = NRF_WIFI_OP_MODE_SYS;
370 out:
371 	return fmac_dev_ctx;
372 }
373 
374 
nrf_wifi_sys_fmac_dev_init(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,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_tx_pwr_ceil_params * tx_pwr_ceil_params,struct nrf_wifi_board_params * board_params,unsigned char * country_code)375 enum nrf_wifi_status nrf_wifi_sys_fmac_dev_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
376 #ifdef NRF_WIFI_LOW_POWER
377 					    int sleep_type,
378 #endif /* NRF_WIFI_LOW_POWER */
379 					    unsigned int phy_calib,
380 					    enum op_band op_band,
381 					    bool beamforming,
382 					    struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params,
383 					    struct nrf_wifi_tx_pwr_ceil_params *tx_pwr_ceil_params,
384 					    struct nrf_wifi_board_params *board_params,
385 					    unsigned char *country_code)
386 {
387 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
388 	struct nrf_wifi_fmac_otp_info otp_info;
389 	struct nrf_wifi_phy_rf_params phy_rf_params;
390 
391 	if (!fmac_dev_ctx) {
392 		nrf_wifi_osal_log_err("%s: Invalid device context",
393 				      __func__);
394 		goto out;
395 	}
396 
397 	if (fmac_dev_ctx->op_mode != NRF_WIFI_OP_MODE_SYS) {
398 		nrf_wifi_osal_log_err("%s: Invalid op mode",
399 				      __func__);
400 		goto out;
401 	}
402 
403 	fmac_dev_ctx->tx_pwr_ceil_params = nrf_wifi_osal_mem_alloc(sizeof(*tx_pwr_ceil_params));
404 	nrf_wifi_osal_mem_cpy(fmac_dev_ctx->tx_pwr_ceil_params,
405 			      tx_pwr_ceil_params,
406 			      sizeof(*tx_pwr_ceil_params));
407 
408 	status = nrf_wifi_hal_dev_init(fmac_dev_ctx->hal_dev_ctx);
409 
410 	if (status != NRF_WIFI_STATUS_SUCCESS) {
411 		nrf_wifi_osal_log_err("%s: nrf_wifi_hal_dev_init failed",
412 				      __func__);
413 		goto out;
414 	}
415 
416 	nrf_wifi_osal_mem_set(&otp_info,
417 			      0xFF,
418 			      sizeof(otp_info));
419 
420 	status = nrf_wifi_hal_otp_info_get(fmac_dev_ctx->hal_dev_ctx,
421 					   &otp_info.info,
422 					   &otp_info.flags);
423 
424 	if (status != NRF_WIFI_STATUS_SUCCESS) {
425 		nrf_wifi_osal_log_err("%s: Fetching of RPU OTP information failed",
426 				      __func__);
427 		goto out;
428 	}
429 
430 	status = nrf_wifi_sys_fmac_rf_params_get(fmac_dev_ctx,
431 						 &phy_rf_params);
432 	if (status != NRF_WIFI_STATUS_SUCCESS) {
433 		nrf_wifi_osal_log_err("%s: RF parameters get failed",
434 				      __func__);
435 		goto out;
436 	}
437 
438 	status = nrf_wifi_sys_fmac_fw_init(fmac_dev_ctx,
439 				       &phy_rf_params,
440 				       true,
441 #ifdef NRF_WIFI_LOW_POWER
442 				       sleep_type,
443 #endif /* NRF_WIFI_LOW_POWER */
444 				       phy_calib,
445 				       op_band,
446 				       beamforming,
447 				       tx_pwr_ctrl_params,
448 				       board_params,
449 				       country_code);
450 
451 	if (status == NRF_WIFI_STATUS_FAIL) {
452 		nrf_wifi_osal_log_err("%s: nrf_wifi_sys_fmac_fw_init failed",
453 				      __func__);
454 		goto out;
455 	}
456 out:
457 	return status;
458 }
459 
460 
nrf_wifi_sys_fmac_dev_deinit(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)461 void nrf_wifi_sys_fmac_dev_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
462 {
463 	if (fmac_dev_ctx->op_mode != NRF_WIFI_OP_MODE_SYS) {
464 		nrf_wifi_osal_log_err("%s: Invalid op mode",
465 				      __func__);
466 		return;
467 	}
468 
469 	nrf_wifi_hal_dev_deinit(fmac_dev_ctx->hal_dev_ctx);
470 	nrf_wifi_sys_fmac_fw_deinit(fmac_dev_ctx);
471 	nrf_wifi_osal_mem_free(fmac_dev_ctx->tx_pwr_ceil_params);
472 }
473 
474 #ifdef NRF_WIFI_RPU_RECOVERY
nrf_wifi_sys_fmac_rpu_recovery_callback(void * mac_dev_ctx,void * event_data,unsigned int len)475 enum nrf_wifi_status nrf_wifi_sys_fmac_rpu_recovery_callback(void *mac_dev_ctx,
476 							     void *event_data,
477 							     unsigned int len)
478 {
479 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
480 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
481 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
482 	struct nrf_wifi_fmac_priv *fpriv = NULL;
483 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
484 
485 	fmac_dev_ctx = mac_dev_ctx;
486 	if (!fmac_dev_ctx) {
487 		goto out;
488 	}
489 
490 	if (fmac_dev_ctx->op_mode != NRF_WIFI_OP_MODE_SYS) {
491 		nrf_wifi_osal_log_err("%s: Invalid op mode",
492 				      __func__);
493 		goto out;
494 	}
495 
496 	fpriv = fmac_dev_ctx->fpriv;
497 	sys_fpriv = wifi_fmac_priv(fpriv);
498 
499 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
500 	if (!sys_dev_ctx) {
501 		nrf_wifi_osal_log_err("%s: Invalid device context",
502 				      __func__);
503 		goto out;
504 	}
505 
506 	if (!sys_fpriv->callbk_fns.rpu_recovery_callbk_fn) {
507 		nrf_wifi_osal_log_err("%s: No RPU recovery callback function",
508 				      __func__);
509 		goto out;
510 	}
511 
512 	/* Here we only care about FMAC, so, just use VIF0 */
513 	sys_fpriv->callbk_fns.rpu_recovery_callbk_fn(sys_dev_ctx->vif_ctx[0],
514 			event_data, len);
515 
516 	status = NRF_WIFI_STATUS_SUCCESS;
517 out:
518 	return status;
519 }
520 #endif /* NRF_WIFI_RPU_RECOVERY */
521 
nrf_wifi_sys_fmac_init(struct nrf_wifi_data_config_params * data_config,struct rx_buf_pool_params * rx_buf_pools,struct nrf_wifi_fmac_callbk_fns * callbk_fns)522 struct nrf_wifi_fmac_priv *nrf_wifi_sys_fmac_init(struct nrf_wifi_data_config_params *data_config,
523 						  struct rx_buf_pool_params *rx_buf_pools,
524 						  struct nrf_wifi_fmac_callbk_fns *callbk_fns)
525 {
526 	struct nrf_wifi_fmac_priv *fpriv = NULL;
527 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
528 	struct nrf_wifi_hal_cfg_params hal_cfg_params;
529 	unsigned int pool_idx = 0;
530 	unsigned int desc = 0;
531 
532 	fpriv = nrf_wifi_osal_mem_zalloc(sizeof(*fpriv) + sizeof(*sys_fpriv));
533 
534 	if (!fpriv) {
535 		nrf_wifi_osal_log_err("%s: Unable to allocate fpriv",
536 				      __func__);
537 		goto out;
538 	}
539 
540 	sys_fpriv = wifi_fmac_priv(fpriv);
541 
542 	nrf_wifi_osal_mem_set(&hal_cfg_params,
543 			      0,
544 			      sizeof(hal_cfg_params));
545 
546 	nrf_wifi_osal_mem_cpy(&sys_fpriv->callbk_fns,
547 			      callbk_fns,
548 			      sizeof(sys_fpriv->callbk_fns));
549 
550 	nrf_wifi_osal_mem_cpy(&sys_fpriv->data_config,
551 			      data_config,
552 			      sizeof(sys_fpriv->data_config));
553 
554 #ifdef NRF70_DATA_TX
555 	sys_fpriv->num_tx_tokens = NRF70_MAX_TX_TOKENS;
556 	sys_fpriv->num_tx_tokens_per_ac = (sys_fpriv->num_tx_tokens / NRF_WIFI_FMAC_AC_MAX);
557 	sys_fpriv->num_tx_tokens_spare = (sys_fpriv->num_tx_tokens % NRF_WIFI_FMAC_AC_MAX);
558 #endif /* NRF70_DATA_TX */
559 	nrf_wifi_osal_mem_cpy(sys_fpriv->rx_buf_pools,
560 			      rx_buf_pools,
561 			      sizeof(sys_fpriv->rx_buf_pools));
562 
563 	for (pool_idx = 0; pool_idx < MAX_NUM_OF_RX_QUEUES; pool_idx++) {
564 		sys_fpriv->rx_desc[pool_idx] = desc;
565 
566 		desc += sys_fpriv->rx_buf_pools[pool_idx].num_bufs;
567 	}
568 
569 	sys_fpriv->num_rx_bufs = desc;
570 
571 	hal_cfg_params.rx_buf_headroom_sz = RX_BUF_HEADROOM;
572 	hal_cfg_params.tx_buf_headroom_sz = TX_BUF_HEADROOM;
573 #ifdef NRF70_DATA_TX
574 	hal_cfg_params.max_tx_frms = (sys_fpriv->num_tx_tokens *
575 				      sys_fpriv->data_config.max_tx_aggregation);
576 #endif /* NRF70_DATA_TX */
577 
578 	for (pool_idx = 0; pool_idx < MAX_NUM_OF_RX_QUEUES; pool_idx++) {
579 		hal_cfg_params.rx_buf_pool[pool_idx].num_bufs =
580 			sys_fpriv->rx_buf_pools[pool_idx].num_bufs;
581 		hal_cfg_params.rx_buf_pool[pool_idx].buf_sz =
582 			sys_fpriv->rx_buf_pools[pool_idx].buf_sz + RX_BUF_HEADROOM;
583 	}
584 
585 	hal_cfg_params.max_tx_frm_sz = NRF_WIFI_IFACE_MTU + NRF_WIFI_FMAC_ETH_HDR_LEN +
586 					TX_BUF_HEADROOM;
587 
588 	hal_cfg_params.max_cmd_size = MAX_NRF_WIFI_UMAC_CMD_SIZE;
589 	hal_cfg_params.max_event_size = MAX_EVENT_POOL_LEN;
590 
591 	fpriv->hpriv = nrf_wifi_hal_init(&hal_cfg_params,
592 					 &nrf_wifi_sys_fmac_event_callback,
593 #ifdef NRF_WIFI_RPU_RECOVERY
594 					 &nrf_wifi_sys_fmac_rpu_recovery_callback);
595 #else
596 					 NULL);
597 #endif
598 
599 	if (!fpriv->hpriv) {
600 		nrf_wifi_osal_log_err("%s: Unable to do HAL init",
601 				      __func__);
602 		nrf_wifi_osal_mem_free(fpriv);
603 		fpriv = NULL;
604 		sys_fpriv = NULL;
605 		goto out;
606 	}
607 
608 	fpriv->op_mode = NRF_WIFI_OP_MODE_SYS;
609 out:
610 	return fpriv;
611 }
612 
613 
nrf_wifi_sys_fmac_scan(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_scan_info * scan_info)614 enum nrf_wifi_status nrf_wifi_sys_fmac_scan(void *dev_ctx,
615 					    unsigned char if_idx,
616 					    struct nrf_wifi_umac_scan_info *scan_info)
617 {
618 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
619 	struct nrf_wifi_umac_cmd_scan *scan_cmd = NULL;
620 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
621 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
622 	int channel_info_len = (sizeof(struct nrf_wifi_channel) *
623 				scan_info->scan_params.num_scan_channels);
624 
625 	fmac_dev_ctx = dev_ctx;
626 
627 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
628 		nrf_wifi_osal_log_err("%s: Invalid op mode",
629 				      __func__);
630 		goto out;
631 	}
632 
633 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
634 
635 	scan_cmd = nrf_wifi_osal_mem_zalloc((sizeof(*scan_cmd) + channel_info_len));
636 
637 	if (!scan_cmd) {
638 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
639 				      __func__);
640 		goto out;
641 	}
642 
643 	scan_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_TRIGGER_SCAN;
644 	scan_cmd->umac_hdr.ids.wdev_id = if_idx;
645 	scan_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
646 
647 	nrf_wifi_osal_mem_cpy(&scan_cmd->info,
648 			      scan_info,
649 			      (sizeof(scan_cmd->info) + channel_info_len));
650 
651 	status = umac_cmd_cfg(fmac_dev_ctx,
652 			      scan_cmd,
653 			      sizeof(*scan_cmd) + channel_info_len);
654 out:
655 	if (scan_cmd) {
656 		nrf_wifi_osal_mem_free(scan_cmd);
657 	}
658 
659 	return status;
660 }
661 
nrf_wifi_sys_fmac_abort_scan(void * dev_ctx,unsigned char if_idx)662 enum nrf_wifi_status nrf_wifi_sys_fmac_abort_scan(void *dev_ctx,
663 						  unsigned char if_idx)
664 {
665 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
666 	struct nrf_wifi_umac_cmd_abort_scan *scan_abort_cmd = NULL;
667 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
668 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
669 
670 	fmac_dev_ctx = dev_ctx;
671 
672 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
673 		nrf_wifi_osal_log_err("%s: Invalid op mode",
674 				      __func__);
675 		goto out;
676 	}
677 
678 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
679 
680 	scan_abort_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*scan_abort_cmd));
681 
682 	if (!scan_abort_cmd) {
683 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
684 				      __func__);
685 		goto out;
686 	}
687 
688 	scan_abort_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_ABORT_SCAN;
689 	scan_abort_cmd->umac_hdr.ids.wdev_id = if_idx;
690 	scan_abort_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
691 
692 	status = umac_cmd_cfg(fmac_dev_ctx,
693 			      scan_abort_cmd,
694 			      sizeof(*scan_abort_cmd));
695 out:
696 	if (scan_abort_cmd) {
697 		nrf_wifi_osal_mem_free(scan_abort_cmd);
698 	}
699 
700 	return status;
701 }
702 
nrf_wifi_sys_fmac_scan_res_get(void * dev_ctx,unsigned char vif_idx,int scan_type)703 enum nrf_wifi_status nrf_wifi_sys_fmac_scan_res_get(void *dev_ctx,
704 						unsigned char vif_idx,
705 						int scan_type)
706 
707 {
708 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
709 	struct nrf_wifi_umac_cmd_get_scan_results *scan_res_cmd = NULL;
710 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
711 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
712 
713 	fmac_dev_ctx = dev_ctx;
714 
715 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
716 		nrf_wifi_osal_log_err("%s: Invalid op mode",
717 				      __func__);
718 		goto out;
719 	}
720 
721 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
722 
723 	scan_res_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*scan_res_cmd));
724 
725 	if (!scan_res_cmd) {
726 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
727 				      __func__);
728 		goto out;
729 	}
730 
731 	scan_res_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_SCAN_RESULTS;
732 	scan_res_cmd->umac_hdr.ids.wdev_id = vif_idx;
733 	scan_res_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
734 	scan_res_cmd->scan_reason = scan_type;
735 
736 	status = umac_cmd_cfg(fmac_dev_ctx,
737 			      scan_res_cmd,
738 			      sizeof(*scan_res_cmd));
739 out:
740 	if (scan_res_cmd) {
741 		nrf_wifi_osal_mem_free(scan_res_cmd);
742 	}
743 
744 	return status;
745 }
746 
747 #ifdef NRF70_STA_MODE
nrf_wifi_sys_fmac_auth(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_auth_info * auth_info)748 enum nrf_wifi_status nrf_wifi_sys_fmac_auth(void *dev_ctx,
749 					    unsigned char if_idx,
750 					    struct nrf_wifi_umac_auth_info *auth_info)
751 {
752 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
753 	struct nrf_wifi_umac_cmd_auth *auth_cmd = NULL;
754 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
755 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
756 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
757 
758 	fmac_dev_ctx = dev_ctx;
759 
760 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
761 		nrf_wifi_osal_log_err("%s: Invalid op mode",
762 				      __func__);
763 		goto out;
764 	}
765 
766 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
767 	vif_ctx = sys_dev_ctx->vif_ctx[if_idx];
768 
769 	auth_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*auth_cmd));
770 
771 	if (!auth_cmd) {
772 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
773 				      __func__);
774 		goto out;
775 	}
776 
777 	auth_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_AUTHENTICATE;
778 	auth_cmd->umac_hdr.ids.wdev_id = if_idx;
779 	auth_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
780 
781 	nrf_wifi_osal_mem_cpy(&auth_cmd->info,
782 			      auth_info,
783 			      sizeof(auth_cmd->info));
784 
785 	if (auth_info->frequency != 0) {
786 		auth_cmd->valid_fields |= NRF_WIFI_CMD_AUTHENTICATE_FREQ_VALID;
787 	}
788 
789 	if (auth_info->ssid.nrf_wifi_ssid_len > 0) {
790 		auth_cmd->valid_fields |= NRF_WIFI_CMD_AUTHENTICATE_SSID_VALID;
791 	}
792 
793 	if (auth_info->key_info.key.nrf_wifi_key_len > 0) {
794 		auth_cmd->info.key_info.valid_fields |= NRF_WIFI_KEY_IDX_VALID;
795 		auth_cmd->info.key_info.valid_fields |= NRF_WIFI_KEY_VALID;
796 		auth_cmd->info.key_info.valid_fields |= NRF_WIFI_CIPHER_SUITE_VALID;
797 
798 		auth_cmd->valid_fields |= NRF_WIFI_CMD_AUTHENTICATE_KEY_INFO_VALID;
799 	}
800 
801 	if (auth_info->sae.sae_data_len > 0) {
802 		auth_cmd->valid_fields |= NRF_WIFI_CMD_AUTHENTICATE_SAE_VALID;
803 	}
804 
805 	status = umac_cmd_cfg(fmac_dev_ctx,
806 			      auth_cmd,
807 			      sizeof(*auth_cmd));
808 out:
809 	if (auth_cmd) {
810 		nrf_wifi_osal_mem_free(auth_cmd);
811 	}
812 
813 	return status;
814 }
815 
816 
nrf_wifi_sys_fmac_deauth(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_disconn_info * deauth_info)817 enum nrf_wifi_status nrf_wifi_sys_fmac_deauth(void *dev_ctx,
818 					      unsigned char if_idx,
819 					      struct nrf_wifi_umac_disconn_info *deauth_info)
820 {
821 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
822 	struct nrf_wifi_umac_cmd_disconn *deauth_cmd = NULL;
823 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
824 
825 	fmac_dev_ctx = dev_ctx;
826 
827 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
828 		nrf_wifi_osal_log_err("%s: Invalid op mode",
829 				      __func__);
830 		goto out;
831 	}
832 
833 	deauth_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*deauth_cmd));
834 
835 	if (!deauth_cmd) {
836 		nrf_wifi_osal_log_err("%s: Unable to allocate memory", __func__);
837 		goto out;
838 	}
839 
840 	deauth_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_DEAUTHENTICATE;
841 	deauth_cmd->umac_hdr.ids.wdev_id = if_idx;
842 	deauth_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
843 
844 	nrf_wifi_osal_mem_cpy(&deauth_cmd->info,
845 			      deauth_info,
846 			      sizeof(deauth_cmd->info));
847 
848 	if (!nrf_wifi_util_is_arr_zero(deauth_info->mac_addr,
849 				       sizeof(deauth_info->mac_addr))) {
850 		deauth_cmd->valid_fields |= NRF_WIFI_CMD_MLME_MAC_ADDR_VALID;
851 	}
852 
853 	status = umac_cmd_cfg(fmac_dev_ctx,
854 			      deauth_cmd,
855 			      sizeof(*deauth_cmd));
856 
857 out:
858 	if (deauth_cmd) {
859 		nrf_wifi_osal_mem_free(deauth_cmd);
860 	}
861 
862 	return status;
863 }
864 
865 
nrf_wifi_sys_fmac_assoc(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_assoc_info * assoc_info)866 enum nrf_wifi_status nrf_wifi_sys_fmac_assoc(void *dev_ctx,
867 					     unsigned char if_idx,
868 					     struct nrf_wifi_umac_assoc_info *assoc_info)
869 {
870 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
871 	struct nrf_wifi_umac_cmd_assoc *assoc_cmd = NULL;
872 	struct nrf_wifi_connect_common_info *connect_common_info = NULL;
873 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
874 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
875 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
876 
877 	fmac_dev_ctx = dev_ctx;
878 
879 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
880 		nrf_wifi_osal_log_err("%s: Invalid op mode",
881 				      __func__);
882 		goto out;
883 	}
884 
885 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
886 
887 	vif_ctx = sys_dev_ctx->vif_ctx[if_idx];
888 
889 	nrf_wifi_osal_mem_cpy(vif_ctx->bssid,
890 			      assoc_info->nrf_wifi_bssid,
891 			      NRF_WIFI_ETH_ADDR_LEN);
892 
893 	assoc_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*assoc_cmd));
894 
895 	if (!assoc_cmd) {
896 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
897 				      __func__);
898 		goto out;
899 	}
900 
901 	assoc_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_ASSOCIATE;
902 	assoc_cmd->umac_hdr.ids.wdev_id = if_idx;
903 	assoc_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
904 
905 	connect_common_info = &assoc_cmd->connect_common_info;
906 
907 	nrf_wifi_osal_mem_cpy(connect_common_info->mac_addr,
908 			      assoc_info->nrf_wifi_bssid,
909 			      NRF_WIFI_ETH_ADDR_LEN);
910 
911 	if (!nrf_wifi_util_is_arr_zero(connect_common_info->mac_addr,
912 				       sizeof(connect_common_info->mac_addr))) {
913 		connect_common_info->valid_fields |=
914 			NRF_WIFI_CONNECT_COMMON_INFO_MAC_ADDR_VALID;
915 	}
916 
917 	if (assoc_info->ssid.nrf_wifi_ssid_len > 0) {
918 		nrf_wifi_osal_mem_cpy(&connect_common_info->ssid,
919 				      &assoc_info->ssid,
920 				      sizeof(connect_common_info->ssid));
921 
922 		connect_common_info->valid_fields |=
923 			NRF_WIFI_CONNECT_COMMON_INFO_SSID_VALID;
924 	}
925 
926 	connect_common_info->frequency = assoc_info->center_frequency;
927 	connect_common_info->valid_fields |= NRF_WIFI_CONNECT_COMMON_INFO_FREQ_VALID;
928 
929 	if (assoc_info->wpa_ie.ie_len > 0) {
930 		nrf_wifi_osal_mem_cpy(&connect_common_info->wpa_ie,
931 				      &assoc_info->wpa_ie,
932 				      sizeof(connect_common_info->wpa_ie));
933 
934 		connect_common_info->valid_fields |=
935 			NRF_WIFI_CONNECT_COMMON_INFO_WPA_IE_VALID;
936 	}
937 
938 	connect_common_info->use_mfp = assoc_info->use_mfp;
939 	connect_common_info->valid_fields |=
940 		NRF_WIFI_CONNECT_COMMON_INFO_USE_MFP_VALID;
941 
942 	connect_common_info->nrf_wifi_flags |=
943 		NRF_WIFI_CMD_CONNECT_COMMON_INFO_USE_RRM;
944 
945 	connect_common_info->control_port =
946 		assoc_info->control_port;
947 
948 	if (assoc_info->prev_bssid_flag) {
949 		nrf_wifi_osal_mem_cpy(connect_common_info->prev_bssid,
950 				      assoc_info->prev_bssid,
951 				      NRF_WIFI_ETH_ADDR_LEN);
952 		connect_common_info->nrf_wifi_flags |= NRF_WIFI_CONNECT_COMMON_INFO_PREV_BSSID;
953 	}
954 
955 	if (assoc_info->bss_max_idle_time) {
956 		connect_common_info->maxidle_insec = assoc_info->bss_max_idle_time;
957 	}
958 
959 	status = umac_cmd_cfg(fmac_dev_ctx,
960 			      assoc_cmd,
961 			      sizeof(*assoc_cmd));
962 out:
963 	if (assoc_cmd) {
964 		nrf_wifi_osal_mem_free(assoc_cmd);
965 	}
966 
967 	return status;
968 }
969 
970 
nrf_wifi_sys_fmac_disassoc(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_disconn_info * disassoc_info)971 enum nrf_wifi_status nrf_wifi_sys_fmac_disassoc(void *dev_ctx,
972 						unsigned char if_idx,
973 						struct nrf_wifi_umac_disconn_info *disassoc_info)
974 {
975 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
976 	struct nrf_wifi_umac_cmd_disconn *disassoc_cmd = NULL;
977 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
978 
979 	fmac_dev_ctx = dev_ctx;
980 
981 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
982 		nrf_wifi_osal_log_err("%s: Invalid op mode",
983 				      __func__);
984 		goto out;
985 	}
986 
987 	disassoc_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*disassoc_cmd));
988 
989 	if (!disassoc_cmd) {
990 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
991 				      __func__);
992 		goto out;
993 	}
994 
995 	disassoc_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_DEAUTHENTICATE;
996 	disassoc_cmd->umac_hdr.ids.wdev_id = if_idx;
997 	disassoc_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
998 
999 	nrf_wifi_osal_mem_cpy(&disassoc_cmd->info,
1000 			      disassoc_info,
1001 			      sizeof(disassoc_cmd->info));
1002 
1003 	if (!nrf_wifi_util_is_arr_zero(disassoc_info->mac_addr,
1004 				       sizeof(disassoc_info->mac_addr))) {
1005 		disassoc_cmd->valid_fields |= NRF_WIFI_CMD_MLME_MAC_ADDR_VALID;
1006 	}
1007 
1008 	status = umac_cmd_cfg(fmac_dev_ctx,
1009 			      disassoc_cmd,
1010 			      sizeof(*disassoc_cmd));
1011 
1012 out:
1013 	if (disassoc_cmd) {
1014 		nrf_wifi_osal_mem_free(disassoc_cmd);
1015 	}
1016 
1017 	return status;
1018 }
1019 
1020 
nrf_wifi_sys_fmac_add_key(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_key_info * key_info,const char * mac_addr)1021 enum nrf_wifi_status nrf_wifi_sys_fmac_add_key(void *dev_ctx,
1022 					       unsigned char if_idx,
1023 					       struct nrf_wifi_umac_key_info *key_info,
1024 					       const char *mac_addr)
1025 {
1026 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1027 	struct nrf_wifi_umac_cmd_key *key_cmd = NULL;
1028 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1029 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1030 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
1031 	int peer_id = -1;
1032 
1033 	fmac_dev_ctx = dev_ctx;
1034 
1035 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1036 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1037 				      __func__);
1038 		goto out;
1039 	}
1040 
1041 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1042 	vif_ctx = sys_dev_ctx->vif_ctx[if_idx];
1043 
1044 	key_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*key_cmd));
1045 
1046 	if (!key_cmd) {
1047 		nrf_wifi_osal_log_err("%s: Unable to allocate memory", __func__);
1048 		goto out;
1049 	}
1050 
1051 	key_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_NEW_KEY;
1052 	key_cmd->umac_hdr.ids.wdev_id = if_idx;
1053 	key_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1054 
1055 	nrf_wifi_osal_mem_cpy(&key_cmd->key_info,
1056 			      key_info,
1057 			      sizeof(key_cmd->key_info));
1058 
1059 	if (mac_addr) {
1060 		nrf_wifi_osal_mem_cpy(key_cmd->mac_addr,
1061 				      mac_addr,
1062 				      NRF_WIFI_ETH_ADDR_LEN);
1063 
1064 		key_cmd->valid_fields |= NRF_WIFI_CMD_KEY_MAC_ADDR_VALID;
1065 	}
1066 
1067 	if (key_info->key_type == NRF_WIFI_KEYTYPE_GROUP) {
1068 		vif_ctx->groupwise_cipher = key_info->cipher_suite;
1069 	} else if (key_info->key_type == NRF_WIFI_KEYTYPE_PAIRWISE) {
1070 		peer_id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx,
1071 						    mac_addr);
1072 
1073 		if (peer_id == -1) {
1074 			nrf_wifi_osal_log_err("%s: Invalid peer",
1075 					      __func__);
1076 			goto out;
1077 		}
1078 
1079 		sys_dev_ctx->tx_config.peers[peer_id].pairwise_cipher = key_info->cipher_suite;
1080 	} else {
1081 		nrf_wifi_osal_log_err("%s: Invalid key type %d",
1082 				      __func__,
1083 				      key_info->key_type);
1084 		goto out;
1085 	}
1086 
1087 	if (key_info->key.nrf_wifi_key_len > 0) {
1088 		key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_VALID;
1089 		key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_IDX_VALID;
1090 	}
1091 
1092 	if (key_info->seq.nrf_wifi_seq_len > 0) {
1093 		key_cmd->key_info.valid_fields |= NRF_WIFI_SEQ_VALID;
1094 	}
1095 
1096 	key_cmd->key_info.valid_fields |= NRF_WIFI_CIPHER_SUITE_VALID;
1097 	key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_TYPE_VALID;
1098 
1099 	status = umac_cmd_cfg(fmac_dev_ctx,
1100 			      key_cmd,
1101 			      sizeof(*key_cmd));
1102 
1103 out:
1104 	if (key_cmd) {
1105 		nrf_wifi_osal_mem_free(key_cmd);
1106 	}
1107 
1108 	return status;
1109 }
1110 
nrf_wifi_sys_fmac_del_key(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_key_info * key_info,const char * mac_addr)1111 enum nrf_wifi_status nrf_wifi_sys_fmac_del_key(void *dev_ctx,
1112 					       unsigned char if_idx,
1113 					       struct nrf_wifi_umac_key_info *key_info,
1114 					       const char *mac_addr)
1115 {
1116 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1117 	struct nrf_wifi_umac_cmd_key *key_cmd = NULL;
1118 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1119 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
1120 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1121 
1122 	fmac_dev_ctx = dev_ctx;
1123 
1124 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1125 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1126 				      __func__);
1127 		goto out;
1128 	}
1129 
1130 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1131 
1132 	key_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*key_cmd));
1133 
1134 	if (!key_cmd) {
1135 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1136 				      __func__);
1137 		goto out;
1138 	}
1139 
1140 	key_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_DEL_KEY;
1141 	key_cmd->umac_hdr.ids.wdev_id = if_idx;
1142 	key_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1143 
1144 	nrf_wifi_osal_mem_cpy(&key_cmd->key_info,
1145 			      key_info,
1146 			      sizeof(key_cmd->key_info));
1147 
1148 	if (mac_addr) {
1149 		nrf_wifi_osal_mem_cpy(key_cmd->mac_addr,
1150 				      mac_addr,
1151 				      NRF_WIFI_ETH_ADDR_LEN);
1152 
1153 		key_cmd->valid_fields |= NRF_WIFI_CMD_KEY_MAC_ADDR_VALID;
1154 	}
1155 
1156 	key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_IDX_VALID;
1157 	key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_TYPE_VALID;
1158 
1159 	vif_ctx = sys_dev_ctx->vif_ctx[if_idx];
1160 
1161 	if (key_info->key_type == NRF_WIFI_KEYTYPE_GROUP) {
1162 		vif_ctx->groupwise_cipher = 0;
1163 	}
1164 
1165 	status = umac_cmd_cfg(fmac_dev_ctx,
1166 			      key_cmd,
1167 			      sizeof(*key_cmd));
1168 
1169 out:
1170 	if (key_cmd) {
1171 		nrf_wifi_osal_mem_free(key_cmd);
1172 	}
1173 
1174 	return status;
1175 }
1176 
1177 
nrf_wifi_sys_fmac_set_key(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_key_info * key_info)1178 enum nrf_wifi_status nrf_wifi_sys_fmac_set_key(void *dev_ctx,
1179 					       unsigned char if_idx,
1180 					       struct nrf_wifi_umac_key_info *key_info)
1181 {
1182 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1183 	struct nrf_wifi_umac_cmd_set_key *set_key_cmd = NULL;
1184 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1185 
1186 	fmac_dev_ctx = dev_ctx;
1187 
1188 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1189 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1190 				      __func__);
1191 		goto out;
1192 	}
1193 
1194 	set_key_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_key_cmd));
1195 
1196 	if (!set_key_cmd) {
1197 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1198 				      __func__);
1199 		goto out;
1200 	}
1201 
1202 	set_key_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_KEY;
1203 	set_key_cmd->umac_hdr.ids.wdev_id = if_idx;
1204 	set_key_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1205 
1206 	nrf_wifi_osal_mem_cpy(&set_key_cmd->key_info,
1207 			      key_info,
1208 			      sizeof(set_key_cmd->key_info));
1209 
1210 	set_key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_IDX_VALID;
1211 
1212 	status = umac_cmd_cfg(fmac_dev_ctx,
1213 			      set_key_cmd,
1214 			      sizeof(*set_key_cmd));
1215 
1216 out:
1217 	if (set_key_cmd) {
1218 		nrf_wifi_osal_mem_free(set_key_cmd);
1219 	}
1220 
1221 	return status;
1222 }
1223 
nrf_wifi_sys_fmac_chg_sta(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_chg_sta_info * chg_sta_info)1224 enum nrf_wifi_status nrf_wifi_sys_fmac_chg_sta(void *dev_ctx,
1225 					       unsigned char if_idx,
1226 					       struct nrf_wifi_umac_chg_sta_info *chg_sta_info)
1227 {
1228 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1229 	struct nrf_wifi_umac_cmd_chg_sta *chg_sta_cmd = NULL;
1230 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1231 
1232 	fmac_dev_ctx = dev_ctx;
1233 
1234 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1235 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1236 				      __func__);
1237 		goto out;
1238 	}
1239 
1240 	chg_sta_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*chg_sta_cmd));
1241 
1242 	if (!chg_sta_cmd) {
1243 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1244 				      __func__);
1245 		goto out;
1246 	}
1247 
1248 	chg_sta_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_STATION;
1249 	chg_sta_cmd->umac_hdr.ids.wdev_id = if_idx;
1250 	chg_sta_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1251 
1252 	nrf_wifi_osal_mem_cpy(&chg_sta_cmd->info,
1253 			      chg_sta_info,
1254 			      sizeof(chg_sta_cmd->info));
1255 
1256 	if (chg_sta_info->aid) {
1257 		chg_sta_cmd->valid_fields |=
1258 			NRF_WIFI_CMD_SET_STATION_AID_VALID;
1259 	}
1260 
1261 
1262 	if (chg_sta_info->supported_channels.supported_channels_len > 0) {
1263 		chg_sta_cmd->valid_fields |=
1264 			NRF_WIFI_CMD_SET_STATION_SUPPORTED_CHANNELS_VALID;
1265 	}
1266 
1267 	if (chg_sta_info->supported_oper_classes.supported_oper_classes_len > 0) {
1268 		chg_sta_cmd->valid_fields |=
1269 			NRF_WIFI_CMD_SET_STATION_SUPPORTED_OPER_CLASSES_VALID;
1270 	}
1271 
1272 	chg_sta_cmd->valid_fields |= NRF_WIFI_CMD_SET_STATION_STA_FLAGS2_VALID;
1273 
1274 	if (chg_sta_info->opmode_notif) {
1275 		chg_sta_cmd->valid_fields |=
1276 			NRF_WIFI_CMD_SET_STATION_OPMODE_NOTIF_VALID;
1277 	}
1278 
1279 	if (chg_sta_info->wme_max_sp) {
1280 		chg_sta_cmd->valid_fields |=
1281 			NRF_WIFI_CMD_SET_STATION_STA_WME_MAX_SP_VALID;
1282 	}
1283 
1284 	status = umac_cmd_cfg(fmac_dev_ctx,
1285 			      chg_sta_cmd,
1286 			      sizeof(*chg_sta_cmd));
1287 
1288 out:
1289 	if (chg_sta_cmd) {
1290 		nrf_wifi_osal_mem_free(chg_sta_cmd);
1291 	}
1292 
1293 	return status;
1294 }
1295 
1296 #ifdef NRF70_AP_MODE
nrf_wifi_sys_fmac_set_bss(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_bss_info * bss_info)1297 enum nrf_wifi_status nrf_wifi_sys_fmac_set_bss(void *dev_ctx,
1298 					       unsigned char if_idx,
1299 					       struct nrf_wifi_umac_bss_info *bss_info)
1300 {
1301 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1302 	struct nrf_wifi_umac_cmd_set_bss *set_bss_cmd = NULL;
1303 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1304 
1305 	fmac_dev_ctx = dev_ctx;
1306 
1307 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1308 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1309 				      __func__);
1310 		goto out;
1311 	}
1312 
1313 	set_bss_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_bss_cmd));
1314 
1315 	if (!set_bss_cmd) {
1316 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1317 				      __func__);
1318 		goto out;
1319 	}
1320 
1321 	set_bss_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_BSS;
1322 	set_bss_cmd->umac_hdr.ids.wdev_id = if_idx;
1323 	set_bss_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1324 
1325 	nrf_wifi_osal_mem_cpy(&set_bss_cmd->bss_info,
1326 			      bss_info,
1327 			      sizeof(set_bss_cmd->bss_info));
1328 
1329 	set_bss_cmd->valid_fields = NRF_WIFI_CMD_SET_BSS_CTS_VALID |
1330 		NRF_WIFI_CMD_SET_BSS_PREAMBLE_VALID |
1331 		NRF_WIFI_CMD_SET_BSS_SLOT_VALID |
1332 		NRF_WIFI_CMD_SET_BSS_HT_OPMODE_VALID |
1333 		NRF_WIFI_CMD_SET_BSS_AP_ISOLATE_VALID;
1334 
1335 	if ((bss_info->p2p_go_ctwindow > 0) &&
1336 	    (bss_info->p2p_go_ctwindow < 127)) {
1337 		set_bss_cmd->valid_fields |=
1338 			(NRF_WIFI_CMD_SET_BSS_P2P_CTWINDOW_VALID |
1339 			 NRF_WIFI_CMD_SET_BSS_P2P_OPPPS_VALID);
1340 	}
1341 
1342 	status = umac_cmd_cfg(fmac_dev_ctx,
1343 			      set_bss_cmd,
1344 			      sizeof(*set_bss_cmd));
1345 
1346 out:
1347 	if (set_bss_cmd) {
1348 		nrf_wifi_osal_mem_free(set_bss_cmd);
1349 	}
1350 
1351 	return status;
1352 }
1353 
nrf_wifi_sys_fmac_chg_bcn(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_set_beacon_info * data)1354 enum nrf_wifi_status nrf_wifi_sys_fmac_chg_bcn(void *dev_ctx,
1355 					       unsigned char if_idx,
1356 					       struct nrf_wifi_umac_set_beacon_info *data)
1357 {
1358 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1359 	struct nrf_wifi_umac_cmd_set_beacon *set_bcn_cmd = NULL;
1360 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1361 
1362 	fmac_dev_ctx = dev_ctx;
1363 
1364 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1365 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1366 				      __func__);
1367 		goto out;
1368 	}
1369 
1370 	set_bcn_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_bcn_cmd));
1371 
1372 	if (!set_bcn_cmd) {
1373 		nrf_wifi_osal_log_err("%s: Unable to allocate memory", __func__);
1374 		goto out;
1375 	}
1376 
1377 	set_bcn_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_BEACON;
1378 	set_bcn_cmd->umac_hdr.ids.wdev_id = if_idx;
1379 	set_bcn_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1380 
1381 	nrf_wifi_osal_mem_cpy(&set_bcn_cmd->info,
1382 			      data,
1383 			      sizeof(set_bcn_cmd->info));
1384 
1385 	nrf_wifi_osal_log_dbg("%s: Sending command to rpu",
1386 			      __func__);
1387 
1388 	status = umac_cmd_cfg(fmac_dev_ctx,
1389 			      set_bcn_cmd,
1390 			      sizeof(*set_bcn_cmd));
1391 
1392 out:
1393 	if (set_bcn_cmd) {
1394 		nrf_wifi_osal_mem_free(set_bcn_cmd);
1395 	}
1396 
1397 	return status;
1398 }
1399 
1400 
nrf_wifi_sys_fmac_start_ap(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_start_ap_info * ap_info)1401 enum nrf_wifi_status nrf_wifi_sys_fmac_start_ap(void *dev_ctx,
1402 						unsigned char if_idx,
1403 						struct nrf_wifi_umac_start_ap_info *ap_info)
1404 {
1405 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1406 	struct nrf_wifi_umac_cmd_start_ap *start_ap_cmd = NULL;
1407 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1408 	struct nrf_wifi_umac_set_wiphy_info *wiphy_info = NULL;
1409 
1410 	fmac_dev_ctx = dev_ctx;
1411 
1412 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1413 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1414 				      __func__);
1415 		goto out;
1416 	}
1417 
1418 	start_ap_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*start_ap_cmd));
1419 
1420 	if (!start_ap_cmd) {
1421 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1422 				      __func__);
1423 		goto out;
1424 	}
1425 
1426 	start_ap_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_START_AP;
1427 	start_ap_cmd->umac_hdr.ids.wdev_id = if_idx;
1428 	start_ap_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1429 
1430 	nrf_wifi_osal_mem_cpy(&start_ap_cmd->info,
1431 			      ap_info,
1432 			      sizeof(start_ap_cmd->info));
1433 
1434 	start_ap_cmd->valid_fields |=
1435 		NRF_WIFI_CMD_BEACON_INFO_BEACON_INTERVAL_VALID |
1436 		NRF_WIFI_CMD_BEACON_INFO_VERSIONS_VALID |
1437 		NRF_WIFI_CMD_BEACON_INFO_CIPHER_SUITE_GROUP_VALID;
1438 
1439 	start_ap_cmd->info.freq_params.valid_fields |=
1440 		NRF_WIFI_SET_FREQ_PARAMS_FREQ_VALID |
1441 		NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_WIDTH_VALID |
1442 		NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ1_VALID |
1443 		NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ2_VALID |
1444 		NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_TYPE_VALID;
1445 
1446 	start_ap_cmd->info.connect_common_info.valid_fields |=
1447 		NRF_WIFI_CONNECT_COMMON_INFO_WPA_VERSIONS_VALID;
1448 
1449 	if (ap_info->connect_common_info.num_cipher_suites_pairwise > 0) {
1450 		start_ap_cmd->info.connect_common_info.valid_fields |=
1451 			NRF_WIFI_CONNECT_COMMON_INFO_CIPHER_SUITES_PAIRWISE_VALID;
1452 	}
1453 
1454 	if (ap_info->connect_common_info.num_akm_suites > 0) {
1455 		start_ap_cmd->info.connect_common_info.valid_fields |=
1456 			NRF_WIFI_CONNECT_COMMON_INFO_AKM_SUITES_VALID;
1457 	}
1458 
1459 	if (ap_info->connect_common_info.control_port_ether_type) {
1460 		start_ap_cmd->info.connect_common_info.valid_fields |=
1461 			NRF_WIFI_CONNECT_COMMON_INFO_CONTROL_PORT_ETHER_TYPE;
1462 	}
1463 
1464 	if (ap_info->connect_common_info.control_port_no_encrypt) {
1465 		start_ap_cmd->info.connect_common_info.valid_fields |=
1466 			NRF_WIFI_CONNECT_COMMON_INFO_CONTROL_PORT_NO_ENCRYPT;
1467 	}
1468 
1469 	if ((ap_info->p2p_go_ctwindow > 0) &&
1470 	    (ap_info->p2p_go_ctwindow < 127)) {
1471 		start_ap_cmd->valid_fields |=
1472 			NRF_WIFI_CMD_BEACON_INFO_P2P_CTWINDOW_VALID;
1473 		start_ap_cmd->valid_fields |=
1474 			NRF_WIFI_CMD_BEACON_INFO_P2P_OPPPS_VALID;
1475 	}
1476 
1477 	wiphy_info = nrf_wifi_osal_mem_zalloc(sizeof(*wiphy_info));
1478 
1479 	if (!wiphy_info) {
1480 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1481 				      __func__);
1482 		goto out;
1483 	}
1484 
1485 	wiphy_info->freq_params.frequency = ap_info->freq_params.frequency;
1486 
1487 	wiphy_info->freq_params.channel_width = ap_info->freq_params.channel_width;
1488 
1489 	wiphy_info->freq_params.center_frequency1 = ap_info->freq_params.center_frequency1;
1490 	wiphy_info->freq_params.center_frequency2 = ap_info->freq_params.center_frequency2;
1491 
1492 	wiphy_info->freq_params.channel_type = ap_info->freq_params.channel_type;
1493 
1494 	status = nrf_wifi_sys_fmac_set_wiphy_params(fmac_dev_ctx,
1495 						if_idx,
1496 						wiphy_info);
1497 
1498 	if (status == NRF_WIFI_STATUS_FAIL) {
1499 		nrf_wifi_osal_log_err("%s: nrf_wifi_sys_fmac_set_wiphy_params failes",
1500 				      __func__);
1501 		goto out;
1502 	}
1503 
1504 	nrf_wifi_fmac_peers_flush(fmac_dev_ctx, if_idx);
1505 
1506 	status = umac_cmd_cfg(fmac_dev_ctx,
1507 			      start_ap_cmd,
1508 			      sizeof(*start_ap_cmd));
1509 
1510 out:
1511 	if (wiphy_info) {
1512 		nrf_wifi_osal_mem_free(wiphy_info);
1513 	}
1514 
1515 	if (start_ap_cmd) {
1516 		nrf_wifi_osal_mem_free(start_ap_cmd);
1517 	}
1518 
1519 	return status;
1520 }
1521 
1522 
nrf_wifi_sys_fmac_stop_ap(void * dev_ctx,unsigned char if_idx)1523 enum nrf_wifi_status nrf_wifi_sys_fmac_stop_ap(void *dev_ctx,
1524 					       unsigned char if_idx)
1525 {
1526 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1527 	struct nrf_wifi_umac_cmd_stop_ap *stop_ap_cmd = NULL;
1528 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1529 
1530 	fmac_dev_ctx = dev_ctx;
1531 
1532 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1533 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1534 				      __func__);
1535 		goto out;
1536 	}
1537 
1538 	stop_ap_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*stop_ap_cmd));
1539 
1540 	if (!stop_ap_cmd) {
1541 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1542 				      __func__);
1543 		goto out;
1544 	}
1545 
1546 	stop_ap_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_STOP_AP;
1547 	stop_ap_cmd->umac_hdr.ids.wdev_id = if_idx;
1548 	stop_ap_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1549 
1550 	nrf_wifi_fmac_peers_flush(fmac_dev_ctx, if_idx);
1551 
1552 	status = umac_cmd_cfg(fmac_dev_ctx,
1553 			      stop_ap_cmd,
1554 			      sizeof(*stop_ap_cmd));
1555 
1556 out:
1557 	if (stop_ap_cmd) {
1558 		nrf_wifi_osal_mem_free(stop_ap_cmd);
1559 	}
1560 
1561 	return status;
1562 }
1563 
nrf_wifi_sys_fmac_del_sta(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_del_sta_info * del_sta_info)1564 enum nrf_wifi_status nrf_wifi_sys_fmac_del_sta(void *dev_ctx,
1565 					       unsigned char if_idx,
1566 					       struct nrf_wifi_umac_del_sta_info *del_sta_info)
1567 {
1568 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1569 	struct nrf_wifi_umac_cmd_del_sta *del_sta_cmd = NULL;
1570 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1571 
1572 	fmac_dev_ctx = dev_ctx;
1573 
1574 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1575 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1576 				      __func__);
1577 		goto out;
1578 	}
1579 
1580 	del_sta_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*del_sta_cmd));
1581 
1582 	if (!del_sta_cmd) {
1583 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1584 				      __func__);
1585 		goto out;
1586 	}
1587 
1588 	del_sta_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_DEL_STATION;
1589 	del_sta_cmd->umac_hdr.ids.wdev_id = if_idx;
1590 	del_sta_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1591 
1592 	nrf_wifi_osal_mem_cpy(&del_sta_cmd->info,
1593 			      del_sta_info,
1594 			      sizeof(del_sta_cmd->info));
1595 
1596 	if (!nrf_wifi_util_is_arr_zero(del_sta_info->mac_addr,
1597 				       sizeof(del_sta_info->mac_addr))) {
1598 		del_sta_cmd->valid_fields |= NRF_WIFI_CMD_DEL_STATION_MAC_ADDR_VALID;
1599 	}
1600 
1601 	if (del_sta_info->mgmt_subtype) {
1602 		del_sta_cmd->valid_fields |=
1603 			NRF_WIFI_CMD_DEL_STATION_MGMT_SUBTYPE_VALID;
1604 	}
1605 
1606 	if (del_sta_info->reason_code) {
1607 		del_sta_cmd->valid_fields |=
1608 			NRF_WIFI_CMD_DEL_STATION_REASON_CODE_VALID;
1609 	}
1610 
1611 	status = umac_cmd_cfg(fmac_dev_ctx,
1612 			      del_sta_cmd,
1613 			      sizeof(*del_sta_cmd));
1614 
1615 out:
1616 	if (del_sta_cmd) {
1617 		nrf_wifi_osal_mem_free(del_sta_cmd);
1618 	}
1619 
1620 	return status;
1621 }
1622 
1623 
nrf_wifi_sys_fmac_add_sta(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_add_sta_info * add_sta_info)1624 enum nrf_wifi_status nrf_wifi_sys_fmac_add_sta(void *dev_ctx,
1625 					       unsigned char if_idx,
1626 					       struct nrf_wifi_umac_add_sta_info *add_sta_info)
1627 {
1628 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1629 	struct nrf_wifi_umac_cmd_add_sta *add_sta_cmd = NULL;
1630 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1631 
1632 	fmac_dev_ctx = dev_ctx;
1633 
1634 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1635 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1636 				      __func__);
1637 		goto out;
1638 	}
1639 
1640 	add_sta_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*add_sta_cmd));
1641 
1642 	if (!add_sta_cmd) {
1643 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1644 				      __func__);
1645 		goto out;
1646 	}
1647 
1648 	add_sta_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_NEW_STATION;
1649 	add_sta_cmd->umac_hdr.ids.wdev_id = if_idx;
1650 	add_sta_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1651 
1652 	nrf_wifi_osal_mem_cpy(&add_sta_cmd->info,
1653 			      add_sta_info,
1654 			      sizeof(add_sta_cmd->info));
1655 
1656 	if (add_sta_info->aid) {
1657 		add_sta_cmd->valid_fields |= NRF_WIFI_CMD_NEW_STATION_AID_VALID;
1658 	}
1659 
1660 	if (add_sta_info->sta_capability) {
1661 		add_sta_cmd->valid_fields |=
1662 			NRF_WIFI_CMD_NEW_STATION_STA_CAPABILITY_VALID;
1663 	}
1664 
1665 	add_sta_cmd->valid_fields |= NRF_WIFI_CMD_NEW_STATION_LISTEN_INTERVAL_VALID;
1666 
1667 	if (add_sta_info->supp_rates.nrf_wifi_num_rates > 0) {
1668 		add_sta_cmd->valid_fields |=
1669 			NRF_WIFI_CMD_NEW_STATION_SUPP_RATES_VALID;
1670 	}
1671 
1672 	if (add_sta_info->ext_capability.ext_capability_len > 0) {
1673 		add_sta_cmd->valid_fields |=
1674 			NRF_WIFI_CMD_NEW_STATION_EXT_CAPABILITY_VALID;
1675 	}
1676 
1677 	if (add_sta_info->supported_channels.supported_channels_len > 0) {
1678 		add_sta_cmd->valid_fields |=
1679 			NRF_WIFI_CMD_NEW_STATION_SUPPORTED_CHANNELS_VALID;
1680 	}
1681 
1682 	if (add_sta_info->supported_oper_classes.supported_oper_classes_len > 0) {
1683 		add_sta_cmd->valid_fields |=
1684 			NRF_WIFI_CMD_NEW_STATION_SUPPORTED_OPER_CLASSES_VALID;
1685 	}
1686 
1687 	add_sta_cmd->valid_fields |= NRF_WIFI_CMD_NEW_STATION_STA_FLAGS2_VALID;
1688 
1689 	if (!nrf_wifi_util_is_arr_zero(add_sta_info->ht_capability,
1690 				       sizeof(add_sta_info->ht_capability))) {
1691 		add_sta_cmd->valid_fields |=
1692 			NRF_WIFI_CMD_NEW_STATION_HT_CAPABILITY_VALID;
1693 	}
1694 
1695 	if (!nrf_wifi_util_is_arr_zero(add_sta_info->vht_capability,
1696 				       sizeof(add_sta_info->vht_capability))) {
1697 		add_sta_cmd->valid_fields |=
1698 			NRF_WIFI_CMD_NEW_STATION_VHT_CAPABILITY_VALID;
1699 	}
1700 
1701 	if (add_sta_info->opmode_notif) {
1702 		add_sta_cmd->valid_fields |=
1703 			NRF_WIFI_CMD_NEW_STATION_OPMODE_NOTIF_VALID;
1704 	}
1705 
1706 	if (add_sta_info->wme_uapsd_queues) {
1707 		add_sta_cmd->valid_fields |=
1708 			NRF_WIFI_CMD_NEW_STATION_STA_WME_UAPSD_QUEUES_VALID;
1709 	}
1710 
1711 	if (add_sta_info->wme_max_sp) {
1712 		add_sta_cmd->valid_fields |=
1713 			NRF_WIFI_CMD_NEW_STATION_STA_WME_MAX_SP_VALID;
1714 	}
1715 
1716 	status = umac_cmd_cfg(fmac_dev_ctx,
1717 			      add_sta_cmd,
1718 			      sizeof(*add_sta_cmd));
1719 
1720 out:
1721 	if (add_sta_cmd) {
1722 		nrf_wifi_osal_mem_free(add_sta_cmd);
1723 	}
1724 
1725 	return status;
1726 }
1727 
nrf_wifi_sys_fmac_mgmt_frame_reg(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_mgmt_frame_info * frame_info)1728 enum nrf_wifi_status nrf_wifi_sys_fmac_mgmt_frame_reg(void *dev_ctx,
1729 						      unsigned char if_idx,
1730 						      struct nrf_wifi_umac_mgmt_frame_info *frame_info)
1731 {
1732 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1733 	struct nrf_wifi_umac_cmd_mgmt_frame_reg *frame_reg_cmd = NULL;
1734 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1735 
1736 	fmac_dev_ctx = dev_ctx;
1737 
1738 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1739 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1740 				      __func__);
1741 		goto out;
1742 	}
1743 
1744 	frame_reg_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*frame_reg_cmd));
1745 
1746 	if (!frame_reg_cmd) {
1747 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1748 				      __func__);
1749 		goto out;
1750 	}
1751 
1752 	frame_reg_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_REGISTER_FRAME;
1753 	frame_reg_cmd->umac_hdr.ids.wdev_id = if_idx;
1754 	frame_reg_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1755 
1756 	nrf_wifi_osal_mem_cpy(&frame_reg_cmd->info,
1757 			      frame_info,
1758 			      sizeof(frame_reg_cmd->info));
1759 
1760 	status = umac_cmd_cfg(fmac_dev_ctx,
1761 			      frame_reg_cmd,
1762 			      sizeof(*frame_reg_cmd));
1763 
1764 out:
1765 	if (frame_reg_cmd) {
1766 		nrf_wifi_osal_mem_free(frame_reg_cmd);
1767 	}
1768 
1769 	return status;
1770 }
1771 
1772 #endif /* NRF70_AP_MODE */
1773 
1774 #ifdef NRF70_P2P_MODE
nrf_wifi_sys_fmac_p2p_dev_start(void * dev_ctx,unsigned char if_idx)1775 enum nrf_wifi_status nrf_wifi_sys_fmac_p2p_dev_start(void *dev_ctx,
1776 						     unsigned char if_idx)
1777 {
1778 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1779 	struct nrf_wifi_cmd_start_p2p *start_p2p_dev_cmd = NULL;
1780 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1781 
1782 	fmac_dev_ctx = dev_ctx;
1783 
1784 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1785 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1786 				      __func__);
1787 		goto out;
1788 	}
1789 
1790 	start_p2p_dev_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*start_p2p_dev_cmd));
1791 
1792 	if (!start_p2p_dev_cmd) {
1793 		nrf_wifi_osal_log_err("%s: Unable to allocate memory", __func__);
1794 		goto out;
1795 	}
1796 
1797 	start_p2p_dev_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_START_P2P_DEVICE;
1798 	start_p2p_dev_cmd->umac_hdr.ids.wdev_id = if_idx;
1799 	start_p2p_dev_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1800 
1801 	status = umac_cmd_cfg(fmac_dev_ctx,
1802 			      start_p2p_dev_cmd,
1803 			      sizeof(*start_p2p_dev_cmd));
1804 
1805 out:
1806 	if (start_p2p_dev_cmd) {
1807 		nrf_wifi_osal_mem_free(start_p2p_dev_cmd);
1808 	}
1809 
1810 	return status;
1811 }
1812 
1813 
nrf_wifi_sys_fmac_p2p_dev_stop(void * dev_ctx,unsigned char if_idx)1814 enum nrf_wifi_status nrf_wifi_sys_fmac_p2p_dev_stop(void *dev_ctx,
1815 						    unsigned char if_idx)
1816 {
1817 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1818 	struct nrf_wifi_umac_cmd_stop_p2p_dev *stop_p2p_dev_cmd = NULL;
1819 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1820 
1821 	fmac_dev_ctx = dev_ctx;
1822 
1823 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1824 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1825 				      __func__);
1826 		goto out;
1827 	}
1828 
1829 	stop_p2p_dev_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*stop_p2p_dev_cmd));
1830 
1831 	if (!stop_p2p_dev_cmd) {
1832 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1833 				      __func__);
1834 		goto out;
1835 	}
1836 
1837 	stop_p2p_dev_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_STOP_P2P_DEVICE;
1838 	stop_p2p_dev_cmd->umac_hdr.ids.wdev_id = if_idx;
1839 	stop_p2p_dev_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1840 
1841 	status = umac_cmd_cfg(fmac_dev_ctx,
1842 			      stop_p2p_dev_cmd,
1843 			      sizeof(*stop_p2p_dev_cmd));
1844 out:
1845 	if (stop_p2p_dev_cmd) {
1846 		nrf_wifi_osal_mem_free(stop_p2p_dev_cmd);
1847 	}
1848 
1849 	return status;
1850 }
1851 
1852 
nrf_wifi_sys_fmac_p2p_roc_start(void * dev_ctx,unsigned char if_idx,struct remain_on_channel_info * roc_info)1853 enum nrf_wifi_status nrf_wifi_sys_fmac_p2p_roc_start(void *dev_ctx,
1854 						     unsigned char if_idx,
1855 						     struct remain_on_channel_info *roc_info)
1856 {
1857 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1858 	struct nrf_wifi_umac_cmd_remain_on_channel *roc_cmd = NULL;
1859 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1860 
1861 	fmac_dev_ctx = dev_ctx;
1862 
1863 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1864 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1865 				      __func__);
1866 		goto out;
1867 	}
1868 
1869 	roc_cmd = nrf_wifi_osal_mem_zalloc(sizeof(struct nrf_wifi_umac_cmd_remain_on_channel));
1870 
1871 	if (!roc_cmd) {
1872 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1873 				      __func__);
1874 		goto out;
1875 	}
1876 
1877 	roc_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_REMAIN_ON_CHANNEL;
1878 	roc_cmd->umac_hdr.ids.wdev_id = if_idx;
1879 	roc_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1880 
1881 	nrf_wifi_osal_mem_cpy(&roc_cmd->info,
1882 			      roc_info,
1883 			      sizeof(roc_cmd->info));
1884 
1885 	if (roc_info->dur != 0) {
1886 		roc_cmd->valid_fields |= NRF_WIFI_CMD_ROC_DURATION_VALID;
1887 	}
1888 
1889 	roc_cmd->info.nrf_wifi_freq_params.valid_fields = NRF_WIFI_SET_FREQ_PARAMS_FREQ_VALID;
1890 	roc_cmd->valid_fields |= NRF_WIFI_CMD_ROC_FREQ_PARAMS_VALID;
1891 
1892 	status = umac_cmd_cfg(fmac_dev_ctx,
1893 			      roc_cmd,
1894 			      sizeof(*roc_cmd));
1895 
1896 out:
1897 	if (roc_cmd) {
1898 		nrf_wifi_osal_mem_free(roc_cmd);
1899 	}
1900 
1901 	return status;
1902 }
1903 
1904 
nrf_wifi_sys_fmac_p2p_roc_stop(void * dev_ctx,unsigned char if_idx,unsigned long long cookie)1905 enum nrf_wifi_status nrf_wifi_sys_fmac_p2p_roc_stop(void *dev_ctx,
1906 						    unsigned char if_idx,
1907 						    unsigned long long cookie)
1908 {
1909 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1910 	struct nrf_wifi_umac_cmd_cancel_remain_on_channel *cancel_roc_cmd = NULL;
1911 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1912 
1913 	fmac_dev_ctx = dev_ctx;
1914 
1915 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1916 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1917 				      __func__);
1918 		goto out;
1919 	}
1920 
1921 	cancel_roc_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*cancel_roc_cmd));
1922 
1923 	if (!cancel_roc_cmd) {
1924 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1925 				      __func__);
1926 		goto out;
1927 	}
1928 
1929 	cancel_roc_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CANCEL_REMAIN_ON_CHANNEL;
1930 	cancel_roc_cmd->umac_hdr.ids.wdev_id = if_idx;
1931 	cancel_roc_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1932 	cancel_roc_cmd->cookie = cookie;
1933 	cancel_roc_cmd->valid_fields |= NRF_WIFI_CMD_CANCEL_ROC_COOKIE_VALID;
1934 
1935 	status = umac_cmd_cfg(fmac_dev_ctx,
1936 			      cancel_roc_cmd,
1937 			      sizeof(*cancel_roc_cmd));
1938 out:
1939 	if (cancel_roc_cmd) {
1940 		nrf_wifi_osal_mem_free(cancel_roc_cmd);
1941 	}
1942 
1943 	return status;
1944 }
1945 
1946 #endif /* NRF70_P2P_MODE */
1947 #endif /* NRF70_STA_MODE */
1948 
nrf_wifi_sys_fmac_mgmt_tx(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_mgmt_tx_info * mgmt_tx_info)1949 enum nrf_wifi_status nrf_wifi_sys_fmac_mgmt_tx(void *dev_ctx,
1950 					       unsigned char if_idx,
1951 					       struct nrf_wifi_umac_mgmt_tx_info *mgmt_tx_info)
1952 {
1953 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1954 	struct nrf_wifi_umac_cmd_mgmt_tx *mgmt_tx_cmd = NULL;
1955 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1956 
1957 	fmac_dev_ctx = dev_ctx;
1958 
1959 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
1960 		nrf_wifi_osal_log_err("%s: Invalid op mode",
1961 				      __func__);
1962 		goto out;
1963 	}
1964 
1965 	mgmt_tx_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*mgmt_tx_cmd));
1966 
1967 	if (!mgmt_tx_cmd) {
1968 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
1969 				      __func__);
1970 		goto out;
1971 	}
1972 
1973 	mgmt_tx_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_FRAME;
1974 	mgmt_tx_cmd->umac_hdr.ids.wdev_id = if_idx;
1975 	mgmt_tx_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
1976 
1977 	nrf_wifi_osal_mem_cpy(&mgmt_tx_cmd->info,
1978 			      mgmt_tx_info,
1979 			      sizeof(mgmt_tx_cmd->info));
1980 
1981 	mgmt_tx_cmd->valid_fields |= (NRF_WIFI_CMD_FRAME_FREQ_VALID |
1982 				      NRF_WIFI_CMD_FRAME_DURATION_VALID |
1983 				      NRF_WIFI_CMD_SET_FRAME_FREQ_PARAMS_VALID);
1984 
1985 	mgmt_tx_cmd->info.freq_params.valid_fields |=
1986 		(NRF_WIFI_SET_FREQ_PARAMS_FREQ_VALID |
1987 		 NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_WIDTH_VALID |
1988 		 NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ1_VALID |
1989 		 NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ2_VALID |
1990 		 NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_TYPE_VALID);
1991 
1992 	status = umac_cmd_cfg(fmac_dev_ctx,
1993 			      mgmt_tx_cmd,
1994 			      sizeof(*mgmt_tx_cmd));
1995 
1996 out:
1997 	if (mgmt_tx_cmd) {
1998 		nrf_wifi_osal_mem_free(mgmt_tx_cmd);
1999 	}
2000 
2001 	return status;
2002 }
2003 
nrf_wifi_sys_fmac_mac_addr(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char * addr)2004 enum nrf_wifi_status nrf_wifi_sys_fmac_mac_addr(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
2005 					        unsigned char *addr)
2006 {
2007 	unsigned char vif_idx = 0;
2008 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
2009 
2010 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2011 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2012 				      __func__);
2013 		return NRF_WIFI_STATUS_FAIL;
2014 	}
2015 
2016 	vif_idx = nrf_wifi_fmac_vif_idx_get(fmac_dev_ctx);
2017 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
2018 
2019 	if (vif_idx == MAX_NUM_VIFS) {
2020 		return NRF_WIFI_STATUS_FAIL;
2021 	}
2022 
2023 	nrf_wifi_osal_mem_cpy(addr,
2024 			      sys_dev_ctx->vif_ctx[vif_idx]->mac_addr,
2025 			      NRF_WIFI_ETH_ADDR_LEN);
2026 
2027 	if (((unsigned short)addr[5] + vif_idx) > 0xff) {
2028 		nrf_wifi_osal_log_err("%s: MAC Address rollover!!",
2029 				      __func__);
2030 	}
2031 
2032 	addr[5] += vif_idx;
2033 
2034 	return NRF_WIFI_STATUS_SUCCESS;
2035 }
2036 
2037 
nrf_wifi_sys_fmac_add_vif(void * dev_ctx,void * os_vif_ctx,struct nrf_wifi_umac_add_vif_info * vif_info)2038 unsigned char nrf_wifi_sys_fmac_add_vif(void *dev_ctx,
2039 					void *os_vif_ctx,
2040 					struct nrf_wifi_umac_add_vif_info *vif_info)
2041 {
2042 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2043 	struct nrf_wifi_umac_cmd_add_vif *add_vif_cmd = NULL;
2044 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2045 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
2046 	unsigned char vif_idx = 0;
2047 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
2048 
2049 	fmac_dev_ctx = dev_ctx;
2050 
2051 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2052 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2053 				      __func__);
2054 		goto out;
2055 	}
2056 
2057 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
2058 
2059 	switch (vif_info->iftype) {
2060 	case NRF_WIFI_IFTYPE_STATION:
2061 	case NRF_WIFI_IFTYPE_P2P_CLIENT:
2062 	case NRF_WIFI_IFTYPE_AP:
2063 	case NRF_WIFI_IFTYPE_P2P_GO:
2064 		break;
2065 	default:
2066 		nrf_wifi_osal_log_err("%s: VIF type not supported",
2067 				      __func__);
2068 		goto err;
2069 	}
2070 
2071 	if (nrf_wifi_fmac_vif_check_if_limit(fmac_dev_ctx,
2072 					     vif_info->iftype)) {
2073 		goto err;
2074 	}
2075 
2076 	vif_ctx = nrf_wifi_osal_mem_zalloc(sizeof(*vif_ctx));
2077 
2078 	if (!vif_ctx) {
2079 		nrf_wifi_osal_log_err("%s: Unable to allocate memory for VIF ctx",
2080 				      __func__);
2081 		goto err;
2082 	}
2083 
2084 	vif_ctx->fmac_dev_ctx = fmac_dev_ctx;
2085 	vif_ctx->os_vif_ctx = os_vif_ctx;
2086 	vif_ctx->if_type = vif_info->iftype;
2087 	vif_ctx->mode = NRF_WIFI_STA_MODE;
2088 
2089 	/**
2090 	 * Set initial packet filter setting to filter all.
2091 	 * subsequent calls to set packet filter will set
2092 	 * packet_filter settings to appropriate value as
2093 	 * desired by application.
2094 	 */
2095 #if defined(NRF70_RAW_DATA_RX) || defined(NRF70_PROMISC_DATA_RX)
2096 	vif_ctx->packet_filter = 1;
2097 #endif
2098 
2099 	nrf_wifi_osal_mem_cpy(vif_ctx->mac_addr,
2100 			      vif_info->mac_addr,
2101 			      sizeof(vif_ctx->mac_addr));
2102 
2103 	vif_idx = nrf_wifi_fmac_vif_idx_get(fmac_dev_ctx);
2104 
2105 	if (vif_idx == MAX_NUM_VIFS) {
2106 		nrf_wifi_osal_log_err("%s: Unable to add additional VIF",
2107 				      __func__);
2108 		goto err;
2109 	}
2110 
2111 	/* We don't need to send a command to the RPU for the default interface,
2112 	 * since the FW is adding that interface by default. We just need to
2113 	 * send commands for non-default interfaces
2114 	 */
2115 	if (vif_idx != 0) {
2116 		add_vif_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*add_vif_cmd));
2117 
2118 		if (!add_vif_cmd) {
2119 			nrf_wifi_osal_log_err("%s: Unable to allocate memory for cmd",
2120 					      __func__);
2121 			goto err;
2122 		}
2123 
2124 		add_vif_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_NEW_INTERFACE;
2125 		add_vif_cmd->umac_hdr.ids.wdev_id = vif_idx;
2126 		add_vif_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2127 
2128 		nrf_wifi_osal_mem_cpy(&add_vif_cmd->info,
2129 				      vif_info,
2130 				      sizeof(add_vif_cmd->info));
2131 
2132 		add_vif_cmd->valid_fields |= NRF_WIFI_CMD_NEW_INTERFACE_IFTYPE_VALID;
2133 		add_vif_cmd->valid_fields |= NRF_WIFI_CMD_NEW_INTERFACE_IFNAME_VALID;
2134 		add_vif_cmd->valid_fields |= NRF_WIFI_CMD_NEW_INTERFACE_MAC_ADDR_VALID;
2135 
2136 		status = umac_cmd_cfg(fmac_dev_ctx,
2137 				      add_vif_cmd,
2138 				      sizeof(*add_vif_cmd));
2139 
2140 		if (status == NRF_WIFI_STATUS_FAIL) {
2141 			nrf_wifi_osal_log_err("%s: NRF_WIFI_UMAC_CMD_NEW_INTERFACE failed",
2142 					      __func__);
2143 			goto err;
2144 		}
2145 
2146 	}
2147 
2148 	sys_dev_ctx->vif_ctx[vif_idx] = vif_ctx;
2149 
2150 	nrf_wifi_fmac_vif_incr_if_type(fmac_dev_ctx,
2151 				       vif_ctx->if_type);
2152 
2153 	goto out;
2154 err:
2155 	if (vif_ctx) {
2156 		nrf_wifi_osal_mem_free(vif_ctx);
2157 	}
2158 
2159 	vif_idx = MAX_NUM_VIFS;
2160 
2161 out:
2162 	if (add_vif_cmd) {
2163 		nrf_wifi_osal_mem_free(add_vif_cmd);
2164 	}
2165 
2166 	return vif_idx;
2167 }
2168 
2169 
nrf_wifi_sys_fmac_del_vif(void * dev_ctx,unsigned char if_idx)2170 enum nrf_wifi_status nrf_wifi_sys_fmac_del_vif(void *dev_ctx,
2171 					       unsigned char if_idx)
2172 {
2173 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2174 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2175 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
2176 	struct nrf_wifi_umac_cmd_del_vif *del_vif_cmd = NULL;
2177 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
2178 
2179 	fmac_dev_ctx = dev_ctx;
2180 
2181 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2182 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2183 				      __func__);
2184 		goto out;
2185 	}
2186 
2187 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
2188 
2189 	switch (sys_dev_ctx->vif_ctx[if_idx]->if_type) {
2190 	case NRF_WIFI_IFTYPE_STATION:
2191 	case NRF_WIFI_IFTYPE_P2P_CLIENT:
2192 	case NRF_WIFI_IFTYPE_AP:
2193 	case NRF_WIFI_IFTYPE_P2P_GO:
2194 		break;
2195 	default:
2196 		nrf_wifi_osal_log_err("%s: VIF type not supported",
2197 				      __func__);
2198 		goto out;
2199 	}
2200 
2201 	vif_ctx = sys_dev_ctx->vif_ctx[if_idx];
2202 
2203 	if (!vif_ctx) {
2204 		nrf_wifi_osal_log_err("%s: VIF ctx does not exist",
2205 				      __func__);
2206 		goto out;
2207 	}
2208 
2209 	/* We should not send a command to the RPU for the default interface,
2210 	 * since the FW is adding that interface by default. We just need to
2211 	 * send commands for non-default interfaces
2212 	 */
2213 	if (if_idx != 0) {
2214 		del_vif_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*del_vif_cmd));
2215 
2216 		if (!del_vif_cmd) {
2217 			nrf_wifi_osal_log_err("%s: Unable to allocate memory for cmd",
2218 					      __func__);
2219 			goto out;
2220 		}
2221 
2222 		del_vif_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_DEL_INTERFACE;
2223 		del_vif_cmd->umac_hdr.ids.wdev_id = if_idx;
2224 		del_vif_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2225 
2226 		status = umac_cmd_cfg(fmac_dev_ctx,
2227 				      del_vif_cmd,
2228 				      sizeof(*del_vif_cmd));
2229 
2230 		if (status != NRF_WIFI_STATUS_SUCCESS) {
2231 			nrf_wifi_osal_log_err("%s: NRF_WIFI_UMAC_CMD_DEL_INTERFACE failed",
2232 					      __func__);
2233 			goto out;
2234 		}
2235 	} else {
2236 		status = NRF_WIFI_STATUS_SUCCESS;
2237 	}
2238 
2239 	nrf_wifi_fmac_vif_decr_if_type(fmac_dev_ctx, vif_ctx->if_type);
2240 
2241 out:
2242 	if (del_vif_cmd) {
2243 		nrf_wifi_osal_mem_free(del_vif_cmd);
2244 	}
2245 
2246 	if (vif_ctx) {
2247 		nrf_wifi_osal_mem_free(vif_ctx);
2248 	}
2249 
2250 	return status;
2251 }
2252 
2253 
nrf_wifi_sys_fmac_chg_vif(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_chg_vif_attr_info * vif_info)2254 enum nrf_wifi_status nrf_wifi_sys_fmac_chg_vif(void *dev_ctx,
2255 					       unsigned char if_idx,
2256 					       struct nrf_wifi_umac_chg_vif_attr_info *vif_info)
2257 {
2258 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2259 	struct nrf_wifi_umac_cmd_chg_vif_attr *chg_vif_cmd = NULL;
2260 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2261 
2262 	fmac_dev_ctx = dev_ctx;
2263 
2264 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2265 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2266 				      __func__);
2267 		goto out;
2268 	}
2269 
2270 	switch (vif_info->iftype) {
2271 	case NRF_WIFI_IFTYPE_STATION:
2272 	case NRF_WIFI_IFTYPE_P2P_CLIENT:
2273 	case NRF_WIFI_IFTYPE_AP:
2274 	case NRF_WIFI_IFTYPE_P2P_GO:
2275 		break;
2276 	default:
2277 		nrf_wifi_osal_log_err("%s: VIF type not supported", __func__);
2278 		goto out;
2279 	}
2280 
2281 	if (nrf_wifi_fmac_vif_check_if_limit(fmac_dev_ctx,
2282 					     vif_info->iftype)) {
2283 		goto out;
2284 	}
2285 
2286 	chg_vif_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*chg_vif_cmd));
2287 
2288 	if (!chg_vif_cmd) {
2289 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
2290 				      __func__);
2291 		goto out;
2292 	}
2293 
2294 	chg_vif_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_INTERFACE;
2295 	chg_vif_cmd->umac_hdr.ids.wdev_id = if_idx;
2296 	chg_vif_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2297 
2298 	nrf_wifi_osal_mem_cpy(&chg_vif_cmd->info,
2299 			      vif_info,
2300 			      sizeof(chg_vif_cmd->info));
2301 
2302 	chg_vif_cmd->valid_fields |= NRF_WIFI_SET_INTERFACE_IFTYPE_VALID;
2303 	chg_vif_cmd->valid_fields |= NRF_WIFI_SET_INTERFACE_USE_4ADDR_VALID;
2304 
2305 	status = umac_cmd_cfg(fmac_dev_ctx,
2306 			      chg_vif_cmd,
2307 			      sizeof(*chg_vif_cmd));
2308 out:
2309 	if (chg_vif_cmd) {
2310 		nrf_wifi_osal_mem_free(chg_vif_cmd);
2311 	}
2312 
2313 	if (status == NRF_WIFI_STATUS_SUCCESS) {
2314 		struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
2315 
2316 		sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
2317 
2318 		nrf_wifi_fmac_vif_update_if_type(fmac_dev_ctx,
2319 						 if_idx,
2320 						 vif_info->iftype);
2321 
2322 		sys_dev_ctx->vif_ctx[if_idx]->if_type = vif_info->iftype;
2323 	}
2324 
2325 	return status;
2326 }
2327 
2328 
2329 #define RPU_CMD_TIMEOUT_MS 10000
nrf_wifi_sys_fmac_chg_vif_state(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_chg_vif_state_info * vif_info)2330 enum nrf_wifi_status nrf_wifi_sys_fmac_chg_vif_state(void *dev_ctx,
2331 						     unsigned char if_idx,
2332 						     struct nrf_wifi_umac_chg_vif_state_info *vif_info)
2333 {
2334 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2335 	struct nrf_wifi_umac_cmd_chg_vif_state *chg_vif_state_cmd = NULL;
2336 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2337 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
2338 	unsigned int count = RPU_CMD_TIMEOUT_MS;
2339 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
2340 
2341 	fmac_dev_ctx = dev_ctx;
2342 
2343 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2344 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2345 				      __func__);
2346 		goto out;
2347 	}
2348 
2349 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
2350 
2351 	chg_vif_state_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*chg_vif_state_cmd));
2352 
2353 	if (!chg_vif_state_cmd) {
2354 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
2355 				      __func__);
2356 		goto out;
2357 	}
2358 
2359 	chg_vif_state_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_IFFLAGS;
2360 	chg_vif_state_cmd->umac_hdr.ids.wdev_id = if_idx;
2361 	chg_vif_state_cmd->umac_hdr.ids.valid_fields |=
2362 		NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2363 
2364 	nrf_wifi_osal_mem_cpy(&chg_vif_state_cmd->info,
2365 			      vif_info,
2366 			      sizeof(chg_vif_state_cmd->info));
2367 
2368 	vif_ctx = sys_dev_ctx->vif_ctx[if_idx];
2369 
2370 	vif_ctx->ifflags = false;
2371 
2372 	status = umac_cmd_cfg(fmac_dev_ctx,
2373 			      chg_vif_state_cmd,
2374 			      sizeof(*chg_vif_state_cmd));
2375 
2376 	while (!vif_ctx->ifflags && (--count > 0))
2377 		nrf_wifi_osal_sleep_ms(1);
2378 
2379 	if (count == 0) {
2380 		status = NRF_WIFI_STATUS_FAIL;
2381 		nrf_wifi_osal_log_err("%s: RPU is unresponsive for %d sec",
2382 				      __func__, RPU_CMD_TIMEOUT_MS / 1000);
2383 		goto out;
2384 	}
2385 #ifdef NRF70_AP_MODE
2386 	if (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP) {
2387 		if (vif_info->state == 1) {
2388 			sys_dev_ctx->tx_config.peers[MAX_PEERS].peer_id = MAX_PEERS;
2389 			sys_dev_ctx->tx_config.peers[MAX_PEERS].if_idx = if_idx;
2390 		} else if (vif_info->state == 0) {
2391 			sys_dev_ctx->tx_config.peers[MAX_PEERS].peer_id = -1;
2392 			sys_dev_ctx->tx_config.peers[MAX_PEERS].if_idx = if_idx;
2393 		}
2394 	}
2395 #endif /* NRF70_AP_MODE */
2396 out:
2397 	if (chg_vif_state_cmd) {
2398 		nrf_wifi_osal_mem_free(chg_vif_state_cmd);
2399 	}
2400 
2401 	return status;
2402 }
2403 
2404 
nrf_wifi_sys_fmac_set_vif_macaddr(void * dev_ctx,unsigned char if_idx,unsigned char * mac_addr)2405 enum nrf_wifi_status nrf_wifi_sys_fmac_set_vif_macaddr(void *dev_ctx,
2406 						       unsigned char if_idx,
2407 						       unsigned char *mac_addr)
2408 {
2409 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2410 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2411 	struct nrf_wifi_umac_cmd_change_macaddr *cmd = NULL;
2412 
2413 	if (!dev_ctx) {
2414 		goto out;
2415 	}
2416 
2417 	if (!mac_addr) {
2418 		nrf_wifi_osal_log_err("%s: Invalid MAC address",
2419 				      __func__);
2420 		goto out;
2421 	}
2422 
2423 	fmac_dev_ctx = dev_ctx;
2424 
2425 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2426 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2427 				      __func__);
2428 		goto out;
2429 	}
2430 
2431 	cmd = nrf_wifi_osal_mem_zalloc(sizeof(*cmd));
2432 
2433 	if (!cmd) {
2434 		nrf_wifi_osal_log_err("%s: Unable to allocate cmd",
2435 				      __func__);
2436 		goto out;
2437 	}
2438 
2439 	cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CHANGE_MACADDR;
2440 	cmd->umac_hdr.ids.wdev_id = if_idx;
2441 	cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2442 
2443 	nrf_wifi_osal_mem_cpy(cmd->macaddr_info.mac_addr,
2444 			      mac_addr,
2445 			      sizeof(cmd->macaddr_info.mac_addr));
2446 
2447 	status = umac_cmd_cfg(fmac_dev_ctx,
2448 			      cmd,
2449 			      sizeof(*cmd));
2450 out:
2451 	if (cmd) {
2452 		nrf_wifi_osal_mem_free(cmd);
2453 	}
2454 
2455 	return status;
2456 }
2457 
nrf_wifi_sys_fmac_set_wiphy_params(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_set_wiphy_info * wiphy_info)2458 enum nrf_wifi_status nrf_wifi_sys_fmac_set_wiphy_params(void *dev_ctx,
2459 						        unsigned char if_idx,
2460 						        struct nrf_wifi_umac_set_wiphy_info *wiphy_info)
2461 {
2462 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2463 	struct nrf_wifi_umac_cmd_set_wiphy *set_wiphy_cmd = NULL;
2464 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2465 	int freq_params_valid = 0;
2466 
2467 	if (!dev_ctx) {
2468 		goto out;
2469 	}
2470 
2471 	fmac_dev_ctx = dev_ctx;
2472 
2473 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2474 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2475 				      __func__);
2476 		goto out;
2477 	}
2478 
2479 	if (!wiphy_info) {
2480 		nrf_wifi_osal_log_err("%s: wiphy_info: Invalid memory",
2481 				       __func__);
2482 		goto out;
2483 	}
2484 
2485 	set_wiphy_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_wiphy_cmd));
2486 
2487 	if (!set_wiphy_cmd) {
2488 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
2489 				      __func__);
2490 		goto out;
2491 	}
2492 
2493 	set_wiphy_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_WIPHY;
2494 	set_wiphy_cmd->umac_hdr.ids.wdev_id = if_idx;
2495 	set_wiphy_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2496 
2497 	if (wiphy_info->freq_params.frequency) {
2498 		freq_params_valid = 1;
2499 		wiphy_info->freq_params.valid_fields |=
2500 			NRF_WIFI_SET_FREQ_PARAMS_FREQ_VALID;
2501 	}
2502 
2503 	if (wiphy_info->freq_params.channel_width) {
2504 		freq_params_valid = 1;
2505 		wiphy_info->freq_params.valid_fields |=
2506 			NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_WIDTH_VALID;
2507 	}
2508 
2509 	if (wiphy_info->freq_params.center_frequency1) {
2510 		freq_params_valid = 1;
2511 		wiphy_info->freq_params.valid_fields |=
2512 			NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ1_VALID;
2513 	}
2514 
2515 	if (wiphy_info->freq_params.center_frequency2) {
2516 		freq_params_valid = 1;
2517 		wiphy_info->freq_params.valid_fields |=
2518 			NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ2_VALID;
2519 	}
2520 
2521 	if (wiphy_info->freq_params.channel_type) {
2522 		freq_params_valid = 1;
2523 		wiphy_info->freq_params.valid_fields |=
2524 			NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_TYPE_VALID;
2525 	}
2526 
2527 	if (freq_params_valid) {
2528 		set_wiphy_cmd->valid_fields |=
2529 			NRF_WIFI_CMD_SET_WIPHY_FREQ_PARAMS_VALID;
2530 	}
2531 
2532 	if (wiphy_info->rts_threshold) {
2533 		set_wiphy_cmd->valid_fields |=
2534 			NRF_WIFI_CMD_SET_WIPHY_RTS_THRESHOLD_VALID;
2535 	}
2536 
2537 	if (wiphy_info->frag_threshold) {
2538 		set_wiphy_cmd->valid_fields |=
2539 			NRF_WIFI_CMD_SET_WIPHY_FRAG_THRESHOLD_VALID;
2540 	}
2541 
2542 	if (wiphy_info->retry_long) {
2543 		set_wiphy_cmd->valid_fields |=
2544 			NRF_WIFI_CMD_SET_WIPHY_RETRY_LONG_VALID;
2545 	}
2546 
2547 	if (wiphy_info->retry_short) {
2548 		set_wiphy_cmd->valid_fields |=
2549 			NRF_WIFI_CMD_SET_WIPHY_RETRY_SHORT_VALID;
2550 	}
2551 
2552 	nrf_wifi_osal_mem_cpy(&set_wiphy_cmd->info,
2553 			      wiphy_info,
2554 			      sizeof(set_wiphy_cmd->info));
2555 
2556 	status = umac_cmd_cfg(fmac_dev_ctx,
2557 			      set_wiphy_cmd,
2558 			      sizeof(*set_wiphy_cmd));
2559 out:
2560 	if (set_wiphy_cmd) {
2561 		nrf_wifi_osal_mem_free(set_wiphy_cmd);
2562 	}
2563 
2564 	return status;
2565 }
2566 
2567 #ifdef NRF70_STA_MODE
nrf_wifi_sys_fmac_get_tx_power(void * dev_ctx,unsigned int if_idx)2568 enum nrf_wifi_status nrf_wifi_sys_fmac_get_tx_power(void *dev_ctx,
2569 						    unsigned int if_idx)
2570 {
2571 
2572 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2573 	struct nrf_wifi_umac_cmd_get_tx_power *cmd = NULL;
2574 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2575 
2576 	fmac_dev_ctx = dev_ctx;
2577 
2578 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2579 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2580 				      __func__);
2581 		goto out;
2582 	}
2583 
2584 	cmd = nrf_wifi_osal_mem_zalloc(sizeof(*cmd));
2585 
2586 	if (!cmd) {
2587 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
2588 				      __func__);
2589 		goto out;
2590 	}
2591 
2592 	cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_TX_POWER;
2593 	cmd->umac_hdr.ids.wdev_id = if_idx;
2594 	cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2595 
2596 	status = umac_cmd_cfg(fmac_dev_ctx, cmd, sizeof(*cmd));
2597 
2598 out:
2599 	if (cmd) {
2600 		nrf_wifi_osal_mem_free(cmd);
2601 	}
2602 
2603 	return status;
2604 }
2605 
2606 
nrf_wifi_sys_fmac_get_channel(void * dev_ctx,unsigned int if_idx)2607 enum nrf_wifi_status nrf_wifi_sys_fmac_get_channel(void *dev_ctx,
2608 						   unsigned int if_idx)
2609 {
2610 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2611 	struct nrf_wifi_umac_cmd_get_channel *cmd = NULL;
2612 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2613 
2614 	fmac_dev_ctx = dev_ctx;
2615 
2616 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2617 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2618 				      __func__);
2619 		goto out;
2620 	}
2621 
2622 	cmd = nrf_wifi_osal_mem_zalloc(sizeof(*cmd));
2623 
2624 	if (!cmd) {
2625 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
2626 				      __func__);
2627 		goto out;
2628 	}
2629 
2630 	cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_CHANNEL;
2631 	cmd->umac_hdr.ids.wdev_id = if_idx;
2632 	cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2633 
2634 	status = umac_cmd_cfg(fmac_dev_ctx,
2635 			      cmd,
2636 			      sizeof(*cmd));
2637 out:
2638 	if (cmd) {
2639 		nrf_wifi_osal_mem_free(cmd);
2640 	}
2641 
2642 	return status;
2643 }
2644 
2645 
nrf_wifi_sys_fmac_get_station(void * dev_ctx,unsigned int if_idx,unsigned char * mac)2646 enum nrf_wifi_status nrf_wifi_sys_fmac_get_station(void *dev_ctx,
2647 						   unsigned int if_idx,
2648 						   unsigned char *mac)
2649 {
2650 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2651 	struct nrf_wifi_umac_cmd_get_sta *cmd = NULL;
2652 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2653 
2654 	fmac_dev_ctx = dev_ctx;
2655 
2656 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2657 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2658 				      __func__);
2659 		goto out;
2660 	}
2661 
2662 	cmd = nrf_wifi_osal_mem_zalloc(sizeof(*cmd));
2663 
2664 	if (!cmd) {
2665 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
2666 				      __func__);
2667 		goto out;
2668 	}
2669 
2670 	cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_STATION;
2671 	cmd->umac_hdr.ids.wdev_id = if_idx;
2672 	cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2673 
2674 	nrf_wifi_osal_mem_cpy(cmd->info.mac_addr,
2675 			      mac,
2676 			      NRF_WIFI_ETH_ADDR_LEN);
2677 
2678 	status = umac_cmd_cfg(fmac_dev_ctx,
2679 			      cmd,
2680 			      sizeof(*cmd));
2681 out:
2682 	if (cmd) {
2683 		nrf_wifi_osal_mem_free(cmd);
2684 	}
2685 
2686 	return status;
2687 }
2688 
nrf_wifi_sys_fmac_get_interface(void * dev_ctx,unsigned int if_idx)2689 enum nrf_wifi_status nrf_wifi_sys_fmac_get_interface(void *dev_ctx,
2690 						     unsigned int if_idx)
2691 {
2692 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2693 	struct nrf_wifi_cmd_get_interface *cmd = NULL;
2694 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2695 
2696 	if (!dev_ctx || if_idx > MAX_NUM_VIFS) {
2697 		goto out;
2698 	}
2699 	fmac_dev_ctx = dev_ctx;
2700 
2701 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2702 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2703 				      __func__);
2704 		goto out;
2705 	}
2706 
2707 	cmd = nrf_wifi_osal_mem_zalloc(sizeof(*cmd));
2708 
2709 	if (!cmd) {
2710 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
2711 				      __func__);
2712 		goto out;
2713 	}
2714 
2715 	cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_INTERFACE;
2716 	cmd->umac_hdr.ids.wdev_id = if_idx;
2717 	cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2718 
2719 	status = umac_cmd_cfg(fmac_dev_ctx,
2720 			      cmd,
2721 			      sizeof(*cmd));
2722 out:
2723 	if (cmd) {
2724 		nrf_wifi_osal_mem_free(cmd);
2725 	}
2726 
2727 	return status;
2728 }
2729 
2730 
nrf_wifi_sys_fmac_set_qos_map(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_qos_map_info * qos_info)2731 enum nrf_wifi_status nrf_wifi_sys_fmac_set_qos_map(void *dev_ctx,
2732 						   unsigned char if_idx,
2733 						   struct nrf_wifi_umac_qos_map_info *qos_info)
2734 {
2735 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2736 	struct nrf_wifi_umac_cmd_set_qos_map *set_qos_cmd = NULL;
2737 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2738 
2739 	fmac_dev_ctx = dev_ctx;
2740 
2741 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2742 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2743 				      __func__);
2744 		goto out;
2745 	}
2746 
2747 	set_qos_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_qos_cmd));
2748 
2749 	if (!set_qos_cmd) {
2750 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
2751 				      __func__);
2752 		goto out;
2753 	}
2754 
2755 	set_qos_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_QOS_MAP;
2756 	set_qos_cmd->umac_hdr.ids.wdev_id = if_idx;
2757 	set_qos_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2758 
2759 	if (qos_info->qos_map_info_len) {
2760 		nrf_wifi_osal_mem_cpy(&set_qos_cmd->info.qos_map_info,
2761 				      qos_info->qos_map_info,
2762 				      qos_info->qos_map_info_len);
2763 
2764 		set_qos_cmd->info.qos_map_info_len =
2765 			qos_info->qos_map_info_len;
2766 	}
2767 
2768 	status = umac_cmd_cfg(fmac_dev_ctx,
2769 			      set_qos_cmd,
2770 			      sizeof(*set_qos_cmd));
2771 out:
2772 	if (set_qos_cmd) {
2773 		nrf_wifi_osal_mem_free(set_qos_cmd);
2774 	}
2775 
2776 	return status;
2777 }
2778 
2779 
nrf_wifi_sys_fmac_set_power_save(void * dev_ctx,unsigned char if_idx,bool state)2780 enum nrf_wifi_status nrf_wifi_sys_fmac_set_power_save(void *dev_ctx,
2781 						      unsigned char if_idx,
2782 						      bool state)
2783 {
2784 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2785 	struct nrf_wifi_umac_cmd_set_power_save *set_ps_cmd = NULL;
2786 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2787 
2788 	fmac_dev_ctx = dev_ctx;
2789 
2790 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2791 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2792 				      __func__);
2793 		goto out;
2794 	}
2795 
2796 	set_ps_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_ps_cmd));
2797 
2798 	if (!set_ps_cmd) {
2799 		nrf_wifi_osal_log_err("%s: Unable to allocate memory", __func__);
2800 		goto out;
2801 	}
2802 
2803 	set_ps_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_POWER_SAVE;
2804 	set_ps_cmd->umac_hdr.ids.wdev_id = if_idx;
2805 	set_ps_cmd->umac_hdr.ids.valid_fields |=
2806 		NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2807 	set_ps_cmd->info.ps_state = state;
2808 
2809 	status = umac_cmd_cfg(fmac_dev_ctx,
2810 			      set_ps_cmd,
2811 			      sizeof(*set_ps_cmd));
2812 out:
2813 	if (set_ps_cmd) {
2814 		nrf_wifi_osal_mem_free(set_ps_cmd);
2815 	}
2816 
2817 	return status;
2818 }
2819 
2820 
nrf_wifi_sys_fmac_set_uapsd_queue(void * dev_ctx,unsigned char if_idx,unsigned int uapsd_queue)2821 enum nrf_wifi_status nrf_wifi_sys_fmac_set_uapsd_queue(void *dev_ctx,
2822 						       unsigned char if_idx,
2823 						       unsigned int uapsd_queue)
2824 {
2825 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2826 	struct nrf_wifi_umac_cmd_config_uapsd  *set_uapsdq_cmd = NULL;
2827 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2828 
2829 	fmac_dev_ctx = dev_ctx;
2830 
2831 	if (!dev_ctx) {
2832 		goto out;
2833 	}
2834 
2835 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2836 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2837 				      __func__);
2838 		goto out;
2839 	}
2840 
2841 	set_uapsdq_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_uapsdq_cmd));
2842 	if (!set_uapsdq_cmd) {
2843 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
2844 				      __func__);
2845 		goto out;
2846 	}
2847 
2848 	set_uapsdq_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CONFIG_UAPSD;
2849 	set_uapsdq_cmd->umac_hdr.ids.wdev_id = if_idx;
2850 	set_uapsdq_cmd->umac_hdr.ids.valid_fields |=
2851 		NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2852 	set_uapsdq_cmd->info.uapsd_queue = uapsd_queue;
2853 
2854 	status = umac_cmd_cfg(fmac_dev_ctx,
2855 			      set_uapsdq_cmd,
2856 			      sizeof(*set_uapsdq_cmd));
2857 out:
2858 	if (set_uapsdq_cmd) {
2859 		nrf_wifi_osal_mem_free(set_uapsdq_cmd);
2860 	}
2861 
2862 	return status;
2863 }
2864 
2865 
nrf_wifi_sys_fmac_set_power_save_timeout(void * dev_ctx,unsigned char if_idx,int ps_timeout)2866 enum nrf_wifi_status nrf_wifi_sys_fmac_set_power_save_timeout(void *dev_ctx,
2867 							      unsigned char if_idx,
2868 							      int ps_timeout)
2869 {
2870 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2871 	struct nrf_wifi_umac_cmd_set_power_save_timeout *set_ps_timeout_cmd = NULL;
2872 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2873 
2874 	fmac_dev_ctx = dev_ctx;
2875 
2876 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2877 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2878 				      __func__);
2879 		goto out;
2880 	}
2881 
2882 	set_ps_timeout_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_ps_timeout_cmd));
2883 
2884 	if (!set_ps_timeout_cmd) {
2885 		nrf_wifi_osal_log_err("%s: Unable to allocate memory", __func__);
2886 		goto out;
2887 	}
2888 
2889 	set_ps_timeout_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_POWER_SAVE_TIMEOUT;
2890 	set_ps_timeout_cmd->umac_hdr.ids.wdev_id = if_idx;
2891 	set_ps_timeout_cmd->umac_hdr.ids.valid_fields |=
2892 		NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2893 	set_ps_timeout_cmd->timeout = ps_timeout;
2894 
2895 	status = umac_cmd_cfg(fmac_dev_ctx,
2896 			      set_ps_timeout_cmd,
2897 			      sizeof(*set_ps_timeout_cmd));
2898 out:
2899 	if (set_ps_timeout_cmd) {
2900 		nrf_wifi_osal_mem_free(set_ps_timeout_cmd);
2901 	}
2902 
2903 	return status;
2904 }
2905 
2906 
nrf_wifi_sys_fmac_get_wiphy(void * dev_ctx,unsigned char if_idx)2907 enum nrf_wifi_status nrf_wifi_sys_fmac_get_wiphy(void *dev_ctx, unsigned char if_idx)
2908 {
2909 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2910 	struct nrf_wifi_cmd_get_wiphy *get_wiphy = NULL;
2911 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2912 
2913 	fmac_dev_ctx = dev_ctx;
2914 
2915 	if (!dev_ctx || (if_idx >= MAX_NUM_VIFS)) {
2916 		goto out;
2917 	}
2918 
2919 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2920 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2921 				      __func__);
2922 		goto out;
2923 	}
2924 
2925 	get_wiphy = nrf_wifi_osal_mem_zalloc(sizeof(*get_wiphy));
2926 
2927 	if (!get_wiphy) {
2928 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
2929 				      __func__);
2930 		goto out;
2931 	}
2932 
2933 	get_wiphy->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_WIPHY;
2934 	get_wiphy->umac_hdr.ids.wdev_id = if_idx;
2935 	get_wiphy->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2936 
2937 	status = umac_cmd_cfg(fmac_dev_ctx,
2938 			      get_wiphy,
2939 			      sizeof(*get_wiphy));
2940 out:
2941 	if (get_wiphy) {
2942 		nrf_wifi_osal_mem_free(get_wiphy);
2943 	}
2944 
2945 	return status;
2946 }
2947 
nrf_wifi_sys_fmac_register_frame(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_mgmt_frame_info * frame_info)2948 enum nrf_wifi_status nrf_wifi_sys_fmac_register_frame(void *dev_ctx, unsigned char if_idx,
2949 						      struct nrf_wifi_umac_mgmt_frame_info *frame_info)
2950 {
2951 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2952 	struct nrf_wifi_umac_cmd_mgmt_frame_reg *frame_reg_cmd = NULL;
2953 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2954 
2955 	fmac_dev_ctx = dev_ctx;
2956 
2957 	if (!dev_ctx || (if_idx >= MAX_NUM_VIFS) || !frame_info) {
2958 		goto out;
2959 	}
2960 
2961 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
2962 		nrf_wifi_osal_log_err("%s: Invalid op mode",
2963 				      __func__);
2964 		goto out;
2965 	}
2966 
2967 	frame_reg_cmd =
2968 		nrf_wifi_osal_mem_zalloc(sizeof(*frame_reg_cmd));
2969 
2970 	if (!frame_reg_cmd) {
2971 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
2972 				      __func__);
2973 		goto out;
2974 	}
2975 
2976 	frame_reg_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_REGISTER_FRAME;
2977 	frame_reg_cmd->umac_hdr.ids.wdev_id = if_idx;
2978 	frame_reg_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
2979 
2980 	nrf_wifi_osal_mem_cpy(&frame_reg_cmd->info, frame_info, sizeof(frame_reg_cmd->info));
2981 
2982 	status = umac_cmd_cfg(fmac_dev_ctx, frame_reg_cmd, sizeof(*frame_reg_cmd));
2983 out:
2984 	if (frame_reg_cmd) {
2985 		nrf_wifi_osal_mem_free(frame_reg_cmd);
2986 	}
2987 
2988 	return status;
2989 }
2990 
nrf_wifi_sys_fmac_twt_setup(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_config_twt_info * twt_params)2991 enum nrf_wifi_status nrf_wifi_sys_fmac_twt_setup(void *dev_ctx,
2992 						 unsigned char if_idx,
2993 						 struct nrf_wifi_umac_config_twt_info *twt_params)
2994 {
2995 
2996 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2997 	struct nrf_wifi_umac_cmd_config_twt *twt_setup_cmd = NULL;
2998 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
2999 
3000 	if (!dev_ctx || !twt_params) {
3001 		goto out;
3002 	}
3003 
3004 	fmac_dev_ctx = dev_ctx;
3005 
3006 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3007 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3008 				      __func__);
3009 		goto out;
3010 	}
3011 
3012 	twt_setup_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*twt_setup_cmd));
3013 
3014 	if (!twt_setup_cmd) {
3015 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
3016 				      __func__);
3017 		goto out;
3018 	}
3019 
3020 	nrf_wifi_osal_mem_cpy(&twt_setup_cmd->info,
3021 			      twt_params,
3022 			      sizeof(twt_setup_cmd->info));
3023 
3024 	twt_setup_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CONFIG_TWT;
3025 	twt_setup_cmd->umac_hdr.ids.wdev_id = if_idx;
3026 	twt_setup_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
3027 
3028 	status = umac_cmd_cfg(fmac_dev_ctx,
3029 			      twt_setup_cmd,
3030 			      sizeof(*twt_setup_cmd));
3031 out:
3032 	if (twt_setup_cmd) {
3033 		nrf_wifi_osal_mem_free(twt_setup_cmd);
3034 	}
3035 
3036 	return status;
3037 }
3038 
3039 
nrf_wifi_sys_fmac_twt_teardown(void * dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_config_twt_info * twt_params)3040 enum nrf_wifi_status nrf_wifi_sys_fmac_twt_teardown(void *dev_ctx,
3041 						    unsigned char if_idx,
3042 						    struct nrf_wifi_umac_config_twt_info *twt_params)
3043 {
3044 
3045 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3046 	struct nrf_wifi_umac_cmd_teardown_twt *twt_teardown_cmd = NULL;
3047 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
3048 
3049 	if (!dev_ctx || !twt_params) {
3050 		goto out;
3051 	}
3052 
3053 	fmac_dev_ctx = dev_ctx;
3054 
3055 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3056 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3057 				      __func__);
3058 		goto out;
3059 	}
3060 
3061 	twt_teardown_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*twt_teardown_cmd));
3062 
3063 	if (!twt_teardown_cmd) {
3064 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
3065 				      __func__);
3066 		goto out;
3067 	}
3068 
3069 	nrf_wifi_osal_mem_cpy(&twt_teardown_cmd->info,
3070 			      twt_params,
3071 			      sizeof(twt_teardown_cmd->info));
3072 
3073 	twt_teardown_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_TEARDOWN_TWT;
3074 	twt_teardown_cmd->umac_hdr.ids.wdev_id = if_idx;
3075 	twt_teardown_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
3076 
3077 	status = umac_cmd_cfg(fmac_dev_ctx,
3078 			      twt_teardown_cmd,
3079 			      sizeof(*twt_teardown_cmd));
3080 out:
3081 	if (twt_teardown_cmd) {
3082 		nrf_wifi_osal_mem_free(twt_teardown_cmd);
3083 	}
3084 
3085 	return status;
3086 }
3087 
nrf_wifi_sys_fmac_set_mcast_addr(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char if_idx,struct nrf_wifi_umac_mcast_cfg * mcast_info)3088 enum nrf_wifi_status nrf_wifi_sys_fmac_set_mcast_addr(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
3089 						      unsigned char if_idx,
3090 						      struct nrf_wifi_umac_mcast_cfg *mcast_info)
3091 {
3092 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3093 	struct nrf_wifi_umac_cmd_mcast_filter *set_mcast_cmd = NULL;
3094 
3095 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3096 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3097 				      __func__);
3098 		goto out;
3099 	}
3100 
3101 	set_mcast_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_mcast_cmd));
3102 
3103 	if (!set_mcast_cmd) {
3104 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
3105 				      __func__);
3106 		goto out;
3107 	}
3108 
3109 	set_mcast_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_MCAST_FILTER;
3110 	set_mcast_cmd->umac_hdr.ids.wdev_id = if_idx;
3111 	set_mcast_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
3112 
3113 	nrf_wifi_osal_mem_cpy(&set_mcast_cmd->info,
3114 			      mcast_info,
3115 			      sizeof(*mcast_info));
3116 
3117 	status = umac_cmd_cfg(fmac_dev_ctx,
3118 			      set_mcast_cmd,
3119 			      sizeof(*set_mcast_cmd));
3120 out:
3121 
3122 	if (set_mcast_cmd) {
3123 		nrf_wifi_osal_mem_free(set_mcast_cmd);
3124 	}
3125 	return status;
3126 }
3127 
3128 
nrf_wifi_sys_fmac_get_conn_info(void * dev_ctx,unsigned char if_idx)3129 enum nrf_wifi_status nrf_wifi_sys_fmac_get_conn_info(void *dev_ctx,
3130 						     unsigned char if_idx)
3131 {
3132 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3133 	struct nrf_wifi_umac_cmd_conn_info *cmd = NULL;
3134 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
3135 
3136 	fmac_dev_ctx = dev_ctx;
3137 
3138 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3139 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3140 				      __func__);
3141 		goto out;
3142 	}
3143 
3144 	cmd = nrf_wifi_osal_mem_zalloc(sizeof(*cmd));
3145 
3146 	if (!cmd) {
3147 		nrf_wifi_osal_log_err("%s: Unable to allocate memory",
3148 				      __func__);
3149 		goto out;
3150 	}
3151 	cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_CONNECTION_INFO;
3152 	cmd->umac_hdr.ids.wdev_id = if_idx;
3153 	cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
3154 
3155 	status = umac_cmd_cfg(fmac_dev_ctx,
3156 			      cmd,
3157 			      sizeof(*cmd));
3158 out:
3159 	if (cmd) {
3160 		nrf_wifi_osal_mem_free(cmd);
3161 	}
3162 
3163 	return status;
3164 }
3165 
nrf_wifi_sys_fmac_get_power_save_info(void * dev_ctx,unsigned char if_idx)3166 enum nrf_wifi_status nrf_wifi_sys_fmac_get_power_save_info(void *dev_ctx,
3167 							   unsigned char if_idx)
3168 {
3169 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3170 	struct nrf_wifi_umac_cmd_get_power_save_info *get_ps_info_cmd = NULL;
3171 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
3172 
3173 	fmac_dev_ctx = dev_ctx;
3174 
3175 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3176 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3177 				      __func__);
3178 		goto out;
3179 	}
3180 
3181 	get_ps_info_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*get_ps_info_cmd));
3182 
3183 	if (!get_ps_info_cmd) {
3184 		nrf_wifi_osal_log_err("%s: Unable to allocate memory", __func__);
3185 		goto out;
3186 	}
3187 
3188 	get_ps_info_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_POWER_SAVE_INFO;
3189 	get_ps_info_cmd->umac_hdr.ids.wdev_id = if_idx;
3190 	get_ps_info_cmd->umac_hdr.ids.valid_fields |=
3191 			NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
3192 
3193 	status = umac_cmd_cfg(fmac_dev_ctx,
3194 			      get_ps_info_cmd,
3195 			      sizeof(*get_ps_info_cmd));
3196 out:
3197 	if (get_ps_info_cmd) {
3198 		nrf_wifi_osal_mem_free(get_ps_info_cmd);
3199 	}
3200 
3201 	return status;
3202 }
3203 
nrf_wifi_sys_fmac_set_listen_interval(void * dev_ctx,unsigned char if_idx,unsigned short listen_interval)3204 enum nrf_wifi_status nrf_wifi_sys_fmac_set_listen_interval(void *dev_ctx,
3205 							   unsigned char if_idx,
3206 							   unsigned short listen_interval)
3207 {
3208 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3209 	struct nrf_wifi_umac_cmd_set_listen_interval *set_listen_interval_cmd = NULL;
3210 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
3211 
3212 	fmac_dev_ctx = dev_ctx;
3213 
3214 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3215 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3216 				      __func__);
3217 		goto out;
3218 	}
3219 
3220 	set_listen_interval_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_listen_interval_cmd));
3221 
3222 	if (!set_listen_interval_cmd) {
3223 		nrf_wifi_osal_log_err("%s: Unable to allocate memory", __func__);
3224 		goto out;
3225 	}
3226 
3227 	set_listen_interval_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_LISTEN_INTERVAL;
3228 	set_listen_interval_cmd->umac_hdr.ids.wdev_id = if_idx;
3229 	set_listen_interval_cmd->umac_hdr.ids.valid_fields |=
3230 		NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
3231 	set_listen_interval_cmd->listen_interval = listen_interval;
3232 
3233 	status = umac_cmd_cfg(fmac_dev_ctx,
3234 			      set_listen_interval_cmd,
3235 			      sizeof(*set_listen_interval_cmd));
3236 out:
3237 	if (set_listen_interval_cmd) {
3238 		nrf_wifi_osal_mem_free(set_listen_interval_cmd);
3239 	}
3240 
3241 	return status;
3242 }
3243 
3244 
nrf_wifi_sys_fmac_set_ps_wakeup_mode(void * dev_ctx,unsigned char if_idx,bool ps_wakeup_mode)3245 enum nrf_wifi_status nrf_wifi_sys_fmac_set_ps_wakeup_mode(void *dev_ctx,
3246 							  unsigned char if_idx,
3247 							  bool ps_wakeup_mode)
3248 {
3249 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3250 	struct nrf_wifi_umac_cmd_config_extended_ps *set_ps_wakeup_mode_cmd = NULL;
3251 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
3252 
3253 	fmac_dev_ctx = dev_ctx;
3254 
3255 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3256 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3257 				      __func__);
3258 		goto out;
3259 	}
3260 
3261 	set_ps_wakeup_mode_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_ps_wakeup_mode_cmd));
3262 
3263 	if (!set_ps_wakeup_mode_cmd) {
3264 		nrf_wifi_osal_log_err("%s: Unable to allocate memory", __func__);
3265 		goto out;
3266 	}
3267 
3268 	set_ps_wakeup_mode_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CONFIG_EXTENDED_PS;
3269 	set_ps_wakeup_mode_cmd->umac_hdr.ids.wdev_id = if_idx;
3270 	set_ps_wakeup_mode_cmd->umac_hdr.ids.valid_fields |=
3271 		NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
3272 	set_ps_wakeup_mode_cmd->enable_extended_ps = ps_wakeup_mode;
3273 
3274 	status = umac_cmd_cfg(fmac_dev_ctx,
3275 			      set_ps_wakeup_mode_cmd,
3276 			      sizeof(*set_ps_wakeup_mode_cmd));
3277 out:
3278 	if (set_ps_wakeup_mode_cmd) {
3279 		nrf_wifi_osal_mem_free(set_ps_wakeup_mode_cmd);
3280 	}
3281 
3282 	return status;
3283 }
3284 
nrf_wifi_sys_fmac_set_ps_exit_strategy(void * dev_ctx,unsigned char if_idx,unsigned int ps_exit_strategy)3285 enum nrf_wifi_status nrf_wifi_sys_fmac_set_ps_exit_strategy(void *dev_ctx,
3286 							    unsigned char if_idx,
3287 							    unsigned int ps_exit_strategy)
3288 {
3289 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3290 	struct nrf_wifi_cmd_ps_exit_strategy *set_ps_exit_strategy_cmd = NULL;
3291 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
3292 
3293 	(void)if_idx;
3294 
3295 	fmac_dev_ctx = dev_ctx;
3296 
3297 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3298 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3299 				      __func__);
3300 		goto out;
3301 	}
3302 
3303 	set_ps_exit_strategy_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*set_ps_exit_strategy_cmd));
3304 
3305 	if (!set_ps_exit_strategy_cmd) {
3306 		nrf_wifi_osal_log_err("%s: Unable to allocate memory\n", __func__);
3307 		goto out;
3308 	}
3309 
3310 	set_ps_exit_strategy_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_PS_EXIT_STRATEGY;
3311 	set_ps_exit_strategy_cmd->umac_hdr.ids.wdev_id = if_idx;
3312 	set_ps_exit_strategy_cmd->umac_hdr.ids.valid_fields |=
3313 		NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
3314 	set_ps_exit_strategy_cmd->ps_exit_strategy = ps_exit_strategy;
3315 
3316 	status = umac_cmd_cfg(fmac_dev_ctx,
3317 			      set_ps_exit_strategy_cmd,
3318 			      sizeof(*set_ps_exit_strategy_cmd));
3319 out:
3320 	if (set_ps_exit_strategy_cmd) {
3321 		nrf_wifi_osal_mem_free(set_ps_exit_strategy_cmd);
3322 	}
3323 
3324 	return status;
3325 }
3326 #endif /* NRF70_STA_MODE */
3327 
nrf_wifi_sys_fmac_stats_get(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,enum rpu_op_mode op_mode,struct rpu_sys_op_stats * stats)3328 enum nrf_wifi_status nrf_wifi_sys_fmac_stats_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
3329 						 enum rpu_op_mode op_mode,
3330 						 struct rpu_sys_op_stats *stats)
3331 {
3332 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3333 	unsigned char count = 0;
3334 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
3335 
3336 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3337 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3338 				      __func__);
3339 		goto out;
3340 	}
3341 
3342 	if (fmac_dev_ctx->stats_req == true) {
3343 		nrf_wifi_osal_log_err("%s: Stats request already pending",
3344 				      __func__);
3345 		goto out;
3346 	}
3347 
3348 	fmac_dev_ctx->stats_req = true;
3349 	fmac_dev_ctx->fw_stats = &stats->fw;
3350 
3351 	status = umac_cmd_sys_prog_stats_get(fmac_dev_ctx);
3352 
3353 	if (status != NRF_WIFI_STATUS_SUCCESS) {
3354 		goto out;
3355 	}
3356 
3357 	do {
3358 		nrf_wifi_osal_sleep_ms(1);
3359 		count++;
3360 	} while ((fmac_dev_ctx->stats_req == true) &&
3361 		 (count < NRF_WIFI_FMAC_STATS_RECV_TIMEOUT));
3362 
3363 	if (count == NRF_WIFI_FMAC_STATS_RECV_TIMEOUT) {
3364 		nrf_wifi_osal_log_err("%s: Timed out",
3365 				      __func__);
3366 		goto out;
3367 	}
3368 
3369 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
3370 
3371 	nrf_wifi_osal_mem_cpy(&stats->host,
3372 			      &sys_dev_ctx->host_stats,
3373 			      sizeof(sys_dev_ctx->host_stats));
3374 
3375 	status = NRF_WIFI_STATUS_SUCCESS;
3376 out:
3377 	return status;
3378 }
3379 
3380 
nrf_wifi_sys_fmac_phy_rf_params_init(struct nrf_wifi_phy_rf_params * prf,unsigned int package_info,unsigned char * str)3381 static int nrf_wifi_sys_fmac_phy_rf_params_init(struct nrf_wifi_phy_rf_params *prf,
3382 						unsigned int package_info,
3383 						unsigned char *str)
3384 {
3385 	int ret = -1;
3386 	unsigned int rf_param_offset = BAND_2G_LW_ED_BKF_DSSS_OFST - NRF_WIFI_RF_PARAMS_CONF_SIZE;
3387 	/* Initilaize reserved bytes */
3388 	nrf_wifi_osal_mem_set(prf,
3389 			      0x0,
3390 			      sizeof(prf));
3391 	/* Initialize PD adjust values for MCS7. Currently these 4 bytes are not being used */
3392 	prf->pd_adjust_val.pd_adjt_lb_chan = PD_ADJUST_VAL;
3393 	prf->pd_adjust_val.pd_adjt_hb_low_chan = PD_ADJUST_VAL;
3394 	prf->pd_adjust_val.pd_adjt_hb_mid_chan = PD_ADJUST_VAL;
3395 	prf->pd_adjust_val.pd_adjt_hb_high_chan = PD_ADJUST_VAL;
3396 
3397 	/* RX Gain offsets */
3398 	prf->rx_gain_offset.rx_gain_lb_chan = CTRL_PWR_OPTIMIZATIONS;
3399 	prf->rx_gain_offset.rx_gain_hb_low_chan = RX_GAIN_OFFSET_HB_LOW_CHAN;
3400 	prf->rx_gain_offset.rx_gain_hb_mid_chan = RX_GAIN_OFFSET_HB_MID_CHAN;
3401 	prf->rx_gain_offset.rx_gain_hb_high_chan = RX_GAIN_OFFSET_HB_HIGH_CHAN;
3402 
3403 	if (package_info == CSP_PACKAGE_INFO) {
3404 		prf->xo_offset.xo_freq_offset = CSP_XO_VAL;
3405 
3406 		/* Configure systematic offset value */
3407 		prf->syst_tx_pwr_offset.syst_off_lb_chan = CSP_SYSTEM_OFFSET_LB;
3408 		prf->syst_tx_pwr_offset.syst_off_hb_low_chan = CSP_SYSTEM_OFFSET_HB_CHAN_LOW;
3409 		prf->syst_tx_pwr_offset.syst_off_hb_mid_chan = CSP_SYSTEM_OFFSET_HB_CHAN_MID;
3410 		prf->syst_tx_pwr_offset.syst_off_hb_high_chan = CSP_SYSTEM_OFFSET_HB_CHAN_HIGH;
3411 
3412 		/* TX power ceiling */
3413 		prf->max_pwr_ceil.max_dsss_pwr = CSP_MAX_TX_PWR_DSSS;
3414 		prf->max_pwr_ceil.max_lb_mcs7_pwr = CSP_MAX_TX_PWR_LB_MCS7;
3415 		prf->max_pwr_ceil.max_lb_mcs0_pwr = CSP_MAX_TX_PWR_LB_MCS0;
3416 		prf->max_pwr_ceil.max_hb_low_chan_mcs7_pwr = CSP_MAX_TX_PWR_HB_LOW_CHAN_MCS7;
3417 		prf->max_pwr_ceil.max_hb_mid_chan_mcs7_pwr = CSP_MAX_TX_PWR_HB_MID_CHAN_MCS7;
3418 		prf->max_pwr_ceil.max_hb_high_chan_mcs7_pwr = CSP_MAX_TX_PWR_HB_HIGH_CHAN_MCS7;
3419 		prf->max_pwr_ceil.max_hb_low_chan_mcs0_pwr = CSP_MAX_TX_PWR_HB_LOW_CHAN_MCS0;
3420 		prf->max_pwr_ceil.max_hb_mid_chan_mcs0_pwr = CSP_MAX_TX_PWR_HB_MID_CHAN_MCS0;
3421 		prf->max_pwr_ceil.max_hb_high_chan_mcs0_pwr = CSP_MAX_TX_PWR_HB_HIGH_CHAN_MCS0;
3422 
3423 		/* Max-Min chip temperature, VT backoffs configuration */
3424 		prf->temp_volt_backoff.max_chip_temp = CSP_MAX_CHIP_TEMP;
3425 		prf->temp_volt_backoff.min_chip_temp = CSP_MIN_CHIP_TEMP;
3426 		prf->temp_volt_backoff.lb_max_pwr_bkf_hi_temp =	CSP_LB_MAX_PWR_BKF_HI_TEMP;
3427 		prf->temp_volt_backoff.lb_max_pwr_bkf_low_temp = CSP_LB_MAX_PWR_BKF_LOW_TEMP;
3428 		prf->temp_volt_backoff.hb_max_pwr_bkf_hi_temp =	CSP_HB_MAX_PWR_BKF_HI_TEMP;
3429 		prf->temp_volt_backoff.hb_max_pwr_bkf_low_temp = CSP_HB_MAX_PWR_BKF_LOW_TEMP;
3430 		prf->temp_volt_backoff.lb_vbt_lt_vlow = CSP_LB_VBT_LT_VLOW;
3431 		prf->temp_volt_backoff.hb_vbt_lt_vlow =	CSP_HB_VBT_LT_VLOW;
3432 		prf->temp_volt_backoff.lb_vbt_lt_low = CSP_LB_VBT_LT_LOW;
3433 		prf->temp_volt_backoff.hb_vbt_lt_low = CSP_HB_VBT_LT_LOW;
3434 	} else {
3435 		/** If nothing is written to OTP field corresponding to package info byte
3436 		 * or if the package info field is corrupted then the default package
3437 		 * package is QFN.
3438 		 */
3439 
3440 		/* Initialize XO */
3441 		prf->xo_offset.xo_freq_offset = QFN_XO_VAL;
3442 
3443 		/* Configure systematic offset value */
3444 		prf->syst_tx_pwr_offset.syst_off_lb_chan = QFN_SYSTEM_OFFSET_LB;
3445 		prf->syst_tx_pwr_offset.syst_off_hb_low_chan = QFN_SYSTEM_OFFSET_HB_CHAN_LOW;
3446 		prf->syst_tx_pwr_offset.syst_off_hb_mid_chan = QFN_SYSTEM_OFFSET_HB_CHAN_MID;
3447 		prf->syst_tx_pwr_offset.syst_off_hb_high_chan = QFN_SYSTEM_OFFSET_HB_CHAN_HIGH;
3448 
3449 		/* TX power ceiling */
3450 		prf->max_pwr_ceil.max_dsss_pwr = QFN_MAX_TX_PWR_DSSS;
3451 		prf->max_pwr_ceil.max_lb_mcs7_pwr = QFN_MAX_TX_PWR_LB_MCS7;
3452 		prf->max_pwr_ceil.max_lb_mcs0_pwr = QFN_MAX_TX_PWR_LB_MCS0;
3453 		prf->max_pwr_ceil.max_hb_low_chan_mcs7_pwr = QFN_MAX_TX_PWR_HB_LOW_CHAN_MCS7;
3454 		prf->max_pwr_ceil.max_hb_mid_chan_mcs7_pwr = QFN_MAX_TX_PWR_HB_MID_CHAN_MCS7;
3455 		prf->max_pwr_ceil.max_hb_high_chan_mcs7_pwr = QFN_MAX_TX_PWR_HB_HIGH_CHAN_MCS7;
3456 		prf->max_pwr_ceil.max_hb_low_chan_mcs0_pwr = QFN_MAX_TX_PWR_HB_LOW_CHAN_MCS0;
3457 		prf->max_pwr_ceil.max_hb_mid_chan_mcs0_pwr = QFN_MAX_TX_PWR_HB_MID_CHAN_MCS0;
3458 		prf->max_pwr_ceil.max_hb_high_chan_mcs0_pwr = QFN_MAX_TX_PWR_HB_HIGH_CHAN_MCS0;
3459 
3460 		/* Max-Min chip temperature, VT backoffs configuration */
3461 		prf->temp_volt_backoff.max_chip_temp = QFN_MAX_CHIP_TEMP;
3462 		prf->temp_volt_backoff.min_chip_temp = QFN_MIN_CHIP_TEMP;
3463 		prf->temp_volt_backoff.lb_max_pwr_bkf_hi_temp =	QFN_LB_MAX_PWR_BKF_HI_TEMP;
3464 		prf->temp_volt_backoff.lb_max_pwr_bkf_low_temp = QFN_LB_MAX_PWR_BKF_LOW_TEMP;
3465 		prf->temp_volt_backoff.hb_max_pwr_bkf_hi_temp =	QFN_HB_MAX_PWR_BKF_HI_TEMP;
3466 		prf->temp_volt_backoff.hb_max_pwr_bkf_low_temp = QFN_HB_MAX_PWR_BKF_LOW_TEMP;
3467 		prf->temp_volt_backoff.lb_vbt_lt_vlow =	QFN_LB_VBT_LT_VLOW;
3468 		prf->temp_volt_backoff.hb_vbt_lt_vlow =	QFN_HB_VBT_LT_VLOW;
3469 		prf->temp_volt_backoff.lb_vbt_lt_low = QFN_LB_VBT_LT_LOW;
3470 		prf->temp_volt_backoff.hb_vbt_lt_low = QFN_HB_VBT_LT_LOW;
3471 	}
3472 
3473 	ret = nrf_wifi_utils_hex_str_to_val((unsigned char *)&prf->phy_params,
3474 					    sizeof(prf->phy_params),
3475 					    str);
3476 
3477 	prf->phy_params[rf_param_offset]  = NRF70_BAND_2G_LOWER_EDGE_BACKOFF_DSSS;
3478 	prf->phy_params[rf_param_offset + 1]  = NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HT;
3479 	prf->phy_params[rf_param_offset + 2]  = NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HE;
3480 	prf->phy_params[rf_param_offset + 3]  = NRF70_BAND_2G_UPPER_EDGE_BACKOFF_DSSS;
3481 	prf->phy_params[rf_param_offset + 4]  = NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HT;
3482 	prf->phy_params[rf_param_offset + 5]  = NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HE;
3483 	prf->phy_params[rf_param_offset + 6]  = NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HT;
3484 	prf->phy_params[rf_param_offset + 7]  = NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HE;
3485 	prf->phy_params[rf_param_offset + 8]  = NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HT;
3486 	prf->phy_params[rf_param_offset + 9]  = NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HE;
3487 	prf->phy_params[rf_param_offset + 10]  = NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HT;
3488 	prf->phy_params[rf_param_offset + 11]  = NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HE;
3489 	prf->phy_params[rf_param_offset + 12]  = NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HT;
3490 	prf->phy_params[rf_param_offset + 13]  = NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HE;
3491 	prf->phy_params[rf_param_offset + 14]  = NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HT;
3492 	prf->phy_params[rf_param_offset + 15]  = NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HE;
3493 	prf->phy_params[rf_param_offset + 16]  = NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HT;
3494 	prf->phy_params[rf_param_offset + 17]  = NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HE;
3495 	prf->phy_params[rf_param_offset + 18]  = NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HT;
3496 	prf->phy_params[rf_param_offset + 19]  = NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HE;
3497 	prf->phy_params[rf_param_offset + 20]  = NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HT;
3498 	prf->phy_params[rf_param_offset + 21]  = NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HE;
3499 	prf->phy_params[rf_param_offset + 22]  = NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HT;
3500 	prf->phy_params[rf_param_offset + 23]  = NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HE;
3501 	prf->phy_params[rf_param_offset + 24]  = NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HT;
3502 	prf->phy_params[rf_param_offset + 25]  = NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HE;
3503 	prf->phy_params[rf_param_offset + 26]  = NRF70_ANT_GAIN_2G;
3504 	prf->phy_params[rf_param_offset + 27]  = NRF70_ANT_GAIN_5G_BAND1;
3505 	prf->phy_params[rf_param_offset + 28]  = NRF70_ANT_GAIN_5G_BAND2;
3506 	prf->phy_params[rf_param_offset + 29]  = NRF70_ANT_GAIN_5G_BAND3;
3507 	prf->phy_params[rf_param_offset + 30]  = NRF70_PCB_LOSS_2G;
3508 	prf->phy_params[rf_param_offset + 31]  = NRF70_PCB_LOSS_5G_BAND1;
3509 	prf->phy_params[rf_param_offset + 32]  = NRF70_PCB_LOSS_5G_BAND2;
3510 	prf->phy_params[rf_param_offset + 33]  = NRF70_PCB_LOSS_5G_BAND3;
3511 
3512 	return(ret);
3513 }
3514 
3515 
nrf_wifi_sys_fmac_rf_params_get(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_phy_rf_params * phy_rf_params)3516 enum nrf_wifi_status nrf_wifi_sys_fmac_rf_params_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
3517 						     struct nrf_wifi_phy_rf_params *phy_rf_params)
3518 {
3519 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3520 	struct nrf_wifi_fmac_otp_info otp_info;
3521 	unsigned int ft_prog_ver;
3522 	int ret = -1;
3523 	/* If package_info is not written to OTP then the default value will be 0xFF. */
3524 	unsigned int package_info = 0xFFFFFFFF;
3525 	struct nrf_wifi_tx_pwr_ceil_params *tx_pwr_ceil_params;
3526 	unsigned char backoff_2g_dsss = 0, backoff_2g_ofdm = 0;
3527 	unsigned char backoff_5g_lowband = 0, backoff_5g_midband = 0, backoff_5g_highband = 0;
3528 
3529 	if (!fmac_dev_ctx || !phy_rf_params) {
3530 		nrf_wifi_osal_log_err("%s: Invalid parameters",
3531 				      __func__);
3532 		goto out;
3533 	}
3534 
3535 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3536 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3537 				      __func__);
3538 		goto out;
3539 	}
3540 
3541 	tx_pwr_ceil_params = fmac_dev_ctx->tx_pwr_ceil_params;
3542 
3543 	nrf_wifi_osal_mem_set(&otp_info,
3544 			      0xFF,
3545 			      sizeof(otp_info));
3546 
3547 	status = nrf_wifi_hal_otp_info_get(fmac_dev_ctx->hal_dev_ctx,
3548 					   &otp_info.info,
3549 					   &otp_info.flags);
3550 
3551 	if (status != NRF_WIFI_STATUS_SUCCESS) {
3552 		nrf_wifi_osal_log_err("%s: Fetching of RPU OTP information failed",
3553 				      __func__);
3554 		goto out;
3555 	}
3556 
3557 	status = nrf_wifi_hal_otp_ft_prog_ver_get(fmac_dev_ctx->hal_dev_ctx,
3558 						  &ft_prog_ver);
3559 	if (status != NRF_WIFI_STATUS_SUCCESS) {
3560 		nrf_wifi_osal_log_err("%s: Fetching of FT program version failed",
3561 				      __func__);
3562 		goto out;
3563 	}
3564 
3565 	status = nrf_wifi_hal_otp_pack_info_get(fmac_dev_ctx->hal_dev_ctx,
3566 						&package_info);
3567 	if (status != NRF_WIFI_STATUS_SUCCESS) {
3568 		nrf_wifi_osal_log_err("%s: Fetching of Package info failed",
3569 				      __func__);
3570 		goto out;
3571 	}
3572 
3573 	ret = nrf_wifi_sys_fmac_phy_rf_params_init(phy_rf_params,
3574 					      package_info,
3575 					      NRF_WIFI_SYS_DEF_RF_PARAMS);
3576 
3577 	if (ret == -1) {
3578 		nrf_wifi_osal_log_err("%s: Initialization of RF params with default values failed",
3579 				      __func__);
3580 		status = NRF_WIFI_STATUS_FAIL;
3581 		goto out;
3582 	}
3583 	if (!(otp_info.flags & (~CALIB_XO_FLAG_MASK))) {
3584 		nrf_wifi_osal_mem_cpy(&phy_rf_params->xo_offset.xo_freq_offset,
3585 				      (char *)otp_info.info.calib + OTP_OFF_CALIB_XO,
3586 				      OTP_SZ_CALIB_XO);
3587 
3588 	}
3589 
3590 	ft_prog_ver = (ft_prog_ver & FT_PROG_VER_MASK) >> 16;
3591 
3592 	if (ft_prog_ver == FT_PROG_VER1) {
3593 		backoff_2g_dsss = FT_PROG_VER1_2G_DSSS_TXCEIL_BKOFF;
3594 		backoff_2g_ofdm = FT_PROG_VER1_2G_OFDM_TXCEIL_BKOFF;
3595 		backoff_5g_lowband = FT_PROG_VER1_5G_LOW_OFDM_TXCEIL_BKOFF;
3596 		backoff_5g_midband = FT_PROG_VER1_5G_MID_OFDM_TXCEIL_BKOFF;
3597 		backoff_5g_highband = FT_PROG_VER1_5G_HIGH_OFDM_TXCEIL_BKOFF;
3598 	} else if (ft_prog_ver == FT_PROG_VER2) {
3599 		backoff_2g_dsss = FT_PROG_VER2_2G_DSSS_TXCEIL_BKOFF;
3600 		backoff_2g_ofdm = FT_PROG_VER2_2G_OFDM_TXCEIL_BKOFF;
3601 		backoff_5g_lowband = FT_PROG_VER2_5G_LOW_OFDM_TXCEIL_BKOFF;
3602 		backoff_5g_midband = FT_PROG_VER2_5G_MID_OFDM_TXCEIL_BKOFF;
3603 		backoff_5g_highband = FT_PROG_VER2_5G_HIGH_OFDM_TXCEIL_BKOFF;
3604 	} else if (ft_prog_ver == FT_PROG_VER3) {
3605 		backoff_2g_dsss = FT_PROG_VER3_2G_DSSS_TXCEIL_BKOFF;
3606 		backoff_2g_ofdm = FT_PROG_VER3_2G_OFDM_TXCEIL_BKOFF;
3607 		backoff_5g_lowband = FT_PROG_VER3_5G_LOW_OFDM_TXCEIL_BKOFF;
3608 		backoff_5g_midband = FT_PROG_VER3_5G_MID_OFDM_TXCEIL_BKOFF;
3609 		backoff_5g_highband = FT_PROG_VER3_5G_HIGH_OFDM_TXCEIL_BKOFF;
3610 	}
3611 	phy_rf_params->max_pwr_ceil.max_dsss_pwr =
3612 	MIN(tx_pwr_ceil_params->max_pwr_2g_dsss, phy_rf_params->max_pwr_ceil.max_dsss_pwr)
3613 	- backoff_2g_dsss;
3614 	phy_rf_params->max_pwr_ceil.max_lb_mcs7_pwr =
3615 	MIN(tx_pwr_ceil_params->max_pwr_2g_mcs7, phy_rf_params->max_pwr_ceil.max_lb_mcs7_pwr)
3616 	- backoff_2g_ofdm;
3617 	phy_rf_params->max_pwr_ceil.max_lb_mcs0_pwr =
3618 	MIN(tx_pwr_ceil_params->max_pwr_2g_mcs0, phy_rf_params->max_pwr_ceil.max_lb_mcs0_pwr)
3619 	- backoff_2g_ofdm;
3620 #ifndef NRF70_2_4G_ONLY
3621 	phy_rf_params->max_pwr_ceil.max_hb_low_chan_mcs7_pwr =
3622 	MIN(tx_pwr_ceil_params->max_pwr_5g_low_mcs7,
3623 		phy_rf_params->max_pwr_ceil.max_hb_low_chan_mcs7_pwr) - backoff_5g_lowband;
3624 	phy_rf_params->max_pwr_ceil.max_hb_mid_chan_mcs7_pwr =
3625 	MIN(tx_pwr_ceil_params->max_pwr_5g_mid_mcs7,
3626 		phy_rf_params->max_pwr_ceil.max_hb_mid_chan_mcs7_pwr) - backoff_5g_midband;
3627 	phy_rf_params->max_pwr_ceil.max_hb_high_chan_mcs7_pwr =
3628 	MIN(tx_pwr_ceil_params->max_pwr_5g_high_mcs7,
3629 		phy_rf_params->max_pwr_ceil.max_hb_high_chan_mcs7_pwr) - backoff_5g_highband;
3630 	phy_rf_params->max_pwr_ceil.max_hb_low_chan_mcs0_pwr =
3631 	MIN(tx_pwr_ceil_params->max_pwr_5g_low_mcs0,
3632 		phy_rf_params->max_pwr_ceil.max_hb_low_chan_mcs0_pwr) - backoff_5g_lowband;
3633 	phy_rf_params->max_pwr_ceil.max_hb_mid_chan_mcs0_pwr =
3634 	MIN(tx_pwr_ceil_params->max_pwr_5g_mid_mcs0,
3635 	        phy_rf_params->max_pwr_ceil.max_hb_mid_chan_mcs0_pwr) - backoff_5g_midband;
3636 	phy_rf_params->max_pwr_ceil.max_hb_high_chan_mcs0_pwr =
3637 	MIN(tx_pwr_ceil_params->max_pwr_5g_high_mcs0,
3638 	        phy_rf_params->max_pwr_ceil.max_hb_high_chan_mcs0_pwr) - backoff_5g_highband;
3639 #endif /* NRF70_2_4G_ONLY */
3640 
3641 	status = NRF_WIFI_STATUS_SUCCESS;
3642 out:
3643 	return status;
3644 }
3645 
3646 
3647 #ifdef NRF70_SYSTEM_WITH_RAW_MODES
nrf_wifi_sys_fmac_set_mode(void * dev_ctx,unsigned char if_idx,unsigned char mode)3648 enum nrf_wifi_status nrf_wifi_sys_fmac_set_mode(void *dev_ctx,
3649 						unsigned char if_idx,
3650 						unsigned char mode)
3651 {
3652 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3653 	struct nrf_wifi_cmd_raw_config_mode *umac_cmd_data = NULL;
3654 	struct host_rpu_msg *umac_cmd = NULL;
3655 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = dev_ctx;
3656 	int len = 0;
3657 
3658 	if (!fmac_dev_ctx) {
3659 		nrf_wifi_osal_log_err("%s: Invalid parameters",
3660 				      __func__);
3661 		goto out;
3662 	}
3663 
3664 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3665 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3666 				      __func__);
3667 		goto out;
3668 	}
3669 
3670 	len = sizeof(*umac_cmd_data);
3671 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
3672 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
3673 				  len);
3674 
3675 	if (!umac_cmd) {
3676 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
3677 				      __func__);
3678 		goto out;
3679 	}
3680 
3681 	umac_cmd_data = (struct nrf_wifi_cmd_raw_config_mode *)(umac_cmd->msg);
3682 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_RAW_CONFIG_MODE;
3683 	umac_cmd_data->sys_head.len = len;
3684 	umac_cmd_data->if_index = if_idx;
3685 	umac_cmd_data->op_mode = mode;
3686 
3687 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
3688 					    umac_cmd,
3689 					    (sizeof(*umac_cmd) + len));
3690 out:
3691 	return status;
3692 }
3693 #endif
3694 
3695 #if defined(NRF70_RAW_DATA_TX) || defined(NRF70_RAW_DATA_RX)
nrf_wifi_sys_fmac_set_channel(void * dev_ctx,unsigned char if_idx,unsigned int channel)3696 enum nrf_wifi_status nrf_wifi_sys_fmac_set_channel(void *dev_ctx,
3697 						   unsigned char if_idx,
3698 						   unsigned int channel)
3699 {
3700 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3701 	struct nrf_wifi_cmd_set_channel *umac_cmd_data = NULL;
3702 	struct host_rpu_msg *umac_cmd = NULL;
3703 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = dev_ctx;
3704 	int len = 0;
3705 
3706 	if (!fmac_dev_ctx) {
3707 		nrf_wifi_osal_log_err("%s: Invalid parameters",
3708 				      __func__);
3709 		goto out;
3710 	}
3711 
3712 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3713 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3714 				      __func__);
3715 		goto out;
3716 	}
3717 
3718 	len = sizeof(*umac_cmd_data);
3719 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
3720 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
3721 				  len);
3722 
3723 	if (!umac_cmd) {
3724 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
3725 				      __func__);
3726 		goto out;
3727 	}
3728 
3729 	umac_cmd_data = (struct nrf_wifi_cmd_set_channel *)(umac_cmd->msg);
3730 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_CHANNEL;
3731 	umac_cmd_data->sys_head.len = len;
3732 	umac_cmd_data->if_index = if_idx;
3733 	umac_cmd_data->chan.primary_num = channel;
3734 
3735 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
3736 					    umac_cmd,
3737 					    (sizeof(*umac_cmd) + len));
3738 out:
3739 	return status;
3740 }
3741 #endif /* NRF70_RAW_DATA_TX || NRF70_RAW_DATA_RX */
3742 
3743 #if defined(NRF70_RAW_DATA_RX) || defined(NRF70_PROMISC_DATA_RX)
nrf_wifi_sys_fmac_set_packet_filter(void * dev_ctx,unsigned char filter,unsigned char if_idx,unsigned short buffer_size)3744 enum nrf_wifi_status nrf_wifi_sys_fmac_set_packet_filter(void *dev_ctx, unsigned char filter,
3745 							 unsigned char if_idx,
3746 							 unsigned short buffer_size)
3747 {
3748 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3749 	struct nrf_wifi_cmd_raw_config_filter *umac_cmd_data = NULL;
3750 	struct host_rpu_msg *umac_cmd = NULL;
3751 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = dev_ctx;
3752 	int len = 0;
3753 
3754 	if (!fmac_dev_ctx) {
3755 		nrf_wifi_osal_log_err("%s: Invalid parameters\n",
3756 				      __func__);
3757 		goto out;
3758 	}
3759 
3760 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3761 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3762 				      __func__);
3763 		goto out;
3764 	}
3765 
3766 	len = sizeof(*umac_cmd_data);
3767 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
3768 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
3769 				  len);
3770 	if (!umac_cmd) {
3771 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed\n",
3772 				      __func__);
3773 		goto out;
3774 	}
3775 
3776 	umac_cmd_data = (struct nrf_wifi_cmd_raw_config_filter *)(umac_cmd->msg);
3777 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_RAW_CONFIG_FILTER;
3778 	umac_cmd_data->sys_head.len = len;
3779 	umac_cmd_data->if_index = if_idx;
3780 	umac_cmd_data->filter = filter;
3781 	umac_cmd_data->capture_len = buffer_size;
3782 
3783 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
3784 					    umac_cmd,
3785 					    (sizeof(*umac_cmd) + len));
3786 out:
3787 	return status;
3788 }
3789 #endif /* NRF70_RAW_DATA_RX || NRF70_PROMISC_DATA_RX */
3790 
3791 
3792 #ifdef NRF70_UTIL
nrf_wifi_sys_fmac_set_tx_rate(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char rate_flag,int data_rate)3793 enum nrf_wifi_status nrf_wifi_sys_fmac_set_tx_rate(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
3794 						   unsigned char rate_flag,
3795 						   int data_rate)
3796 {
3797 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3798 	struct host_rpu_msg *umac_cmd = NULL;
3799 	struct nrf_wifi_cmd_fix_tx_rate *umac_cmd_data = NULL;
3800 	int len = 0;
3801 
3802 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3803 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3804 				      __func__);
3805 		goto out;
3806 	}
3807 
3808 	len = sizeof(*umac_cmd_data);
3809 
3810 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
3811 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
3812 				  len);
3813 
3814 	if (!umac_cmd) {
3815 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
3816 				      __func__);
3817 		goto out;
3818 	}
3819 
3820 	umac_cmd_data = (struct nrf_wifi_cmd_fix_tx_rate *)(umac_cmd->msg);
3821 
3822 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_TX_FIX_DATA_RATE;
3823 	umac_cmd_data->sys_head.len = len;
3824 
3825 	umac_cmd_data->rate_flags = rate_flag;
3826 	umac_cmd_data->fixed_rate = data_rate;
3827 
3828 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
3829 					    umac_cmd,
3830 					    (sizeof(*umac_cmd) + len));
3831 out:
3832 	return status;
3833 }
3834 
nrf_wifi_sys_fmac_conf_ltf_gi(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char he_ltf,unsigned char he_gi,unsigned char enabled)3835 enum nrf_wifi_status nrf_wifi_sys_fmac_conf_ltf_gi(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
3836 						   unsigned char he_ltf,
3837 						   unsigned char he_gi,
3838 						   unsigned char enabled)
3839 {
3840 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3841 
3842 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3843 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3844 				      __func__);
3845 		goto out;
3846 	}
3847 
3848 	status = umac_cmd_sys_he_ltf_gi(fmac_dev_ctx, he_ltf, he_gi, enabled);
3849 
3850 out:
3851 	return status;
3852 }
3853 
3854 #ifdef NRF_WIFI_LOW_POWER
nrf_wifi_sys_fmac_get_host_rpu_ps_ctrl_state(void * dev_ctx,int * rpu_ps_ctrl_state)3855 enum nrf_wifi_status nrf_wifi_sys_fmac_get_host_rpu_ps_ctrl_state(void *dev_ctx,
3856 								  int *rpu_ps_ctrl_state)
3857 {
3858 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3859 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
3860 
3861 	fmac_dev_ctx = dev_ctx;
3862 
3863 	if (!fmac_dev_ctx || !rpu_ps_ctrl_state) {
3864 		nrf_wifi_osal_log_err("%s: Invalid parameters",
3865 				      __func__);
3866 		goto out;
3867 	}
3868 
3869 	if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_SYS) {
3870 		nrf_wifi_osal_log_err("%s: Invalid op mode",
3871 				      __func__);
3872 		goto out;
3873 	}
3874 
3875 	status = nrf_wifi_hal_get_rpu_ps_state(fmac_dev_ctx->hal_dev_ctx,
3876 					       rpu_ps_ctrl_state);
3877 
3878 	if (status != NRF_WIFI_STATUS_SUCCESS) {
3879 		nrf_wifi_osal_log_err("%s: Fetching of RPU PS state failed",
3880 				      __func__);
3881 		goto out;
3882 	}
3883 out:
3884 	return status;
3885 }
3886 #endif /* NRF_WIFI_LOW_POWER */
3887 #endif /* NRF70_UTIL */
3888