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