1 /****************************************************************************** 2 * 3 * Copyright (C) 2012-2013 Broadcom Corporation 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 19 #include <string.h> 20 #include "nfc_hal_int.h" 21 #include "userial.h" 22 23 /***************************************************************************** 24 * Definitions 25 *****************************************************************************/ 26 27 /* Internal flags */ 28 #define NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF 0x01 /* Application provided patchram in a single buffer */ 29 #define NFC_HAL_PRM_FLAGS_RFU 0x02 /* Reserved for future use */ 30 #define NFC_HAL_PRM_FLAGS_SIGNATURE_SENT 0x04 /* Signature sent to NFCC */ 31 #define NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED 0x08 /* PreI2C patch required */ 32 #define NFC_HAL_PRM_FLAGS_BCM20791B3 0x10 /* B3 Patch (no RESET_NTF after patch download) */ 33 34 /* Secure patch download definitions */ 35 #define NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN 7 /* PRJID + MAJORVER + MINORVER + COUNT */ 36 37 /* Enumeration of power modes IDs */ 38 #define NFC_HAL_PRM_SPD_POWER_MODE_LPM 0 39 #define NFC_HAL_PRM_SPD_POWER_MODE_FPM 1 40 41 /* Version string for BCM20791B3 */ 42 const UINT8 NFC_HAL_PRM_BCM20791B3_STR[] = "20791B3"; 43 #define NFC_HAL_PRM_BCM20791B3_STR_LEN (sizeof (NFC_HAL_PRM_BCM20791B3_STR)-1) 44 45 #define NFC_HAL_PRM_SPD_TOUT (6000) /* timeout for SPD events (in ms) */ 46 #define NFC_HAL_PRM_END_DELAY (250) /* delay before sending any new command (ms)*/ 47 48 #if (NFC_HAL_PRM_DEBUG == TRUE) 49 #define NFC_HAL_PRM_STATE(str) HAL_TRACE_DEBUG2 ("%s st: %d", str, nfc_hal_cb.prm.state) 50 #else 51 #define NFC_HAL_PRM_STATE(str) 52 #endif 53 54 void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status); 55 56 /***************************************************************************** 57 ** Extern variable from nfc_hal_dm_cfg.c 58 *****************************************************************************/ 59 extern tNFC_HAL_CFG *p_nfc_hal_cfg; 60 61 /******************************************************************************* 62 ** 63 ** Function nfc_hal_prm_spd_handle_download_complete 64 ** 65 ** Description Patch download complete (for secure patch download) 66 ** 67 ** Returns void 68 ** 69 *******************************************************************************/ 70 void nfc_hal_prm_spd_handle_download_complete (UINT8 event) 71 { 72 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_IDLE; 73 74 /* Notify application now */ 75 if (nfc_hal_cb.prm.p_cback) 76 (nfc_hal_cb.prm.p_cback) (event); 77 } 78 79 /******************************************************************************* 80 ** 81 ** Function nfc_hal_prm_spd_send_next_segment 82 ** 83 ** Description Send next patch segment (for secure patch download) 84 ** 85 ** Returns void 86 ** 87 *******************************************************************************/ 88 void nfc_hal_prm_spd_send_next_segment (void) 89 { 90 UINT8 *p_src; 91 UINT16 len, offset = nfc_hal_cb.prm.cur_patch_offset; 92 UINT8 hcit, oid, hdr0, type; 93 UINT8 chipverlen; 94 UINT8 chipverstr[NCI_SPD_HEADER_CHIPVER_LEN]; 95 UINT8 patch_hdr_size = NCI_MSG_HDR_SIZE + 1; /* 1 is for HCIT */ 96 97 /* Validate that segment is at least big enought to have NCI_MSG_HDR_SIZE + 1 (hcit) */ 98 if (nfc_hal_cb.prm.cur_patch_len_remaining < patch_hdr_size) 99 { 100 HAL_TRACE_ERROR0 ("Unexpected end of patch."); 101 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT); 102 return; 103 } 104 105 /* Parse NCI command header */ 106 p_src = (UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset); 107 STREAM_TO_UINT8 (hcit, p_src); 108 STREAM_TO_UINT8 (hdr0, p_src); 109 STREAM_TO_UINT8 (oid, p_src); 110 STREAM_TO_UINT8 (len, p_src); 111 STREAM_TO_UINT8 (type, p_src); 112 113 114 /* Update number of bytes comsumed */ 115 nfc_hal_cb.prm.cur_patch_offset += (len + patch_hdr_size); 116 nfc_hal_cb.prm.cur_patch_len_remaining -= (len + patch_hdr_size); 117 118 /* Check if sending signature byte */ 119 if ( (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD ) 120 &&(type == NCI_SPD_TYPE_SIGNATURE) ) 121 { 122 nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_SIGNATURE_SENT; 123 } 124 /* Check for header */ 125 else if ( (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD ) 126 &&(type == NCI_SPD_TYPE_HEADER) ) 127 { 128 /* Check if patch is for BCM20791B3 */ 129 p_src += NCI_SPD_HEADER_OFFSET_CHIPVERLEN; 130 STREAM_TO_UINT8 (chipverlen, p_src); 131 if (memcmp (nfc_hal_cb.nvm_cb.chip_ver, p_src, chipverlen) != 0) 132 { 133 HAL_TRACE_ERROR0 ("Unexpected chip ver."); 134 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT); 135 return; 136 } 137 STREAM_TO_ARRAY (chipverstr, p_src, NCI_SPD_HEADER_CHIPVER_LEN); 138 139 if (memcmp (NFC_HAL_PRM_BCM20791B3_STR, chipverstr, NFC_HAL_PRM_BCM20791B3_STR_LEN) == 0) 140 { 141 /* Patch is for BCM2079B3 - do not wait for RESET_NTF after patch download */ 142 nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_BCM20791B3; 143 } 144 else 145 { 146 /* Patch is for BCM2079B4 or newer - wait for RESET_NTF after patch download */ 147 nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_BCM20791B3; 148 } 149 } 150 151 /* Send the command (not including HCIT here) */ 152 nfc_hal_dm_send_nci_cmd ((UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset + 1), (UINT8) (len + NCI_MSG_HDR_SIZE), 153 nfc_hal_prm_nci_command_complete_cback); 154 } 155 156 /******************************************************************************* 157 ** 158 ** Function nfc_hal_prm_spd_handle_next_patch_start 159 ** 160 ** Description Handle start of next patch (for secure patch download) 161 ** 162 ** Returns void 163 ** 164 *******************************************************************************/ 165 void nfc_hal_prm_spd_handle_next_patch_start (void) 166 { 167 UINT32 cur_patch_mask; 168 UINT32 cur_patch_len; 169 BOOLEAN found_patch_to_download = FALSE; 170 171 while (!found_patch_to_download) 172 { 173 /* Get length of current patch */ 174 cur_patch_len = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len; 175 176 /* Check if this is a patch we need to download */ 177 cur_patch_mask = ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode); 178 if (nfc_hal_cb.prm.spd_patch_needed_mask & cur_patch_mask) 179 { 180 found_patch_to_download = TRUE; 181 } 182 else 183 { 184 /* Do not need to download this patch. Skip to next patch */ 185 HAL_TRACE_DEBUG1 ("Skipping patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode); 186 187 nfc_hal_cb.prm.spd_cur_patch_idx++; 188 if (nfc_hal_cb.prm.spd_cur_patch_idx >= nfc_hal_cb.prm.spd_patch_count) 189 { 190 /* No more to download */ 191 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT); 192 return; 193 } 194 else if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)) 195 { 196 /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch header */ 197 (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH); 198 return; 199 } 200 else 201 { 202 /* Patch in buffer. Skip over current patch. Check next patch */ 203 nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) cur_patch_len; 204 nfc_hal_cb.prm.cur_patch_offset += (UINT16) cur_patch_len; 205 } 206 } 207 } 208 209 210 /* Begin downloading patch */ 211 HAL_TRACE_DEBUG1 ("Downloading patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode); 212 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_DOWNLOADING; 213 nfc_hal_prm_spd_send_next_segment (); 214 } 215 216 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE)) 217 /******************************************************************************* 218 ** 219 ** Function nfc_hal_prm_spd_download_i2c_fix 220 ** 221 ** Description Start downloading patch for i2c fix 222 ** 223 ** Returns void 224 ** 225 *******************************************************************************/ 226 void nfc_hal_prm_spd_download_i2c_fix (void) 227 { 228 UINT8 *p, *p_start; 229 UINT16 patchfile_project_id; 230 UINT16 patchfile_ver_major; 231 UINT16 patchfile_ver_minor; 232 UINT16 patchfile_patchsize; 233 UINT8 u8; 234 235 HAL_TRACE_DEBUG0 ("Downloading I2C fix..."); 236 237 /* Save pointer and offset of patchfile, so we can resume after downloading the i2c fix */ 238 nfc_hal_cb.prm.spd_patch_offset = nfc_hal_cb.prm.cur_patch_offset; 239 nfc_hal_cb.prm.spd_patch_len_remaining = nfc_hal_cb.prm.cur_patch_len_remaining; 240 241 /* Initialize pointers for downloading i2c fix */ 242 nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm_i2c.p_patch; 243 nfc_hal_cb.prm.cur_patch_offset = 0; 244 nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm_i2c.len; 245 246 /* Parse the i2c patchfile */ 247 if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN) 248 { 249 /* Parse patchfile header */ 250 p = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data; 251 p_start = p; 252 STREAM_TO_UINT16 (patchfile_project_id, p); 253 STREAM_TO_UINT16 (patchfile_ver_major, p); 254 STREAM_TO_UINT16 (patchfile_ver_minor, p); 255 256 /* RFU */ 257 p++; 258 259 /* Check how many patches are in the patch file */ 260 STREAM_TO_UINT8 (u8, p); 261 262 /* Should only be one patch */ 263 if (u8 > 1) 264 { 265 HAL_TRACE_ERROR1 ("Invalid i2c fix: invalid number of patches (%i)", u8); 266 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT); 267 return; 268 } 269 270 271 /* Get info about the i2c patch*/ 272 STREAM_TO_UINT8 (u8, p); /* power mode (not needed for i2c patch) */ 273 STREAM_TO_UINT16 (patchfile_patchsize, p); /* size of patch */ 274 275 /* 5 byte RFU */ 276 p += 5; 277 278 /* Adjust length to exclude patchfiloe header */ 279 nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start); /* Adjust size of patchfile */ 280 nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start); /* Bytes of patchfile transmitted/processed so far */ 281 282 /* Begin sending patch to the NFCC */ 283 nfc_hal_prm_spd_send_next_segment (); 284 } 285 else 286 { 287 /* ERROR: Bad length for patchfile */ 288 HAL_TRACE_ERROR0 ("Invalid i2c fix: unexpected end of patch"); 289 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT); 290 } 291 } 292 #endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */ 293 294 /******************************************************************************* 295 ** 296 ** Function nfc_hal_prm_spd_check_version 297 ** 298 ** Description Check patchfile version with current downloaded version 299 ** 300 ** Returns void 301 ** 302 *******************************************************************************/ 303 void nfc_hal_prm_spd_check_version (void) 304 { 305 UINT8 *p, *p_start, i; 306 UINT32 nvm_patch_present_mask = 0; 307 UINT32 patchfile_patch_present_mask; 308 UINT16 patchfile_project_id = 0; 309 UINT16 patchfile_ver_major = 0; 310 UINT16 patchfile_ver_minor = 0; 311 UINT16 patchfile_patchsize; 312 313 UINT8 return_code = NFC_HAL_PRM_COMPLETE_EVT; 314 315 /* Initialize patchfile offset pointers */ 316 p = p_start = NULL; 317 patchfile_patchsize = 0; 318 319 /* the good patches in NVM */ 320 if (nfc_hal_cb.nvm_cb.lpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_LPM_BAD))) 321 nvm_patch_present_mask |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_LPM); 322 323 if (nfc_hal_cb.nvm_cb.fpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_FPM_BAD))) 324 nvm_patch_present_mask |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_FPM); 325 326 /* Get patchfile version */ 327 if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN) 328 { 329 /* Parse patchfile header */ 330 p = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data; 331 p_start = p; 332 STREAM_TO_UINT16 (patchfile_project_id, p); 333 STREAM_TO_UINT16 (patchfile_ver_major, p); 334 STREAM_TO_UINT16 (patchfile_ver_minor, p); 335 336 /* RFU */ 337 p++; 338 339 /* Check how many patches are in the patch file */ 340 STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_count, p); 341 342 if (nfc_hal_cb.prm.spd_patch_count > NFC_HAL_PRM_MAX_PATCH_COUNT) 343 { 344 HAL_TRACE_ERROR2 ("Unsupported patchfile (number of patches (%i) exceeds maximum (%i)", 345 nfc_hal_cb.prm.spd_patch_count, NFC_HAL_PRM_MAX_PATCH_COUNT); 346 } 347 348 /* Mask of patches that are present in the patchfile */ 349 patchfile_patch_present_mask = 0; 350 351 /* Get lengths for each patch */ 352 for (i = 0; i < nfc_hal_cb.prm.spd_patch_count; i++) 353 { 354 /* Get power mode for this patch */ 355 STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_desc[i].power_mode, p); 356 357 /* Update mask of power-modes present in the patchfile */ 358 patchfile_patch_present_mask |= ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[i].power_mode); 359 360 /* Get length of patch */ 361 STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_patch_desc[i].len, p); 362 363 /* Add total size of patches */ 364 patchfile_patchsize += nfc_hal_cb.prm.spd_patch_desc[i].len; 365 366 /* 5 byte RFU */ 367 p += 5; 368 } 369 370 /* Adjust offset to after the patch file header */ 371 nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start); /* Bytes of patchfile transmitted/processed so far */ 372 nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start); /* Adjust size of patchfile */ 373 374 375 HAL_TRACE_DEBUG4 ("NVM Patch info: flags=0x%04x, Ver=%i.%i, PatchMask=0x%08x", 376 nfc_hal_cb.nvm_cb.flags, nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor, nvm_patch_present_mask ); 377 HAL_TRACE_DEBUG6 ("Patchfile info: ProjID=0x%04x, Ver=%i.%i, Num patches=%i, PatchMask=0x%08x, PatchSize=%i", 378 patchfile_project_id, patchfile_ver_major, patchfile_ver_minor, 379 nfc_hal_cb.prm.spd_patch_count, patchfile_patch_present_mask, patchfile_patchsize); 380 381 /********************************************************************* 382 * Version check of patchfile against NVM 383 ******************************************************************** 384 /* Download the patchfile if no patches in NVM */ 385 if ((nfc_hal_cb.nvm_cb.project_id == 0) || !(nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_PATCH_PRESENT)) 386 { 387 /* No patch in NVM, need to download all */ 388 nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask; 389 390 HAL_TRACE_DEBUG2 ("No previous patch detected. Downloading patch %i.%i", 391 patchfile_ver_major, patchfile_ver_minor); 392 } 393 /* Skip download if project ID of patchfile does not match NVM */ 394 else if (nfc_hal_cb.nvm_cb.project_id != patchfile_project_id) 395 { 396 /* Project IDs mismatch */ 397 HAL_TRACE_DEBUG2 ("Patch download skipped: Mismatched Project ID (NVM ProjId: 0x%04x, Patchfile ProjId: 0x%04x)", 398 nfc_hal_cb.nvm_cb.project_id, patchfile_project_id); 399 400 return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT; 401 } 402 /* Skip download if version of patchfile is equal to version in NVM */ 403 /* and patches of the power modes are the same as the good patches in NVM */ 404 else if ( (nfc_hal_cb.nvm_cb.ver_major == patchfile_ver_major) 405 &&(nfc_hal_cb.nvm_cb.ver_minor == patchfile_ver_minor) 406 &&((nvm_patch_present_mask | patchfile_patch_present_mask) == nvm_patch_present_mask) ) /* if the NVM patch include all the patched in file */ 407 { 408 HAL_TRACE_DEBUG2 ("Patch download skipped. NVM patch (version %i.%i) is the same than the patchfile ", 409 nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor); 410 411 return_code = NFC_HAL_PRM_COMPLETE_EVT; 412 } 413 /* Remaining cases: Download all patches in the patchfile */ 414 else 415 { 416 nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask; 417 418 HAL_TRACE_DEBUG4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...", 419 patchfile_ver_major, patchfile_ver_minor, 420 nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor); 421 } 422 423 } 424 else 425 { 426 /* Invalid patch file header */ 427 HAL_TRACE_ERROR0 ("Invalid patch file header."); 428 429 return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT; 430 } 431 432 /* If we need to download anything, get the first patch to download */ 433 if (nfc_hal_cb.prm.spd_patch_needed_mask) 434 { 435 HAL_TRACE_ERROR4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...", 436 patchfile_ver_major, patchfile_ver_minor, 437 nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor); 438 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE)) 439 /* Check if I2C patch is needed: if */ 440 /* - I2C patch file was provided using HAL_NfcPrmSetI2cPatch, and */ 441 /* - current patch in NVM has ProjectID=0, or */ 442 /* FPM is not present or corrupted, or */ 443 /* or patchfile is major-ver 76+ */ 444 /* or patchfile is not for B3 (always download for B4 onward) */ 445 if ( (nfc_hal_cb.prm_i2c.p_patch) 446 &&( (nfc_hal_cb.nvm_cb.project_id == 0) 447 ||(nfc_hal_cb.nvm_cb.fpm_size == 0) 448 ||(nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_FPM_BAD) 449 ||(patchfile_ver_major >= 76) 450 ||(!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3)) )) 451 { 452 HAL_TRACE_DEBUG0 ("I2C patch fix required."); 453 nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED; 454 455 /* Download i2c fix first */ 456 nfc_hal_prm_spd_download_i2c_fix (); 457 return; 458 } 459 #endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */ 460 461 /* Download first segment */ 462 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER; 463 if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)) 464 { 465 /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch segment */ 466 (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH); 467 } 468 else 469 { 470 nfc_hal_prm_spd_handle_next_patch_start (); 471 } 472 } 473 else 474 { 475 static BOOLEAN firstTime = TRUE; 476 if (firstTime) 477 { 478 HAL_TRACE_ERROR2 ("NVM patch version is %d.%d", 479 nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor); 480 firstTime = FALSE; 481 } 482 /* Download complete */ 483 nfc_hal_prm_spd_handle_download_complete (return_code); 484 } 485 } 486 487 #if (NFC_HAL_TRACE_VERBOSE == TRUE) 488 /******************************************************************************* 489 ** 490 ** Function nfc_hal_prm_spd_status_str 491 ** 492 ** Description Return status string for a given spd status code 493 ** 494 ** Returns Status string 495 ** 496 *******************************************************************************/ 497 UINT8 *nfc_hal_prm_spd_status_str (UINT8 spd_status_code) 498 { 499 char *p_str; 500 501 switch (spd_status_code) 502 { 503 case NCI_STATUS_SPD_ERROR_DEST: 504 p_str = "SPD_ERROR_DEST"; 505 break; 506 507 case NCI_STATUS_SPD_ERROR_PROJECTID: 508 p_str = "SPD_ERROR_PROJECTID"; 509 break; 510 511 case NCI_STATUS_SPD_ERROR_CHIPVER: 512 p_str = "SPD_ERROR_CHIPVER"; 513 break; 514 515 case NCI_STATUS_SPD_ERROR_MAJORVER: 516 p_str = "SPD_ERROR_MAJORVER"; 517 break; 518 519 case NCI_STATUS_SPD_ERROR_INVALID_PARAM: 520 p_str = "SPD_ERROR_INVALID_PARAM"; 521 break; 522 523 case NCI_STATUS_SPD_ERROR_INVALID_SIG: 524 p_str = "SPD_ERROR_INVALID_SIG"; 525 break; 526 527 case NCI_STATUS_SPD_ERROR_NVM_CORRUPTED: 528 p_str = "SPD_ERROR_NVM_CORRUPTED"; 529 break; 530 531 case NCI_STATUS_SPD_ERROR_PWR_MODE: 532 p_str = "SPD_ERROR_PWR_MODE"; 533 break; 534 535 case NCI_STATUS_SPD_ERROR_MSG_LEN: 536 p_str = "SPD_ERROR_MSG_LEN"; 537 break; 538 539 case NCI_STATUS_SPD_ERROR_PATCHSIZE: 540 p_str = "SPD_ERROR_PATCHSIZE"; 541 break; 542 543 default: 544 p_str = "Unspecified Error"; 545 break; 546 547 } 548 549 return ((UINT8*) p_str); 550 } 551 #endif /* (NFC_HAL_TRACE_VERBOSE == TRUE) */ 552 553 /******************************************************************************* 554 ** 555 ** Function nfc_hal_prm_nci_command_complete_cback 556 ** 557 ** Description Callback for NCI vendor specific command complete 558 ** (for secure patch download) 559 ** 560 ** Returns void 561 ** 562 *******************************************************************************/ 563 void nfc_hal_prm_nci_command_complete_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data) 564 { 565 UINT8 status, u8; 566 UINT8 *p; 567 UINT32 post_signature_delay; 568 569 NFC_HAL_PRM_STATE ("nfc_hal_prm_nci_command_complete_cback"); 570 571 /* Stop the command-timeout timer */ 572 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer); 573 574 /* Skip over NCI header */ 575 p = p_data + NCI_MSG_HDR_SIZE; 576 577 /* Handle SECURE_PATCH_DOWNLOAD Rsp */ 578 if (event == NFC_VS_SEC_PATCH_DOWNLOAD_EVT) 579 { 580 /* Status and error code */ 581 STREAM_TO_UINT8 (status, p); 582 STREAM_TO_UINT8 (u8, p); 583 584 if (status != NCI_STATUS_OK) 585 { 586 #if (NFC_HAL_TRACE_VERBOSE == TRUE) 587 HAL_TRACE_ERROR2 ("Patch download failed, reason code=0x%X (%s)", status, nfc_hal_prm_spd_status_str (status)); 588 #else 589 HAL_TRACE_ERROR1 ("Patch download failed, reason code=0x%X", status); 590 #endif 591 592 /* Notify application */ 593 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT); 594 return; 595 } 596 597 /* If last segment (SIGNATURE) sent */ 598 if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_SIGNATURE_SENT) 599 { 600 /* Wait for authentication complete (SECURE_PATCH_DOWNLOAD NTF), including time to commit to NVM (for BCM43341B0) */ 601 int auth_delay = NFC_HAL_PRM_SPD_TOUT; 602 if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3)) 603 { 604 /* XXX maco only wait 30 seconds for B4+ revisions to avoid watchdog timeouts */ 605 auth_delay = NFC_HAL_PRM_COMMIT_DELAY; 606 } 607 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTHENTICATING; 608 nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00, 609 (auth_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000); 610 return; 611 } 612 /* Download next segment */ 613 else if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF) 614 { 615 /* If patch is in a buffer, get next patch from buffer */ 616 nfc_hal_prm_spd_send_next_segment (); 617 } 618 else 619 { 620 /* Notify adaptation layer to get next patch segment (via HAL_NfcPrmDownloadContinue) */ 621 (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_CONTINUE_EVT); 622 } 623 } 624 /* Handle SECURE_PATCH_DOWNLOAD NTF */ 625 else if (event == NFC_VS_SEC_PATCH_AUTH_EVT) 626 { 627 HAL_TRACE_DEBUG1 ("prm flags:0x%x.", nfc_hal_cb.prm.flags); 628 /* Status and error code */ 629 STREAM_TO_UINT8 (status, p); 630 STREAM_TO_UINT8 (u8, p); 631 632 /* Sanity check - should only get this NTF while in AUTHENTICATING stage */ 633 if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTHENTICATING) 634 { 635 if (status != NCI_STATUS_OK) 636 { 637 HAL_TRACE_ERROR0 ("Patch authentication failed"); 638 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT); 639 return; 640 } 641 642 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE)) 643 if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED) 644 { 645 HAL_TRACE_DEBUG1 ("PreI2C patch downloaded...waiting %i ms for NFCC to reboot.", nfc_hal_cb.prm_i2c.prei2c_delay); 646 647 /* Restore pointers to patchfile */ 648 nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED; 649 nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm.p_spd_patch; 650 nfc_hal_cb.prm.cur_patch_offset = nfc_hal_cb.prm.spd_patch_offset; 651 nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm.spd_patch_len_remaining; 652 653 /* Resume normal patch download */ 654 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER; 655 nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT; 656 657 /* Post PreI2C delay */ 658 nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00, (nfc_hal_cb.prm_i2c.prei2c_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000); 659 660 return; 661 } 662 #endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */ 663 664 665 /* Wait for NFCC to save the patch to NVM */ 666 if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3)) 667 { 668 /* 20791B4 or newer - wait for RESET_NTF; including time to commit to NVM (for BCM20791B4+) */ 669 post_signature_delay = NFC_HAL_PRM_COMMIT_DELAY; 670 HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for RESET NTF...", post_signature_delay); 671 672 } 673 else if (nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_NO_NVM) 674 { 675 /* No NVM. Wait for NFCC to restart */ 676 post_signature_delay = NFC_HAL_PRM_END_DELAY; 677 HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NFCC to restart...", post_signature_delay); 678 } 679 else 680 { 681 /* Wait for NFCC to save the patch to NVM (need about 1 ms per byte) */ 682 post_signature_delay = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len; 683 if (post_signature_delay < nfc_hal_cb.prm.patchram_delay) 684 post_signature_delay = nfc_hal_cb.prm.patchram_delay; 685 HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NVM update to complete...", post_signature_delay); 686 } 687 688 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTH_DONE; 689 690 nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00, 691 (post_signature_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000); 692 } 693 else 694 { 695 HAL_TRACE_ERROR0 ("Got unexpected SECURE_PATCH_DOWNLOAD NTF"); 696 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT); 697 } 698 } 699 /* Handle NCI_MSG_GET_PATCH_VERSION RSP */ 700 else if (event == NFC_VS_GET_PATCH_VERSION_EVT) 701 { 702 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT); 703 } 704 else 705 { 706 /* Invalid response from NFCC during patch download */ 707 HAL_TRACE_ERROR1 ("Invalid response from NFCC during patch download (opcode=0x%02X)", event); 708 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT); 709 } 710 711 NFC_HAL_PRM_STATE ("prm_nci_command_complete_cback"); 712 } 713 714 /******************************************************************************* 715 ** 716 ** Function nfc_hal_prm_nfcc_ready_to_continue 717 ** 718 ** Description Continue to download patch or notify application completition 719 ** 720 ** Returns void 721 ** 722 *******************************************************************************/ 723 void nfc_hal_prm_nfcc_ready_to_continue (void) 724 { 725 UINT8 get_patch_version_cmd [NCI_MSG_HDR_SIZE] = 726 { 727 NCI_MTS_CMD|NCI_GID_PROP, 728 NCI_MSG_GET_PATCH_VERSION, 729 0x00 730 }; 731 732 /* Clear the bit for the patch we just downloaded */ 733 nfc_hal_cb.prm.spd_patch_needed_mask &= ~ ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode); 734 735 /* Check if another patch to download */ 736 nfc_hal_cb.prm.spd_cur_patch_idx++; 737 if ((nfc_hal_cb.prm.spd_patch_needed_mask) && (nfc_hal_cb.prm.spd_cur_patch_idx < nfc_hal_cb.prm.spd_patch_count)) 738 { 739 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER; 740 nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT; 741 742 if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF) 743 { 744 /* If patch is in a buffer, get next patch from buffer */ 745 nfc_hal_prm_spd_handle_next_patch_start (); 746 } 747 else 748 { 749 /* Notify adaptation layer to get next patch header (via HAL_NfcPrmDownloadContinue) */ 750 (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH); 751 } 752 753 } 754 else 755 { 756 /* Done downloading */ 757 HAL_TRACE_DEBUG0 ("Patch downloaded and authenticated. Get new patch version."); 758 /* add get patch info again to verify the effective FW version */ 759 nfc_hal_dm_send_nci_cmd (get_patch_version_cmd, NCI_MSG_HDR_SIZE, nfc_hal_prm_nci_command_complete_cback); 760 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_W4_GET_VERSION; 761 } 762 } 763 764 /******************************************************************************* 765 ** 766 ** Function nfc_hal_prm_spd_reset_ntf 767 ** 768 ** Description Received RESET NTF from NFCC, indicating it has completed 769 ** reset after patch download. 770 ** 771 ** Returns void 772 ** 773 *******************************************************************************/ 774 void nfc_hal_prm_spd_reset_ntf (UINT8 reset_reason, UINT8 reset_type) 775 { 776 /* Check if we were expecting a RESET NTF */ 777 if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE) 778 { 779 HAL_TRACE_DEBUG2 ("Received RESET NTF after patch download (reset_reason=%i, reset_type=%i)", reset_reason, reset_type); 780 781 /* Stop waiting for RESET NTF */ 782 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer); 783 784 { 785 /* Continue with patch download */ 786 nfc_hal_prm_nfcc_ready_to_continue (); 787 } 788 } 789 else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER) 790 { 791 HAL_TRACE_DEBUG0 ("Received RESET NTF after pre-I2C patch download. Proceeding with patch download..."); 792 793 /* Stop waiting for RESET NTF */ 794 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer); 795 nfc_hal_prm_spd_handle_next_patch_start (); 796 } 797 else 798 { 799 HAL_TRACE_ERROR2 ("Received unexpected RESET NTF (reset_reason=%i, reset_type=%i)", reset_reason, reset_type); 800 } 801 } 802 803 /******************************************************************************* 804 ** 805 ** Function: nfc_post_final_baud_update 806 ** 807 ** Description: Called after baud rate udate 808 ** 809 ** Returns: Nothing 810 ** 811 *******************************************************************************/ 812 void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status) 813 { 814 NFC_HAL_PRM_STATE ("nfc_hal_prm_post_baud_update"); 815 816 if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE) 817 { 818 /* Proceed with next step of patch download sequence */ 819 nfc_hal_prm_nfcc_ready_to_continue (); 820 } 821 } 822 823 /******************************************************************************* 824 ** 825 ** Function nfc_hal_prm_process_timeout 826 ** 827 ** Description Process timer expireation for patch download 828 ** 829 ** Returns void 830 ** 831 *******************************************************************************/ 832 void nfc_hal_prm_process_timeout (void *p_tle) 833 { 834 NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout"); 835 836 if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE) 837 { 838 if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3)) 839 { 840 /* Timeout waiting for RESET NTF after signature sent */ 841 HAL_TRACE_ERROR0 ("Timeout waiting for RESET NTF after patch download"); 842 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT); 843 } 844 else 845 { 846 nfc_hal_prm_nfcc_ready_to_continue (); 847 } 848 } 849 else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER) 850 { 851 HAL_TRACE_DEBUG0 ("Delay after PreI2C patch download...proceeding to download firmware patch"); 852 nfc_hal_prm_spd_handle_next_patch_start (); 853 } 854 else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_W4_GET_VERSION) 855 { 856 HAL_TRACE_DEBUG0 ("get patch version timeout???"); 857 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT); 858 } 859 else 860 { 861 HAL_TRACE_ERROR1 ("Patch download: command timeout (state=%i)", nfc_hal_cb.prm.state); 862 863 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT); 864 } 865 866 NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout"); 867 } 868 869 870 /******************************************************************************* 871 ** 872 ** Function HAL_NfcPrmDownloadStart 873 ** 874 ** Description Initiate patch download 875 ** 876 ** Input Params 877 ** format_type patch format type 878 ** (NFC_HAL_PRM_FORMAT_BIN, NFC_HAL_PRM_FORMAT_HCD, or 879 ** NFC_HAL_PRM_FORMAT_NCD) 880 ** 881 ** dest_address destination adderess (needed for BIN format only) 882 ** 883 ** p_patchram_buf pointer to patchram buffer. If NULL, 884 ** then app must call HAL_NfcPrmDownloadContinue when 885 ** NFC_HAL_PRM_CONTINUE_EVT is received, to send the next 886 ** segment of patchram 887 ** 888 ** patchram_len size of p_patchram_buf (if non-NULL) 889 ** 890 ** patchram_delay The delay after each patch. 891 ** If the given value is less than the size of the patchram, 892 ** the size of patchram is used instead. 893 ** 894 ** p_cback callback for download status 895 ** 896 ** 897 ** Returns TRUE if successful, otherwise FALSE 898 ** 899 ** 900 *******************************************************************************/ 901 BOOLEAN HAL_NfcPrmDownloadStart (tNFC_HAL_PRM_FORMAT format_type, 902 UINT32 dest_address, 903 UINT8 *p_patchram_buf, 904 UINT32 patchram_len, 905 UINT32 patchram_delay, 906 tNFC_HAL_PRM_CBACK *p_cback) 907 { 908 HAL_TRACE_API0 ("HAL_NfcPrmDownloadStart ()"); 909 910 memset (&nfc_hal_cb.prm, 0, sizeof (tNFC_HAL_PRM_CB)); 911 912 if (p_patchram_buf) 913 { 914 nfc_hal_cb.prm.p_cur_patch_data = p_patchram_buf; 915 nfc_hal_cb.prm.cur_patch_offset = 0; 916 nfc_hal_cb.prm.cur_patch_len_remaining = (UINT16) patchram_len; 917 nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF; 918 919 if (patchram_len == 0) 920 return FALSE; 921 } 922 923 nfc_hal_cb.prm.p_cback = p_cback; 924 nfc_hal_cb.prm.dest_ram = dest_address; 925 nfc_hal_cb.prm.format = format_type; 926 nfc_hal_cb.prm.patchram_delay = patchram_delay; 927 928 nfc_hal_cb.prm.timer.p_cback = nfc_hal_prm_process_timeout; 929 930 if (format_type == NFC_HAL_PRM_FORMAT_NCD) 931 { 932 /* Store patch buffer pointer and length */ 933 nfc_hal_cb.prm.p_spd_patch = p_patchram_buf; 934 nfc_hal_cb.prm.spd_patch_len_remaining = (UINT16)patchram_len; 935 nfc_hal_cb.prm.spd_patch_offset = 0; 936 937 /* If patch download is required, but no NVM is available, then abort */ 938 if ((p_nfc_hal_cfg->nfc_hal_prm_nvm_required) && (nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_NO_NVM)) 939 { 940 HAL_TRACE_ERROR0 ("This platform requires NVM and the NVM is not available - Abort"); 941 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_NO_NVM_EVT); 942 return FALSE; 943 } 944 945 /* Compare patch version in NVM with version in patchfile */ 946 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_COMPARE_VERSION; 947 if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF) 948 { 949 /* If patchfile is in a buffer, get patch version from buffer */ 950 nfc_hal_prm_spd_check_version (); 951 } 952 else 953 { 954 /* If patchfile is not in a buffer, then request patchfile header from adaptation layer. */ 955 (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_PATCHFILE_HDR_EVT); 956 } 957 } 958 else 959 { 960 HAL_TRACE_ERROR0 ("Unexpected patch format."); 961 return FALSE; 962 } 963 964 return TRUE; 965 } 966 967 /******************************************************************************* 968 ** 969 ** Function HAL_NfcPrmDownloadContinue 970 ** 971 ** Description Send next segment of patchram to controller. Called when 972 ** NFC_HAL_PRM_CONTINUE_EVT is received. 973 ** 974 ** Only needed if HAL_NfcPrmDownloadStart was called with 975 ** p_patchram_buf=NULL 976 ** 977 ** Input Params p_patch_data pointer to patch data 978 ** patch_data_len patch data len 979 ** 980 ** Returns TRUE if successful, otherwise FALSE 981 ** 982 *******************************************************************************/ 983 BOOLEAN HAL_NfcPrmDownloadContinue (UINT8 *p_patch_data, 984 UINT16 patch_data_len) 985 { 986 HAL_TRACE_API2 ("HAL_NfcPrmDownloadContinue ():state = %d, patch_data_len=%d", 987 nfc_hal_cb.prm.state, patch_data_len); 988 989 /* Check if we are in a valid state for this API */ 990 if ( (nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_COMPARE_VERSION) 991 &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER) 992 &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_DOWNLOADING) ) 993 return FALSE; 994 995 if (patch_data_len == 0) 996 return FALSE; 997 998 nfc_hal_cb.prm.cur_patch_offset = 0; 999 nfc_hal_cb.prm.p_cur_patch_data = p_patch_data; 1000 nfc_hal_cb.prm.cur_patch_len_remaining = patch_data_len; 1001 1002 /* Call appropriate handler */ 1003 if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_COMPARE_VERSION) 1004 { 1005 nfc_hal_prm_spd_check_version (); 1006 } 1007 else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER) 1008 { 1009 nfc_hal_prm_spd_handle_next_patch_start (); 1010 } 1011 else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_DOWNLOADING) 1012 { 1013 nfc_hal_prm_spd_send_next_segment (); 1014 } 1015 else 1016 { 1017 HAL_TRACE_ERROR1 ("Unexpected patch state:%d.", nfc_hal_cb.prm.state); 1018 } 1019 1020 return TRUE; 1021 } 1022 1023 /******************************************************************************* 1024 ** 1025 ** Function HAL_NfcPrmSetI2cPatch 1026 ** 1027 ** Description Specify patchfile for BCM20791B3 I2C fix. This fix 1028 ** must be downloaded prior to initial patch download for I2C 1029 ** transport 1030 ** 1031 ** Input Params p_i2c_patchfile_buf: pointer to patch for i2c fix 1032 ** i2c_patchfile_len: length of patch 1033 ** prei2c_delay: the delay before downloading main patch 1034 ** if 0 is given, NFC_HAL_PRM_POST_I2C_FIX_DELAY is used instead. 1035 ** 1036 ** Returns Nothing 1037 ** 1038 ** 1039 *******************************************************************************/ 1040 void HAL_NfcPrmSetI2cPatch (UINT8 *p_i2c_patchfile_buf, UINT16 i2c_patchfile_len, UINT32 prei2c_delay) 1041 { 1042 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE)) 1043 HAL_TRACE_API0 ("HAL_NfcPrmSetI2cPatch ()"); 1044 1045 nfc_hal_cb.prm_i2c.prei2c_delay = NFC_HAL_PRM_POST_I2C_FIX_DELAY; 1046 if (prei2c_delay) 1047 nfc_hal_cb.prm_i2c.prei2c_delay = prei2c_delay; 1048 nfc_hal_cb.prm_i2c.p_patch = p_i2c_patchfile_buf; 1049 nfc_hal_cb.prm_i2c.len = i2c_patchfile_len; 1050 #endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */ 1051 } 1052 1053 /******************************************************************************* 1054 ** 1055 ** Function HAL_NfcPrmSetSpdNciCmdPayloadSize 1056 ** 1057 ** Description Set Host-to-NFCC NCI message size for secure patch download 1058 ** 1059 ** This API must be called before calling HAL_NfcPrmDownloadStart. 1060 ** If the API is not called, then PRM will use the default 1061 ** message size. 1062 ** 1063 ** Typically, this API is only called for platforms that have 1064 ** message-size limitations in the transport/driver. 1065 ** 1066 ** Valid message size range: NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE to 255. 1067 ** 1068 ** Returns HAL_NFC_STATUS_OK if successful 1069 ** HAL_NFC_STATUS_FAILED otherwise 1070 ** 1071 ** 1072 *******************************************************************************/ 1073 tHAL_NFC_STATUS HAL_NfcPrmSetSpdNciCmdPayloadSize (UINT8 max_payload_size) 1074 { 1075 /* Validate: minimum size is NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE */ 1076 if (max_payload_size < NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE) 1077 { 1078 HAL_TRACE_ERROR2 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: invalid size (%i). Must be between %i and 255", max_payload_size, NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE); 1079 return (HAL_NFC_STATUS_FAILED); 1080 } 1081 else 1082 { 1083 HAL_TRACE_API1 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: new message size during download: %i", max_payload_size); 1084 nfc_hal_cb.ncit_cb.nci_ctrl_size = max_payload_size; 1085 return (HAL_NFC_STATUS_OK); 1086 } 1087 } 1088