whd_resources.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /*
  2. * Copyright 2024, 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. /** @file
  18. * Defines WHD resource functions for BCM943340WCD1 platform
  19. */
  20. #include "resources.h"
  21. #if !defined(NO_CLM_BLOB_FILE)
  22. #include "clm_resources.h"
  23. #endif /* NO_CLM_BLOB_FILE */
  24. #include "wifi_nvram_image.h"
  25. #include "whd_resource_api.h"
  26. #include "whd_debug.h"
  27. #include "whd.h"
  28. /******************************************************
  29. * Macros
  30. ******************************************************/
  31. #define BLOCK_BUFFER_SIZE (1024)
  32. /******************************************************
  33. * Constants
  34. ******************************************************/
  35. #if defined(WHD_DYNAMIC_NVRAM)
  36. #define NVRAM_SIZE dynamic_nvram_size
  37. #define NVRAM_IMAGE_VARIABLE dynamic_nvram_image
  38. #else
  39. #define NVRAM_SIZE sizeof(wifi_nvram_image)
  40. #define NVRAM_IMAGE_VARIABLE wifi_nvram_image
  41. #endif
  42. /******************************************************
  43. * Enumerations
  44. ******************************************************/
  45. /******************************************************
  46. * Type Definitions
  47. ******************************************************/
  48. /******************************************************
  49. * Structures
  50. ******************************************************/
  51. /******************************************************
  52. * Static Function Declarations
  53. ******************************************************/
  54. whd_result_t host_platform_resource_size(whd_driver_t whd_drv, whd_resource_type_t resource, uint32_t *size_out);
  55. whd_result_t host_get_resource_block(whd_driver_t whd_drv, whd_resource_type_t type,
  56. uint32_t blockno, const uint8_t **data, uint32_t *size_out);
  57. whd_result_t host_get_resource_no_of_blocks(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *block_count);
  58. whd_result_t host_get_resource_block_size(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *size_out);
  59. resource_result_t resource_read(const resource_hnd_t *resource, uint32_t offset, uint32_t maxsize, uint32_t *size,
  60. void *buffer);
  61. whd_result_t host_resource_read(whd_driver_t whd_drv, whd_resource_type_t type,
  62. uint32_t offset, uint32_t size, uint32_t *size_out, void *buffer);
  63. /******************************************************
  64. * Variable Definitions
  65. ******************************************************/
  66. #ifdef WLAN_MFG_FIRMWARE
  67. extern const resource_hnd_t wifi_mfg_firmware_image;
  68. extern const resource_hnd_t wifi_mfg_firmware_clm_blob;
  69. #else
  70. extern const resource_hnd_t wifi_firmware_image;
  71. extern const resource_hnd_t wifi_firmware_clm_blob;
  72. #endif /* WLAN_MFG_FIRMWARE */
  73. unsigned char r_buffer[BLOCK_BUFFER_SIZE];
  74. #if defined(WHD_DYNAMIC_NVRAM)
  75. uint32_t dynamic_nvram_size = sizeof(wifi_nvram_image);
  76. void *dynamic_nvram_image = &wifi_nvram_image;
  77. #endif
  78. /******************************************************
  79. * Function Definitions
  80. ******************************************************/
  81. resource_result_t resource_read(const resource_hnd_t *resource, uint32_t offset, uint32_t maxsize, uint32_t *size,
  82. void *buffer)
  83. {
  84. if (offset > resource->size)
  85. {
  86. return RESOURCE_OFFSET_TOO_BIG;
  87. }
  88. *size = MIN(maxsize, resource->size - offset);
  89. if (resource->location == RESOURCE_IN_MEMORY)
  90. {
  91. memcpy(buffer, &resource->val.mem.data[offset], *size);
  92. }
  93. #ifdef USES_RESOURCES_IN_EXTERNAL_STORAGE
  94. else if (resource->location == RESOURCE_IN_EXTERNAL_STORAGE)
  95. {
  96. return platform_read_external_resource(resource, offset, maxsize, size, buffer);
  97. }
  98. #endif
  99. #ifdef USES_RESOURCE_GENERIC_FILESYSTEM
  100. else
  101. {
  102. wiced_file_t file_handle;
  103. uint64_t size64;
  104. uint64_t maxsize64 = maxsize;
  105. if (WICED_SUCCESS !=
  106. wiced_filesystem_file_open (&resource_fs_handle, &file_handle, resource->val.fs.filename,
  107. WICED_FILESYSTEM_OPEN_FOR_READ) )
  108. {
  109. return RESOURCE_FILE_OPEN_FAIL;
  110. }
  111. if (WICED_SUCCESS != wiced_filesystem_file_seek (&file_handle, (offset + resource->val.fs.offset), SEEK_SET) )
  112. {
  113. return RESOURCE_FILE_SEEK_FAIL;
  114. }
  115. if (WICED_SUCCESS != wiced_filesystem_file_read (&file_handle, buffer, maxsize64, &size64) )
  116. {
  117. wiced_filesystem_file_close (&file_handle);
  118. return RESOURCE_FILE_READ_FAIL;
  119. }
  120. *size = (uint32_t)size64;
  121. wiced_filesystem_file_close (&file_handle);
  122. }
  123. #else
  124. #ifdef USES_RESOURCE_FILESYSTEM
  125. else
  126. {
  127. wicedfs_file_t file_hnd;
  128. if (0 != wicedfs_fopen(&resource_fs_handle, &file_hnd, resource->val.fs.filename) )
  129. {
  130. return RESOURCE_FILE_OPEN_FAIL;
  131. }
  132. if (0 != wicedfs_fseek(&file_hnd, (long)(offset + resource->val.fs.offset), SEEK_SET) )
  133. {
  134. wicedfs_fclose(&file_hnd);
  135. return RESOURCE_FILE_SEEK_FAIL;
  136. }
  137. if (*size != wicedfs_fread(buffer, 1, *size, &file_hnd) )
  138. {
  139. wicedfs_fclose(&file_hnd);
  140. return RESOURCE_FILE_READ_FAIL;
  141. }
  142. wicedfs_fclose(&file_hnd);
  143. }
  144. #endif /* ifdef USES_RESOURCE_FILESYSTEM */
  145. #endif /* USES_RESOURCE_GENERIC_FILESYSTEM */
  146. return RESOURCE_SUCCESS;
  147. }
  148. whd_result_t host_platform_resource_size(whd_driver_t whd_drv, whd_resource_type_t resource, uint32_t *size_out)
  149. {
  150. if (resource == WHD_RESOURCE_WLAN_FIRMWARE)
  151. {
  152. #ifdef NO_WIFI_FIRMWARE
  153. whd_assert("Request firmware in a no wifi firmware application", 0 == 1);
  154. *size_out = 0;
  155. #else
  156. #ifdef WIFI_FIRMWARE_IN_MULTI_APP
  157. wiced_app_t wifi_app;
  158. *size_out = 0;
  159. if (wiced_waf_app_open(DCT_WIFI_FIRMWARE_INDEX, &wifi_app) != WICED_SUCCESS)
  160. {
  161. return ( whd_result_t )RESOURCE_UNSUPPORTED;
  162. }
  163. wiced_waf_app_get_size(&wifi_app, size_out);
  164. #else
  165. #ifdef WLAN_MFG_FIRMWARE
  166. *size_out = (uint32_t)resource_get_size(&wifi_mfg_firmware_image);
  167. #else
  168. *size_out = (uint32_t)resource_get_size(&wifi_firmware_image);
  169. #endif /* WLAN_MFG_FIRMWARE */
  170. #endif /* WIFI_FIRMWARE_IN_MULTI_APP */
  171. #endif /* NO_WIFI_FIRMWARE */
  172. }
  173. else if (resource == WHD_RESOURCE_WLAN_NVRAM)
  174. {
  175. *size_out = NVRAM_SIZE;
  176. }
  177. else
  178. {
  179. #if defined(NO_CLM_BLOB_FILE)
  180. *size_out = 0;
  181. #else
  182. #ifdef WLAN_MFG_FIRMWARE
  183. *size_out = (uint32_t)resource_get_size(&wifi_mfg_firmware_clm_blob);
  184. #else
  185. *size_out = (uint32_t)resource_get_size(&wifi_firmware_clm_blob);
  186. #endif /* WLAN_MFG_FIRMWARE */
  187. #endif /* NO_CLM_BLOB_FILE */
  188. }
  189. return WHD_SUCCESS;
  190. }
  191. whd_result_t host_get_resource_block(whd_driver_t whd_drv, whd_resource_type_t type,
  192. uint32_t blockno, const uint8_t **data, uint32_t *size_out)
  193. {
  194. uint32_t resource_size;
  195. uint32_t block_size;
  196. uint32_t block_count;
  197. uint32_t read_pos;
  198. uint32_t result;
  199. host_platform_resource_size(whd_drv, type, &resource_size);
  200. host_get_resource_block_size(whd_drv, type, &block_size);
  201. host_get_resource_no_of_blocks(whd_drv, type, &block_count);
  202. memset(r_buffer, 0, block_size);
  203. read_pos = blockno * block_size;
  204. if (blockno >= block_count)
  205. {
  206. return WHD_BADARG;
  207. }
  208. if (type == WHD_RESOURCE_WLAN_FIRMWARE)
  209. {
  210. #ifdef WLAN_MFG_FIRMWARE
  211. result = resource_read( (const resource_hnd_t *)&wifi_mfg_firmware_image, read_pos, block_size, size_out,
  212. r_buffer );
  213. #else
  214. result = resource_read( (const resource_hnd_t *)&wifi_firmware_image, read_pos, block_size, size_out,
  215. r_buffer );
  216. #endif /* WLAN_MFG_FIRMWARE */
  217. if (result != WHD_SUCCESS)
  218. {
  219. return result;
  220. }
  221. *data = (uint8_t *)&r_buffer;
  222. /*
  223. * In case of local buffer read use the following code
  224. *
  225. * *size_out = MIN(BLOCK_BUFFER_SIZE, resource_size - transfer_progress);
  226. * *data = (uint8_t *)wifi_firmware_image_data;
  227. *
  228. * For sending the entire buffer in single block set size out as following
  229. * *size_out = (uint32_t)resource_get_size(&wifi_firmware_image);
  230. */
  231. }
  232. else if (type == WHD_RESOURCE_WLAN_NVRAM)
  233. {
  234. if (NVRAM_SIZE - read_pos > block_size)
  235. {
  236. *size_out = block_size;
  237. }
  238. else
  239. {
  240. *size_out = NVRAM_SIZE - read_pos;
  241. }
  242. *data = ( (uint8_t *)NVRAM_IMAGE_VARIABLE ) + read_pos;
  243. }
  244. else
  245. {
  246. #if defined(NO_CLM_BLOB_FILE)
  247. size_out = 0;
  248. return WHD_SUCCESS;
  249. #else
  250. #ifdef WLAN_MFG_FIRMWARE
  251. result = resource_read( (const resource_hnd_t *)&wifi_mfg_firmware_clm_blob, read_pos, block_size,
  252. size_out,
  253. r_buffer );
  254. #else
  255. result = resource_read( (const resource_hnd_t *)&wifi_firmware_clm_blob, read_pos, block_size,
  256. size_out,
  257. r_buffer );
  258. #endif /* WLAN_MFG_FIRMWARE */
  259. #endif /* NO_CLM_BLOB_FILE */
  260. if (result != WHD_SUCCESS)
  261. {
  262. return result;
  263. }
  264. *data = (uint8_t *)&r_buffer;
  265. /*
  266. * In case of local buffer read use the following code
  267. *
  268. * *size_out = MIN(BLOCK_BUFFER_SIZE, resource_size - transfer_progress);
  269. * *data = (uint8_t *)wifi_firmware_clm_blob_image_data;
  270. *
  271. * For sending the entire buffer in single block set size out as following
  272. * *size_out = sizeof(wifi_firmware_clm_blob_image_data);
  273. */
  274. }
  275. return WHD_SUCCESS;
  276. }
  277. whd_result_t host_get_resource_block_size(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *size_out)
  278. {
  279. *size_out = BLOCK_BUFFER_SIZE;
  280. return WHD_SUCCESS;
  281. }
  282. whd_result_t host_get_resource_no_of_blocks(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *block_count)
  283. {
  284. uint32_t resource_size;
  285. uint32_t block_size;
  286. host_platform_resource_size(whd_drv, type, &resource_size);
  287. host_get_resource_block_size(whd_drv, type, &block_size);
  288. *block_count = resource_size / block_size;
  289. if (resource_size % block_size)
  290. *block_count += 1;
  291. return WHD_SUCCESS;
  292. }
  293. whd_result_t host_resource_read(whd_driver_t whd_drv, whd_resource_type_t type,
  294. uint32_t offset, uint32_t size, uint32_t *size_out, void *buffer)
  295. {
  296. uint32_t result;
  297. if (type == WHD_RESOURCE_WLAN_FIRMWARE)
  298. {
  299. #ifdef WLAN_MFG_FIRMWARE
  300. result = resource_read( (const resource_hnd_t *)&wifi_mfg_firmware_image, offset, size,
  301. size_out, buffer );
  302. #else
  303. result = resource_read( (const resource_hnd_t *)&wifi_firmware_image, offset, size,
  304. size_out, buffer );
  305. #endif /* WLAN_MFG_FIRMWARE */
  306. if (result != WHD_SUCCESS)
  307. return result;
  308. }
  309. else if (type == WHD_RESOURCE_WLAN_NVRAM)
  310. {
  311. if (size != sizeof(wifi_nvram_image) )
  312. {
  313. return WHD_BUFFER_SIZE_SET_ERROR;
  314. }
  315. memcpy( (uint8_t *)buffer, wifi_nvram_image, sizeof(wifi_nvram_image) );
  316. *size_out = sizeof(wifi_nvram_image);
  317. }
  318. return WHD_SUCCESS;
  319. }
  320. whd_resource_source_t resource_ops =
  321. {
  322. .whd_resource_size = host_platform_resource_size,
  323. .whd_get_resource_block_size = host_get_resource_block_size,
  324. .whd_get_resource_no_of_blocks = host_get_resource_no_of_blocks,
  325. .whd_get_resource_block = host_get_resource_block,
  326. .whd_resource_read = host_resource_read
  327. };