1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @brief File containing register read/write specific definitions for the
9 * HAL Layer of the Wi-Fi driver.
10 */
11
12 #include "common/pal.h"
13 #include "common/hal_api_common.h"
14 #include "common/hal_common.h"
15
16
hal_rpu_is_reg(unsigned int addr_val)17 static bool hal_rpu_is_reg(unsigned int addr_val)
18 {
19 unsigned int addr_base = (addr_val & RPU_ADDR_MASK_BASE);
20
21 if ((addr_base == RPU_ADDR_SBUS_START) ||
22 (addr_base == RPU_ADDR_PBUS_START)) {
23 return true;
24 } else {
25 return false;
26 }
27 }
28
29
hal_rpu_reg_read(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,unsigned int * val,unsigned int rpu_reg_addr)30 enum nrf_wifi_status hal_rpu_reg_read(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
31 unsigned int *val,
32 unsigned int rpu_reg_addr)
33 {
34 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
35 unsigned long addr_offset = 0;
36
37 #ifdef NRF_WIFI_LOW_POWER
38 unsigned long flags = 0;
39 #endif /* NRF_WIFI_LOW_POWER */
40
41 if (!hal_dev_ctx) {
42 return status;
43 }
44
45 if ((val == NULL) ||
46 !hal_rpu_is_reg(rpu_reg_addr)) {
47 nrf_wifi_osal_log_err("%s: Invalid params, val = %p, rpu_reg (0x%x)",
48 __func__,
49 val,
50 rpu_reg_addr);
51 return status;
52 }
53
54 status = pal_rpu_addr_offset_get(rpu_reg_addr,
55 &addr_offset,
56 hal_dev_ctx->curr_proc);
57
58 if (status != NRF_WIFI_STATUS_SUCCESS) {
59 nrf_wifi_osal_log_err("%s: pal_rpu_addr_offset_get failed",
60 __func__);
61 return status;
62 }
63
64 #ifdef NRF_WIFI_LOW_POWER
65 nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->rpu_ps_lock,
66 &flags);
67
68 status = hal_rpu_ps_wake(hal_dev_ctx);
69
70 if (status != NRF_WIFI_STATUS_SUCCESS) {
71 nrf_wifi_osal_log_err("%s: RPU wake failed",
72 __func__);
73 goto out;
74 }
75 #endif /* NRF_WIFI_LOW_POWER */
76
77 *val = nrf_wifi_bal_read_word(hal_dev_ctx->bal_dev_ctx,
78 addr_offset);
79
80 if (*val == 0xFFFFFFFF) {
81 nrf_wifi_osal_log_err("%s: Error !! Value read at addr_offset = %lx is = %X",
82 __func__,
83 addr_offset,
84 *val);
85 status = NRF_WIFI_STATUS_FAIL;
86 goto out;
87 }
88
89 status = NRF_WIFI_STATUS_SUCCESS;
90 out:
91 #ifdef NRF_WIFI_LOW_POWER
92 nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->rpu_ps_lock,
93 &flags);
94 #endif /* NRF_WIFI_LOW_POWER */
95
96 return status;
97 }
98
hal_rpu_reg_write(struct nrf_wifi_hal_dev_ctx * hal_dev_ctx,unsigned int rpu_reg_addr,unsigned int val)99 enum nrf_wifi_status hal_rpu_reg_write(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
100 unsigned int rpu_reg_addr,
101 unsigned int val)
102 {
103 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
104 unsigned long addr_offset = 0;
105
106 #ifdef NRF_WIFI_LOW_POWER
107 unsigned long flags = 0;
108 #endif /* NRF_WIFI_LOW_POWER */
109
110 if (!hal_dev_ctx) {
111 return status;
112 }
113
114 if (!hal_rpu_is_reg(rpu_reg_addr)) {
115 nrf_wifi_osal_log_err("%s: Invalid params, rpu_reg_addr (0x%X)",
116 __func__,
117 rpu_reg_addr);
118 return status;
119 }
120
121 status = pal_rpu_addr_offset_get(rpu_reg_addr,
122 &addr_offset,
123 hal_dev_ctx->curr_proc);
124
125 if (status != NRF_WIFI_STATUS_SUCCESS) {
126 nrf_wifi_osal_log_err("%s: pal_rpu_get_region_offset failed",
127 __func__);
128 return status;
129 }
130
131 #ifdef NRF_WIFI_LOW_POWER
132 nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->rpu_ps_lock,
133 &flags);
134
135 status = hal_rpu_ps_wake(hal_dev_ctx);
136
137 if (status != NRF_WIFI_STATUS_SUCCESS) {
138 nrf_wifi_osal_log_err("%s: RPU wake failed",
139 __func__);
140 goto out;
141 }
142 #endif /* NRF_WIFI_LOW_POWER */
143
144 nrf_wifi_bal_write_word(hal_dev_ctx->bal_dev_ctx,
145 addr_offset,
146 val);
147
148 status = NRF_WIFI_STATUS_SUCCESS;
149
150 #ifdef NRF_WIFI_LOW_POWER
151 out:
152 nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->rpu_ps_lock,
153 &flags);
154 #endif /* NRF_WIFI_LOW_POWER */
155
156 return status;
157 }
158