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 * HAL Layer of the Wi-Fi driver.
10 */
11
12 #include "queue.h"
13 #include "common/hal_structs_common.h"
14 #include "common/hal_common.h"
15 #include "common/hal_reg.h"
16 #include "common/hal_mem.h"
17 #include "common/hal_interrupt.h"
18 #include "common/pal.h"
19
20 #ifdef NRF_WIFI_LOW_POWER
21 #ifdef NRF_WIFI_RPU_RECOVERY
did_rpu_had_sleep_opp(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)22 static void did_rpu_had_sleep_opp(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
23 {
24 unsigned int deassert_time_diff_ms = nrf_wifi_osal_time_elapsed_ms(
25 hal_dev_ctx->last_wakeup_now_deasserted_time_ms);
26
27 if (deassert_time_diff_ms > NRF_WIFI_RPU_MIN_TIME_TO_ENTER_SLEEP_MS) {
28 hal_dev_ctx->last_rpu_sleep_opp_time_ms =
29 hal_dev_ctx->last_wakeup_now_deasserted_time_ms;
30 }
31 }
32 #endif /* NRF_WIFI_RPU_RECOVERY */
33
hal_rpu_ps_wake(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)34 enum nrf_wifi_status hal_rpu_ps_wake(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
35 {
36 unsigned int reg_val = 0;
37 unsigned int rpu_ps_state_mask = 0;
38 unsigned long start_time_us = 0;
39 unsigned long idle_time_start_us = 0;
40 unsigned long idle_time_us = 0;
41 unsigned long elapsed_time_sec = 0;
42 unsigned long elapsed_time_usec = 0;
43 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
44
45 if (!hal_dev_ctx) {
46 nrf_wifi_osal_log_err("%s: Invalid parameters",
47 __func__);
48 return status;
49 }
50
51
52 /* If the FW is not yet booted up (e.g. during the FW load stage of Host FW load)
53 * then skip the RPU wake attempt since RPU sleep/wake kicks in only after FW boot
54 */
55 if (!hal_dev_ctx->rpu_fw_booted)
56 return NRF_WIFI_STATUS_SUCCESS;
57
58 if (hal_dev_ctx->rpu_ps_state == RPU_PS_STATE_AWAKE) {
59 status = NRF_WIFI_STATUS_SUCCESS;
60
61 goto out;
62 }
63
64 nrf_wifi_bal_rpu_ps_wake(hal_dev_ctx->bal_dev_ctx);
65 #ifdef NRF_WIFI_RPU_RECOVERY
66 hal_dev_ctx->is_wakeup_now_asserted = true;
67 hal_dev_ctx->last_wakeup_now_asserted_time_ms =
68 nrf_wifi_osal_time_get_curr_ms();
69 #endif /* NRF_WIFI_RPU_RECOVERY */
70 start_time_us = nrf_wifi_osal_time_get_curr_us();
71
72 rpu_ps_state_mask = ((1 << RPU_REG_BIT_PS_STATE) |
73 (1 << RPU_REG_BIT_READY_STATE));
74
75 /* Add a delay to avoid a race condition in the RPU */
76 /* TODO: Reduce to 200 us after sleep has been stabilized */
77 nrf_wifi_osal_delay_us(1000);
78
79 do {
80 /* Poll the RPU PS state */
81 reg_val = nrf_wifi_bal_rpu_ps_status(hal_dev_ctx->bal_dev_ctx);
82
83 if ((reg_val & rpu_ps_state_mask) == rpu_ps_state_mask) {
84 status = NRF_WIFI_STATUS_SUCCESS;
85 break;
86 }
87
88 idle_time_start_us = nrf_wifi_osal_time_get_curr_us();
89
90 do {
91 idle_time_us = nrf_wifi_osal_time_elapsed_us(idle_time_start_us);
92 } while ((idle_time_us / 1000) < RPU_PS_WAKE_INTERVAL_MS);
93
94 elapsed_time_usec = nrf_wifi_osal_time_elapsed_us(start_time_us);
95 elapsed_time_sec = (elapsed_time_usec / 1000000);
96 } while (elapsed_time_sec < RPU_PS_WAKE_TIMEOUT_S);
97
98 if (status != NRF_WIFI_STATUS_SUCCESS) {
99 nrf_wifi_osal_log_err("%s: RPU is not ready for more than %d sec,"
100 "reg_val = 0x%X rpu_ps_state_mask = 0x%X",
101 __func__,
102 RPU_PS_WAKE_TIMEOUT_S,
103 reg_val,
104 rpu_ps_state_mask);
105 #ifdef NRF_WIFI_RPU_RECOVERY
106 nrf_wifi_osal_tasklet_schedule(hal_dev_ctx->recovery_tasklet);
107 #endif /* NRF_WIFI_RPU_RECOVERY */
108 goto out;
109 }
110 hal_dev_ctx->rpu_ps_state = RPU_PS_STATE_AWAKE;
111 #ifdef NRF_WIFI_RPU_RECOVERY
112 did_rpu_had_sleep_opp(hal_dev_ctx);
113 #endif /* NRF_WIFI_RPU_RECOVERY */
114 #ifdef NRF_WIFI_RPU_RECOVERY_PS_STATE_DEBUG
115 nrf_wifi_osal_log_info("%s: RPU PS state is AWAKE\n",
116 __func__);
117 #endif /* NRF_WIFI_RPU_RECOVERY_PS_STATE_DEBUG */
118
119 out:
120
121 nrf_wifi_osal_timer_schedule(hal_dev_ctx->rpu_ps_timer,
122 NRF70_RPU_PS_IDLE_TIMEOUT_MS);
123 return status;
124 }
125
126
hal_rpu_ps_sleep(unsigned long data)127 static void hal_rpu_ps_sleep(unsigned long data)
128 {
129 struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL;
130 unsigned long flags = 0;
131
132 hal_dev_ctx = (struct nrf_wifi_hal_dev_ctx *)data;
133
134 nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->rpu_ps_lock,
135 &flags);
136
137 nrf_wifi_bal_rpu_ps_sleep(hal_dev_ctx->bal_dev_ctx);
138 #ifdef NRF_WIFI_RPU_RECOVERY
139 hal_dev_ctx->is_wakeup_now_asserted = false;
140 hal_dev_ctx->last_wakeup_now_deasserted_time_ms =
141 nrf_wifi_osal_time_get_curr_ms();
142 #endif /* NRF_WIFI_RPU_RECOVERY */
143 hal_dev_ctx->rpu_ps_state = RPU_PS_STATE_ASLEEP;
144
145 #ifdef NRF_WIFI_RPU_RECOVERY_PS_STATE_DEBUG
146 nrf_wifi_osal_log_info("%s: RPU PS state is ASLEEP\n",
147 __func__);
148 #endif /* NRF_WIFI_RPU_RECOVERY_PS_STATE_DEBUG */
149 nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->rpu_ps_lock,
150 &flags);
151 }
152
153
hal_rpu_ps_init(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)154 enum nrf_wifi_status hal_rpu_ps_init(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
155 {
156 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
157
158 hal_dev_ctx->rpu_ps_lock = nrf_wifi_osal_spinlock_alloc();
159
160 if (!hal_dev_ctx->rpu_ps_lock) {
161 nrf_wifi_osal_log_err("%s: Unable to allocate lock",
162 __func__);
163 goto out;
164 }
165
166 nrf_wifi_osal_spinlock_init(hal_dev_ctx->rpu_ps_lock);
167
168 hal_dev_ctx->rpu_ps_timer = nrf_wifi_osal_timer_alloc();
169
170 if (!hal_dev_ctx->rpu_ps_timer) {
171 nrf_wifi_osal_log_err("%s: Unable to allocate timer",
172 __func__);
173 nrf_wifi_osal_spinlock_free(hal_dev_ctx->rpu_ps_lock);
174 goto out;
175 }
176
177 nrf_wifi_osal_timer_init(hal_dev_ctx->rpu_ps_timer,
178 hal_rpu_ps_sleep,
179 (unsigned long)hal_dev_ctx);
180
181 hal_dev_ctx->rpu_ps_state = RPU_PS_STATE_ASLEEP;
182 hal_dev_ctx->dbg_enable = true;
183
184 status = NRF_WIFI_STATUS_SUCCESS;
185 out:
186 return status;
187 }
188
189
hal_rpu_ps_deinit(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)190 static void hal_rpu_ps_deinit(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
191 {
192 nrf_wifi_osal_timer_kill(hal_dev_ctx->rpu_ps_timer);
193
194 nrf_wifi_osal_timer_free(hal_dev_ctx->rpu_ps_timer);
195
196 nrf_wifi_osal_spinlock_free(hal_dev_ctx->rpu_ps_lock);
197 }
198
nrf_wifi_hal_get_rpu_ps_state(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,int * rpu_ps_ctrl_state)199 enum nrf_wifi_status nrf_wifi_hal_get_rpu_ps_state(
200 struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
201 int *rpu_ps_ctrl_state)
202 {
203 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
204
205 if (!hal_dev_ctx) {
206 nrf_wifi_osal_log_err("%s: Invalid parameters",
207 __func__);
208 goto out;
209 }
210
211 *rpu_ps_ctrl_state = hal_dev_ctx->rpu_ps_state;
212
213 return NRF_WIFI_STATUS_SUCCESS;
214 out:
215 return status;
216 }
217 #endif /* NRF_WIFI_LOW_POWER */
218
219
hal_rpu_hpq_is_empty(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,struct host_rpu_hpq * hpq)220 static bool hal_rpu_hpq_is_empty(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
221 struct host_rpu_hpq *hpq)
222 {
223 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
224 unsigned int val = 0;
225
226 status = hal_rpu_reg_read(hal_dev_ctx,
227 &val,
228 hpq->dequeue_addr);
229
230 if (status != NRF_WIFI_STATUS_SUCCESS) {
231 nrf_wifi_osal_log_err("%s: Read from dequeue address failed, val (0x%X)",
232 __func__,
233 val);
234 return true;
235 }
236
237 if (val) {
238 return false;
239 }
240
241 return true;
242 }
243
244
hal_rpu_ready(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,enum NRF_WIFI_HAL_MSG_TYPE msg_type)245 static enum nrf_wifi_status hal_rpu_ready(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
246 enum NRF_WIFI_HAL_MSG_TYPE msg_type)
247 {
248 bool is_empty = false;
249 struct host_rpu_hpq *avl_buf_q = NULL;
250
251 if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) {
252 avl_buf_q = &hal_dev_ctx->rpu_info.hpqm_info.cmd_avl_queue;
253 } else {
254 nrf_wifi_osal_log_err("%s: Invalid msg type %d",
255 __func__,
256 msg_type);
257
258 return NRF_WIFI_STATUS_FAIL;
259 }
260
261 /* Check if any command pointers are available to post a message */
262 is_empty = hal_rpu_hpq_is_empty(hal_dev_ctx,
263 avl_buf_q);
264
265 if (is_empty == true) {
266 return NRF_WIFI_STATUS_FAIL;
267 }
268
269 return NRF_WIFI_STATUS_SUCCESS;
270 }
271
272
hal_rpu_ready_wait(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,enum NRF_WIFI_HAL_MSG_TYPE msg_type)273 static enum nrf_wifi_status hal_rpu_ready_wait(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
274 enum NRF_WIFI_HAL_MSG_TYPE msg_type)
275 {
276 unsigned long start_time_us = 0;
277 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
278
279 start_time_us = nrf_wifi_osal_time_get_curr_us();
280
281 while (hal_rpu_ready(hal_dev_ctx, msg_type) != NRF_WIFI_STATUS_SUCCESS) {
282 if (nrf_wifi_osal_time_elapsed_us(start_time_us) >= MAX_HAL_RPU_READY_WAIT) {
283 nrf_wifi_osal_log_err("%s: Timed out waiting (msg_type = %d)",
284 __func__,
285 msg_type);
286 goto out;
287 }
288 }
289
290 status = NRF_WIFI_STATUS_SUCCESS;
291 out:
292 return status;
293 }
294
295
hal_rpu_msg_trigger(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)296 static enum nrf_wifi_status hal_rpu_msg_trigger(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
297 {
298 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
299
300 status = hal_rpu_reg_write(hal_dev_ctx,
301 RPU_REG_INT_TO_MCU_CTRL,
302 (hal_dev_ctx->num_cmds | 0x7fff0000));
303
304 if (status != NRF_WIFI_STATUS_SUCCESS) {
305 nrf_wifi_osal_log_err("%s: Writing to MCU cmd register failed",
306 __func__);
307 goto out;
308 }
309
310 hal_dev_ctx->num_cmds++;
311 out:
312 return status;
313 }
314
315
hal_rpu_msg_post(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,enum NRF_WIFI_HAL_MSG_TYPE msg_type,unsigned int queue_id,unsigned int msg_addr)316 enum nrf_wifi_status hal_rpu_msg_post(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
317 enum NRF_WIFI_HAL_MSG_TYPE msg_type,
318 unsigned int queue_id,
319 unsigned int msg_addr)
320 {
321 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
322 struct host_rpu_hpq *busy_queue = NULL;
323
324 if (queue_id >= MAX_NUM_OF_RX_QUEUES) {
325 nrf_wifi_osal_log_err("%s: Invalid queue_id (%d)",
326 __func__,
327 queue_id);
328 goto out;
329 }
330
331 if ((msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) ||
332 (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_TX)) {
333 busy_queue = &hal_dev_ctx->rpu_info.hpqm_info.cmd_busy_queue;
334 } else if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX) {
335 busy_queue = &hal_dev_ctx->rpu_info.hpqm_info.rx_buf_busy_queue[queue_id];
336 } else {
337 nrf_wifi_osal_log_err("%s: Invalid msg_type (%d)",
338 __func__,
339 msg_type);
340 goto out;
341 }
342
343 /* Copy the address, to which information was posted,
344 * to the busy queue.
345 */
346 status = hal_rpu_hpq_enqueue(hal_dev_ctx,
347 busy_queue,
348 msg_addr);
349
350 if (status != NRF_WIFI_STATUS_SUCCESS) {
351 nrf_wifi_osal_log_err("%s: Queueing of message to RPU failed",
352 __func__);
353 goto out;
354 }
355
356 if (msg_type != NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX) {
357 /* Indicate to the RPU that the information has been posted */
358 status = hal_rpu_msg_trigger(hal_dev_ctx);
359
360 if (status != NRF_WIFI_STATUS_SUCCESS) {
361 nrf_wifi_osal_log_err("%s: Posting command to RPU failed",
362 __func__);
363 goto out;
364 }
365 }
366 out:
367 return status;
368 }
369
370
hal_rpu_msg_get_addr(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,enum NRF_WIFI_HAL_MSG_TYPE msg_type,unsigned int * msg_addr)371 static enum nrf_wifi_status hal_rpu_msg_get_addr(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
372 enum NRF_WIFI_HAL_MSG_TYPE msg_type,
373 unsigned int *msg_addr)
374 {
375 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
376 struct host_rpu_hpq *avl_queue = NULL;
377
378 if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) {
379 avl_queue = &hal_dev_ctx->rpu_info.hpqm_info.cmd_avl_queue;
380 } else {
381 nrf_wifi_osal_log_err("%s: Invalid msg_type (%d)",
382 __func__,
383 msg_type);
384 goto out;
385 }
386
387 status = hal_rpu_hpq_dequeue(hal_dev_ctx,
388 avl_queue,
389 msg_addr);
390
391 if (status != NRF_WIFI_STATUS_SUCCESS) {
392 nrf_wifi_osal_log_err("%s: Dequeue of address failed msg_addr 0x%X",
393 __func__,
394 *msg_addr);
395 *msg_addr = 0;
396 goto out;
397 }
398 out:
399 return status;
400 }
401
402
hal_rpu_msg_write(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,enum NRF_WIFI_HAL_MSG_TYPE msg_type,void * msg,unsigned int len)403 static enum nrf_wifi_status hal_rpu_msg_write(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
404 enum NRF_WIFI_HAL_MSG_TYPE msg_type,
405 void *msg,
406 unsigned int len)
407 {
408 unsigned int msg_addr = 0;
409 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
410
411 /* Get the address from the RPU to which
412 * the command needs to be copied to
413 */
414 status = hal_rpu_msg_get_addr(hal_dev_ctx,
415 msg_type,
416 &msg_addr);
417
418 if (status != NRF_WIFI_STATUS_SUCCESS) {
419 nrf_wifi_osal_log_err("%s: Getting address (0x%X) to post message failed",
420 __func__,
421 msg_addr);
422 goto out;
423 }
424
425 /* Copy the information to the suggested address */
426 status = hal_rpu_mem_write(hal_dev_ctx,
427 msg_addr,
428 msg,
429 len);
430
431 if (status != NRF_WIFI_STATUS_SUCCESS) {
432 nrf_wifi_osal_log_err("%s: Copying information to RPU failed",
433 __func__);
434 goto out;
435 }
436
437 /* Post the updated information to the RPU */
438 status = hal_rpu_msg_post(hal_dev_ctx,
439 msg_type,
440 0,
441 msg_addr);
442
443 if (status != NRF_WIFI_STATUS_SUCCESS) {
444 nrf_wifi_osal_log_err("%s: Posting command to RPU failed",
445 __func__);
446 goto out;
447 }
448
449 out:
450 return status;
451 }
452
453
hal_rpu_cmd_process_queue(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)454 static enum nrf_wifi_status hal_rpu_cmd_process_queue(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
455 {
456 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
457 struct nrf_wifi_hal_msg *cmd = NULL;
458
459 while ((cmd = nrf_wifi_utils_q_dequeue(hal_dev_ctx->cmd_q))) {
460 status = hal_rpu_ready_wait(hal_dev_ctx,
461 NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL);
462
463 if (status != NRF_WIFI_STATUS_SUCCESS) {
464 nrf_wifi_osal_log_err("%s: Timeout waiting to get free cmd buff from RPU",
465 __func__);
466 nrf_wifi_osal_mem_free(cmd);
467 cmd = NULL;
468 continue;
469 }
470
471 status = hal_rpu_msg_write(hal_dev_ctx,
472 NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL,
473 cmd->data,
474 cmd->len);
475
476 if (status != NRF_WIFI_STATUS_SUCCESS) {
477 nrf_wifi_osal_log_err("%s: Writing command to RPU failed",
478 __func__);
479 nrf_wifi_osal_mem_free(cmd);
480 cmd = NULL;
481 continue;
482 }
483
484 /* Free the command data and command */
485 nrf_wifi_osal_mem_free(cmd);
486 cmd = NULL;
487 }
488
489 return status;
490 }
491
492
hal_rpu_cmd_queue(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,void * cmd,unsigned int cmd_size)493 static enum nrf_wifi_status hal_rpu_cmd_queue(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
494 void *cmd,
495 unsigned int cmd_size)
496 {
497 int len = 0;
498 int size = 0;
499 char *data = NULL;
500 struct nrf_wifi_hal_msg *hal_msg = NULL;
501 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
502
503 len = cmd_size;
504 data = cmd;
505
506 if (len > hal_dev_ctx->hpriv->cfg_params.max_cmd_size) {
507 while (len > 0) {
508 if (len > hal_dev_ctx->hpriv->cfg_params.max_cmd_size) {
509 size = hal_dev_ctx->hpriv->cfg_params.max_cmd_size;
510 } else {
511 size = len;
512 }
513
514 hal_msg = nrf_wifi_osal_mem_zalloc(sizeof(*hal_msg) + size);
515
516 if (!hal_msg) {
517 nrf_wifi_osal_log_err("%s: Unable to alloc buff for frag HAL cmd",
518 __func__);
519 status = NRF_WIFI_STATUS_FAIL;
520 goto out;
521 }
522
523 nrf_wifi_osal_mem_cpy(hal_msg->data,
524 data,
525 size);
526
527 hal_msg->len = size;
528
529 status = nrf_wifi_utils_q_enqueue(hal_dev_ctx->cmd_q,
530 hal_msg);
531
532 if (status != NRF_WIFI_STATUS_SUCCESS) {
533 nrf_wifi_osal_log_err("%s: Unable to queue frag HAL cmd",
534 __func__);
535 goto out;
536 }
537
538 len -= size;
539 data += size;
540 }
541 } else {
542 hal_msg = nrf_wifi_osal_mem_zalloc(sizeof(*hal_msg) + len);
543
544 if (!hal_msg) {
545 nrf_wifi_osal_log_err("%s: Unable to allocate buffer for HAL command",
546 __func__);
547 status = NRF_WIFI_STATUS_FAIL;
548 goto out;
549 }
550
551 nrf_wifi_osal_mem_cpy(hal_msg->data,
552 cmd,
553 len);
554
555 hal_msg->len = len;
556
557 status = nrf_wifi_utils_q_enqueue(hal_dev_ctx->cmd_q,
558 hal_msg);
559
560 if (status != NRF_WIFI_STATUS_SUCCESS) {
561 nrf_wifi_osal_log_err("%s: Unable to queue fragmented command",
562 __func__);
563 goto out;
564 }
565 }
566
567 /* Free the original command data */
568 nrf_wifi_osal_mem_free(cmd);
569
570 out:
571 return status;
572 }
573
574
nrf_wifi_hal_ctrl_cmd_send(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,void * cmd,unsigned int cmd_size)575 enum nrf_wifi_status nrf_wifi_hal_ctrl_cmd_send(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
576 void *cmd,
577 unsigned int cmd_size)
578 {
579 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
580
581
582 #ifdef CONFIG_NRF_WIFI_CMD_EVENT_LOG
583 nrf_wifi_osal_log_info("%s: caller %p\n",
584 __func__,
585 __builtin_return_address(0));
586 #else
587 nrf_wifi_osal_log_dbg("%s: caller %p\n",
588 __func__,
589 __builtin_return_address(0));
590 #endif
591 nrf_wifi_osal_spinlock_take(hal_dev_ctx->lock_hal);
592
593 status = hal_rpu_cmd_queue(hal_dev_ctx,
594 cmd,
595 cmd_size);
596
597 if (status != NRF_WIFI_STATUS_SUCCESS) {
598 nrf_wifi_osal_log_err("%s: Queueing of command failed",
599 __func__);
600 goto out;
601 }
602
603 status = hal_rpu_cmd_process_queue(hal_dev_ctx);
604
605 out:
606 nrf_wifi_osal_spinlock_rel(hal_dev_ctx->lock_hal);
607
608 return status;
609 }
610
611
hal_rpu_eventq_process(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)612 enum nrf_wifi_status hal_rpu_eventq_process(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
613 {
614 enum nrf_wifi_status status = NRF_WIFI_STATUS_SUCCESS;
615 struct nrf_wifi_hal_msg *event = NULL;
616 void *event_data = NULL;
617 unsigned int event_len = 0;
618
619 while (1) {
620 event = nrf_wifi_utils_q_dequeue(hal_dev_ctx->event_q);
621 if (!event) {
622 goto out;
623 }
624
625 event_data = event->data;
626 event_len = event->len;
627
628 /* Process the event further */
629 status = hal_dev_ctx->hpriv->intr_callbk_fn(hal_dev_ctx->mac_dev_ctx,
630 event_data,
631 event_len);
632
633 if (status != NRF_WIFI_STATUS_SUCCESS) {
634 nrf_wifi_osal_log_err("%s: Interrupt callback failed",
635 __func__);
636 }
637
638 /* Free up the local buffer */
639 nrf_wifi_osal_mem_free(event);
640 event = NULL;
641 }
642
643 out:
644 return status;
645 }
646
hal_rpu_eventq_drain(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)647 static void hal_rpu_eventq_drain(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
648 {
649 struct nrf_wifi_hal_msg *event = NULL;
650 unsigned long flags = 0;
651
652 while (1) {
653 nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->lock_rx,
654 &flags);
655
656 event = nrf_wifi_utils_q_dequeue(hal_dev_ctx->event_q);
657
658 nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->lock_rx,
659 &flags);
660
661 if (!event) {
662 goto out;
663 }
664
665 /* Free up the local buffer */
666 nrf_wifi_osal_mem_free(event);
667 event = NULL;
668 }
669
670 out:
671 return;
672 }
673
nrf_wifi_hal_proc_ctx_set(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,enum RPU_PROC_TYPE proc)674 void nrf_wifi_hal_proc_ctx_set(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
675 enum RPU_PROC_TYPE proc)
676 {
677 hal_dev_ctx->curr_proc = proc;
678 }
679
680
nrf_wifi_hal_dev_rem(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)681 void nrf_wifi_hal_dev_rem(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
682 {
683 unsigned int i = 0;
684
685 nrf_wifi_osal_tasklet_kill(hal_dev_ctx->recovery_tasklet);
686 nrf_wifi_osal_tasklet_free(hal_dev_ctx->recovery_tasklet);
687 nrf_wifi_osal_spinlock_free(hal_dev_ctx->lock_recovery);
688
689 nrf_wifi_osal_tasklet_kill(hal_dev_ctx->event_tasklet);
690
691 nrf_wifi_osal_tasklet_free(hal_dev_ctx->event_tasklet);
692
693 hal_rpu_eventq_drain(hal_dev_ctx);
694
695 nrf_wifi_osal_spinlock_free(hal_dev_ctx->lock_hal);
696 nrf_wifi_osal_spinlock_free(hal_dev_ctx->lock_rx);
697
698 nrf_wifi_utils_q_free(hal_dev_ctx->event_q);
699
700 nrf_wifi_utils_q_free(hal_dev_ctx->cmd_q);
701
702 #ifdef NRF_WIFI_LOW_POWER
703 hal_rpu_ps_deinit(hal_dev_ctx);
704 #endif /* NRF_WIFI_LOW_POWER */
705
706 nrf_wifi_bal_dev_rem(hal_dev_ctx->bal_dev_ctx);
707
708 nrf_wifi_osal_mem_free(hal_dev_ctx->tx_buf_info);
709 hal_dev_ctx->tx_buf_info = NULL;
710
711 for (i = 0; i < MAX_NUM_OF_RX_QUEUES; i++) {
712 nrf_wifi_osal_mem_free(hal_dev_ctx->rx_buf_info[i]);
713 hal_dev_ctx->rx_buf_info[i] = NULL;
714 }
715
716 hal_dev_ctx->hpriv->num_devs--;
717
718 nrf_wifi_osal_mem_free(hal_dev_ctx);
719 }
720
721
nrf_wifi_hal_dev_init(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)722 enum nrf_wifi_status nrf_wifi_hal_dev_init(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
723 {
724 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
725
726 #ifdef NRF_WIFI_LOW_POWER
727 hal_dev_ctx->rpu_fw_booted = true;
728 #endif /* NRF_WIFI_LOW_POWER */
729
730 status = nrf_wifi_bal_dev_init(hal_dev_ctx->bal_dev_ctx);
731
732 if (status != NRF_WIFI_STATUS_SUCCESS) {
733 nrf_wifi_osal_log_err("%s: nrf_wifi_bal_dev_init failed",
734 __func__);
735 goto out;
736 }
737
738 /* Read the HPQM info for all the queues provided by the RPU
739 * (like command, event, RX buf queues etc)
740 */
741 status = hal_rpu_mem_read(hal_dev_ctx,
742 &hal_dev_ctx->rpu_info.hpqm_info,
743 RPU_MEM_HPQ_INFO,
744 sizeof(hal_dev_ctx->rpu_info.hpqm_info));
745
746 if (status != NRF_WIFI_STATUS_SUCCESS) {
747 nrf_wifi_osal_log_err("%s: Failed to get the HPQ info",
748 __func__);
749 goto out;
750 }
751
752 status = hal_rpu_mem_read(hal_dev_ctx,
753 &hal_dev_ctx->rpu_info.rx_cmd_base,
754 RPU_MEM_RX_CMD_BASE,
755 sizeof(hal_dev_ctx->rpu_info.rx_cmd_base));
756
757 if (status != NRF_WIFI_STATUS_SUCCESS) {
758 nrf_wifi_osal_log_err("%s: Reading the RX cmd base failed",
759 __func__);
760 goto out;
761 }
762
763 hal_dev_ctx->rpu_info.tx_cmd_base = RPU_MEM_TX_CMD_BASE;
764 nrf_wifi_hal_enable(hal_dev_ctx);
765 out:
766 return status;
767 }
768
769
nrf_wifi_hal_dev_deinit(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)770 void nrf_wifi_hal_dev_deinit(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
771 {
772 nrf_wifi_hal_disable(hal_dev_ctx);
773 nrf_wifi_bal_dev_deinit(hal_dev_ctx->bal_dev_ctx);
774 hal_rpu_eventq_drain(hal_dev_ctx);
775 }
776
777
nrf_wifi_hal_irq_handler(void * data)778 enum nrf_wifi_status nrf_wifi_hal_irq_handler(void *data)
779 {
780 struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL;
781 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
782 unsigned long flags = 0;
783 bool do_rpu_recovery = false;
784
785 hal_dev_ctx = (struct nrf_wifi_hal_dev_ctx *)data;
786
787 nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->lock_rx,
788 &flags);
789
790 if (hal_dev_ctx->hal_status != NRF_WIFI_HAL_STATUS_ENABLED) {
791 /* Ignore the interrupt if the HAL is not enabled */
792 status = NRF_WIFI_STATUS_SUCCESS;
793 goto out;
794 }
795
796
797 status = hal_rpu_irq_process(hal_dev_ctx, &do_rpu_recovery);
798
799 if (status != NRF_WIFI_STATUS_SUCCESS) {
800 goto out;
801 }
802
803 if (do_rpu_recovery) {
804 nrf_wifi_osal_tasklet_schedule(hal_dev_ctx->recovery_tasklet);
805 goto out;
806 }
807
808 nrf_wifi_osal_tasklet_schedule(hal_dev_ctx->event_tasklet);
809
810 out:
811 nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->lock_rx,
812 &flags);
813 return status;
814 }
815
816
nrf_wifi_hal_poll_reg(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,unsigned int reg_addr,unsigned int mask,unsigned int req_value,unsigned int poll_delay)817 static int nrf_wifi_hal_poll_reg(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
818 unsigned int reg_addr,
819 unsigned int mask,
820 unsigned int req_value,
821 unsigned int poll_delay)
822 {
823 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
824 unsigned int val = 0;
825 unsigned int count = 50;
826
827 do {
828 status = hal_rpu_reg_read(hal_dev_ctx,
829 &val,
830 reg_addr);
831
832 if (status != NRF_WIFI_STATUS_SUCCESS) {
833 nrf_wifi_osal_log_err("%s: Read from address (0x%X) failed, val (0x%X)",
834 __func__,
835 reg_addr,
836 val);
837 }
838
839 if ((val & mask) == req_value) {
840 status = NRF_WIFI_STATUS_SUCCESS;
841 break;
842 }
843
844 nrf_wifi_osal_sleep_ms(poll_delay);
845 } while (count-- > 0);
846
847 if (count == 0) {
848 nrf_wifi_osal_log_err("%s: Timed out polling on (0x%X)",
849 __func__,
850 reg_addr);
851
852 status = NRF_WIFI_STATUS_FAIL;
853 goto out;
854 }
855 out:
856 return status;
857 }
858
859
860 /* Perform MIPS reset */
nrf_wifi_hal_proc_reset(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,enum RPU_PROC_TYPE rpu_proc)861 enum nrf_wifi_status nrf_wifi_hal_proc_reset(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
862 enum RPU_PROC_TYPE rpu_proc)
863 {
864 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
865
866 if ((rpu_proc != RPU_PROC_TYPE_MCU_LMAC) &&
867 (rpu_proc != RPU_PROC_TYPE_MCU_UMAC)) {
868 nrf_wifi_osal_log_err("%s: Unsupported RPU processor(%d)",
869 __func__,
870 rpu_proc);
871 goto out;
872 }
873
874 hal_dev_ctx->curr_proc = rpu_proc;
875
876 /* Perform pulsed soft reset of MIPS */
877 if (rpu_proc == RPU_PROC_TYPE_MCU_LMAC) {
878 status = hal_rpu_reg_write(hal_dev_ctx,
879 RPU_REG_MIPS_MCU_CONTROL,
880 0x1);
881 } else {
882 status = hal_rpu_reg_write(hal_dev_ctx,
883 RPU_REG_MIPS_MCU2_CONTROL,
884 0x1);
885 }
886
887 if (status != NRF_WIFI_STATUS_SUCCESS) {
888 nrf_wifi_osal_log_err("%s: Pulsed soft reset of MCU failed for (%d) processor",
889 __func__,
890 rpu_proc);
891 goto out;
892 }
893
894
895 /* Wait for it to come out of reset */
896 if (rpu_proc == RPU_PROC_TYPE_MCU_LMAC) {
897 status = nrf_wifi_hal_poll_reg(hal_dev_ctx,
898 RPU_REG_MIPS_MCU_CONTROL,
899 0x1,
900 0,
901 10);
902 } else {
903 status = nrf_wifi_hal_poll_reg(hal_dev_ctx,
904 RPU_REG_MIPS_MCU2_CONTROL,
905 0x1,
906 0,
907 10);
908 }
909
910 if (status != NRF_WIFI_STATUS_SUCCESS) {
911 nrf_wifi_osal_log_err("%s: MCU (%d) failed to come out of reset",
912 __func__,
913 rpu_proc);
914 goto out;
915 }
916
917 /* MIPS will restart from it's boot exception registers
918 * and hit its default wait instruction
919 */
920 if (rpu_proc == RPU_PROC_TYPE_MCU_LMAC) {
921 status = nrf_wifi_hal_poll_reg(hal_dev_ctx,
922 0xA4000018,
923 0x1,
924 0x1,
925 10);
926 } else {
927 status = nrf_wifi_hal_poll_reg(hal_dev_ctx,
928 0xA4000118,
929 0x1,
930 0x1,
931 10);
932 }
933 out:
934 hal_dev_ctx->curr_proc = RPU_PROC_TYPE_MCU_LMAC;
935 return status;
936 }
937
938 #define MCU_FW_BOOT_TIMEOUT_MS 1000
nrf_wifi_hal_fw_chk_boot(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,enum RPU_PROC_TYPE rpu_proc)939 enum nrf_wifi_status nrf_wifi_hal_fw_chk_boot(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
940 enum RPU_PROC_TYPE rpu_proc)
941 {
942 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
943 unsigned int addr = 0;
944 unsigned int val = 0;
945 unsigned int exp_val = 0;
946 int mcu_ready_wait_count = MCU_FW_BOOT_TIMEOUT_MS / 10;
947
948 if (rpu_proc == RPU_PROC_TYPE_MCU_LMAC) {
949 addr = RPU_MEM_LMAC_BOOT_SIG;
950 exp_val = NRF_WIFI_LMAC_BOOT_SIG;
951 } else if (rpu_proc == RPU_PROC_TYPE_MCU_UMAC) {
952 addr = RPU_MEM_UMAC_BOOT_SIG;
953 exp_val = NRF_WIFI_UMAC_BOOT_SIG;
954 } else {
955 nrf_wifi_osal_log_err("%s: Invalid RPU processor (%d)",
956 __func__,
957 rpu_proc);
958 }
959
960 hal_dev_ctx->curr_proc = rpu_proc;
961
962 while (mcu_ready_wait_count-- > 0) {
963 status = hal_rpu_mem_read(hal_dev_ctx,
964 (unsigned char *)&val,
965 addr,
966 sizeof(val));
967
968 if (status != NRF_WIFI_STATUS_SUCCESS) {
969 nrf_wifi_osal_log_err("%s: Reading of boot signature failed for RPU(%d)",
970 __func__,
971 rpu_proc);
972 }
973
974 if (val == exp_val) {
975 break;
976 }
977
978 /* Sleep for 10 ms */
979 nrf_wifi_osal_sleep_ms(10);
980 };
981
982 if (mcu_ready_wait_count <= 0) {
983 nrf_wifi_osal_log_err("%s: Boot_sig check failed for RPU(%d), "
984 "Expected: 0x%X, Actual: 0x%X",
985 __func__,
986 rpu_proc,
987 exp_val,
988 val);
989 status = NRF_WIFI_STATUS_FAIL;
990 goto out;
991 }
992
993 status = NRF_WIFI_STATUS_SUCCESS;
994 out:
995 hal_dev_ctx->curr_proc = RPU_PROC_TYPE_MCU_LMAC;
996
997 return status;
998 }
999
1000
1001 struct nrf_wifi_hal_priv *
nrf_wifi_hal_init(struct nrf_wifi_hal_cfg_params * cfg_params,enum nrf_wifi_status (* intr_callbk_fn)(void * dev_ctx,void * event_data,unsigned int len),enum nrf_wifi_status (* rpu_recovery_callbk_fn)(void * mac_ctx,void * event_data,unsigned int len))1002 nrf_wifi_hal_init(struct nrf_wifi_hal_cfg_params *cfg_params,
1003 enum nrf_wifi_status (*intr_callbk_fn)(void *dev_ctx,
1004 void *event_data,
1005 unsigned int len),
1006 enum nrf_wifi_status (*rpu_recovery_callbk_fn)(void *mac_ctx,
1007 void *event_data,
1008 unsigned int len))
1009 {
1010 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1011 struct nrf_wifi_hal_priv *hpriv = NULL;
1012 struct nrf_wifi_bal_cfg_params bal_cfg_params;
1013
1014 hpriv = nrf_wifi_osal_mem_zalloc(sizeof(*hpriv));
1015
1016 if (!hpriv) {
1017 nrf_wifi_osal_log_err("%s: Unable to allocate memory for hpriv",
1018 __func__);
1019 goto out;
1020 }
1021
1022 nrf_wifi_osal_mem_cpy(&hpriv->cfg_params,
1023 cfg_params,
1024 sizeof(hpriv->cfg_params));
1025
1026 hpriv->intr_callbk_fn = intr_callbk_fn;
1027 hpriv->rpu_recovery_callbk_fn = rpu_recovery_callbk_fn;
1028
1029 status = pal_rpu_addr_offset_get(RPU_ADDR_PKTRAM_START,
1030 &hpriv->addr_pktram_base,
1031 RPU_PROC_TYPE_MAX);
1032
1033 if (status != NRF_WIFI_STATUS_SUCCESS) {
1034 nrf_wifi_osal_log_err("%s: pal_rpu_addr_offset_get failed",
1035 __func__);
1036 goto out;
1037 }
1038
1039 bal_cfg_params.addr_pktram_base = hpriv->addr_pktram_base;
1040
1041 hpriv->bpriv = nrf_wifi_bal_init(&bal_cfg_params,
1042 &nrf_wifi_hal_irq_handler);
1043
1044 if (!hpriv->bpriv) {
1045 nrf_wifi_osal_log_err("%s: Failed",
1046 __func__);
1047 nrf_wifi_osal_mem_free(hpriv);
1048 hpriv = NULL;
1049 }
1050 out:
1051 return hpriv;
1052 }
1053
1054
nrf_wifi_hal_deinit(struct nrf_wifi_hal_priv * hpriv)1055 void nrf_wifi_hal_deinit(struct nrf_wifi_hal_priv *hpriv)
1056 {
1057 nrf_wifi_bal_deinit(hpriv->bpriv);
1058
1059 nrf_wifi_osal_mem_free(hpriv);
1060 }
1061
1062
nrf_wifi_hal_otp_info_get(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,struct host_rpu_umac_info * otp_info,unsigned int * otp_flags)1063 enum nrf_wifi_status nrf_wifi_hal_otp_info_get(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
1064 struct host_rpu_umac_info *otp_info,
1065 unsigned int *otp_flags)
1066 {
1067 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1068
1069 if (!hal_dev_ctx || !otp_info) {
1070 nrf_wifi_osal_log_err("%s: Invalid parameters",
1071 __func__);
1072 goto out;
1073 }
1074
1075 status = hal_rpu_mem_read(hal_dev_ctx,
1076 otp_info,
1077 RPU_MEM_UMAC_BOOT_SIG,
1078 sizeof(*otp_info));
1079
1080 if (status != NRF_WIFI_STATUS_SUCCESS) {
1081 nrf_wifi_osal_log_err("%s: OTP info get failed",
1082 __func__);
1083 goto out;
1084 }
1085
1086 status = hal_rpu_mem_read(hal_dev_ctx,
1087 otp_flags,
1088 RPU_MEM_OTP_INFO_FLAGS,
1089 sizeof(*otp_flags));
1090
1091 if (status != NRF_WIFI_STATUS_SUCCESS) {
1092 nrf_wifi_osal_log_err("%s: OTP flags get failed",
1093 __func__);
1094 goto out;
1095 }
1096 out:
1097 return status;
1098 }
1099
1100
nrf_wifi_hal_otp_ft_prog_ver_get(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,unsigned int * ft_prog_ver)1101 enum nrf_wifi_status nrf_wifi_hal_otp_ft_prog_ver_get(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
1102 unsigned int *ft_prog_ver)
1103 {
1104 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1105
1106 if (!hal_dev_ctx || !ft_prog_ver) {
1107 nrf_wifi_osal_log_err("%s: Invalid parameters",
1108 __func__);
1109 goto out;
1110 }
1111
1112 status = hal_rpu_mem_read(hal_dev_ctx,
1113 ft_prog_ver,
1114 RPU_MEM_OTP_FT_PROG_VERSION,
1115 sizeof(*ft_prog_ver));
1116
1117 if (status != NRF_WIFI_STATUS_SUCCESS) {
1118 nrf_wifi_osal_log_err("%s: FT program version get failed",
1119 __func__);
1120 goto out;
1121 }
1122 out:
1123 return status;
1124 }
1125
nrf_wifi_hal_otp_pack_info_get(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,unsigned int * package_info)1126 enum nrf_wifi_status nrf_wifi_hal_otp_pack_info_get(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
1127 unsigned int *package_info)
1128 {
1129 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1130
1131 if (!hal_dev_ctx || !package_info) {
1132 nrf_wifi_osal_log_err("%s: Invalid parameters",
1133 __func__);
1134 goto out;
1135 }
1136
1137 status = hal_rpu_mem_read(hal_dev_ctx,
1138 package_info,
1139 RPU_MEM_OTP_PACKAGE_TYPE,
1140 sizeof(*package_info));
1141
1142 if (status != NRF_WIFI_STATUS_SUCCESS) {
1143 nrf_wifi_osal_log_err("%s: Package info get failed",
1144 __func__);
1145 goto out;
1146 }
1147 out:
1148 return status;
1149 }
1150
nrf_wifi_hal_enable(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)1151 void nrf_wifi_hal_enable(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
1152 {
1153 nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->lock_rx,
1154 NULL);
1155 hal_dev_ctx->hal_status = NRF_WIFI_HAL_STATUS_ENABLED;
1156 nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->lock_rx,
1157 NULL);
1158 }
1159
nrf_wifi_hal_disable(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)1160 void nrf_wifi_hal_disable(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
1161 {
1162 nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->lock_rx,
1163 NULL);
1164 hal_dev_ctx->hal_status = NRF_WIFI_HAL_STATUS_DISABLED;
1165 nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->lock_rx,
1166 NULL);
1167 }
1168
nrf_wifi_hal_status_unlocked(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)1169 enum NRF_WIFI_HAL_STATUS nrf_wifi_hal_status_unlocked(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
1170 {
1171 return hal_dev_ctx->hal_status;
1172 }
1173