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