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