1 /*
2 * Copyright (c) 2025 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 in the system mode of operation.
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 #include "system/hal_api.h"
20
21
22 static enum nrf_wifi_status
nrf_wifi_sys_hal_rpu_pktram_buf_map_init(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)23 nrf_wifi_sys_hal_rpu_pktram_buf_map_init(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
24 {
25 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
26 unsigned int pool_idx = 0;
27
28 status = pal_rpu_addr_offset_get(RPU_MEM_PKT_BASE,
29 &hal_dev_ctx->addr_rpu_pktram_base,
30 hal_dev_ctx->curr_proc);
31
32 if (status != NRF_WIFI_STATUS_SUCCESS) {
33 nrf_wifi_osal_log_err("%s: pal_rpu_addr_offset_get failed",
34 __func__);
35 goto out;
36 }
37
38 hal_dev_ctx->addr_rpu_pktram_base_tx = hal_dev_ctx->addr_rpu_pktram_base;
39
40 hal_dev_ctx->addr_rpu_pktram_base_rx_pool[0] =
41 (hal_dev_ctx->addr_rpu_pktram_base + RPU_PKTRAM_SIZE) -
42 (NRF70_RX_NUM_BUFS * NRF70_RX_MAX_DATA_SIZE);
43
44 for (pool_idx = 1; pool_idx < MAX_NUM_OF_RX_QUEUES; pool_idx++) {
45 hal_dev_ctx->addr_rpu_pktram_base_rx_pool[pool_idx] =
46 hal_dev_ctx->addr_rpu_pktram_base_rx_pool[pool_idx - 1] +
47 (hal_dev_ctx->hpriv->cfg_params.rx_buf_pool[pool_idx - 1].num_bufs *
48 hal_dev_ctx->hpriv->cfg_params.rx_buf_pool[pool_idx - 1].buf_sz);
49 }
50
51 status = NRF_WIFI_STATUS_SUCCESS;
52 out:
53 return status;
54 }
55
56
event_tasklet_fn(unsigned long data)57 static void event_tasklet_fn(unsigned long data)
58 {
59 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
60 struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL;
61 unsigned long flags = 0;
62
63 hal_dev_ctx = (struct nrf_wifi_hal_dev_ctx *)data;
64
65 nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->lock_rx,
66 &flags);
67
68 if (hal_dev_ctx->hal_status != NRF_WIFI_HAL_STATUS_ENABLED) {
69 /* Ignore the interrupt if the HAL is not enabled */
70 status = NRF_WIFI_STATUS_SUCCESS;
71 goto out;
72 }
73
74 status = hal_rpu_eventq_process(hal_dev_ctx);
75
76 if (status != NRF_WIFI_STATUS_SUCCESS) {
77 nrf_wifi_osal_log_err("%s: Event queue processing failed",
78 __func__);
79 }
80
81 out:
82 nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->lock_rx,
83 &flags);
84 }
85
86
hal_rpu_recovery(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)87 static enum nrf_wifi_status hal_rpu_recovery(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
88 {
89 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
90
91 if (!hal_dev_ctx->hpriv->rpu_recovery_callbk_fn) {
92 nrf_wifi_osal_log_dbg("%s: RPU recovery callback not registered",
93 __func__);
94 goto out;
95 }
96
97 status = hal_dev_ctx->hpriv->rpu_recovery_callbk_fn(hal_dev_ctx->mac_dev_ctx, NULL, 0);
98 if (status != NRF_WIFI_STATUS_SUCCESS) {
99 nrf_wifi_osal_log_err("%s: RPU recovery failed",
100 __func__);
101 goto out;
102 }
103
104 out:
105 return status;
106 }
107
recovery_tasklet_fn(unsigned long data)108 static void recovery_tasklet_fn(unsigned long data)
109 {
110 struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL;
111 unsigned long flags = 0;
112
113 hal_dev_ctx = (struct nrf_wifi_hal_dev_ctx *)data;
114 if (!hal_dev_ctx) {
115 nrf_wifi_osal_log_err("%s: Invalid hal_dev_ctx",
116 __func__);
117 return;
118 }
119
120 nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->lock_recovery,
121 &flags);
122 hal_rpu_recovery(hal_dev_ctx);
123 nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->lock_recovery,
124 &flags);
125 }
126
127
nrf_wifi_sys_hal_buf_map_rx(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,unsigned long buf,unsigned int buf_len,unsigned int pool_id,unsigned int buf_id)128 unsigned long nrf_wifi_sys_hal_buf_map_rx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
129 unsigned long buf,
130 unsigned int buf_len,
131 unsigned int pool_id,
132 unsigned int buf_id)
133 {
134 struct nrf_wifi_hal_buf_map_info *rx_buf_info = NULL;
135 unsigned long addr_to_map = 0;
136 unsigned long bounce_buf_addr = 0;
137 unsigned long rpu_addr = 0;
138
139 if (!hal_dev_ctx || !hal_dev_ctx->rx_buf_info[pool_id]) {
140 nrf_wifi_osal_log_err("%s: Invalid parameters\n",
141 __func__);
142 goto out;
143 }
144
145 rx_buf_info = &hal_dev_ctx->rx_buf_info[pool_id][buf_id];
146
147 if (rx_buf_info->mapped) {
148 nrf_wifi_osal_log_err("%s: Called for already mapped RX buffer",
149 __func__);
150 goto out;
151 }
152
153 rx_buf_info->virt_addr = buf;
154 rx_buf_info->buf_len = buf_len;
155
156 if (buf_len != hal_dev_ctx->hpriv->cfg_params.rx_buf_pool[pool_id].buf_sz) {
157 nrf_wifi_osal_log_err("%s: Invalid buf_len (%d) for pool_id (%d)",
158 __func__,
159 buf_len,
160 pool_id);
161 goto out;
162 }
163
164 bounce_buf_addr = hal_dev_ctx->addr_rpu_pktram_base_rx_pool[pool_id] +
165 (buf_id * buf_len);
166
167 rpu_addr = RPU_MEM_PKT_BASE + (bounce_buf_addr - hal_dev_ctx->addr_rpu_pktram_base);
168
169 hal_rpu_mem_write(hal_dev_ctx,
170 (unsigned int)rpu_addr,
171 (void *)buf,
172 hal_dev_ctx->hpriv->cfg_params.rx_buf_headroom_sz);
173
174 addr_to_map = bounce_buf_addr + hal_dev_ctx->hpriv->cfg_params.rx_buf_headroom_sz;
175
176 rx_buf_info->phy_addr = nrf_wifi_bal_dma_map(hal_dev_ctx->bal_dev_ctx,
177 addr_to_map,
178 buf_len,
179 NRF_WIFI_OSAL_DMA_DIR_FROM_DEV);
180
181 if (!rx_buf_info->phy_addr) {
182 nrf_wifi_osal_log_err("%s: DMA map failed",
183 __func__);
184 goto out;
185 }
186
187 out:
188 if (rx_buf_info->phy_addr) {
189 rx_buf_info->mapped = true;
190 }
191
192 return rx_buf_info->phy_addr;
193 }
194
195
nrf_wifi_sys_hal_buf_unmap_rx(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,unsigned int data_len,unsigned int pool_id,unsigned int buf_id)196 unsigned long nrf_wifi_sys_hal_buf_unmap_rx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
197 unsigned int data_len,
198 unsigned int pool_id,
199 unsigned int buf_id)
200 {
201 struct nrf_wifi_hal_buf_map_info *rx_buf_info = NULL;
202 unsigned long unmapped_addr = 0;
203 unsigned long virt_addr = 0;
204 unsigned long rpu_addr = 0;
205
206 rx_buf_info = &hal_dev_ctx->rx_buf_info[pool_id][buf_id];
207
208 if (!rx_buf_info->mapped) {
209 nrf_wifi_osal_log_err("%s: Called for unmapped RX buffer",
210 __func__);
211 goto out;
212 }
213
214 unmapped_addr = nrf_wifi_bal_dma_unmap(hal_dev_ctx->bal_dev_ctx,
215 rx_buf_info->phy_addr,
216 rx_buf_info->buf_len,
217 NRF_WIFI_OSAL_DMA_DIR_FROM_DEV);
218
219 rpu_addr = RPU_MEM_PKT_BASE + (unmapped_addr - hal_dev_ctx->addr_rpu_pktram_base);
220
221 if (data_len) {
222 if (!unmapped_addr) {
223 nrf_wifi_osal_log_err("%s: DMA unmap failed",
224 __func__);
225 goto out;
226 }
227
228 hal_rpu_mem_read(hal_dev_ctx,
229 (void *)(rx_buf_info->virt_addr +
230 hal_dev_ctx->hpriv->cfg_params.rx_buf_headroom_sz),
231 (unsigned int)rpu_addr,
232 data_len);
233 }
234
235 virt_addr = rx_buf_info->virt_addr;
236
237 nrf_wifi_osal_mem_set(rx_buf_info,
238 0,
239 sizeof(*rx_buf_info));
240 out:
241 return virt_addr;
242 }
243
244
nrf_wifi_sys_hal_buf_map_tx(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,unsigned long buf,unsigned int buf_len,unsigned int desc_id,unsigned int token,unsigned int buf_indx)245 unsigned long nrf_wifi_sys_hal_buf_map_tx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
246 unsigned long buf,
247 unsigned int buf_len,
248 unsigned int desc_id,
249 unsigned int token,
250 unsigned int buf_indx)
251 {
252 struct nrf_wifi_hal_buf_map_info *tx_buf_info = NULL;
253 unsigned long addr_to_map = 0;
254 unsigned long bounce_buf_addr = 0;
255 unsigned long tx_token_base_addr = hal_dev_ctx->addr_rpu_pktram_base_tx +
256 (token * hal_dev_ctx->hpriv->cfg_params.max_ampdu_len_per_token);
257 unsigned long rpu_addr = 0;
258
259 tx_buf_info = &hal_dev_ctx->tx_buf_info[desc_id];
260
261 if (tx_buf_info->mapped) {
262 nrf_wifi_osal_log_err("%s: Called for already mapped TX buffer",
263 __func__);
264 goto out;
265 }
266
267 tx_buf_info->virt_addr = buf;
268
269 if (buf_len > (hal_dev_ctx->hpriv->cfg_params.max_tx_frm_sz -
270 hal_dev_ctx->hpriv->cfg_params.tx_buf_headroom_sz)) {
271 nrf_wifi_osal_log_err("%s: Invalid TX buf_len (%d) for (%d)",
272 __func__,
273 buf_len,
274 desc_id);
275 goto out;
276 }
277
278 if (buf_indx == 0) {
279 hal_dev_ctx->tx_frame_offset = tx_token_base_addr;
280 }
281
282 bounce_buf_addr = hal_dev_ctx->tx_frame_offset;
283
284 /* Align bounce buffer and buffer length to 4-byte boundary */
285 bounce_buf_addr = (bounce_buf_addr + 3) & ~3;
286 buf_len = (buf_len + 3) & ~3;
287
288 hal_dev_ctx->tx_frame_offset += (bounce_buf_addr - hal_dev_ctx->tx_frame_offset) +
289 buf_len + hal_dev_ctx->hpriv->cfg_params.tx_buf_headroom_sz;
290
291 rpu_addr = RPU_MEM_PKT_BASE + (bounce_buf_addr - hal_dev_ctx->addr_rpu_pktram_base);
292
293 nrf_wifi_osal_log_dbg("%s: bounce_buf_addr: 0x%lx, rpu_addr: 0x%lx, buf_len: %d off:%d",
294 __func__,
295 bounce_buf_addr,
296 rpu_addr,
297 buf_len,
298 hal_dev_ctx->tx_frame_offset);
299
300 hal_rpu_mem_write(hal_dev_ctx,
301 (unsigned int)rpu_addr,
302 (void *)buf,
303 buf_len);
304
305 addr_to_map = bounce_buf_addr;
306
307 tx_buf_info->phy_addr = nrf_wifi_bal_dma_map(hal_dev_ctx->bal_dev_ctx,
308 addr_to_map,
309 buf_len,
310 NRF_WIFI_OSAL_DMA_DIR_TO_DEV);
311
312 if (!tx_buf_info->phy_addr) {
313 nrf_wifi_osal_log_err("%s: DMA map failed",
314 __func__);
315 goto out;
316 }
317 tx_buf_info->buf_len = buf_len;
318
319 out:
320 if (tx_buf_info->phy_addr) {
321 tx_buf_info->mapped = true;
322 }
323
324 return tx_buf_info->phy_addr;
325 }
326
327
nrf_wifi_sys_hal_buf_unmap_tx(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,unsigned int desc_id)328 unsigned long nrf_wifi_sys_hal_buf_unmap_tx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
329 unsigned int desc_id)
330 {
331 struct nrf_wifi_hal_buf_map_info *tx_buf_info = NULL;
332 unsigned long unmapped_addr = 0;
333 unsigned long virt_addr = 0;
334
335 tx_buf_info = &hal_dev_ctx->tx_buf_info[desc_id];
336
337 if (!tx_buf_info->mapped) {
338 nrf_wifi_osal_log_err("%s: Called for unmapped TX buffer",
339 __func__);
340 goto out;
341 }
342
343 unmapped_addr = nrf_wifi_bal_dma_unmap(hal_dev_ctx->bal_dev_ctx,
344 tx_buf_info->phy_addr,
345 tx_buf_info->buf_len,
346 NRF_WIFI_OSAL_DMA_DIR_TO_DEV);
347
348 if (!unmapped_addr) {
349 nrf_wifi_osal_log_err("%s: DMA unmap failed",
350 __func__);
351 goto out;
352 }
353
354 virt_addr = tx_buf_info->virt_addr;
355
356 nrf_wifi_osal_mem_set(tx_buf_info,
357 0,
358 sizeof(*tx_buf_info));
359 out:
360 return virt_addr;
361 }
362
nrf_wifi_sys_hal_data_cmd_send(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,enum NRF_WIFI_HAL_MSG_TYPE cmd_type,void * cmd,unsigned int cmd_size,unsigned int desc_id,unsigned int pool_id)363 enum nrf_wifi_status nrf_wifi_sys_hal_data_cmd_send(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
364 enum NRF_WIFI_HAL_MSG_TYPE cmd_type,
365 void *cmd,
366 unsigned int cmd_size,
367 unsigned int desc_id,
368 unsigned int pool_id)
369 {
370 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
371 unsigned int addr_base = 0;
372 unsigned int max_cmd_size = 0;
373 unsigned int addr = 0;
374 unsigned int host_addr = 0;
375
376
377 nrf_wifi_osal_spinlock_take(hal_dev_ctx->lock_hal);
378
379 if (cmd_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX) {
380 addr_base = hal_dev_ctx->rpu_info.rx_cmd_base;
381 max_cmd_size = RPU_DATA_CMD_SIZE_MAX_RX;
382 } else if (cmd_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_TX) {
383 addr_base = hal_dev_ctx->rpu_info.tx_cmd_base;
384 max_cmd_size = RPU_DATA_CMD_SIZE_MAX_TX;
385 } else {
386 nrf_wifi_osal_log_err("%s: Invalid data command type %d",
387 __func__,
388 cmd_type);
389 }
390
391 addr = addr_base + (max_cmd_size * desc_id);
392 host_addr = addr;
393
394 /* This is a indrect write to core memory */
395 if (cmd_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX) {
396 host_addr &= RPU_ADDR_MASK_OFFSET;
397 host_addr |= RPU_MCU_CORE_INDIRECT_BASE;
398 }
399
400 /* Copy the information to the suggested address */
401 status = hal_rpu_mem_write(hal_dev_ctx,
402 host_addr,
403 cmd,
404 cmd_size);
405
406 if (status != NRF_WIFI_STATUS_SUCCESS) {
407 nrf_wifi_osal_log_err("%s: Copying data cmd(%d) to RPU failed",
408 __func__,
409 cmd_type);
410 goto out;
411 }
412
413 /* Post the updated information to the RPU */
414 status = hal_rpu_msg_post(hal_dev_ctx,
415 cmd_type,
416 pool_id,
417 addr);
418
419 if (status != NRF_WIFI_STATUS_SUCCESS) {
420 nrf_wifi_osal_log_err("%s: Posting RX buf info to RPU failed",
421 __func__);
422 goto out;
423 }
424 out:
425 nrf_wifi_osal_spinlock_rel(hal_dev_ctx->lock_hal);
426
427
428 return status;
429 }
430
431
nrf_wifi_sys_hal_dev_add(struct nrf_wifi_hal_priv * hpriv,void * mac_dev_ctx)432 struct nrf_wifi_hal_dev_ctx *nrf_wifi_sys_hal_dev_add(struct nrf_wifi_hal_priv *hpriv,
433 void *mac_dev_ctx)
434 {
435 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
436 struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL;
437 unsigned int i = 0;
438 unsigned int num_rx_bufs = 0;
439 unsigned int size = 0;
440
441 hal_dev_ctx = nrf_wifi_osal_mem_zalloc(sizeof(*hal_dev_ctx));
442
443 if (!hal_dev_ctx) {
444 nrf_wifi_osal_log_err("%s: Unable to allocate hal_dev_ctx",
445 __func__);
446 goto err;
447 }
448
449 hal_dev_ctx->hpriv = hpriv;
450 hal_dev_ctx->mac_dev_ctx = mac_dev_ctx;
451 hal_dev_ctx->idx = hpriv->num_devs++;
452
453 hal_dev_ctx->num_cmds = RPU_CMD_START_MAGIC;
454
455 hal_dev_ctx->cmd_q = nrf_wifi_utils_q_alloc();
456
457 if (!hal_dev_ctx->cmd_q) {
458 nrf_wifi_osal_log_err("%s: Unable to allocate command queue",
459 __func__);
460 goto hal_dev_free;
461 }
462
463 hal_dev_ctx->event_q = nrf_wifi_utils_q_alloc();
464
465 if (!hal_dev_ctx->event_q) {
466 nrf_wifi_osal_log_err("%s: Unable to allocate event queue",
467 __func__);
468 goto cmd_q_free;
469 }
470
471 hal_dev_ctx->lock_hal = nrf_wifi_osal_spinlock_alloc();
472
473 if (!hal_dev_ctx->lock_hal) {
474 nrf_wifi_osal_log_err("%s: Unable to allocate HAL lock", __func__);
475 hal_dev_ctx = NULL;
476 goto event_q_free;
477 }
478
479 nrf_wifi_osal_spinlock_init(hal_dev_ctx->lock_hal);
480
481 hal_dev_ctx->lock_rx = nrf_wifi_osal_spinlock_alloc();
482
483 if (!hal_dev_ctx->lock_rx) {
484 nrf_wifi_osal_log_err("%s: Unable to allocate HAL lock",
485 __func__);
486 goto lock_hal_free;
487 }
488
489 nrf_wifi_osal_spinlock_init(hal_dev_ctx->lock_rx);
490
491 hal_dev_ctx->event_tasklet = nrf_wifi_osal_tasklet_alloc(NRF_WIFI_TASKLET_TYPE_BH);
492
493 if (!hal_dev_ctx->event_tasklet) {
494 nrf_wifi_osal_log_err("%s: Unable to allocate event_tasklet",
495 __func__);
496 goto lock_rx_free;
497 }
498
499 nrf_wifi_osal_tasklet_init(hal_dev_ctx->event_tasklet,
500 event_tasklet_fn,
501 (unsigned long)hal_dev_ctx);
502
503 hal_dev_ctx->recovery_tasklet = nrf_wifi_osal_tasklet_alloc(NRF_WIFI_TASKLET_TYPE_BH);
504 if (!hal_dev_ctx->recovery_tasklet) {
505 nrf_wifi_osal_log_err("%s: Unable to allocate recovery_tasklet",
506 __func__);
507 goto event_tasklet_free;
508 }
509 nrf_wifi_osal_tasklet_init(hal_dev_ctx->recovery_tasklet,
510 recovery_tasklet_fn,
511 (unsigned long)hal_dev_ctx);
512
513 hal_dev_ctx->lock_recovery = nrf_wifi_osal_spinlock_alloc();
514 if (!hal_dev_ctx->lock_recovery) {
515 nrf_wifi_osal_log_err("%s: Unable to allocate recovery lock",
516 __func__);
517 goto recovery_tasklet_free;
518 }
519
520 nrf_wifi_osal_spinlock_init(hal_dev_ctx->lock_recovery);
521 #ifdef NRF_WIFI_LOW_POWER
522 status = hal_rpu_ps_init(hal_dev_ctx);
523
524 if (status != NRF_WIFI_STATUS_SUCCESS) {
525 nrf_wifi_osal_log_err("%s: hal_rpu_ps_init failed",
526 __func__);
527 goto lock_recovery_free;
528 }
529 #endif /* NRF_WIFI_LOW_POWER */
530
531 hal_dev_ctx->bal_dev_ctx = nrf_wifi_bal_dev_add(hpriv->bpriv,
532 hal_dev_ctx);
533
534 if (!hal_dev_ctx->bal_dev_ctx) {
535 nrf_wifi_osal_log_err("%s: nrf_wifi_bal_dev_add failed",
536 __func__);
537 goto lock_recovery_free;
538 }
539
540 status = hal_rpu_irq_enable(hal_dev_ctx);
541
542 if (status != NRF_WIFI_STATUS_SUCCESS) {
543 nrf_wifi_osal_log_err("%s: hal_rpu_irq_enable failed",
544 __func__);
545 goto bal_dev_free;
546 }
547
548 for (i = 0; i < MAX_NUM_OF_RX_QUEUES; i++) {
549 num_rx_bufs = hal_dev_ctx->hpriv->cfg_params.rx_buf_pool[i].num_bufs;
550
551 size = (num_rx_bufs * sizeof(struct nrf_wifi_hal_buf_map_info));
552
553 hal_dev_ctx->rx_buf_info[i] = nrf_wifi_osal_mem_zalloc(size);
554
555 if (!hal_dev_ctx->rx_buf_info[i]) {
556 nrf_wifi_osal_log_err("%s: No space for RX buf info[%d]",
557 __func__,
558 i);
559 goto bal_dev_free;
560 }
561 }
562 #ifdef NRF70_DATA_TX
563 size = (hal_dev_ctx->hpriv->cfg_params.max_tx_frms *
564 sizeof(struct nrf_wifi_hal_buf_map_info));
565
566 hal_dev_ctx->tx_buf_info = nrf_wifi_osal_mem_zalloc(size);
567
568 if (!hal_dev_ctx->tx_buf_info) {
569 nrf_wifi_osal_log_err("%s: No space for TX buf info",
570 __func__);
571 goto rx_buf_free;
572 }
573 #endif /* NRF70_DATA_TX */
574
575 status = nrf_wifi_sys_hal_rpu_pktram_buf_map_init(hal_dev_ctx);
576
577 if (status != NRF_WIFI_STATUS_SUCCESS) {
578 nrf_wifi_osal_log_err("%s: Buffer map init failed",
579 __func__);
580 #ifdef NRF70_DATA_TX
581 goto tx_buf_free;
582 #endif /* NRF70_DATA_TX */
583 }
584
585 return hal_dev_ctx;
586
587 #ifdef NRF70_DATA_TX
588 tx_buf_free:
589 nrf_wifi_osal_mem_free(hal_dev_ctx->tx_buf_info);
590 hal_dev_ctx->tx_buf_info = NULL;
591 rx_buf_free:
592
593 for (i = 0; i < MAX_NUM_OF_RX_QUEUES; i++) {
594 nrf_wifi_osal_mem_free(hal_dev_ctx->rx_buf_info[i]);
595 hal_dev_ctx->rx_buf_info[i] = NULL;
596 }
597 #endif /* NRF70_DATA_TX */
598 bal_dev_free:
599 nrf_wifi_bal_dev_rem(hal_dev_ctx->bal_dev_ctx);
600 lock_recovery_free:
601 nrf_wifi_osal_spinlock_free(hal_dev_ctx->lock_recovery);
602 recovery_tasklet_free:
603 nrf_wifi_osal_tasklet_free(hal_dev_ctx->recovery_tasklet);
604 event_tasklet_free:
605 nrf_wifi_osal_tasklet_free(hal_dev_ctx->event_tasklet);
606 lock_rx_free:
607 nrf_wifi_osal_spinlock_free(hal_dev_ctx->lock_rx);
608 lock_hal_free:
609 nrf_wifi_osal_spinlock_free(hal_dev_ctx->lock_hal);
610 event_q_free:
611 nrf_wifi_utils_q_free(hal_dev_ctx->event_q);
612 cmd_q_free:
613 nrf_wifi_utils_q_free(hal_dev_ctx->cmd_q);
614 hal_dev_free:
615 nrf_wifi_osal_mem_free(hal_dev_ctx);
616 hal_dev_ctx = NULL;
617 err:
618 return NULL;
619 }
620
621
nrf_wifi_sys_hal_lock_rx(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)622 void nrf_wifi_sys_hal_lock_rx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
623 {
624 unsigned long flags = 0;
625
626 nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->lock_rx,
627 &flags);
628 }
629
nrf_wifi_sys_hal_unlock_rx(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx)630 void nrf_wifi_sys_hal_unlock_rx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
631 {
632 unsigned long flags = 0;
633
634 nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->lock_rx,
635 &flags);
636 }