1 /*
2 * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company)
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /** @file
19 * Defines WHD resource functions for BCM943340WCD1 platform
20 */
21 #include "cmsis_compiler.h"
22 #include "cy_utils.h"
23 #include "resources.h"
24 #include "clm_resources.h"
25 #include "wifi_nvram_image.h"
26 #include "whd_resource_api.h"
27 #include "whd_debug.h"
28 #include "whd.h"
29
30 /******************************************************
31 * Macros
32 ******************************************************/
33 #define BLOCK_BUFFER_SIZE (1024)
34
35 /******************************************************
36 * Constants
37 ******************************************************/
38
39 #if defined(WHD_DYNAMIC_NVRAM)
40 #define NVRAM_SIZE dynamic_nvram_size
41 #define NVRAM_IMAGE_VARIABLE dynamic_nvram_image
42 #else
43 #define NVRAM_SIZE sizeof(wifi_nvram_image)
44 #define NVRAM_IMAGE_VARIABLE wifi_nvram_image
45 #endif
46
47 /******************************************************
48 * Enumerations
49 ******************************************************/
50
51 /******************************************************
52 * Type Definitions
53 ******************************************************/
54
55 /******************************************************
56 * Structures
57 ******************************************************/
58
59 /******************************************************
60 * Static Function Declarations
61 ******************************************************/
62 uint32_t host_platform_resource_size(whd_driver_t whd_drv, whd_resource_type_t resource, uint32_t *size_out);
63 uint32_t host_get_resource_block(whd_driver_t whd_drv, whd_resource_type_t type,
64 uint32_t blockno, const uint8_t **data, uint32_t *size_out);
65 uint32_t host_get_resource_no_of_blocks(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *block_count);
66 uint32_t host_get_resource_block_size(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *size_out);
67 resource_result_t resource_read(const resource_hnd_t *resource, uint32_t offset, uint32_t maxsize, uint32_t *size,
68 void *buffer);
69 uint32_t host_resource_read(whd_driver_t whd_drv, whd_resource_type_t type,
70 uint32_t offset, uint32_t size, uint32_t *size_out, void *buffer);
71 /******************************************************
72 * Variable Definitions
73 ******************************************************/
74
75 #ifdef WLAN_MFG_FIRMWARE
76 extern const resource_hnd_t wifi_mfg_firmware_image;
77 extern const resource_hnd_t wifi_mfg_firmware_clm_blob;
78 #else
79 extern const resource_hnd_t wifi_firmware_image;
80 extern const resource_hnd_t wifi_firmware_clm_blob;
81 #endif
82
83 // Need to be aligned as whd_bus_spi_protocol.c reads a uint32_t
84 CY_ALIGN(4) unsigned char r_buffer[BLOCK_BUFFER_SIZE];
85
86 #if defined(WHD_DYNAMIC_NVRAM)
87 uint32_t dynamic_nvram_size = sizeof(wifi_nvram_image);
88 void *dynamic_nvram_image = &wifi_nvram_image;
89 #endif
90
91 /******************************************************
92 * Function Definitions
93 ******************************************************/
94
resource_read(const resource_hnd_t * resource,uint32_t offset,uint32_t maxsize,uint32_t * size,void * buffer)95 resource_result_t resource_read(const resource_hnd_t *resource, uint32_t offset, uint32_t maxsize, uint32_t *size,
96 void *buffer)
97 {
98 if (offset > resource->size)
99 {
100 return RESOURCE_OFFSET_TOO_BIG;
101 }
102
103 *size = MIN(maxsize, resource->size - offset);
104
105 if (resource->location == RESOURCE_IN_MEMORY)
106 {
107 memcpy(buffer, &resource->val.mem.data[offset], *size);
108 }
109 #ifdef USES_RESOURCES_IN_EXTERNAL_STORAGE
110 else if (resource->location == RESOURCE_IN_EXTERNAL_STORAGE)
111 {
112 return platform_read_external_resource(resource, offset, maxsize, size, buffer);
113 }
114 #endif
115 #ifdef USES_RESOURCE_GENERIC_FILESYSTEM
116 else
117 {
118 wiced_file_t file_handle;
119 uint64_t size64;
120 uint64_t maxsize64 = maxsize;
121 if (WICED_SUCCESS !=
122 wiced_filesystem_file_open (&resource_fs_handle, &file_handle, resource->val.fs.filename,
123 WICED_FILESYSTEM_OPEN_FOR_READ) )
124 {
125 return RESOURCE_FILE_OPEN_FAIL;
126 }
127 if (WICED_SUCCESS != wiced_filesystem_file_seek (&file_handle, (offset + resource->val.fs.offset), SEEK_SET) )
128 {
129 return RESOURCE_FILE_SEEK_FAIL;
130 }
131 if (WICED_SUCCESS != wiced_filesystem_file_read (&file_handle, buffer, maxsize64, &size64) )
132 {
133 wiced_filesystem_file_close (&file_handle);
134 return RESOURCE_FILE_READ_FAIL;
135 }
136 *size = (uint32_t)size64;
137 wiced_filesystem_file_close (&file_handle);
138 }
139 #else
140 #ifdef USES_RESOURCE_FILESYSTEM
141 else
142 {
143 wicedfs_file_t file_hnd;
144
145 if (0 != wicedfs_fopen(&resource_fs_handle, &file_hnd, resource->val.fs.filename) )
146 {
147 return RESOURCE_FILE_OPEN_FAIL;
148 }
149
150 if (0 != wicedfs_fseek(&file_hnd, (long)(offset + resource->val.fs.offset), SEEK_SET) )
151 {
152 wicedfs_fclose(&file_hnd);
153 return RESOURCE_FILE_SEEK_FAIL;
154 }
155
156 if (*size != wicedfs_fread(buffer, 1, *size, &file_hnd) )
157 {
158 wicedfs_fclose(&file_hnd);
159 return RESOURCE_FILE_READ_FAIL;
160 }
161
162 wicedfs_fclose(&file_hnd);
163 }
164 #endif /* ifdef USES_RESOURCE_FILESYSTEM */
165 #endif /* USES_RESOURCE_GENERIC_FILESYSTEM */
166 return RESOURCE_SUCCESS;
167 }
168
host_platform_resource_size(whd_driver_t whd_drv,whd_resource_type_t resource,uint32_t * size_out)169 uint32_t host_platform_resource_size(whd_driver_t whd_drv, whd_resource_type_t resource, uint32_t *size_out)
170 {
171 if (resource == WHD_RESOURCE_WLAN_FIRMWARE)
172 {
173 #ifdef NO_WIFI_FIRMWARE
174 whd_assert("Request firmware in a no wifi firmware application", 0 == 1);
175 *size_out = 0;
176 #else
177 #ifdef WIFI_FIRMWARE_IN_MULTI_APP
178 wiced_app_t wifi_app;
179
180 *size_out = 0;
181 if (wiced_waf_app_open(DCT_WIFI_FIRMWARE_INDEX, &wifi_app) != WICED_SUCCESS)
182 {
183 return ( whd_result_t )RESOURCE_UNSUPPORTED;
184 }
185 wiced_waf_app_get_size(&wifi_app, size_out);
186 #else
187 #ifdef WLAN_MFG_FIRMWARE
188 *size_out = (uint32_t)resource_get_size(&wifi_mfg_firmware_image);
189 #else
190 *size_out = (uint32_t)resource_get_size(&wifi_firmware_image);
191 #endif /* WLAN_MFG_FIRMWARE */
192 #endif /* WIFI_FIRMWARE_IN_MULTI_APP */
193 #endif /* NO_WIFI_FIRMWARE */
194
195 }
196 else if (resource == WHD_RESOURCE_WLAN_NVRAM)
197 {
198 *size_out = NVRAM_SIZE;
199 }
200 else
201 {
202 #ifdef WLAN_MFG_FIRMWARE
203 *size_out = (uint32_t)resource_get_size(&wifi_mfg_firmware_clm_blob);
204 #else
205 *size_out = (uint32_t)resource_get_size(&wifi_firmware_clm_blob);
206 #endif /* WLAN_MFG_FIRMWARE */
207 }
208 return WHD_SUCCESS;
209 }
210
host_get_resource_block(whd_driver_t whd_drv,whd_resource_type_t type,uint32_t blockno,const uint8_t ** data,uint32_t * size_out)211 uint32_t host_get_resource_block(whd_driver_t whd_drv, whd_resource_type_t type,
212 uint32_t blockno, const uint8_t **data, uint32_t *size_out)
213 {
214 uint32_t resource_size;
215 uint32_t block_size;
216 uint32_t block_count;
217 uint32_t read_pos;
218 uint32_t result;
219
220 host_platform_resource_size(whd_drv, type, &resource_size);
221 host_get_resource_block_size(whd_drv, type, &block_size);
222 host_get_resource_no_of_blocks(whd_drv, type, &block_count);
223 memset(r_buffer, 0, block_size);
224 read_pos = blockno * block_size;
225
226 if (blockno >= block_count)
227 {
228 return WHD_BADARG;
229 }
230
231 if (type == WHD_RESOURCE_WLAN_FIRMWARE)
232 {
233 #ifdef WLAN_MFG_FIRMWARE
234 result = resource_read( (const resource_hnd_t *)&wifi_mfg_firmware_image, read_pos, block_size, size_out,
235 r_buffer );
236 #else
237 result = resource_read( (const resource_hnd_t *)&wifi_firmware_image, read_pos, block_size, size_out,
238 r_buffer );
239 #endif /* WLAN_MFG_FIRMWARE */
240 if (result != WHD_SUCCESS)
241 {
242 return result;
243 }
244 *data = (uint8_t *)&r_buffer;
245 /*
246 * In case of local buffer read use the following code
247 *
248 * *size_out = MIN(BLOCK_BUFFER_SIZE, resource_size - transfer_progress);
249 * *data = (uint8_t *)wifi_firmware_image_data;
250 *
251 * For sending the entire buffer in single block set size out as following
252 * *size_out = (uint32_t)resource_get_size(&wifi_firmware_image);
253 */
254 }
255 else if (type == WHD_RESOURCE_WLAN_NVRAM)
256 {
257 if (NVRAM_SIZE - read_pos > block_size)
258 {
259 *size_out = block_size;
260 }
261 else
262 {
263 *size_out = NVRAM_SIZE - read_pos;
264 }
265 *data = ( (uint8_t *)NVRAM_IMAGE_VARIABLE ) + read_pos;
266 }
267 else
268 {
269 #ifdef WLAN_MFG_FIRMWARE
270 result = resource_read( (const resource_hnd_t *)&wifi_mfg_firmware_clm_blob, read_pos, block_size,
271 size_out,
272 r_buffer );
273 #else
274 result = resource_read( (const resource_hnd_t *)&wifi_firmware_clm_blob, read_pos, block_size,
275 size_out,
276 r_buffer );
277 #endif /* WLAN_MFG_FIRMWARE */
278 if (result != WHD_SUCCESS)
279 {
280 return result;
281 }
282 *data = (uint8_t *)&r_buffer;
283 /*
284 * In case of local buffer read use the following code
285 *
286 * *size_out = MIN(BLOCK_BUFFER_SIZE, resource_size - transfer_progress);
287 * *data = (uint8_t *)wifi_firmware_clm_blob_image_data;
288 *
289 * For sending the entire buffer in single block set size out as following
290 * *size_out = sizeof(wifi_firmware_clm_blob_image_data);
291 */
292
293 }
294
295 return WHD_SUCCESS;
296 }
297
host_get_resource_block_size(whd_driver_t whd_drv,whd_resource_type_t type,uint32_t * size_out)298 uint32_t host_get_resource_block_size(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *size_out)
299 {
300 *size_out = BLOCK_BUFFER_SIZE;
301 return WHD_SUCCESS;
302 }
303
host_get_resource_no_of_blocks(whd_driver_t whd_drv,whd_resource_type_t type,uint32_t * block_count)304 uint32_t host_get_resource_no_of_blocks(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *block_count)
305 {
306 uint32_t resource_size;
307 uint32_t block_size;
308
309 host_platform_resource_size(whd_drv, type, &resource_size);
310 host_get_resource_block_size(whd_drv, type, &block_size);
311 *block_count = resource_size / block_size;
312 if (resource_size % block_size)
313 *block_count += 1;
314
315 return WHD_SUCCESS;
316 }
317
host_resource_read(whd_driver_t whd_drv,whd_resource_type_t type,uint32_t offset,uint32_t size,uint32_t * size_out,void * buffer)318 uint32_t host_resource_read(whd_driver_t whd_drv, whd_resource_type_t type,
319 uint32_t offset, uint32_t size, uint32_t *size_out, void *buffer)
320 {
321 uint32_t result;
322
323 if (type == WHD_RESOURCE_WLAN_FIRMWARE)
324 {
325 #ifdef WLAN_MFG_FIRMWARE
326 result = resource_read( (const resource_hnd_t *)&wifi_mfg_firmware_image, offset, size,
327 size_out, buffer );
328 #else
329 result = resource_read( (const resource_hnd_t *)&wifi_firmware_image, offset, size,
330 size_out, buffer );
331 #endif /* WLAN_MFG_FIRMWARE */
332
333 if (result != WHD_SUCCESS)
334 return result;
335
336 }
337 else if (type == WHD_RESOURCE_WLAN_NVRAM)
338 {
339 if (size != sizeof(wifi_nvram_image) )
340 {
341 return WHD_BUFFER_SIZE_SET_ERROR;
342 }
343 memcpy( (uint8_t *)buffer, wifi_nvram_image, sizeof(wifi_nvram_image) );
344 *size_out = sizeof(wifi_nvram_image);
345 }
346 return WHD_SUCCESS;
347 }
348
349 whd_resource_source_t resource_ops =
350 {
351 .whd_resource_size = host_platform_resource_size,
352 .whd_get_resource_block_size = host_get_resource_block_size,
353 .whd_get_resource_no_of_blocks = host_get_resource_no_of_blocks,
354 .whd_get_resource_block = host_get_resource_block,
355 .whd_resource_read = host_resource_read
356 };
357
358