1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @brief File containing ztests for nrf70 buslib library
9 */
10
11 #include <zephyr/shell/shell.h>
12 #include <zephyr/logging/log.h>
13 #include <zephyr/ztest.h>
14 #include <zephyr/drivers/wifi/nrf_wifi/bus/rpu_hw_if.h>
15 #include <zephyr/drivers/wifi/nrf_wifi/bus/qspi_if.h>
16
17 LOG_MODULE_REGISTER(nrf70_bustest, CONFIG_WIFI_NRF70_BUSLIB_LOG_LEVEL);
18
19 #define DATARAM_ADDR 0x0C0000
20 static struct qspi_dev *dev;
21
wifi_on(void * state)22 static int wifi_on(void *state)
23 {
24 int ret;
25
26 ARG_UNUSED(state);
27
28 dev = qspi_dev();
29
30 ret = rpu_init();
31 if (ret) {
32 LOG_ERR("%s: RPU init failed with error %d", __func__, ret);
33 return -1;
34 }
35
36 ret = dev->init(qspi_defconfig());
37 if (ret) {
38 LOG_ERR("%s: QSPI device init failed", __func__);
39 return -1;
40 }
41
42 ret = rpu_enable();
43 if (ret) {
44 LOG_ERR("%s: RPU enable failed with error %d", __func__, ret);
45 return -1;
46 }
47 k_sleep(K_MSEC(10));
48 LOG_INF("Wi-Fi ON done");
49 return 0;
50 }
51
wifi_off(void * state)52 static void wifi_off(void *state)
53 {
54 ARG_UNUSED(state);
55
56 int ret;
57
58 ret = rpu_disable();
59 if (ret) {
60 LOG_ERR("%s: RPU disable failed with error %d", __func__, ret);
61 }
62
63 ret = dev->deinit();
64 if (ret) {
65 LOG_ERR("%s: QSPI device de-init failed", __func__);
66 }
67 k_sleep(K_MSEC(10));
68 LOG_INF("Wi-Fi OFF done");
69 }
70
71
memtest(uint32_t addr,char * memblock_name)72 static int memtest(uint32_t addr, char *memblock_name)
73 {
74 const uint32_t pattern = 0x12345678;
75 uint32_t offset = 1;
76 uint32_t *buff, *rxbuff;
77 int i;
78
79 int err_count;
80 int32_t rem_words = CONFIG_NRF70BUS_MEMTEST_LENGTH;
81 uint32_t test_chunk, chunk_no = 0;
82 int ret = -1;
83
84 buff = k_malloc(CONFIG_NRF70BUS_MEMTEST_LENGTH * 4);
85 if (buff == NULL) {
86 LOG_ERR("Failed to allocate memory for buff");
87 return -1;
88 }
89
90 rxbuff = k_malloc(CONFIG_NRF70BUS_MEMTEST_LENGTH * 4);
91 if (rxbuff == NULL) {
92 LOG_ERR("Failed to allocate memory for rxbuff");
93 k_free(buff);
94 return -1;
95 }
96
97 while (rem_words > 0) {
98 test_chunk = (rem_words < CONFIG_NRF70BUS_MEMTEST_LENGTH) ?
99 rem_words : CONFIG_NRF70BUS_MEMTEST_LENGTH;
100
101 for (i = 0; i < test_chunk; i++) {
102 buff[i] = pattern +
103 (i + chunk_no * CONFIG_NRF70BUS_MEMTEST_LENGTH) * offset;
104 }
105
106 addr = addr + chunk_no * CONFIG_NRF70BUS_MEMTEST_LENGTH;
107
108 if (rpu_write(addr, buff, test_chunk * 4) ||
109 rpu_read(addr, rxbuff, test_chunk * 4)) {
110 goto err;
111 }
112
113 err_count = 0;
114 for (i = 0; i < test_chunk; i++) {
115 if (buff[i] != rxbuff[i]) {
116 err_count++;
117 LOG_ERR("%s: failed (%d), Expected 0x%x, Read 0x%x",
118 __func__, i, buff[i], rxbuff[i]);
119 if (err_count > 4)
120 goto err;
121 }
122 }
123 if (err_count) {
124 goto err;
125 }
126 rem_words -= CONFIG_NRF70BUS_MEMTEST_LENGTH;
127 chunk_no++;
128 }
129 ret = 0;
130 err:
131 k_free(rxbuff);
132 k_free(buff);
133 return ret;
134 }
135
test_sysbus(void)136 static int test_sysbus(void)
137 {
138 int val, i;
139 /* List of some SYS bus addresses and default values to test bus read
140 * integrity
141 */
142 const uint32_t addr[] = {0x714, 0x71c, 0x720,
143 0x728, 0x734, 0x738};
144 const uint32_t val_arr[] = {
145 0x000003f3, 0x0110f13f, 0x000003f3,
146 0x0003073f, 0x0003073f, 0x03013f8f};
147
148 for (i = 0; i < ARRAY_SIZE(addr); i++) {
149 rpu_read(addr[i], &val, 4);
150 if (val != val_arr[i]) {
151 LOG_ERR("%s: SYSBUS R/W failed (%d) : read = 0x%x, expected = 0x%x",
152 __func__, i, val, val_arr[i]);
153 return -1;
154 }
155 }
156 return 0;
157 }
158
test_peripbus(void)159 static int test_peripbus(void)
160 {
161 uint32_t val;
162 int i;
163 /* Some Perip bus addresses that we can write/read to validate bus access*/
164 const uint32_t addr[] = {0x62820, 0x62830, 0x62840, 0x62850, 0x62860, 0x62870};
165
166 for (i = 0; i < ARRAY_SIZE(addr); i++) {
167 val = 0xA5A5A5A5; /* Test pattern */
168 rpu_write(addr[i], &val, 4);
169 val = 0;
170 rpu_read(addr[i], &val, 4);
171 /* Perip bus is 24-bit and hence LS 8 bits read are invalid, so discard them
172 * in the check
173 */
174 if (val >> 8 != 0xA5A5A5) {
175 LOG_ERR("%s: PERIP BUS R/W failed (%d): read = 0x%x",
176 __func__, i, val >> 8);
177 return -1;
178 }
179 }
180 return 0;
181 }
182
183 ZTEST_SUITE(bustest_suite, NULL, (void *)wifi_on, NULL, NULL, wifi_off);
184
ZTEST(bustest_suite,test_sysbus)185 ZTEST(bustest_suite, test_sysbus)
186 {
187 zassert_equal(0, test_sysbus(), "SYSBUS read validation failed!!!");
188 }
189
ZTEST(bustest_suite,test_peripbus)190 ZTEST(bustest_suite, test_peripbus)
191 {
192 zassert_equal(0, test_peripbus(), "PERIP BUS read/write validation failed!!!");
193 }
194
ZTEST(bustest_suite,test_dataram)195 ZTEST(bustest_suite, test_dataram)
196 {
197 zassert_equal(0, memtest(DATARAM_ADDR, "DATA RAM"), "DATA RAM memtest failed!!!");
198 }
199