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