1 /*
2 * Copyright 2021-2023 NXP
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <sys/ioctl.h>
18 #include <dlfcn.h>
19
20 #include "fwd_hdll.h"
21 #include "phNxpConfig.h"
22 #include "phNxpLog.h"
23 #include "phNxpUciHal_fwd_utils.h"
24 #include "phNxpUciHal_utils.h"
25 #include "phTmlUwb_spi.h"
26
27 #define MAX_FRAME_LEN 4200
28 static uint8_t is_fw_download_log_enabled = 0x00;
29
30 static phFWD_Status_t openFwBinFile(phUwbFWImageContext_t *pfwImageCtx);
31 static phFWD_Status_t openFwSoFile(phUwbFWImageContext_t *pfwImageCtx);
32 static phFWD_Status_t phNxpUciHal_fw_recovery(phUwbFWImageContext_t *pfwImageCtx);
33
34 char default_fw_path[FILEPATH_MAXLEN] = "/vendor/firmware/uwb/";
35 const char *default_dev_fw_bin = "libsr200t_fw.bin";
36 const char *default_dev_fw_so = "libsr200t_fw.so";
37 const char *default_so_file_extn = ".so";
38 extern uint32_t timeoutTimerId;
39 static bool isHdllReadTmeoutExpired = false;
40 static bool bSkipEdlCheck = false;
41 static bool glcRotation = false;
42
43 phUwbFWImageContext_t fwImageCtx;
44
45 /*******************************************************************************
46 **
47 ** Function : phGenericSendAndRecv
48 **
49 ** Description : This function sends the HDLL commands to HeliosX chip over
50 SPI using phHdll_PutApdu() and gets the response using
51 phHdll_GetApdu().
52 **
53 ** Parameters : payload - HDLL command to be sent
54 len - HDLL command length
55 readbuff - HDLL command response buffer
56 rsp_buf_len - HDLL command rsponse buffer length
57 **
58 ** Returns : phFWD_Status_t : 0 - success
59 1 - failure
60 **
61 **
62 *******************************************************************************/
phGenericSendAndRecv(uint8_t * payload,uint16_t len,uint8_t * read_buff,uint16_t * rsp_buf_len)63 phFWD_Status_t phGenericSendAndRecv(uint8_t *payload, uint16_t len,
64 uint8_t *read_buff, uint16_t *rsp_buf_len) {
65 phFWD_Status_t ret = FW_DNLD_FAILURE;
66 if (FW_DNLD_SUCCESS != (ret = phHdll_PutApdu((uint8_t *)&payload[0], len))) {
67 return ret;
68 }
69 if (FW_DNLD_SUCCESS !=
70 (ret = phHdll_GetApdu((uint8_t *)&read_buff[0], HDLL_READ_BUFF_SIZE,
71 rsp_buf_len))) {
72 return ret;
73 }
74 return ret;
75 }
76
77 /*******************************************************************************
78 **
79 ** Function : print_getInfoRsp
80 **
81 ** Description : This function prints the HDLL GetInfo command's response
82 **
83 ** Parameters : getInfoRsp - Struct which has the GetInfo response details.
84 **
85 ** Returns : None
86 **
87 **
88 *******************************************************************************/
print_getInfoRsp(phHDLLGetInfo_t * getInfoRsp)89 void print_getInfoRsp(phHDLLGetInfo_t *getInfoRsp) {
90 uint8_t i = 0, offset = 0;
91 char buff[HDLL_READ_BUFF_SIZE] = {0};
92 if (NULL == getInfoRsp) {
93 return;
94 }
95 NXPLOG_FWDNLD_D("=====================GET_INFO =======================\n");
96 NXPLOG_FWDNLD_D("Boot Status: 0x%02X\n", getInfoRsp->boot_status);
97 NXPLOG_FWDNLD_D("Session Control: 0x%02X\n", getInfoRsp->session_control);
98 NXPLOG_FWDNLD_D("Session Type: 0x%02X\n", getInfoRsp->session_type);
99 NXPLOG_FWDNLD_D("ROM Version: 0x%02X\n", getInfoRsp->rom_version);
100 NXPLOG_FWDNLD_D("AT Page Status: 0x%02X\n", getInfoRsp->AT_page_status);
101 NXPLOG_FWDNLD_D("Chip Version: Major.Minor: %02X.%02X\n",
102 getInfoRsp->chip_major_ver, getInfoRsp->chip_minor_ver);
103 NXPLOG_FWDNLD_D("FW Version: Major.Minor: %02X.%02X\n",
104 getInfoRsp->fw_major_ver, getInfoRsp->fw_minor_ver);
105
106 for (i = 0; i != 8; i += 2) { // 4bytes
107 sprintf(&buff[i], "%02X", getInfoRsp->chip_variant[offset++]);
108 }
109 buff[i] = '\0';
110 NXPLOG_FWDNLD_D("Chip Variant: 0x%s\n", buff);
111 NXPLOG_FWDNLD_D("Device Lifecycle: 0x%X\n", getInfoRsp->device_life_cycle);
112
113 for (i = 0, offset = 0; i != 32; i += 2) { // 16bytes
114 sprintf(&buff[i], "%02X", getInfoRsp->chip_id[offset++]);
115 }
116 buff[i] = '\0';
117 NXPLOG_FWDNLD_D("Chip ID: 0x%s\n", buff);
118
119 for (i = 0, offset = 0; i != 8; i += 2) { // 4bytes
120 sprintf(&buff[i], "%02X", getInfoRsp->chip_id_crc[offset++]);
121 }
122 buff[i] = '\0';
123 NXPLOG_FWDNLD_D("Chip ID CRC:0x%s\n", buff);
124 NXPLOG_FWDNLD_D("=====================================================\n");
125 }
126
127 /*******************************************************************************
128 **
129 ** Function : process_getInfo_rsp
130 **
131 ** Description : This function processes the HDLL GetInfo command's response
132 **
133 ** Parameters : payload - Struct in which the processed info will be kept
134 **
135 ** Returns : On failure - NULL
136 On success - Pointer to the phHDLLGetInfo_t struct
137 **
138 **
139 *******************************************************************************/
process_getInfo_rsp(uint8_t * payload)140 phHDLLGetInfo_t *process_getInfo_rsp(uint8_t *payload) {
141 uint8_t offset = 0;
142 phHDLLGetInfo_t *getInfoRsp = NULL;
143 uint8_t device_lc_mode[4] = {0};
144
145 getInfoRsp = (phHDLLGetInfo_t *)malloc(sizeof(phHDLLGetInfo_t));
146 if (NULL == getInfoRsp) {
147 return NULL;
148 }
149 memset(getInfoRsp, 0, sizeof(phHDLLGetInfo_t));
150 getInfoRsp->boot_status = payload[offset++];
151 getInfoRsp->session_control = payload[offset++];
152 getInfoRsp->session_type = payload[offset++];
153 getInfoRsp->rom_version = (eUWBD_Rom_Version_t)payload[offset++];
154 getInfoRsp->AT_page_status = (eUWBD_AT_Page_status_t)payload[offset++];
155 offset += 2; // padding bytes
156 getInfoRsp->chip_major_ver = payload[offset++];
157 getInfoRsp->chip_minor_ver = payload[offset++];
158 getInfoRsp->fw_major_ver = payload[offset++];
159 getInfoRsp->fw_minor_ver = payload[offset++];
160 memcpy(getInfoRsp->chip_variant, payload + offset, sizeof(uint8_t) * 4);
161 offset += 4;
162 memcpy(device_lc_mode, payload + offset, sizeof(uint8_t) * 4);
163 getInfoRsp->device_life_cycle = (eUWBD_LC_mode_t)(device_lc_mode[0] | (device_lc_mode[1] << 8) | (device_lc_mode[2] << 16) | (device_lc_mode[3] << 24));
164 offset += 4;
165 memcpy(getInfoRsp->chip_id, payload + offset, sizeof(uint8_t) * 16);
166 offset += 16;
167 memcpy(getInfoRsp->chip_id_crc, payload + offset, sizeof(uint8_t) * 4);
168 return getInfoRsp;
169 }
170
171 /*******************************************************************************
172 **
173 ** Function : getFwImageCtx
174 **
175 ** Description : This function use to get the FW image context
176 **
177 ** Parameters : pfwImageCtx -> pointer to fw image context
178 **
179 ** Returns : On failure - returns FW_DNLD_FAILURE
180 - or FW_DNLD_FILE_NOT_FOUND if FW file not present
181 in the MW.
182 On success - returns FW_DNLD_SUCCESS.
183 **
184 **
185 *******************************************************************************/
getFwImageCtx(phUwbFWImageContext_t * pfwImageCtx)186 phFWD_Status_t getFwImageCtx(phUwbFWImageContext_t *pfwImageCtx) {
187 phFWD_Status_t status = FW_DNLD_SUCCESS;
188 char *configured_fw_name = NULL;
189 const uint16_t fw_file_max_len = FILENAME_MAXLEN;
190 const char *pDefaultFwFileName = NULL;
191 char* ret = NULL;
192
193 configured_fw_name = (char *)malloc(fw_file_max_len * sizeof(char));
194 int maxSrcLen = (FILEPATH_MAXLEN - strlen(pfwImageCtx->default_fw_path)) - 1;
195 if (configured_fw_name == NULL) {
196 NXPLOG_FWDNLD_E("malloc of configured_fw_name failed ");
197 return FW_DNLD_FAILURE;
198 }
199
200 /* Default FW download configset to bin file */
201 pDefaultFwFileName = default_dev_fw_bin;
202
203 if (!NxpConfig_GetStr(NAME_NXP_UWB_FW_FILENAME, configured_fw_name,
204 fw_file_max_len)) {
205 NXPLOG_FWDNLD_D("Invalid Dev Fw name keeping the default name: %s",
206 pDefaultFwFileName);
207 strncat(pfwImageCtx->default_fw_path, pDefaultFwFileName, maxSrcLen);
208 } else {
209 NXPLOG_FWDNLD_D("configured_fw_name : %s", configured_fw_name);
210 strncat(pfwImageCtx->default_fw_path, configured_fw_name, maxSrcLen);
211 }
212
213 NXPLOG_FWDNLD_D("fw file path : %s", pfwImageCtx->default_fw_path);
214 // Search for so extension in filename
215 ret = strstr(configured_fw_name, default_so_file_extn);
216 if(ret) {
217 pfwImageCtx->fw_dnld_config = SO_FILE_BASED_FW_DOWNLOAD;
218 /* Get Fw Context from so file */
219 status = openFwSoFile(pfwImageCtx);
220 } else {
221 /* Get Fw Context from bin file */
222 status = openFwBinFile(pfwImageCtx);
223 }
224
225 if (configured_fw_name != NULL) {
226 free(configured_fw_name);
227 }
228 memset(pfwImageCtx->default_fw_path, '\0', sizeof(char) * FILEPATH_MAXLEN);
229 strcpy(pfwImageCtx->default_fw_path, "/vendor/firmware/uwb/");
230 return status;
231 }
232
233 /*******************************************************************************
234 **
235 ** Function : printManifestInfo
236 **
237 ** Description : This function is use to get UWB Manifest info
238 **
239 ** Parameters : pfwImageCtx -> pointer to fw image context
240 **
241 ** Returns : On failure - returns FW_DNLD_FAILURE
242 - or FW_DNLD_FILE_NOT_FOUND if FW file not present
243 in the MW.
244 On success - returns FW_DNLD_SUCCESS.
245 **
246 **
247 *******************************************************************************/
printManifest_info(UWBManifest_t * fwLibManifest)248 void printManifest_info(UWBManifest_t *fwLibManifest) {
249
250 if(fwLibManifest == NULL) {
251 return;
252 }
253 NXPLOG_FWDNLD_D("================= FW Lib Manifest ====================\n");
254 NXPLOG_FWDNLD_D("UWB manifest version = %x\n",fwLibManifest->layout_version);
255 NXPLOG_FWDNLD_D("UWB manifest creation year = %d\n",fwLibManifest->creation_date_yy);
256 NXPLOG_FWDNLD_D("UWB manifest creation month = %d\n",fwLibManifest->creation_date_month);
257 NXPLOG_FWDNLD_D("UWB manifest creation day = %d\n",fwLibManifest->creation_date_day);
258 NXPLOG_FWDNLD_D("UWB manifest creation hour = %d\n",fwLibManifest->creation_date_hour);
259 NXPLOG_FWDNLD_D("UWB manifest creation minutes = %d\n",fwLibManifest->creation_date_minutes);
260 NXPLOG_FWDNLD_D("UWB manifest creation seconds = %d\n",fwLibManifest->creation_date_seconds);
261 NXPLOG_FWDNLD_D("UWB manifest count = %d\n",fwLibManifest->countMWCESFW);
262
263 return;
264
265 }
266
267 /*******************************************************************************
268 **
269 ** Function : openFwSoFile
270 **
271 ** Description : This function loads the FW shared library context
272 if the FW file exists otherwise returns failure.
273 **
274 ** Parameters : pfwImageCtx -> pointer to fw image context
275 **
276 ** Returns : On failure - returns FW_DNLD_FAILURE
277 - or FW_DNLD_FILE_NOT_FOUND if FW file not present
278 in the MW.
279 On success - returns FW_DNLD_SUCCESS.
280 **
281 **
282 *******************************************************************************/
openFwSoFile(phUwbFWImageContext_t * pfwImageCtx)283 static phFWD_Status_t openFwSoFile(phUwbFWImageContext_t *pfwImageCtx) {
284 void *flibptr = NULL;
285 UWBManifest_t *currentFwLib = NULL;
286 pfwImageCtx->gFwLib = NULL;
287 phFWD_Status_t status = FW_DNLD_SUCCESS;
288
289 NXPLOG_FWDNLD_D("%s:%d enter", __func__,__LINE__);
290
291 pfwImageCtx->gFwLib = dlopen(pfwImageCtx->default_fw_path, RTLD_LAZY);
292 if (pfwImageCtx->gFwLib == NULL) {
293 // Apparently, the library could not be opened
294 NXPLOG_FWDNLD_E("%s: Error! opening FW file %s\n", __func__,
295 pfwImageCtx->default_fw_path);
296 status = FW_DNLD_FILE_NOT_FOUND;
297 goto cleanup;
298 }
299 flibptr = dlsym(pfwImageCtx->gFwLib, "gUWBManifest");
300 if (!flibptr) {
301 NXPLOG_FWDNLD_E("%s: Could not get function pointer\n", __func__);
302 status = FW_DNLD_FAILURE;
303 goto cleanup;
304 }
305
306 currentFwLib = (UWBManifest_t *)flibptr;
307 if (currentFwLib == NULL) {
308 NXPLOG_FWDNLD_E("%s:%d UwbManifest is null exiting.....", __func__, __LINE__);
309 status = FW_DNLD_FAILURE;
310 goto cleanup;
311 }
312
313 printManifest_info(currentFwLib);
314
315 // read the FW bytes into buffer
316 if (pfwImageCtx->deviceInfo->rom_version == VER_A1V1) {
317 if(currentFwLib->mwCESFW[MWCESFW_A1V1_RECOVERY_FW_OFFSET] == NULL || currentFwLib->mwCESFW[MWCESFW_A1V1_FW_OFFSET] == NULL) {
318 NXPLOG_FWDNLD_E("%s:%d UwbManifest mwCESFW is null exiting.....", __func__, __LINE__);
319 status = FW_DNLD_FAILURE;
320 goto cleanup;
321 }
322 if(pfwImageCtx->deviceInfo->AT_page_status == STATUS_PAGE_ERROR) {
323 pfwImageCtx->fwRecovery = true;
324 pfwImageCtx->fwImgSize = currentFwLib->mwCESFW[MWCESFW_A1V1_RECOVERY_FW_OFFSET]->lenCESFW;
325 pfwImageCtx->fwImage = currentFwLib->mwCESFW[MWCESFW_A1V1_RECOVERY_FW_OFFSET]->pCESFW;
326 } else if((pfwImageCtx->deviceInfo->device_life_cycle == CUSTOMER_MODE) && glcRotation == true) {
327 if(currentFwLib->mwCESFW[MWCESFW_A1V1_LC_FW_OFFSET] == NULL ) {
328 NXPLOG_FWDNLD_E("%s:%d LC FW does not exist.....", __func__, __LINE__);
329 status = FW_DNLD_FAILURE;
330 goto cleanup;
331 } else {
332 pfwImageCtx->fwImgSize = currentFwLib->mwCESFW[MWCESFW_A1V1_LC_FW_OFFSET]->lenCESFW;
333 pfwImageCtx->fwImage = currentFwLib->mwCESFW[MWCESFW_A1V1_LC_FW_OFFSET]->pCESFW;
334 }
335 }else {
336 pfwImageCtx->fwImgSize = currentFwLib->mwCESFW[MWCESFW_A1V1_FW_OFFSET]->lenCESFW;
337 pfwImageCtx->fwImage = currentFwLib->mwCESFW[MWCESFW_A1V1_FW_OFFSET]->pCESFW;
338 }
339 }
340 else if (pfwImageCtx->deviceInfo->rom_version == VER_A1V2) {
341 if(currentFwLib->mwCESFW[MWCESFW_A1V2_RECOVERY_FW_OFFSET] == NULL || currentFwLib->mwCESFW[MWCESFW_A1V2_FW_OFFSET] == NULL) {
342 NXPLOG_FWDNLD_E("%s:%d UwbManifest mwCESFW is null exiting.....", __func__, __LINE__);
343 status = FW_DNLD_FAILURE;
344 goto cleanup;
345 }
346 if(pfwImageCtx->deviceInfo->AT_page_status == STATUS_PAGE_ERROR) {
347 pfwImageCtx->fwRecovery = true;
348 pfwImageCtx->fwImgSize = currentFwLib->mwCESFW[MWCESFW_A1V2_RECOVERY_FW_OFFSET]->lenCESFW;
349 pfwImageCtx->fwImage = currentFwLib->mwCESFW[MWCESFW_A1V2_RECOVERY_FW_OFFSET]->pCESFW;
350 } else if((pfwImageCtx->deviceInfo->device_life_cycle == CUSTOMER_MODE) && glcRotation == true) {
351 if(currentFwLib->mwCESFW[MWCESFW_A1V2_LC_FW_OFFSET] == NULL ) {
352 NXPLOG_FWDNLD_E("%s:%d LC FW does not exist.....", __func__, __LINE__);
353 status = FW_DNLD_FAILURE;
354 goto cleanup;
355 } else {
356 pfwImageCtx->fwImgSize = currentFwLib->mwCESFW[MWCESFW_A1V2_LC_FW_OFFSET]->lenCESFW;
357 pfwImageCtx->fwImage = currentFwLib->mwCESFW[MWCESFW_A1V2_LC_FW_OFFSET]->pCESFW;
358 }
359 } else {
360 pfwImageCtx->fwImgSize = currentFwLib->mwCESFW[MWCESFW_A1V2_FW_OFFSET]->lenCESFW;
361 pfwImageCtx->fwImage = currentFwLib->mwCESFW[MWCESFW_A1V2_FW_OFFSET]->pCESFW;
362 }
363 }
364 if ((!(pfwImageCtx->fwImgSize)) || (NULL == pfwImageCtx->fwImage)) {
365 NXPLOG_FWDNLD_E("%s: Error! File %s is empty\n", __func__, pfwImageCtx->default_fw_path);
366 status = FW_DNLD_FAILURE;
367 goto cleanup;
368 }
369
370 NXPLOG_FWDNLD_E("exiting %s fwImgSize %d" , __func__, pfwImageCtx->fwImgSize);
371
372 return status;
373
374 cleanup:
375 if (pfwImageCtx->gFwLib != NULL) {
376 dlclose(pfwImageCtx->gFwLib);
377 pfwImageCtx->gFwLib = NULL;
378 }
379 return status;
380
381 }
382
383 /*******************************************************************************
384 **
385 ** Function : openFwBinFile
386 **
387 ** Description : This function copies the entire Bin FW file content into a buffer
388 if the FW file exists otherwise returns failure.
389 **
390 ** Parameters : pfwImageCtx -> pointer to fw image context
391 **
392 ** Returns : On failure - returns FW_DNLD_FAILURE
393 - or FW_DNLD_FILE_NOT_FOUND if FW file not present
394 in the MW.
395 On success - returns FW_DNLD_SUCCESS.
396 **
397 **
398 *******************************************************************************/
openFwBinFile(phUwbFWImageContext_t * pfwImageCtx)399 static phFWD_Status_t openFwBinFile(phUwbFWImageContext_t *pfwImageCtx) {
400 phFWD_Status_t status = FW_DNLD_SUCCESS;
401 long int file_size = 0;
402 size_t ret_size = 0;
403 FILE *fptr = NULL;
404
405 NXPLOG_FWDNLD_D("%s:%d enter", __func__,__LINE__);
406
407 // open FW binary file
408 if ((fptr = fopen(pfwImageCtx->default_fw_path, "rb")) == NULL) {
409 NXPLOG_FWDNLD_E("%s: Error! opening FW file %s\n", __func__,
410 pfwImageCtx->default_fw_path);
411 status = FW_DNLD_FILE_NOT_FOUND;
412 goto exit;
413 }
414
415 // find the FW binary file size
416 fseek(fptr, 0L, SEEK_END);
417 file_size = ftell(fptr);
418 if (!file_size || (-1L == file_size)) {
419 NXPLOG_FWDNLD_E("%s: Error! File %s is empty\n", __func__, pfwImageCtx->default_fw_path);
420 status = FW_DNLD_FAILURE;
421 goto exit;
422 }
423 else {
424 pfwImageCtx->fwImgSize = file_size;
425 }
426
427 // read the FW bytes into buffer
428 pfwImageCtx->fwImage = (uint8_t *)malloc(sizeof(uint8_t) * pfwImageCtx->fwImgSize);
429 if (NULL == pfwImageCtx->fwImage)
430 {
431 status = FW_DNLD_FAILURE;
432 NXPLOG_FWDNLD_E("%s: Error in allocating memory\n", __func__);
433 goto exit;
434 }
435 rewind(fptr);
436 ret_size = fread(pfwImageCtx->fwImage, sizeof(uint8_t), pfwImageCtx->fwImgSize, fptr);
437 if (ret_size != pfwImageCtx->fwImgSize) {
438 if (feof(fptr))
439 {
440 NXPLOG_FWDNLD_E("%s: Error reading file %s, unexpected end of file\n",
441 __func__, pfwImageCtx->default_fw_path);
442 }
443 else if (ferror(fptr))
444 {
445 NXPLOG_FWDNLD_E("%s: Error reading file %s\n", __func__, pfwImageCtx->default_fw_path);
446 }
447 status = FW_DNLD_FAILURE;
448 goto exit;
449 }
450
451 exit:
452 if (NULL != fptr)
453 {
454 fclose(fptr);
455 }
456
457 return status;
458 }
459
460 /*******************************************************************************
461 **
462 ** Function : check_fw_update_required
463 **
464 ** Description : This function checks whether FW update is required or not
465 based on FW version from MW binary and FW version present in
466 the HeliosX chip.
467 **
468 ** Parameters : getInfoRsp - Struct which has the GetInfo response details.
469 **
470 ** Returns : FW_DNLD_FAILURE - If any un expected failure
471 FW_DNLD_NOT_REQUIRED - FW update not required
472 FW_DNLD_REQUIRED - FW update required
473 FW_DNLD_FILE_NOT_FOUND - if the FW bin file is unable to
474 open or not present
475 **
476 **
477 *******************************************************************************/
check_fw_update_required(phHDLLGetInfo_t * getInfoRsp)478 phFWD_Status_t check_fw_update_required(phHDLLGetInfo_t *getInfoRsp) {
479 uint32_t next_frame_first_byte_index = 0;
480 uint32_t index = 0;
481 uint8_t mw_fw_major_ver = 0;
482 uint8_t mw_fw_minor_ver = 0;
483 uint32_t frame_payload_length = 0;
484 uint32_t frame_length = 0;
485 unsigned long num = 0;
486 phFWD_Status_t status = FW_DNLD_FAILURE;
487
488 fwImageCtx.deviceInfo = getInfoRsp;
489 fwImageCtx.fw_dnld_config = BIN_FILE_BASED_FW_DOWNLOAD;
490 fwImageCtx.fw_flash_config = FLASH_UPPER_VER_UPDATE;
491 fwImageCtx.fwRecovery = false;
492 strcpy(fwImageCtx.default_fw_path, default_fw_path);
493
494 status = getFwImageCtx(&fwImageCtx);
495 if (status != FW_DNLD_SUCCESS) {
496 return status;
497 }
498
499 if (NxpConfig_GetNum(NAME_NXP_UWB_FLASH_CONFIG, &num, sizeof(num))) {
500 fwImageCtx.fw_flash_config = (uint8_t)num;
501 NXPLOG_FWDNLD_D("NAME_NXP_UWB_FLASH_CONFIG: 0x%02x\n", fwImageCtx.fw_flash_config);
502 if (!(fwImageCtx.fw_flash_config == FLASH_UPPER_VER_UPDATE ||
503 fwImageCtx.fw_flash_config == FLASH_DIFFERENT_VER_UPDATE ||
504 fwImageCtx.fw_flash_config == FLASH_FORCE_UPDATE))
505 {
506 fwImageCtx.fw_flash_config = FLASH_UPPER_VER_UPDATE;
507 }
508 }
509 else {
510 NXPLOG_FWDNLD_D("NAME_NXP_UWB_FLASH_CONFIG: failed 0x%02x\n",
511 fwImageCtx.fw_flash_config);
512 }
513
514 frame_payload_length = (fwImageCtx.fwImage[next_frame_first_byte_index] << 8) +
515 (fwImageCtx.fwImage[next_frame_first_byte_index + 1]);
516 frame_length = frame_payload_length + HDLL_HEADER_LEN + HDLL_FOOTER_LEN;
517
518 // get the index of first_write_cmd_payload
519 next_frame_first_byte_index = next_frame_first_byte_index + frame_length;
520 index = next_frame_first_byte_index;
521 mw_fw_major_ver = fwImageCtx.fwImage[index + MW_MAJOR_FW_VER_OFFSET];
522 mw_fw_minor_ver = fwImageCtx.fwImage[index + MW_MINOR_FW_VER_OFFSET];
523 NXPLOG_FWDNLD_D("mw_fw_ver: %02X.%02X chip_fw_ver: %02X.%02X\n",
524 mw_fw_major_ver, mw_fw_minor_ver, getInfoRsp->fw_major_ver,
525 getInfoRsp->fw_minor_ver);
526
527 if(getInfoRsp->session_control == SESSION_CONTROL_OPEN){
528 NXPLOG_FWDNLD_D("FW Update required as session control is open \n");
529 status = FW_DNLD_REQUIRED;
530 } else {
531 switch (fwImageCtx.fw_flash_config) {
532 case FLASH_UPPER_VER_UPDATE: {
533 if (mw_fw_major_ver > getInfoRsp->fw_major_ver) {
534 NXPLOG_FWDNLD_D("FLASH_UPPER_VER_UPDATE:FW Update required\n");
535 status = FW_DNLD_REQUIRED;
536 } else if (mw_fw_major_ver == getInfoRsp->fw_major_ver) {
537 if (mw_fw_minor_ver > getInfoRsp->fw_minor_ver) {
538 NXPLOG_FWDNLD_D("FLASH_UPPER_VER_UPDATE:FW Update required\n");
539 status = FW_DNLD_REQUIRED;
540 } else {
541 NXPLOG_FWDNLD_E(
542 "FLASH_UPPER_VER_UPDATE:FW lower Minor version is not supported\n");
543 status = FW_DNLD_NOT_REQUIRED;
544 }
545 } else {
546 NXPLOG_FWDNLD_E(
547 "FLASH_UPPER_VER_UPDATE:FW lower Major version is not supported\n");
548 status = FW_DNLD_NOT_REQUIRED;
549 }
550 } break;
551 case FLASH_FORCE_UPDATE: {
552 if (mw_fw_major_ver < getInfoRsp->fw_major_ver) {
553 NXPLOG_FWDNLD_E(
554 "FLASH_FORCE_UPDATE:FW lower Major version is not supported\n");
555 status = FW_DNLD_NOT_REQUIRED;
556 } else {
557 NXPLOG_FWDNLD_D("FLASH_FORCE_UPDATE:FW Update required\n");
558 status = FW_DNLD_REQUIRED;
559 }
560 } break;
561 case FLASH_DIFFERENT_VER_UPDATE: {
562 if (mw_fw_major_ver > getInfoRsp->fw_major_ver) {
563 NXPLOG_FWDNLD_D("FLASH_DIFFERENT_VER_UPDATE:FW Update required\n");
564 status = FW_DNLD_REQUIRED;
565 } else if(mw_fw_major_ver == getInfoRsp->fw_major_ver) {
566 if(mw_fw_minor_ver == getInfoRsp->fw_minor_ver) {
567 NXPLOG_FWDNLD_E(
568 "FLASH_DIFFERENT_VER_UPDATE:Same Minor FW version update is not supported\n");
569 status = FW_DNLD_NOT_REQUIRED;
570 } else {
571 NXPLOG_FWDNLD_E(
572 "FLASH_DIFFERENT_VER_UPDATE:FW Update required\n");
573 status = FW_DNLD_REQUIRED;
574 }
575 } else {
576 NXPLOG_FWDNLD_D("FLASH_DIFFERENT_VER_UPDATE:lower Major FW version update is not supported\n");
577 status = FW_DNLD_NOT_REQUIRED;;
578 }
579 } break;
580 }
581 }
582 return status;
583 }
584
585 /*******************************************************************************
586 **
587 ** Function : handleGetInfoRsp
588 **
589 ** Description : This function handles the GetInfo response that is received
590 from the HeliosX chip.
591 **
592 ** Parameters : hdll_payload - HDLL response buffer
593 **
594 ** Returns : FW_DNLD_FAILURE - If any un expected failure
595 FW_DNLD_NOT_REQUIRED - FW update not required
596 FW_DNLD_REQUIRED - FW update required
597 FW_DNLD_FILE_NOT_FOUND - if the FW bin file is unable to
598 open or not present
599 **
600 **
601 *******************************************************************************/
handleGetInfoRsp(uint8_t * hdll_payload)602 phFWD_Status_t handleGetInfoRsp(uint8_t *hdll_payload) {
603 phFWD_Status_t ret = FW_DNLD_FAILURE;
604 phHDLLGetInfo_t *getInfoRsp = NULL;
605
606 getInfoRsp = process_getInfo_rsp(hdll_payload);
607 if (NULL == getInfoRsp) {
608 return ret;
609 }
610 print_getInfoRsp(getInfoRsp);
611 ret = check_fw_update_required(getInfoRsp);
612
613 if (NULL != getInfoRsp) {
614 free(getInfoRsp);
615 }
616 return ret;
617 }
618
619 /*******************************************************************************
620 **
621 ** Function : printHDLLRspStatus
622 **
623 ** Description : This function prints the HDLL response status string based on
624 the given status code
625
626 ** Parameters : status - status code
627 **
628 ** Returns : None
629 **
630 **
631 *******************************************************************************/
632
printHDLLRspStatus(uint8_t status)633 void printHDLLRspStatus(uint8_t status) {
634 switch (status) {
635 case GENERIC_SUCCESS:
636 NXPLOG_FWDNLD_D("Received status: GENERIC_SUCCESS");
637 break;
638 case ACKNOWLEDGE:
639 NXPLOG_FWDNLD_D("Received status: ACKNOWLEDGE");
640 break;
641 case READY:
642 NXPLOG_FWDNLD_D("Received status: READY");
643 break;
644 case GENERIC_ERROR:
645 NXPLOG_FWDNLD_D("Received status: GENERIC_ERROR");
646 break;
647 case MEMORY_ERROR:
648 NXPLOG_FWDNLD_D("Received status: MEMORY_ERROR");
649 break;
650 case TIMEOUT_ERROR:
651 NXPLOG_FWDNLD_D("Received status: TIMEOUT_ERROR");
652 break;
653 case CRC_ERROR:
654 NXPLOG_FWDNLD_D("Received status: CRC_ERROR");
655 break;
656 case INVALID_ERROR:
657 NXPLOG_FWDNLD_D("Received status: INVALID_ERROR");
658 break;
659 case INVALID_LENGTH_ERROR:
660 NXPLOG_FWDNLD_D("Received status: INVALID_LENGTH_ERROR");
661 break;
662 case INVALID_ADDRESS_ERROR:
663 NXPLOG_FWDNLD_D("Received status: INVALID_ADDRESS_ERROR");
664 break;
665 case ECC_SIGNATURE_ERROR:
666 NXPLOG_FWDNLD_D("Received status: ECC_SIGNATURE_ERROR");
667 break;
668 case SHA384_HASH_ERROR:
669 NXPLOG_FWDNLD_D("Received status: SHA384_HASH_ERROR");
670 break;
671 case LIFECYCLE_VALIDITY_ERROR:
672 NXPLOG_FWDNLD_D("Received status: LIFECYCLE_VALIDITY_ERROR");
673 break;
674 case CHIP_ID_ERROR:
675 NXPLOG_FWDNLD_D("Received status: CHIP_ID_ERROR");
676 break;
677 case CHIP_VERSION_ERROR:
678 NXPLOG_FWDNLD_D("Received status: CHIP_VERSION_ERROR");
679 break;
680 case CERTIFICATE_VERSION_ERROR:
681 NXPLOG_FWDNLD_D("Received status: CERTIFICATE_VERSION_ERROR");
682 break;
683 case FIRMWARE_VERSION_ERROR:
684 NXPLOG_FWDNLD_D("Received status: FIRMWARE_VERSION_ERROR");
685 break;
686 case SRAM_DOWNLOAD_ALLOW_ERROR:
687 NXPLOG_FWDNLD_D("Received status: SRAM_DOWNLOAD_ALLOW_ERROR");
688 break;
689 case KEY_DERIVATION_ERROR:
690 NXPLOG_FWDNLD_D("Received status: KEY_DERIVATION_ERROR");
691 break;
692 case ENCRYPTED_PAYLOAD_DECRYPTION_ERROR:
693 NXPLOG_FWDNLD_D("Received status: ENCRYPTED_PAYLOAD_DECRYPTION_ERROR");
694 break;
695 case INVALID_ENCRYPTED_PAYLOAD_ERROR:
696 NXPLOG_FWDNLD_D("Received status: INVALID_ENCRYPTED_PAYLOAD_ERROR");
697 break;
698 case PROTECTED_CACHE_LOAD_ERROR:
699 NXPLOG_FWDNLD_D("Received status: PROTECTED_CACHE_LOAD_ERROR");
700 break;
701 case PROTECTED_CACHE_DEPLOY_ERROR:
702 NXPLOG_FWDNLD_D("Received status: PROTECTED_CACHE_DEPLOY_ERROR");
703 break;
704 case LIFECYCLE_UPDATE_ERROR:
705 NXPLOG_FWDNLD_D("Received status: LIFECYCLE_UPDATE_ERROR");
706 break;
707 case FLASH_BLANK_PAGE_ERROR:
708 NXPLOG_FWDNLD_D("Received status: FLASH_BLANK_PAGE_ERROR");
709 break;
710 case FLASH_CHECK_MARGIN_ERROR:
711 NXPLOG_FWDNLD_D("Received status: FLASH_CHECK_MARGIN_ERROR");
712 break;
713 default:
714 break;
715 };
716 }
717
718 /*******************************************************************************
719 **
720 ** Function : process_hdll_response
721 **
722 ** Description : This function processes the HDLL response
723
724 ** Parameters : hdllCmdRsp - HDLL command response structure which has the
725 received response info as well as the expected
726 response info.
727 **
728 ** Returns : FW_DNLD_FAILURE - If any undesired response received
729 FW_DNLD_SUCCESS - On proper response
730 **
731 **
732 *******************************************************************************/
733
734 /*
735 * HDLL Response:
736 * <-------HDLL Header--->|<------------------HDLL payload--------------------->
737 * <-------HDLL (2bytes)->|<-----HCP (2bytes)------->|<-Application--> <--CRC-->
738 * <31 30> <29> <28 -16> |<15 -14><13 - 8> <7 - 0> |<status><Payload><2 bytes>
739 * <--R--><Chunk><length> |< Type ><Group><Operation>|<1 byte>
740 *
741 */
process_hdll_response(phHDLLCmdRsp_t * hdllCmdRsp)742 phFWD_Status_t process_hdll_response(phHDLLCmdRsp_t *hdllCmdRsp) {
743 uint8_t hdll_msg_type = 0;
744 uint8_t hdll_rsp_status = 0;
745 uint16_t hdll_packet_len = 0;
746 uint8_t hdll_group = 0;
747 uint8_t hdll_operation = 0;
748 uint8_t *hdll_payload = NULL;
749 uint16_t hdll_payload_len = 0;
750 phFWD_Status_t ret = FW_DNLD_FAILURE;
751
752 if (hdllCmdRsp == NULL || hdllCmdRsp->rsp_buf == NULL) {
753 NXPLOG_FWDNLD_E("%s HDLL response buffer is NULL\n", __func__);
754 return ret;
755 }
756 if (hdllCmdRsp->rsp_buf_len < HDLL_MIN_RSP_LEN) {
757 NXPLOG_FWDNLD_E(
758 "%s Error! HDLL response buffer length is %d, expected min %d bytes\n",
759 __func__, hdllCmdRsp->rsp_buf_len, HDLL_MIN_RSP_LEN);
760 return ret;
761 }
762
763 // parse hdll frame
764 hdll_packet_len = (uint16_t)(hdllCmdRsp->rsp_buf[0] << 8) |
765 (hdllCmdRsp->rsp_buf[HDLL_LEN_OFFSET]);
766 hdll_packet_len &= HDLL_PKT_LEN_BITMASK;
767 NXPLOG_FWDNLD_D("Received RSP packet len :0x%04X\n", hdll_packet_len);
768 if (hdll_packet_len == 0) {
769 NXPLOG_FWDNLD_D("Error in hdll response.. hdll_packet_len = 0\n");
770 return ret;
771 }
772
773 hdll_msg_type = hdllCmdRsp->rsp_buf[HDLL_TYPE_OFFSET] >> HCP_GROUP_LEN;
774 hdll_group =
775 (hdllCmdRsp->rsp_buf[HDLL_GROUP_OFFSET] & HDLL_RSP_GROUP_BIT_MASK);
776 hdll_operation = hdllCmdRsp->rsp_buf[HDLL_OPERATION_OFFSET];
777 hdll_rsp_status = hdllCmdRsp->rsp_buf[HDLL_RSP_STATUS_OFFSET];
778
779 NXPLOG_FWDNLD_D("Received RSP msg type :0x%02X\n", hdll_msg_type);
780 NXPLOG_FWDNLD_D("Received RSP group operation :0x%02X%02X\n", hdll_group,
781 hdll_operation);
782 NXPLOG_FWDNLD_D("Received RSP status code :0x%02X\n", hdll_rsp_status);
783 printHDLLRspStatus(hdll_rsp_status);
784
785 hdll_payload_len = hdllCmdRsp->rsp_buf_len - (HDLL_RSP_PAYLOAD_OFFSET + HDLL_CRC_LEN);
786 NXPLOG_FWDNLD_D("hdll payload len = 0x%02x" , hdll_payload_len);
787
788 if (hdll_payload_len > 0) {
789 hdll_payload = (uint8_t *)malloc(
790 sizeof(uint8_t) *
791 (hdll_payload_len));
792 if (NULL == hdll_payload) {
793 return ret;
794 }
795 memcpy(hdll_payload, &hdllCmdRsp->rsp_buf[HDLL_RSP_PAYLOAD_OFFSET],
796 hdll_payload_len);
797 }
798
799 // validate the response
800 if (hdllCmdRsp->status != hdll_rsp_status) {
801 NXPLOG_FWDNLD_D("Error! expected response status code is 0x%02X but "
802 "received 0x%02X\n",
803 hdllCmdRsp->status, hdll_rsp_status);
804 ret = FW_DNLD_FAILURE;
805 } else if (hdllCmdRsp->type != hdll_msg_type) {
806 NXPLOG_FWDNLD_D(
807 "Error! expected HDLL type code is 0x%02X but received 0x%02X\n",
808 hdllCmdRsp->type, hdll_msg_type);
809 ret = FW_DNLD_FAILURE;
810 } else if ((hdllCmdRsp->group != hdll_group) ||
811 (hdllCmdRsp->operation != hdll_operation)) {
812 NXPLOG_FWDNLD_D("Error! expected response operation code is 0x%02X%02X but "
813 "received 0x%02X%02X \n",
814 hdllCmdRsp->group, hdllCmdRsp->operation, hdll_group,
815 hdll_operation);
816 ret = FW_DNLD_FAILURE;
817 } else
818 {
819 ret = FW_DNLD_SUCCESS;
820 }
821
822 if (ret == FW_DNLD_FAILURE){
823 goto exit;
824 }
825
826 // Handle the response according to the operation
827 switch (hdll_group) {
828 case HCP_OPERATION_GROUP_PROTOCOL: {
829 switch (hdll_operation) {
830 case PROTOCOL_GROUP_OP_CODE_HDLL: {
831 NXPLOG_FWDNLD_D("Received PROTOCOL_GROUP_HDLL_OP_CODE\n");
832 } break;
833 case PROTOCOL_GROUP_OP_CODE_HCP: {
834 NXPLOG_FWDNLD_D("Received PROTOCOL_GROUP_HCP_OP_CODE\n");
835 } break;
836 case PROTOCOL_GROUP_OP_CODE_EDL: {
837 NXPLOG_FWDNLD_D("Received PROTOCOL_GROUP_EDL_OP_CODE\n");
838 } break;
839 }
840 } break;
841
842 case HCP_OPERATION_GROUP_GENERIC: {
843 switch (hdll_operation) {
844 case GENERIC_GROUP_OP_CODE_RESET: {
845 NXPLOG_FWDNLD_D("Received OP_GENERIC_RESET\n");
846 // Generic reset cmd will have the rsp only in case of error.
847 // How to handle the situation.
848 } break;
849 case GENERIC_GROUP_OP_CODE_GETINFO: {
850 NXPLOG_FWDNLD_D("Received OP_GENERIC_GET_INFO\n");
851 if (hdll_payload != NULL) {
852 ret = handleGetInfoRsp(hdll_payload);
853 }
854 } break;
855 }
856 } break;
857
858 case HCP_OPERATION_GROUP_EDL: {
859 switch (hdll_operation) {
860 case EDL_DOWNLOAD_CERTIFICATE: {
861 NXPLOG_FWDNLD_D("Received OP_EDL_DOWNLOAD_CERTIFICATE\n");
862 } break;
863 case EDL_DOWNLOAD_FLASH_WRITE_FIRST: {
864 NXPLOG_FWDNLD_D("Received OP_EDL_DOWNLOAD_FLASH_WRITE_FIRST\n");
865 }
866 break;
867 case EDL_DOWNLOAD_FLASH_WRITE: {
868 NXPLOG_FWDNLD_D("Received OP_EDL_DOWNLOAD_FLASH_WRITE\n");
869 } break;
870 case EDL_DOWNLOAD_FLASH_WRITE_LAST: {
871 NXPLOG_FWDNLD_D("Received OP_EDL_DOWNLOAD_FLASH_WRITE_LAST\n");
872 } break;
873 case EDL_DOWNLOAD_SRAM_WRITE_FIRST: {
874 NXPLOG_FWDNLD_D("Received OP_EDL_DOWNLOAD_SRAM_WRITE_FIRST\n");
875 } break;
876 case EDL_DOWNLOAD_SRAM_WRITE: {
877 NXPLOG_FWDNLD_D("Received OP_EDL_DOWNLOAD_SRAM_WRITE\n");
878 } break;
879 case EDL_DOWNLOAD_SRAM_WRITE_LAST: {
880 NXPLOG_FWDNLD_D("Received OP_EDL_DOWNLOAD_SRAM_WRITE_LAST\n");
881 } break;
882 case EDL_LIFECYCLE_CERTIFICATE: {
883 NXPLOG_FWDNLD_D("Received OP_EDL_LIFECYCLE_CERTIFICATE\n");
884 } break;
885 case EDL_LIFECYCLE_WRITE_FIRST: {
886 NXPLOG_FWDNLD_D("Received OP_EDL_LIFECYCLE_WRITE_FIRST\n");
887 } break;
888 case EDL_LIFECYCLE_WRITE_LAST: {
889 NXPLOG_FWDNLD_D("Received OP_EDL_LIFECYCLE_WRITE_LAST\n");
890 } break;
891 case EDL_PATCH_SRAM_WRITE: {
892 NXPLOG_FWDNLD_D("Received OP_EDL_PATCH_SRAM_WRITE\n");
893 } break;
894 case EDL_PATCH_SRAM_WRITE_LAST: {
895 NXPLOG_FWDNLD_D("Received OP_EDL_PATCH_SRAM_WRITE_LAST\n");
896 } break;
897 case EDL_PATCH_FLASH_WRITE: {
898 NXPLOG_FWDNLD_D("Received OP_EDL_PATCH_FLASH_WRITE\n");
899 } break;
900 }
901 } break;
902 default:
903 break;
904 }
905
906 exit:
907 if (hdll_payload != NULL) {
908 free(hdll_payload);
909 }
910 return ret;
911 }
912
913 /*******************************************************************************
914 **
915 ** Function : sendEdlDownloadCertificateCmd
916 **
917 ** Description : This function frames the EdlDownloadCertificateCmd which
918 needs to be sent as part of FW download sequence.
919 **
920 ** Parameters : payload - HDLL command buffer
921 len - command buffer length
922 rsp_buf - response buffer that will be received from the
923 HeliosX chip.
924 **
925 ** Returns : FW_DNLD_FAILURE - If any undesired response received
926 FW_DNLD_SUCCESS - On proper response
927 **
928 **
929 *******************************************************************************/
sendEdlDownloadCertificateCmd(uint8_t * payload,uint16_t len,uint8_t * rsp_buf)930 phFWD_Status_t sendEdlDownloadCertificateCmd(uint8_t *payload, uint16_t len,
931 uint8_t *rsp_buf) {
932
933 uint16_t rsp_buf_len = 0x0;
934 phFWD_Status_t ret = FW_DNLD_SUCCESS;
935 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
936
937 ret = phGenericSendAndRecv(payload, len, rsp_buf, &rsp_buf_len);
938 if (!rsp_buf_len || ret == FW_DNLD_FAILURE) {
939 NXPLOG_FWDNLD_D("Error in sending/receiving OP_EDL_DOWNLOAD_CERTIFICATE "
940 "cmd/response\n");
941 return ret;
942 }
943
944 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
945 if (NULL == hdllCmdRsp) {
946 return ret;
947 }
948
949 hdllCmdRsp->group = HCP_OPERATION_GROUP_EDL;
950 hdllCmdRsp->operation = EDL_DOWNLOAD_CERTIFICATE;
951 hdllCmdRsp->rsp_buf = rsp_buf;
952 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
953 hdllCmdRsp->status = GENERIC_SUCCESS;
954 hdllCmdRsp->type = HCP_TYPE_RESPONSE;
955 ret = process_hdll_response(hdllCmdRsp);
956
957 if (NULL != hdllCmdRsp) {
958 free(hdllCmdRsp);
959 }
960
961 return ret;
962 }
963
964 /*******************************************************************************
965 **
966 ** Function : sendEdlFlashWriteFirstCmd
967 **
968 ** Description : This function frames the EdlFlashWriteFirstCmd which
969 needs to be sent as part of FW download sequence.
970 **
971 ** Parameters : payload - HDLL command buffer
972 len - command buffer length
973 rsp_buf - response buffer that will be received from the
974 HeliosX chip.
975 **
976 ** Returns : FW_DNLD_FAILURE - If any undesired response received
977 FW_DNLD_SUCCESS - On proper response
978 **
979 **
980 *******************************************************************************/
sendEdlFlashWriteFirstCmd(uint8_t * payload,uint16_t len,uint8_t * rsp_buf)981 phFWD_Status_t sendEdlFlashWriteFirstCmd(uint8_t *payload, uint16_t len,
982 uint8_t *rsp_buf) {
983 uint16_t rsp_buf_len = 0x0;
984 phFWD_Status_t ret = FW_DNLD_SUCCESS;
985 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
986
987 ret = phGenericSendAndRecv(payload, len, rsp_buf, &rsp_buf_len);
988 if (!rsp_buf_len || ret == FW_DNLD_FAILURE) {
989 NXPLOG_FWDNLD_D("Error in sending/receiving "
990 "OP_EDL_DOWNLOAD_FLASH_WRITE_FIRST cmd/response\n");
991 return ret;
992 }
993
994 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
995 if (NULL == hdllCmdRsp) {
996 return ret;
997 }
998
999 hdllCmdRsp->group = HCP_OPERATION_GROUP_EDL;
1000 hdllCmdRsp->operation = EDL_DOWNLOAD_FLASH_WRITE_FIRST;
1001 hdllCmdRsp->rsp_buf = rsp_buf;
1002 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1003 hdllCmdRsp->status = GENERIC_SUCCESS;
1004 hdllCmdRsp->type = HCP_TYPE_RESPONSE;
1005 ret = process_hdll_response(hdllCmdRsp);
1006
1007 if (NULL != hdllCmdRsp) {
1008 free(hdllCmdRsp);
1009 }
1010
1011 return ret;
1012 }
1013
1014 /*******************************************************************************
1015 **
1016 ** Function : sendEdlFlashWriteCmd
1017 **
1018 ** Description : This function frames the sendEdlFlashWriteCmd which
1019 will have the actual FW chunk.
1020 **
1021 ** Parameters : payload - HDLL command buffer
1022 len - command buffer length
1023 rsp_buf - response buffer that will be received from the
1024 HeliosX chip.
1025 **
1026 ** Returns : FW_DNLD_FAILURE - If any undesired response received
1027 FW_DNLD_SUCCESS - On proper response
1028 **
1029 **
1030 *******************************************************************************/
sendEdlFlashWriteCmd(uint8_t * payload,uint16_t len,uint8_t * rsp_buf)1031 phFWD_Status_t sendEdlFlashWriteCmd(uint8_t *payload, uint16_t len,
1032 uint8_t *rsp_buf) {
1033 uint16_t rsp_buf_len = 0x0;
1034 phFWD_Status_t ret = FW_DNLD_SUCCESS;
1035 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
1036
1037 ret = phGenericSendAndRecv(payload, len, rsp_buf, &rsp_buf_len);
1038 if (!rsp_buf_len || ret == FW_DNLD_FAILURE) {
1039 NXPLOG_FWDNLD_D("Error in sending/receiving OP_EDL_DOWNLOAD_FLASH_WRITE "
1040 "cmd/response\n");
1041 return ret;
1042 }
1043
1044 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
1045 if (NULL == hdllCmdRsp) {
1046 return ret;
1047 }
1048
1049 hdllCmdRsp->group = HCP_OPERATION_GROUP_EDL;
1050 hdllCmdRsp->operation = EDL_DOWNLOAD_FLASH_WRITE;
1051 hdllCmdRsp->rsp_buf = rsp_buf;
1052 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1053 hdllCmdRsp->status = GENERIC_SUCCESS;
1054 hdllCmdRsp->type = HCP_TYPE_RESPONSE;
1055 ret = process_hdll_response(hdllCmdRsp);
1056
1057 if (NULL != hdllCmdRsp) {
1058 free(hdllCmdRsp);
1059 }
1060
1061 return ret;
1062 }
1063
1064 /*******************************************************************************
1065 **
1066 ** Function : sendEdlFlashWriteLastCmd
1067 **
1068 ** Description : This function frames the EdlFlashWriteLastCmd which
1069 needs to be sent as part of FW download sequence.
1070 **
1071 ** Parameters : payload - HDLL command buffer
1072 len - command buffer length
1073 rsp_buf - response buffer that will be received from the
1074 HeliosX chip.
1075 **
1076 ** Returns : FW_DNLD_FAILURE - If any undesired response received
1077 FW_DNLD_SUCCESS - On proper response
1078 **
1079 **
1080 *******************************************************************************/
sendEdlFlashWriteLastCmd(uint8_t * payload,uint16_t len,uint8_t * rsp_buf)1081 phFWD_Status_t sendEdlFlashWriteLastCmd(uint8_t *payload, uint16_t len,
1082 uint8_t *rsp_buf) {
1083 uint16_t rsp_buf_len = 0x0;
1084 phFWD_Status_t ret = FW_DNLD_SUCCESS;
1085 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
1086
1087 ret = phGenericSendAndRecv(payload, len, rsp_buf, &rsp_buf_len);
1088 if (!rsp_buf_len || ret == FW_DNLD_FAILURE) {
1089 NXPLOG_FWDNLD_D("Error in sending/receiving "
1090 "OP_EDL_DOWNLOAD_FLASH_WRITE_LAST cmd/response\n");
1091 return ret;
1092 }
1093
1094 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
1095 if (NULL == hdllCmdRsp) {
1096 return ret;
1097 }
1098
1099 hdllCmdRsp->group = HCP_OPERATION_GROUP_EDL;
1100 hdllCmdRsp->operation = EDL_DOWNLOAD_FLASH_WRITE_LAST;
1101 hdllCmdRsp->rsp_buf = rsp_buf;
1102 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1103 hdllCmdRsp->status = GENERIC_SUCCESS;
1104 hdllCmdRsp->type = HCP_TYPE_RESPONSE;
1105 ret = process_hdll_response(hdllCmdRsp);
1106
1107 if (NULL != hdllCmdRsp) {
1108 free(hdllCmdRsp);
1109 }
1110
1111 return ret;
1112 }
1113
1114 /*******************************************************************************
1115 **
1116 ** Function : sendEdlLifecycleCertificateCmd
1117 **
1118 ** Description : This function frames the EdlLifecycleCertificateCmd which
1119 needs to be sent as part of Lifecycle update.
1120 **
1121 ** Parameters : payload - HDLL command buffer
1122 len - command buffer length
1123 rsp_buf - response buffer that will be received from the
1124 HeliosX chip.
1125 **
1126 ** Returns : FW_DNLD_FAILURE - If any undesired response received
1127 FW_DNLD_SUCCESS - On proper response
1128 **
1129 **
1130 *******************************************************************************/
sendEdlLifecycleCertificateCmd(uint8_t * payload,uint16_t len,uint8_t * rsp_buf)1131 phFWD_Status_t sendEdlLifecycleCertificateCmd(uint8_t *payload, uint16_t len,
1132 uint8_t *rsp_buf) {
1133 uint16_t rsp_buf_len = 0x0;
1134 phFWD_Status_t ret = FW_DNLD_SUCCESS;
1135 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
1136
1137 ret = phGenericSendAndRecv(payload, len, rsp_buf, &rsp_buf_len);
1138 if (!rsp_buf_len || ret == FW_DNLD_FAILURE) {
1139 NXPLOG_FWDNLD_D("Error in sending/receiving "
1140 "EDL_LIFECYCLE_CERTIFICATE cmd/response\n");
1141 return ret;
1142 }
1143
1144 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
1145 if (NULL == hdllCmdRsp) {
1146 return ret;
1147 }
1148
1149 hdllCmdRsp->group = HCP_OPERATION_GROUP_EDL;
1150 hdllCmdRsp->operation = EDL_LIFECYCLE_CERTIFICATE;
1151 hdllCmdRsp->rsp_buf = rsp_buf;
1152 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1153 hdllCmdRsp->status = GENERIC_SUCCESS;
1154 hdllCmdRsp->type = HCP_TYPE_RESPONSE;
1155 ret = process_hdll_response(hdllCmdRsp);
1156
1157 if (NULL != hdllCmdRsp) {
1158 free(hdllCmdRsp);
1159 }
1160
1161 return ret;
1162 }
1163
1164 /*******************************************************************************
1165 **
1166 ** Function : sendEdlLifecycleWriteFirstCmd
1167 **
1168 ** Description : This function frames the EdlLifecycleWriteFirstCmd which
1169 needs to be sent as part of Lifecycle update.
1170 **
1171 ** Parameters : payload - HDLL command buffer
1172 len - command buffer length
1173 rsp_buf - response buffer that will be received from the
1174 HeliosX chip.
1175 **
1176 ** Returns : FW_DNLD_FAILURE - If any undesired response received
1177 FW_DNLD_SUCCESS - On proper response
1178 **
1179 **
1180 *******************************************************************************/
sendEdlLifecycleWriteFirstCmd(uint8_t * payload,uint16_t len,uint8_t * rsp_buf)1181 phFWD_Status_t sendEdlLifecycleWriteFirstCmd(uint8_t *payload, uint16_t len,
1182 uint8_t *rsp_buf) {
1183 uint16_t rsp_buf_len = 0x0;
1184 phFWD_Status_t ret = FW_DNLD_SUCCESS;
1185 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
1186
1187 ret = phGenericSendAndRecv(payload, len, rsp_buf, &rsp_buf_len);
1188 if (!rsp_buf_len || ret == FW_DNLD_FAILURE) {
1189 NXPLOG_FWDNLD_D("Error in sending/receiving "
1190 "EDL_LIFECYCLE_WRITE_FIRST cmd/response\n");
1191 return ret;
1192 }
1193
1194 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
1195 if (NULL == hdllCmdRsp) {
1196 return ret;
1197 }
1198
1199 hdllCmdRsp->group = HCP_OPERATION_GROUP_EDL;
1200 hdllCmdRsp->operation = EDL_LIFECYCLE_WRITE_FIRST;
1201 hdllCmdRsp->rsp_buf = rsp_buf;
1202 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1203 hdllCmdRsp->status = GENERIC_SUCCESS;
1204 hdllCmdRsp->type = HCP_TYPE_RESPONSE;
1205 ret = process_hdll_response(hdllCmdRsp);
1206
1207 if (NULL != hdllCmdRsp) {
1208 free(hdllCmdRsp);
1209 }
1210
1211 return ret;
1212 }
1213
1214 /*******************************************************************************
1215 **
1216 ** Function : sendEdlLifecycleWriteLastCmd
1217 **
1218 ** Description : This function frames the EdlLifecycleWriteLastCmd which
1219 needs to be sent as part of Lifecycle update.
1220 **
1221 ** Parameters : payload - HDLL command buffer
1222 len - command buffer length
1223 rsp_buf - response buffer that will be received from the
1224 HeliosX chip.
1225 **
1226 ** Returns : FW_DNLD_FAILURE - If any undesired response received
1227 FW_DNLD_SUCCESS - On proper response
1228 **
1229 **
1230 *******************************************************************************/
sendEdlLifecycleWriteLastCmd(uint8_t * payload,uint16_t len,uint8_t * rsp_buf)1231 phFWD_Status_t sendEdlLifecycleWriteLastCmd(uint8_t *payload, uint16_t len,
1232 uint8_t *rsp_buf) {
1233 uint16_t rsp_buf_len = 0x0;
1234 phFWD_Status_t ret = FW_DNLD_SUCCESS;
1235 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
1236
1237 ret = phGenericSendAndRecv(payload, len, rsp_buf, &rsp_buf_len);
1238 if (!rsp_buf_len || ret == FW_DNLD_FAILURE) {
1239 NXPLOG_FWDNLD_D("Error in sending/receiving "
1240 "EDL_LIFECYCLE_WRITE_LAST cmd/response\n");
1241 return ret;
1242 }
1243
1244 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
1245 if (NULL == hdllCmdRsp) {
1246 return ret;
1247 }
1248
1249 hdllCmdRsp->group = HCP_OPERATION_GROUP_EDL;
1250 hdllCmdRsp->operation = EDL_LIFECYCLE_WRITE_LAST;
1251 hdllCmdRsp->rsp_buf = rsp_buf;
1252 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1253 hdllCmdRsp->status = GENERIC_SUCCESS;
1254 hdllCmdRsp->type = HCP_TYPE_RESPONSE;
1255 ret = process_hdll_response(hdllCmdRsp);
1256
1257 if (NULL != hdllCmdRsp) {
1258 free(hdllCmdRsp);
1259 }
1260
1261 return ret;
1262 }
1263
1264 /*******************************************************************************
1265 **
1266 ** Function : sendEdlPatchFlashWriteCmd
1267 **
1268 ** Description : This function frames the sendEdlPatchlFlashWriteCmd which
1269 will send the EDL Patch Flash Write cmd
1270 **
1271 ** Parameters : payload - HDLL command buffer
1272 len - command buffer length
1273 rsp_buf - response buffer that will be received from the
1274 HeliosX chip.
1275 **
1276 ** Returns : FW_DNLD_FAILURE - If any undesired response received
1277 FW_DNLD_SUCCESS - On proper response
1278 **
1279 **
1280 *******************************************************************************/
sendEdlPatchFlashWriteCmd(uint8_t * payload,uint16_t len,uint8_t * rsp_buf)1281 phFWD_Status_t sendEdlPatchFlashWriteCmd(uint8_t *payload, uint16_t len,
1282 uint8_t *rsp_buf) {
1283 uint16_t rsp_buf_len = 0x0;
1284 phFWD_Status_t ret = FW_DNLD_SUCCESS;
1285 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
1286
1287 ret = phGenericSendAndRecv(payload, len, rsp_buf, &rsp_buf_len);
1288 if (!rsp_buf_len || ret == FW_DNLD_FAILURE) {
1289 NXPLOG_FWDNLD_D("Error in sending/receiving OP_EDL_PATCH_FLASH_WRITE "
1290 "cmd/response\n");
1291 return ret;
1292 }
1293
1294 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
1295 if (NULL == hdllCmdRsp) {
1296 return ret;
1297 }
1298
1299 hdllCmdRsp->group = HCP_OPERATION_GROUP_EDL;
1300 hdllCmdRsp->operation = EDL_PATCH_FLASH_WRITE;
1301 hdllCmdRsp->rsp_buf = rsp_buf;
1302 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1303 hdllCmdRsp->status = GENERIC_SUCCESS;
1304 hdllCmdRsp->type = HCP_TYPE_RESPONSE;
1305 ret = process_hdll_response(hdllCmdRsp);
1306
1307 if (NULL != hdllCmdRsp) {
1308 free(hdllCmdRsp);
1309 }
1310
1311 return ret;
1312 }
1313
1314 /*******************************************************************************
1315 **
1316 ** Function : phHal_Host_CalcCrc16
1317 **
1318 ** Description : This function calculates the HDLL command's CRC
1319 **
1320 ** Parameters : p - HDLL command buffer
1321 dwLength - command buffer length
1322 **
1323 ** Returns : the calculated CRC value
1324 **
1325 **
1326 *******************************************************************************/
phHal_Host_CalcCrc16(uint8_t * p,uint32_t dwLength)1327 static uint16_t phHal_Host_CalcCrc16(uint8_t *p, uint32_t dwLength) {
1328 uint32_t i;
1329 uint16_t crc_new;
1330 uint16_t crc = 0xffffU;
1331
1332 for (i = 0; i < dwLength; i++) {
1333 crc_new = (uint8_t)(crc >> 8) | (crc << 8);
1334 crc_new ^= p[i];
1335 crc_new ^= (uint8_t)(crc_new & 0xff) >> 4;
1336 crc_new ^= crc_new << 12;
1337 crc_new ^= (crc_new & 0xff) << 5;
1338 crc = crc_new;
1339 }
1340 return crc;
1341 }
1342
1343 /*******************************************************************************
1344 **
1345 ** Function : phBuildHdllCmd
1346 **
1347 ** Description : This function frames the final HDLL command (HDLL header +
1348 HDLL payload + CRC) by framing HDLL payload and HDLL frame
1349 using 2 different APIs.
1350 **
1351 ** Parameters : hdllCmd - HDLL command structure which has the information
1352 to build the corresponding HDLL command.
1353 **
1354 ** Returns : NULL - on failure
1355 HDLL command buffer - On success
1356 **
1357 **
1358 *******************************************************************************/
1359
1360 /*
1361 * HDLL Command:
1362 * <--------HDLL Header---->|<------------------HDLL payload------------------->
1363 * <--------HDLL (2bytes)-->|<-----HCP (2bytes)------->|<-Application-><--CRC-->
1364 * <31 30> <29> <28 -16> |<15 -14><13 - 8><7 - 0> |<---Payload---><2 bytes>
1365 * <--R--> <Chunk> <length> |< Type ><Group><Operation>|
1366 *
1367 */
1368
phBuildHdllCmd(phHDLLCmd_t * hdllCmd)1369 uint8_t *phBuildHdllCmd(phHDLLCmd_t *hdllCmd) {
1370 uint8_t type = 0;
1371 uint8_t *hdll_frame = NULL;
1372 uint16_t hdll_frame_size = 0;
1373 uint16_t hdll_crc = 0x0;
1374 uint16_t hdll_header = 0x0;
1375 NXPLOG_FWDNLD_D("phBuildHdllCmd:\n");
1376
1377 if (NULL == hdllCmd) {
1378 return NULL;
1379 }
1380 // header len =2 bytes + hdll_payload_len + crc =2 bytes
1381 hdll_frame_size = HDLL_HEADER_LEN + HCP_MSG_HEADER_LEN +
1382 hdllCmd->payload_len + HDLL_CRC_LEN;
1383 hdll_frame = (uint8_t *)malloc(sizeof(uint8_t) * hdll_frame_size);
1384 if (NULL == hdll_frame) {
1385 return hdll_frame;
1386 }
1387
1388 // build hdll frame
1389 hdll_header |= hdllCmd->payload_len + HCP_MSG_HEADER_LEN;
1390 hdll_header &= HDLL_PKT_LEN_BITMASK;
1391 hdll_header = hdllCmd->chunk_size ? (HDLL_PKT_CHUNK_BITMASK | hdll_header)
1392 : hdll_header;
1393
1394 // hdll_header uint16 to uint8
1395 hdll_frame[HDLL_CHUNK_OFFSET] = (hdll_header >> 8);
1396 hdll_frame[HDLL_LEN_OFFSET] = (hdll_header & 0xFF);
1397
1398 type = HCP_TYPE_COMMAND;
1399 type <<= HCP_GROUP_LEN;
1400 hdll_frame[HDLL_TYPE_OFFSET] = type | hdllCmd->group;
1401 hdll_frame[HDLL_OPERATION_OFFSET] = hdllCmd->operation;
1402
1403 if (hdllCmd->payload_len > 0 && hdllCmd->payload != NULL) {
1404 // copy hdll payload into hdll frame
1405 memcpy(&hdll_frame[HDLL_PAYLOAD_OFFSET], hdllCmd->payload,
1406 hdllCmd->payload_len);
1407 }
1408
1409 hdll_crc = phHal_Host_CalcCrc16(hdll_frame, hdll_frame_size - 2);
1410 hdll_frame[hdll_frame_size - 2] = (hdll_crc >> 8);
1411 hdll_frame[hdll_frame_size - 1] = (hdll_crc & 0xFF);
1412
1413 hdllCmd->frame_size = hdll_frame_size;
1414 return hdll_frame;
1415 }
1416
1417 /*******************************************************************************
1418 **
1419 ** Function : sendEdlResetCmd
1420 **
1421 ** Description : This function frames the EdlResetCmd and sends to the HeliosX
1422 chip
1423 **
1424 ** Parameters : None
1425 **
1426 ** Returns : FW_DNLD_FAILURE - If any failure occurs while framing or
1427 sending the command or while receiving the
1428 response
1429 FW_DNLD_SUCCESS - On success
1430 **
1431 **
1432 *******************************************************************************/
sendEdlResetCmd()1433 phFWD_Status_t sendEdlResetCmd() {
1434 uint8_t rsp_buf[HDLL_READ_BUFF_SIZE] = {0};
1435 uint8_t *hdll_frame = NULL;
1436 phFWD_Status_t ret = FW_DNLD_FAILURE;
1437 uint16_t rsp_buf_len = 0x0;
1438 phHDLLCmd_t *hdllCmd = NULL;
1439 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
1440
1441 hdllCmd = (phHDLLCmd_t *)malloc(sizeof(phHDLLCmd_t));
1442 if (NULL == hdllCmd) {
1443 goto exit;
1444 }
1445
1446 hdllCmd->group = HCP_OPERATION_GROUP_GENERIC;
1447 hdllCmd->operation = GENERIC_GROUP_OP_CODE_RESET;
1448 hdllCmd->chunk_size = 0;
1449 hdllCmd->frame_size = 0;
1450 hdllCmd->payload = NULL;
1451 hdllCmd->payload_len = 0;
1452
1453 hdll_frame = phBuildHdllCmd(hdllCmd);
1454 if (NULL == hdll_frame) {
1455 goto exit;
1456 }
1457 NXPLOG_FWDNLD_D("Sending operation: OP_GENERIC_RESET\n");
1458 ret = phGenericSendAndRecv(hdll_frame, hdllCmd->frame_size, rsp_buf,
1459 &rsp_buf_len);
1460 if (ret == FW_DNLD_FAILURE) {
1461 // treat is as success as generic reset will have response only if there
1462 // is an error.
1463 ret = FW_DNLD_SUCCESS;
1464 }
1465 if (rsp_buf_len > 0) {
1466 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
1467 if (NULL == hdllCmdRsp) {
1468 ret = FW_DNLD_FAILURE;
1469 goto exit;
1470 }
1471 hdllCmdRsp->group = HCP_OPERATION_GROUP_GENERIC;
1472 hdllCmdRsp->operation = GENERIC_GROUP_OP_CODE_RESET;
1473 hdllCmdRsp->rsp_buf = rsp_buf;
1474 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1475 hdllCmdRsp->status = GENERIC_SUCCESS;
1476 hdllCmdRsp->type = HCP_TYPE_RESPONSE;
1477 ret = process_hdll_response(hdllCmdRsp);
1478 }
1479 exit:
1480 if (hdll_frame != NULL) {
1481 free(hdll_frame);
1482 }
1483 if (NULL != hdllCmd) {
1484 free(hdllCmd);
1485 }
1486 if (NULL != hdllCmdRsp) {
1487 free(hdllCmdRsp);
1488 }
1489 return ret;
1490 }
1491
1492 /*******************************************************************************
1493 **
1494 ** Function : phGetEdlReadyNtf
1495 **
1496 ** Description : This function frames the GetEdlReadyNtf command and sends to
1497 the HeliosX chip
1498 **
1499 ** Parameters : None
1500 **
1501 ** Returns : FW_DNLD_FAILURE - If any failure occurs while framing or
1502 sending the command or while receiving the
1503 response
1504 FW_DNLD_SUCCESS - On success
1505 **
1506 **
1507 *******************************************************************************/
phGetEdlReadyNtf()1508 phFWD_Status_t phGetEdlReadyNtf() {
1509 uint8_t rsp_buf[HDLL_READ_BUFF_SIZE] = {0};
1510 phFWD_Status_t ret = FW_DNLD_FAILURE;
1511 uint16_t rsp_buf_len = 0x0;
1512 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
1513
1514 NXPLOG_FWDNLD_D("Wait for EDL_READY notification\n");
1515 ret =
1516 phHdll_GetApdu((uint8_t *)&rsp_buf[0], HDLL_READ_BUFF_SIZE, &rsp_buf_len);
1517
1518 if (!rsp_buf_len || ret == FW_DNLD_FAILURE) {
1519 NXPLOG_FWDNLD_D("Error in sending/receiving GET_EDL_READY cmd/response\n");
1520 return ret;
1521 }
1522
1523 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
1524 if (NULL == hdllCmdRsp) {
1525 return ret;
1526 }
1527
1528 hdllCmdRsp->group = HCP_OPERATION_GROUP_PROTOCOL;
1529 hdllCmdRsp->operation = PROTOCOL_GROUP_OP_CODE_EDL;
1530 hdllCmdRsp->rsp_buf = rsp_buf;
1531 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1532 hdllCmdRsp->status = READY;
1533 hdllCmdRsp->type = HCP_TYPE_NOTIFICATION;
1534 ret = process_hdll_response(hdllCmdRsp);
1535
1536 if (NULL != hdllCmdRsp) {
1537 free(hdllCmdRsp);
1538 }
1539 return ret;
1540 }
1541
1542 /*******************************************************************************
1543 **
1544 ** Function : phGenericGetInfo
1545 **
1546 ** Description : This function frames the GenericGetInfo command and sends to
1547 the HeliosX chip
1548 **
1549 ** Parameters : None
1550 **
1551 ** Returns : FW_DNLD_FAILURE - If any failure occurs while framing or
1552 sending the command or while receiving the
1553 response
1554 FW_DNLD_SUCCESS - On success
1555 **
1556 **
1557 *******************************************************************************/
phGenericGetInfo()1558 phFWD_Status_t phGenericGetInfo() {
1559 uint8_t rsp_buf[HDLL_READ_BUFF_SIZE] = {0};
1560 uint8_t *hdll_frame = NULL;
1561 phFWD_Status_t ret = FW_DNLD_FAILURE;
1562 uint16_t rsp_buf_len = 0x0;
1563 phHDLLCmd_t *hdllCmd = NULL;
1564 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
1565
1566 hdllCmd = (phHDLLCmd_t *)malloc(sizeof(phHDLLCmd_t));
1567 if (NULL == hdllCmd) {
1568 ret = FW_DNLD_FAILURE;
1569 goto exit;
1570 }
1571 hdllCmd->group = HCP_OPERATION_GROUP_GENERIC;
1572 hdllCmd->operation = GENERIC_GROUP_OP_CODE_GETINFO;
1573 hdllCmd->chunk_size = 0;
1574 hdllCmd->frame_size = 0;
1575 hdllCmd->payload = NULL;
1576 hdllCmd->payload_len = 0;
1577
1578 hdll_frame = phBuildHdllCmd(hdllCmd);
1579 if (NULL == hdll_frame) {
1580 goto exit;
1581 }
1582 NXPLOG_FWDNLD_D("Sending operation: OP_GENERIC_GET_INFO\n");
1583 ret = phGenericSendAndRecv(hdll_frame, hdllCmd->frame_size, rsp_buf,
1584 &rsp_buf_len);
1585 if (!rsp_buf_len || ret == FW_DNLD_FAILURE) {
1586 NXPLOG_FWDNLD_D("Error in sending/receiving hdll cmd/response\n");
1587 return ret;
1588 }
1589
1590 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
1591 if (NULL == hdllCmdRsp) {
1592 ret = FW_DNLD_FAILURE;
1593 goto exit;
1594 }
1595 hdllCmdRsp->group = HCP_OPERATION_GROUP_GENERIC;
1596 hdllCmdRsp->operation = GENERIC_GROUP_OP_CODE_GETINFO;
1597 hdllCmdRsp->rsp_buf = rsp_buf;
1598 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1599 hdllCmdRsp->status = GENERIC_SUCCESS;
1600 hdllCmdRsp->type = HCP_TYPE_RESPONSE;
1601 ret = process_hdll_response(hdllCmdRsp);
1602 exit:
1603 if (NULL != hdll_frame) {
1604 free(hdll_frame);
1605 }
1606 if (NULL != hdllCmd) {
1607 free(hdllCmd);
1608 }
1609 if (NULL != hdllCmdRsp) {
1610 free(hdllCmdRsp);
1611 }
1612 return ret;
1613 }
1614
1615 /*******************************************************************************
1616 **
1617 ** Function : phHdll_GetHdllReadyNtf
1618 **
1619 ** Description : This function frames the GetHdllReadyNtf command and sends to
1620 the HeliosX chip
1621 **
1622 ** Parameters : None
1623 **
1624 ** Returns : FW_DNLD_FAILURE - If any failure occurs while framing or
1625 sending the command or while receiving the
1626 response
1627 FW_DNLD_SUCCESS - On success
1628 **
1629 **
1630 *******************************************************************************/
phHdll_GetHdllReadyNtf()1631 phFWD_Status_t phHdll_GetHdllReadyNtf() {
1632 uint8_t rsp_buf[HDLL_READ_BUFF_SIZE] = {0};
1633 phFWD_Status_t ret = FW_DNLD_FAILURE;
1634 uint16_t rsp_buf_len = 0x0;
1635 phHDLLCmdRsp_t *hdllCmdRsp = NULL;
1636
1637 NXPLOG_FWDNLD_D("Wait for HDL_READY notification\n");
1638 ret =
1639 phHdll_GetApdu((uint8_t *)&rsp_buf[0], HDLL_READ_BUFF_SIZE, &rsp_buf_len);
1640
1641 if (!rsp_buf_len || ret == FW_DNLD_FAILURE) {
1642 NXPLOG_FWDNLD_D("Error in reading GET_HDL_READY notification\n");
1643 return ret;
1644 }
1645
1646 hdllCmdRsp = (phHDLLCmdRsp_t *)malloc(sizeof(phHDLLCmdRsp_t));
1647 if (NULL == hdllCmdRsp) {
1648 return ret;
1649 }
1650
1651 hdllCmdRsp->group = HCP_OPERATION_GROUP_PROTOCOL;
1652 hdllCmdRsp->operation = PROTOCOL_GROUP_OP_CODE_HDLL;
1653 hdllCmdRsp->rsp_buf = rsp_buf;
1654 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1655 hdllCmdRsp->status = READY;
1656 hdllCmdRsp->type = HCP_TYPE_NOTIFICATION;
1657 ret = process_hdll_response(hdllCmdRsp);
1658
1659 if (FW_DNLD_SUCCESS != ret) {
1660 // check whether we received EDL ready notification or not
1661 // if yes, perform FW download directly.
1662 hdllCmdRsp->group = HCP_OPERATION_GROUP_PROTOCOL;
1663 hdllCmdRsp->operation = PROTOCOL_GROUP_OP_CODE_EDL;
1664 hdllCmdRsp->rsp_buf = rsp_buf;
1665 hdllCmdRsp->rsp_buf_len = rsp_buf_len;
1666 hdllCmdRsp->status = READY;
1667 hdllCmdRsp->type = HCP_TYPE_NOTIFICATION;
1668 ret = process_hdll_response(hdllCmdRsp);
1669
1670 if (FW_DNLD_SUCCESS == ret) {
1671 bSkipEdlCheck = true;
1672 }
1673 }
1674
1675 if (NULL != hdllCmdRsp) {
1676 free(hdllCmdRsp);
1677 }
1678
1679 return ret;
1680 }
1681
1682 /*******************************************************************************
1683 **
1684 ** Function : phEdl_send_and_recv
1685 **
1686 ** Description : This function sends and receives the EDL group commands and
1687 responses based on the given operation code.
1688 **
1689 ** Parameters : hdll_data - HDLL command buffer
1690 hdll_data_len - HDLL command buffer len
1691 group - HCP group code
1692 operation - operation code.
1693 **
1694 ** Returns : FW_DNLD_FAILURE - If any failure occurs while framing or
1695 sending the command or while receiving the
1696 response
1697 FW_DNLD_SUCCESS - On success
1698 **
1699 **
1700 *******************************************************************************/
1701
phEdl_send_and_recv(uint8_t * hdll_data,uint32_t hdll_data_len,uint8_t group,uint8_t operation)1702 phFWD_Status_t phEdl_send_and_recv(uint8_t *hdll_data, uint32_t hdll_data_len,
1703 uint8_t group, uint8_t operation) {
1704 phFWD_Status_t ret = FW_DNLD_FAILURE;
1705 uint8_t rsp_buff[HDLL_READ_BUFF_SIZE] = {0};
1706
1707 if (group != HCP_OPERATION_GROUP_EDL) {
1708 NXPLOG_FWDNLD_D("Error! HCP operation group is not EDL\n");
1709 return ret;
1710 }
1711 switch (operation) {
1712 case EDL_DOWNLOAD_CERTIFICATE: {
1713 ret = sendEdlDownloadCertificateCmd(hdll_data, hdll_data_len, rsp_buff);
1714 } break;
1715 case EDL_DOWNLOAD_FLASH_WRITE_FIRST: {
1716 ret = sendEdlFlashWriteFirstCmd(hdll_data, hdll_data_len, rsp_buff);
1717 } break;
1718 case EDL_DOWNLOAD_FLASH_WRITE: {
1719 ret = sendEdlFlashWriteCmd(hdll_data, hdll_data_len, rsp_buff);
1720 } break;
1721 case EDL_DOWNLOAD_FLASH_WRITE_LAST: {
1722 ret = sendEdlFlashWriteLastCmd(hdll_data, hdll_data_len, rsp_buff);
1723 } break;
1724 case EDL_LIFECYCLE_CERTIFICATE: {
1725 ret = sendEdlLifecycleCertificateCmd(hdll_data, hdll_data_len, rsp_buff);
1726 } break;
1727 case EDL_LIFECYCLE_WRITE_FIRST: {
1728 ret = sendEdlLifecycleWriteFirstCmd(hdll_data, hdll_data_len, rsp_buff);
1729 } break;
1730 case EDL_LIFECYCLE_WRITE_LAST: {
1731 ret = sendEdlLifecycleWriteLastCmd(hdll_data, hdll_data_len, rsp_buff);
1732 } break;
1733 case EDL_PATCH_FLASH_WRITE: {
1734 ret = sendEdlPatchFlashWriteCmd(hdll_data, hdll_data_len, rsp_buff);
1735 } break;
1736
1737 default:
1738 break;
1739 }
1740 return ret;
1741 }
1742
1743 /*******************************************************************************
1744 **
1745 ** Function : phLoadFwBinary
1746 **
1747 ** Description : This function reads the MW FW binary file and writes to
1748 HeliosX chip.
1749 **
1750 ** Parameters : pfwImageCtx -> pointer to fw image context
1751 **
1752 ** Returns : FW_DNLD_FAILURE - on failure
1753 FW_DNLD_SUCCESS - On success
1754 **
1755 **
1756 *******************************************************************************/
phLoadFwBinary(phUwbFWImageContext_t * pfwImageCtx)1757 phFWD_Status_t phLoadFwBinary(phUwbFWImageContext_t *pfwImageCtx) {
1758 uint32_t next_frame_first_byte_index = 0;
1759 uint8_t current_op_group;
1760 uint8_t current_op;
1761 uint32_t frame_payload_length = 0;
1762 uint32_t frame_length = 0;
1763 phFWD_Status_t status = FW_DNLD_FAILURE;
1764 uint8_t current_frame[MAX_FRAME_LEN] = {0};
1765
1766 if (NULL == pfwImageCtx->fwImage) {
1767 return status;
1768 }
1769 NXPLOG_FWDNLD_D("phLoadFwBinary\n");
1770 while (1) {
1771 // compute next frame payload length
1772 // TODO: warning this is not HDLL fragmentation compatible (valid header can
1773 // have chunk flag (biy 10 (13)) set) Assuming header length is 2 bytes
1774 frame_payload_length = (pfwImageCtx->fwImage[next_frame_first_byte_index] << 8) +
1775 (pfwImageCtx->fwImage[next_frame_first_byte_index + 1]);
1776
1777 // if max_payload_length is not None and (frame_payload_length >=
1778 // max_payload_length): raise Exception('Invalid SFWU content (not an HDLL
1779 // header).')
1780
1781 // copy the header, the payload and the footer (crc) from the file bytes
1782 // into a byte array
1783 frame_length = frame_payload_length + HDLL_HEADER_LEN + HDLL_FOOTER_LEN;
1784 if (frame_length > MAX_FRAME_LEN) {
1785 NXPLOG_FWDNLD_E("%s: Error while performing FW download frame_length > "
1786 "MAX_FRAME_LEN\n",
1787 __func__);
1788 status = FW_DNLD_FAILURE;
1789 break;
1790 }
1791 memcpy(current_frame, &pfwImageCtx->fwImage[next_frame_first_byte_index],
1792 frame_length);
1793 current_op_group = current_frame[2];
1794 current_op = current_frame[3];
1795
1796 status = phEdl_send_and_recv(current_frame, frame_length, current_op_group,
1797 current_op);
1798 if (status != FW_DNLD_SUCCESS) {
1799 NXPLOG_FWDNLD_E("%s: Error while performing FW download\n", __func__);
1800 break;
1801 }
1802
1803 // update byte index
1804 next_frame_first_byte_index = next_frame_first_byte_index + frame_length;
1805
1806 // check end of file
1807 if (next_frame_first_byte_index >= pfwImageCtx->fwImgSize) {
1808 break;
1809 }
1810 }
1811
1812 // clean-up
1813 if (pfwImageCtx->fwImage != NULL) {
1814 if (pfwImageCtx->fw_dnld_config == BIN_FILE_BASED_FW_DOWNLOAD) {
1815 free(pfwImageCtx->fwImage);
1816 } else if (pfwImageCtx->fw_dnld_config == SO_FILE_BASED_FW_DOWNLOAD) {
1817 if (pfwImageCtx->gFwLib != NULL) {
1818 dlclose(pfwImageCtx->gFwLib);
1819 pfwImageCtx->gFwLib = NULL;
1820 }
1821 }
1822
1823 pfwImageCtx->fwImage = NULL;
1824 }
1825 return status;
1826 }
1827
1828 /******************************************************************************
1829 * Function phHandle_hdll_read_timeout_cb
1830 *
1831 * Description Timer call back function
1832 *
1833 * Returns None
1834 *
1835 ******************************************************************************/
phHandle_hdll_read_timeout_cb(uint32_t timerId,void * pContext)1836 static void phHandle_hdll_read_timeout_cb(uint32_t timerId, void *pContext) {
1837 UNUSED(timerId);
1838 UNUSED(pContext);
1839 NXPLOG_FWDNLD_E("ERROR: phHandle_hdll_read_timeout_cb - HDLL read timeout\n");
1840 ioctl((intptr_t)tPalConfig.pDevHandle, SRXXX_SET_PWR, ABORT_READ_PENDING);
1841 isHdllReadTmeoutExpired = true;
1842 }
1843
1844 /******************************************************************************/
1845 /* GLOBAL FUNCTIONS */
1846 /******************************************************************************/
1847
1848 /*******************************************************************************
1849 **
1850 ** Function : phHdll_GetApdu
1851 **
1852 ** Description : This function reads the HDLL command's response from HeliosX
1853 chip over SPI.
1854 **
1855 ** Parameters : pApdu - HDLL response buffer
1856 sz - Max buffer size to be read
1857 rsp_buf_len - HDLL response buffer length
1858 **
1859 ** Returns : phFWD_Status_t : 0 - success
1860 1 - failure
1861 **
1862 **
1863 *******************************************************************************/
1864
phHdll_GetApdu(uint8_t * pApdu,uint16_t sz,uint16_t * rsp_buf_len)1865 phFWD_Status_t phHdll_GetApdu(uint8_t *pApdu, uint16_t sz,
1866 uint16_t *rsp_buf_len) {
1867 // NXPLOG_FWDNLD_D("phHdll_GetApdu Enter\n");
1868 int ret_len = 0;
1869 int status = 0;
1870
1871 if (sz == 0 || sz > PHHDLL_MAX_LEN_PAYLOAD_MISO) {
1872 NXPLOG_FWDNLD_E("ERROR: phHdll_GetApdu data len is 0 or greater than max "
1873 "palyload length supported\n");
1874 return FW_DNLD_FAILURE;
1875 }
1876
1877 /* Start timer */
1878 status = phOsalUwb_Timer_Start(timeoutTimerId, HDLL_READ_OP_TIMEOUT,
1879 &phHandle_hdll_read_timeout_cb, NULL);
1880 if (UWBSTATUS_SUCCESS != status) {
1881 NXPLOG_FWDNLD_E("%s: Response timer not started!!!", __func__);
1882 return FW_DNLD_FAILURE;
1883 }
1884 ret_len = read((intptr_t)tPalConfig.pDevHandle, (void *)pApdu, (sz));
1885
1886 if (true == isHdllReadTmeoutExpired) {
1887 isHdllReadTmeoutExpired = false;
1888 return FW_DNLD_FAILURE;
1889 } else {
1890 /* Stop Timer */
1891 status = phOsalUwb_Timer_Stop(timeoutTimerId);
1892 if (UWBSTATUS_SUCCESS != status) {
1893 NXPLOG_FWDNLD_E("%s: Response timer stop ERROR!!!", __func__);
1894 return FW_DNLD_FAILURE;
1895 }
1896 }
1897
1898 if (ret_len <= 0) {
1899 NXPLOG_FWDNLD_E("ERROR: Get APDU %u bytes failed!\n", sz);
1900 return FW_DNLD_FAILURE;
1901 }
1902 *rsp_buf_len = ret_len;
1903 if (is_fw_download_log_enabled == 0x01) {
1904 phNxpUciHal_print_packet(NXP_TML_FW_DNLD_RSP_UWBS_2_AP, pApdu, ret_len);
1905 }
1906
1907 return FW_DNLD_SUCCESS;
1908 }
1909
1910 /*******************************************************************************
1911 **
1912 ** Function : phHdll_PutApdu
1913 **
1914 ** Description : This function sends the HDLL command to HeliosX chip over SPI
1915 **
1916 ** Parameters : pApdu - HDLL command to be sent
1917 sz - HDLL command length
1918 **
1919 ** Returns : phFWD_Status_t : 0 - success
1920 1 - failure
1921 **
1922 **
1923 *******************************************************************************/
1924
phHdll_PutApdu(uint8_t * pApdu,uint16_t sz)1925 phFWD_Status_t phHdll_PutApdu(uint8_t *pApdu, uint16_t sz) {
1926 int ret;
1927 int numWrote = 0;
1928 if (is_fw_download_log_enabled == 0x01) {
1929 phNxpUciHal_print_packet(NXP_TML_FW_DNLD_CMD_AP_2_UWBS, pApdu, sz);
1930 }
1931
1932 ret = write((intptr_t)tPalConfig.pDevHandle, pApdu, sz);
1933 if (ret > 0) {
1934 numWrote += ret;
1935 } else if (ret == 0) {
1936 NXPLOG_FWDNLD_E("_spi_write() EOF");
1937 return FW_DNLD_FAILURE;
1938 } else {
1939 NXPLOG_FWDNLD_E("_spi_write() errno : %x", ret);
1940 return FW_DNLD_FAILURE;
1941 }
1942 return FW_DNLD_SUCCESS;
1943 }
1944
1945 /*******************************************************************************
1946 * Function hdll_fw_download
1947 *
1948 * Description This function is called by jni when wired mode is
1949 * performed.First SRXXX driver will give the access
1950 * permission whether wired mode is allowed or not
1951 * arg (0):
1952 * Returns FW_DNLD_SUCCESS - on success
1953 FW_DNLD_FAILURE - on failure
1954 FW_DNLD_FILE_NOT_FOUND - if the FW binary is not found or
1955 unable to open
1956 *
1957 ******************************************************************************/
hdll_fw_download()1958 int hdll_fw_download()
1959 {
1960 phFWD_Status_t ret = FW_DNLD_FAILURE;
1961 unsigned long num = 0;
1962 NXPLOG_FWDNLD_D("hdll_fw_download enter.....\n");
1963
1964 isHdllReadTmeoutExpired = false;
1965 bSkipEdlCheck = false;
1966 if (NxpConfig_GetNum(NAME_UWB_FW_DOWNLOAD_LOG, &num, sizeof(num))) {
1967 is_fw_download_log_enabled = (uint8_t)num;
1968 ALOGD("NAME_UWB_FW_DOWNLOAD_LOG: 0x%02x\n", is_fw_download_log_enabled);
1969 } else {
1970 ALOGD("NAME_UWB_FW_DOWNLOAD_LOG: failed 0x%02x\n",
1971 is_fw_download_log_enabled);
1972 }
1973 ioctl((intptr_t)tPalConfig.pDevHandle, SRXXX_SET_FWD, PWR_ENABLE);
1974
1975 ret = phHdll_GetHdllReadyNtf();
1976 if (ret != FW_DNLD_SUCCESS) {
1977 NXPLOG_FWDNLD_E("%s:%d error in getting the hdll ready notification...\n",
1978 __func__,__LINE__);
1979 return ret;
1980 }
1981 /* Get the Device information */
1982 ret = phGenericGetInfo();
1983 if (ret == FW_DNLD_FILE_NOT_FOUND) {
1984 goto exit;
1985 }
1986
1987 if (ret == FW_DNLD_FAILURE) {
1988 NXPLOG_FWDNLD_E("%s: error in getting the getInfo notification...\n",
1989 __func__);
1990 return ret;
1991 }
1992
1993 if (!bSkipEdlCheck) {
1994 if (ret == FW_DNLD_NOT_REQUIRED)
1995 {
1996 goto exit;
1997 }
1998 ret = phGetEdlReadyNtf();
1999 if (ret != FW_DNLD_SUCCESS) {
2000 NXPLOG_FWDNLD_E("%s: error in getting the EDL ready notification...\n",
2001 __func__);
2002 return ret;
2003 }
2004 }
2005
2006 if(fwImageCtx.fwRecovery)
2007 {
2008 /* perform FW recovery */
2009 ret = phNxpUciHal_fw_recovery(&fwImageCtx);
2010 if (ret == FW_DNLD_FAILURE) {
2011 NXPLOG_FWDNLD_E("%s: error downloading recovery FW...\n",
2012 __func__);
2013 return ret;
2014 }
2015 // TODO: Remove this after recovrry FW tested added to avoid endless loop of fw download.
2016 fwImageCtx.fwRecovery = false;
2017 }
2018
2019 /* */
2020 ret = phLoadFwBinary(&fwImageCtx);
2021 if (ret != FW_DNLD_SUCCESS) {
2022 NXPLOG_FWDNLD_E("%s: error in phLoadFwBinary...\n", __func__);
2023 return ret;
2024 }
2025
2026 exit:
2027 // do chip reset
2028 phTmlUwb_Chip_Reset();
2029 ret = phHdll_GetHdllReadyNtf();
2030
2031 ioctl((intptr_t)tPalConfig.pDevHandle, SRXXX_SET_FWD, PWR_DISABLE);
2032 NXPLOG_FWDNLD_D("hdll_fw_download completed.....\n");
2033 return ret;
2034 }
2035
2036 /*******************************************************************************
2037 * Function phNxpUciHal_fw_recovery
2038 *
2039 * Description This function is use to download recovery FW
2040 * Returns FW_DNLD_SUCCESS - on success
2041 FW_DNLD_FAILURE - on failure
2042 FW_DNLD_FILE_NOT_FOUND - if the FW binary is not found or
2043 unable to open
2044 *
2045 ******************************************************************************/
2046
phNxpUciHal_fw_recovery(phUwbFWImageContext_t * pfwImageCtx)2047 static phFWD_Status_t phNxpUciHal_fw_recovery(phUwbFWImageContext_t *pfwImageCtx) {
2048 phFWD_Status_t ret = FW_DNLD_FAILURE;
2049 NXPLOG_FWDNLD_D("phNxpUciHal_fw_recovery enter.....\n");
2050
2051 ret = phLoadFwBinary(pfwImageCtx);
2052 if (ret != FW_DNLD_SUCCESS) {
2053 NXPLOG_FWDNLD_E("%s: error in phLoadFwBinary...\n", __func__);
2054 return ret;
2055 }
2056
2057 // do chip reset
2058 phTmlUwb_Chip_Reset();
2059 ret = phHdll_GetHdllReadyNtf();
2060 if (ret != FW_DNLD_SUCCESS) {
2061 NXPLOG_FWDNLD_E("%s:%d error in getting the hdll ready notification...\n",
2062 __func__,__LINE__);
2063 return ret;
2064 }
2065 /* Get the Device information */
2066 ret = phGenericGetInfo();
2067 if (ret == FW_DNLD_FAILURE || ret == FW_DNLD_FILE_NOT_FOUND) {
2068 NXPLOG_FWDNLD_E("%s:%d error in getting the getInfo notification...\n",
2069 __func__,__LINE__);
2070 return ret;
2071 }
2072
2073 if (!bSkipEdlCheck) {
2074 if (ret == FW_DNLD_NOT_REQUIRED) {
2075 return ret;
2076 }
2077
2078 ret = phGetEdlReadyNtf();
2079 if (ret != FW_DNLD_SUCCESS) {
2080 NXPLOG_FWDNLD_E("%s:%d error in getting the EDL ready notification...\n",
2081 __func__,__LINE__);
2082 return ret;
2083 }
2084 }
2085
2086 return ret;
2087 }
2088
2089 /*******************************************************************************
2090 * Function phNxpUciHal_fw_lcrotation
2091 *
2092 * Description This function is use to download recovery FW
2093 * Returns FW_DNLD_SUCCESS - on success
2094 FW_DNLD_FAILURE - on failure
2095 FW_DNLD_FILE_NOT_FOUND - if the FW binary is not found or
2096 unable to open
2097 *
2098 ******************************************************************************/
2099
phNxpUciHal_fw_lcrotation()2100 phFWD_Status_t phNxpUciHal_fw_lcrotation() {
2101 phFWD_Status_t ret = FW_DNLD_FAILURE;
2102 glcRotation = true;
2103 NXPLOG_FWDNLD_D("phNxpUciHal_fw_lcrotation enter.....\n");
2104
2105 ioctl((intptr_t)tPalConfig.pDevHandle, SRXXX_SET_FWD, PWR_ENABLE);
2106
2107 ret = phHdll_GetHdllReadyNtf();
2108 if (ret != FW_DNLD_SUCCESS) {
2109 NXPLOG_FWDNLD_E("%s:%d error in getting the hdll ready notification...\n",
2110 __func__,__LINE__);
2111 return ret;
2112 }
2113 /* Get the Device information */
2114 ret = phGenericGetInfo();
2115 if (ret == FW_DNLD_FILE_NOT_FOUND) {
2116 goto exit;
2117 }
2118
2119 if (ret == FW_DNLD_FAILURE) {
2120 NXPLOG_FWDNLD_E("%s:%d error in getting the getInfo notification...\n",
2121 __func__,__LINE__);
2122 return ret;
2123 }
2124
2125 if (!bSkipEdlCheck) {
2126
2127 ret = phGetEdlReadyNtf();
2128 if (ret != FW_DNLD_SUCCESS) {
2129 NXPLOG_FWDNLD_E("%s:%d error in getting the EDL ready notification...\n",
2130 __func__,__LINE__);
2131 return ret;
2132 }
2133 }
2134 ret = phLoadFwBinary(&fwImageCtx);
2135 if (ret != FW_DNLD_SUCCESS) {
2136 NXPLOG_FWDNLD_E("%s: error in phLoadFwBinary...\n", __func__);
2137 glcRotation = false;
2138 return ret;
2139 }
2140 glcRotation = false;
2141
2142 exit:
2143 // do chip reset
2144 phTmlUwb_Chip_Reset();
2145 ret = phHdll_GetHdllReadyNtf();
2146
2147 ioctl((intptr_t)tPalConfig.pDevHandle, SRXXX_SET_FWD, PWR_DISABLE);
2148 NXPLOG_FWDNLD_D("hdll_fw_download completed.....\n");
2149 return ret;
2150 }
2151
2152 /*******************************************************************************
2153 * Function setDeviceHandle
2154 *
2155 * Description This function sets the SPI device handle that needs to be
2156 used in this file for SPI communication
2157 * Parameters pDevHandle - SPI device handle
2158 * Returns None
2159 *
2160 ******************************************************************************/
setDeviceHandle(void * pDevHandle)2161 void setDeviceHandle(void *pDevHandle) {
2162 NXPLOG_FWDNLD_D("Set the device handle!\n");
2163 if (pDevHandle == NULL) {
2164 NXPLOG_FWDNLD_E("device handle is NULL!\n");
2165 } else {
2166 tPalConfig.pDevHandle = (void *)((intptr_t)pDevHandle);
2167 }
2168 }
2169