1 /****************************************************************************** 2 * 3 * Copyright (C) 1999-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 "OverrideLog.h" 19 #include "config.h" 20 #include "nfc_hal_int.h" 21 #include "userial.h" 22 extern "C" 23 { 24 #include "nfc_hal_post_reset.h" 25 } 26 #include <string> 27 #include <cutils/properties.h> 28 #include "spdhelper.h" 29 #include "StartupConfig.h" 30 31 #define LOG_TAG "NfcNciHal" 32 33 #define FW_PRE_PATCH "FW_PRE_PATCH" 34 #define FW_PATCH "FW_PATCH" 35 #define MAX_RF_DATA_CREDITS "MAX_RF_DATA_CREDITS" 36 37 #define MAX_BUFFER (512) 38 static char sPrePatchFn[MAX_BUFFER+1]; 39 static char sPatchFn[MAX_BUFFER+1]; 40 static void * sPrmBuf = NULL; 41 static void * sI2cFixPrmBuf = NULL; 42 43 #define CONFIG_MAX_LEN 256 44 static UINT8 sConfig [CONFIG_MAX_LEN]; 45 static StartupConfig sStartupConfig; 46 static StartupConfig sLptdConfig; 47 static StartupConfig sPreDiscoveryConfig; 48 extern UINT8 *p_nfc_hal_dm_start_up_cfg; //defined in the HAL 49 static UINT8 nfa_dm_start_up_vsc_cfg[CONFIG_MAX_LEN]; 50 extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg; //defined in the HAL 51 extern UINT8 *p_nfc_hal_dm_lptd_cfg; //defined in the HAL 52 extern UINT8 *p_nfc_hal_pre_discover_cfg; //defined in the HAL 53 54 extern tSNOOZE_MODE_CONFIG gSnoozeModeCfg; 55 extern tNFC_HAL_CFG *p_nfc_hal_cfg; 56 static void mayDisableSecureElement (StartupConfig& config); 57 58 /* Default patchfile (in NCD format) */ 59 #ifndef NFA_APP_DEFAULT_PATCHFILE_NAME 60 #define NFA_APP_DEFAULT_PATCHFILE_NAME "\0" 61 #endif 62 63 /* Default patchfile (in NCD format) */ 64 #ifndef NFA_APP_DEFAULT_I2C_PATCHFILE_NAME 65 #define NFA_APP_DEFAULT_I2C_PATCHFILE_NAME "\0" 66 #endif 67 68 #define BRCM_43341B0_ID 0x43341b00 69 70 tNFC_POST_RESET_CB nfc_post_reset_cb = 71 { 72 /* Default Patch & Pre-Patch */ 73 NFA_APP_DEFAULT_PATCHFILE_NAME, 74 NULL, 75 NFA_APP_DEFAULT_I2C_PATCHFILE_NAME, 76 NULL, 77 78 /* Default UART baud rate */ 79 NFC_HAL_DEFAULT_BAUD, 80 81 /* Default tNFC_HAL_DEV_INIT_CFG (flags, num_xtal_cfg, {brcm_hw_id, xtal-freq, xtal-index} ) */ 82 { 83 1, /* number of valid entries */ 84 { 85 {BRCM_43341B0_ID, 37400, NFC_HAL_XTAL_INDEX_37400}, 86 {0, 0, 0}, 87 {0, 0, 0}, 88 {0, 0, 0}, 89 {0, 0, 0}, 90 } 91 }, 92 93 /* Default low power mode settings */ 94 NFC_HAL_LP_SNOOZE_MODE_NONE, /* Snooze Mode */ 95 NFC_HAL_LP_IDLE_THRESHOLD_HOST, /* Idle Threshold Host */ 96 NFC_HAL_LP_IDLE_THRESHOLD_HC, /* Idle Threshold HC */ 97 NFC_HAL_LP_ACTIVE_LOW, /* NFC_WAKE Active Mode */ 98 NFC_HAL_LP_ACTIVE_HIGH, /* DH_WAKE Active Mode */ 99 100 NFA_APP_MAX_NUM_REINIT, /* max retry to get NVM type */ 101 0, /* current retry count */ 102 TRUE, /* debug mode for downloading patchram */ 103 FALSE /* skip downloading patchram after reinit because of patch download failure */ 104 }; 105 106 107 /******************************************************************************* 108 ** 109 ** Function getFileLength 110 ** 111 ** Description return the size of a file 112 ** 113 ** Returns file size in number of bytes 114 ** 115 *******************************************************************************/ 116 static long getFileLength(FILE* fp) 117 { 118 long sz; 119 fseek(fp, 0L, SEEK_END); 120 sz = ftell(fp); 121 fseek(fp, 0L, SEEK_SET); 122 123 return sz; 124 } 125 126 /******************************************************************************* 127 ** 128 ** Function isFileExist 129 ** 130 ** Description Check if file name exists (android does not support fexists) 131 ** 132 ** Returns TRUE if file exists 133 ** 134 *******************************************************************************/ 135 static BOOLEAN isFileExist(const char *pFilename) 136 { 137 FILE *pf; 138 139 if ((pf = fopen(pFilename, "r")) != NULL) 140 { 141 fclose(pf); 142 return TRUE; 143 } 144 return FALSE; 145 } 146 147 /******************************************************************************* 148 ** 149 ** Function findPatchramFile 150 ** 151 ** Description Find the patchram file name specified in the .conf 152 ** 153 ** Returns pointer to the file name 154 ** 155 *******************************************************************************/ 156 static const char* findPatchramFile(const char * pConfigName, char * pBuffer, int bufferLen) 157 { 158 ALOGD("%s: config=%s", __FUNCTION__, pConfigName); 159 160 if (pConfigName == NULL) 161 { 162 ALOGD("%s No patchfile defined\n", __FUNCTION__); 163 return NULL; 164 } 165 166 if (GetStrValue(pConfigName, &pBuffer[0], bufferLen)) 167 { 168 ALOGD("%s found patchfile %s\n", __FUNCTION__, pBuffer); 169 return (pBuffer[0] == '\0') ? NULL : pBuffer; 170 } 171 172 ALOGD("%s Cannot find patchfile '%s'\n", __FUNCTION__, pConfigName); 173 return NULL; 174 } 175 176 /******************************************************************************* 177 ** 178 ** Function: continueAfterSetSnoozeMode 179 ** 180 ** Description: Called after Snooze Mode is enabled. 181 ** 182 ** Returns: none 183 ** 184 *******************************************************************************/ 185 static void continueAfterSetSnoozeMode(tHAL_NFC_STATUS status) 186 { 187 ALOGD("%s: status=%u", __FUNCTION__, status); 188 if (status == NCI_STATUS_OK) 189 HAL_NfcPreInitDone (HAL_NFC_STATUS_OK); 190 else 191 HAL_NfcPreInitDone (HAL_NFC_STATUS_FAILED); 192 } 193 194 /******************************************************************************* 195 ** 196 ** Function: postDownloadPatchram 197 ** 198 ** Description: Called after patch download 199 ** 200 ** Returns: none 201 ** 202 *******************************************************************************/ 203 static void postDownloadPatchram(tHAL_NFC_STATUS status) 204 { 205 ALOGD("%s: status=%i", __FUNCTION__, status); 206 207 if (status != HAL_NFC_STATUS_OK) 208 { 209 ALOGE("Patch download failed"); 210 if (status == HAL_NFC_STATUS_REFUSED) 211 { 212 SpdHelper::setPatchAsBad(); 213 } 214 else 215 SpdHelper::incErrorCount(); 216 217 /* If in SPD Debug mode, fail immediately and obviously */ 218 if (SpdHelper::isSpdDebug()) 219 HAL_NfcPreInitDone (HAL_NFC_STATUS_FAILED); 220 else 221 { 222 /* otherwise, power cycle the chip and let the stack startup normally */ 223 USERIAL_PowerupDevice(0); 224 HAL_NfcPreInitDone (HAL_NFC_STATUS_OK); 225 } 226 } 227 /* Set snooze mode here */ 228 else if (gSnoozeModeCfg.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) 229 { 230 status = HAL_NfcSetSnoozeMode(gSnoozeModeCfg.snooze_mode, 231 gSnoozeModeCfg.idle_threshold_dh, 232 gSnoozeModeCfg.idle_threshold_nfcc, 233 gSnoozeModeCfg.nfc_wake_active_mode, 234 gSnoozeModeCfg.dh_wake_active_mode, 235 continueAfterSetSnoozeMode); 236 if (status != NCI_STATUS_OK) 237 { 238 ALOGE("%s: Setting snooze mode failed, status=%i", __FUNCTION__, status); 239 HAL_NfcPreInitDone(HAL_NFC_STATUS_FAILED); 240 } 241 } 242 else 243 { 244 ALOGD("%s: Not using Snooze Mode", __FUNCTION__); 245 HAL_NfcPreInitDone(HAL_NFC_STATUS_OK); 246 } 247 } 248 249 250 /******************************************************************************* 251 ** 252 ** Function: prmCallback 253 ** 254 ** Description: Patchram callback (for static patchram mode) 255 ** 256 ** Returns: none 257 ** 258 *******************************************************************************/ 259 void prmCallback(UINT8 event) 260 { 261 ALOGD("%s: event=0x%x", __FUNCTION__, event); 262 switch (event) 263 { 264 case NFC_HAL_PRM_CONTINUE_EVT: 265 /* This event does not occur if static patchram buf is used */ 266 break; 267 268 case NFC_HAL_PRM_COMPLETE_EVT: 269 postDownloadPatchram(HAL_NFC_STATUS_OK); 270 break; 271 272 case NFC_HAL_PRM_ABORT_EVT: 273 postDownloadPatchram(HAL_NFC_STATUS_FAILED); 274 break; 275 276 case NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT: 277 ALOGD("%s: invalid patch...skipping patch download", __FUNCTION__); 278 postDownloadPatchram(HAL_NFC_STATUS_REFUSED); 279 break; 280 281 case NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT: 282 ALOGD("%s: patch authentication failed", __FUNCTION__); 283 postDownloadPatchram(HAL_NFC_STATUS_REFUSED); 284 break; 285 286 case NFC_HAL_PRM_ABORT_NO_NVM_EVT: 287 ALOGD("%s: No NVM detected", __FUNCTION__); 288 HAL_NfcPreInitDone(HAL_NFC_STATUS_FAILED); 289 break; 290 291 default: 292 ALOGD("%s: not handled event=0x%x", __FUNCTION__, event); 293 break; 294 } 295 } 296 297 298 /******************************************************************************* 299 ** 300 ** Function getNfaValues 301 ** 302 ** Description Get configuration values needed by NFA layer 303 ** 304 ** Returns: None 305 ** 306 *******************************************************************************/ 307 static void getNfaValues() 308 { 309 unsigned long num = 0; 310 int actualLen = 0; 311 312 p_nfc_hal_cfg->nfc_hal_prm_nvm_required = TRUE; //don't download firmware if controller cannot detect EERPOM 313 sStartupConfig.initialize (); 314 sLptdConfig.initialize (); 315 sPreDiscoveryConfig.initialize(); 316 317 318 actualLen = GetStrValue (NAME_NFA_DM_START_UP_CFG, (char*)sConfig, sizeof(sConfig)); 319 if (actualLen >= 8) 320 { 321 ALOGD ( "START_UP_CFG[0] = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 322 sConfig[0], 323 sConfig[1], 324 sConfig[2], 325 sConfig[3], 326 sConfig[4], 327 sConfig[5], 328 sConfig[6], 329 sConfig[7] ); 330 sStartupConfig.append (sConfig, actualLen); 331 } 332 333 // Set antenna tuning configuration if configured. 334 actualLen = GetStrValue(NAME_PREINIT_DSP_CFG, (char*)sConfig, sizeof(sConfig)); 335 if (actualLen) 336 sStartupConfig.append (sConfig, actualLen); 337 338 if ( GetStrValue ( NAME_NFA_DM_START_UP_VSC_CFG, (char*)nfa_dm_start_up_vsc_cfg, sizeof (nfa_dm_start_up_vsc_cfg) ) ) 339 { 340 p_nfc_hal_dm_start_up_vsc_cfg = &nfa_dm_start_up_vsc_cfg[0]; 341 ALOGD ( "START_UP_VSC_CFG[0] = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 342 nfa_dm_start_up_vsc_cfg[0], 343 nfa_dm_start_up_vsc_cfg[1], 344 nfa_dm_start_up_vsc_cfg[2], 345 nfa_dm_start_up_vsc_cfg[3], 346 nfa_dm_start_up_vsc_cfg[4], 347 nfa_dm_start_up_vsc_cfg[5], 348 nfa_dm_start_up_vsc_cfg[6], 349 nfa_dm_start_up_vsc_cfg[7] ); 350 } 351 352 actualLen = GetStrValue(NAME_LPTD_CFG, (char*)sConfig, sizeof(sConfig)); 353 if (actualLen) 354 { 355 sLptdConfig.append (sConfig, actualLen); 356 p_nfc_hal_dm_lptd_cfg = const_cast<UINT8*> (sLptdConfig.getInternalBuffer ()); 357 } 358 359 mayDisableSecureElement (sStartupConfig); 360 p_nfc_hal_dm_start_up_cfg = const_cast<UINT8*> (sStartupConfig.getInternalBuffer ()); 361 362 actualLen = GetStrValue(NAME_NFA_DM_PRE_DISCOVERY_CFG, (char*)sConfig, sizeof(sConfig)); 363 if (actualLen) 364 { 365 sPreDiscoveryConfig.append (sConfig, actualLen); 366 p_nfc_hal_pre_discover_cfg = const_cast<UINT8*> (sPreDiscoveryConfig.getInternalBuffer ()); 367 } 368 } 369 370 /******************************************************************************* 371 ** 372 ** Function StartPatchDownload 373 ** 374 ** Description Reads configuration settings, and begins the download 375 ** process if patch files are configured. 376 ** 377 ** Returns: None 378 ** 379 *******************************************************************************/ 380 static void StartPatchDownload(UINT32 chipid) 381 { 382 ALOGD ("%s: chipid=%lx",__FUNCTION__, chipid); 383 384 char chipID[30]; 385 sprintf(chipID, "%lx", chipid); 386 ALOGD ("%s: chidId=%s", __FUNCTION__, chipID); 387 388 readOptionalConfig(chipID); // Read optional chip specific settings 389 readOptionalConfig("fime"); // Read optional FIME specific settings 390 getNfaValues(); // Get NFA configuration values into variables 391 392 393 findPatchramFile(FW_PATCH, sPatchFn, sizeof(sPatchFn)); 394 findPatchramFile(FW_PRE_PATCH, sPrePatchFn, sizeof(sPatchFn)); 395 396 { 397 FILE *fd; 398 /* If an I2C fix patch file was specified, then tell the stack about it */ 399 if (sPrePatchFn[0] != '\0') 400 { 401 if ((fd = fopen(sPrePatchFn, "rb")) != NULL) 402 { 403 UINT32 lenPrmBuffer = getFileLength(fd); 404 405 if ((sI2cFixPrmBuf = malloc(lenPrmBuffer)) != NULL) 406 { 407 fread(sI2cFixPrmBuf, lenPrmBuffer, 1, fd); 408 409 ALOGD("%s Setting I2C fix to %s (size: %lu)", __FUNCTION__, sPrePatchFn, lenPrmBuffer); 410 HAL_NfcPrmSetI2cPatch((UINT8*)sI2cFixPrmBuf, (UINT16)lenPrmBuffer, 0); 411 } 412 else 413 { 414 ALOGE("%s Unable to get buffer to i2c fix (%lu bytes)", __FUNCTION__, lenPrmBuffer); 415 } 416 417 fclose(fd); 418 } 419 else 420 { 421 ALOGE("%s Unable to open i2c fix patchfile %s", __FUNCTION__, sPrePatchFn); 422 } 423 } 424 } 425 426 { 427 FILE *fd; 428 429 /* If a patch file was specified, then download it now */ 430 if (sPatchFn[0] != '\0') 431 { 432 UINT32 bDownloadStarted = false; 433 434 /* open patchfile, read it into a buffer */ 435 if ((fd = fopen(sPatchFn, "rb")) != NULL) 436 { 437 UINT32 lenPrmBuffer = getFileLength(fd); 438 ALOGD("%s Downloading patchfile %s (size: %lu) format=%u", __FUNCTION__, sPatchFn, lenPrmBuffer, NFC_HAL_PRM_FORMAT_NCD); 439 if ((sPrmBuf = malloc(lenPrmBuffer)) != NULL) 440 { 441 fread(sPrmBuf, lenPrmBuffer, 1, fd); 442 443 if (!SpdHelper::isPatchBad((UINT8*)sPrmBuf, lenPrmBuffer)) 444 { 445 /* Download patch using static memeory mode */ 446 HAL_NfcPrmDownloadStart(NFC_HAL_PRM_FORMAT_NCD, 0, (UINT8*)sPrmBuf, lenPrmBuffer, 0, prmCallback); 447 bDownloadStarted = true; 448 } 449 } 450 else 451 ALOGE("%s Unable to buffer to hold patchram (%lu bytes)", __FUNCTION__, lenPrmBuffer); 452 453 fclose(fd); 454 } 455 else 456 ALOGE("%s Unable to open patchfile %s", __FUNCTION__, sPatchFn); 457 458 /* If the download never got started */ 459 if (!bDownloadStarted) 460 { 461 /* If debug mode, fail in an obvious way, otherwise try to start stack */ 462 postDownloadPatchram(SpdHelper::isSpdDebug() ? HAL_NFC_STATUS_FAILED : 463 HAL_NFC_STATUS_OK); 464 } 465 } 466 else 467 { 468 ALOGE("%s: No patchfile specified or disabled. Proceeding to post-download procedure...", __FUNCTION__); 469 postDownloadPatchram(HAL_NFC_STATUS_OK); 470 } 471 } 472 473 ALOGD ("%s: exit", __FUNCTION__); 474 } 475 476 /******************************************************************************* 477 ** 478 ** Function: nfc_hal_post_reset_init 479 ** 480 ** Description: Called by the NFC HAL after controller has been reset. 481 ** Begin to download firmware patch files. 482 ** 483 ** Returns: none 484 ** 485 *******************************************************************************/ 486 void nfc_hal_post_reset_init (UINT32 brcm_hw_id, UINT8 nvm_type) 487 { 488 ALOGD("%s: brcm_hw_id=0x%lx, nvm_type=%d", __FUNCTION__, brcm_hw_id, nvm_type); 489 tHAL_NFC_STATUS stat = HAL_NFC_STATUS_FAILED; 490 UINT8 max_credits = 1; 491 492 if (nvm_type == NCI_SPD_NVM_TYPE_NONE) 493 { 494 ALOGD("%s: No NVM detected, FAIL the init stage to force a retry", __FUNCTION__); 495 USERIAL_PowerupDevice (0); 496 stat = HAL_NfcReInit (); 497 } 498 else 499 { 500 /* Start downloading the patch files */ 501 StartPatchDownload(brcm_hw_id); 502 503 if (GetNumValue(MAX_RF_DATA_CREDITS, &max_credits, sizeof(max_credits)) && (max_credits > 0)) 504 { 505 ALOGD("%s : max_credits=%d", __FUNCTION__, max_credits); 506 HAL_NfcSetMaxRfDataCredits(max_credits); 507 } 508 } 509 } 510 511 512 /******************************************************************************* 513 ** 514 ** Function: mayDisableSecureElement 515 ** 516 ** Description: Optionally adjust a TLV to disable secure element. This feature 517 ** is enabled by setting the system property 518 ** nfc.disable_secure_element to a bit mask represented by a hex 519 ** octet: C0 = do not detect any secure element. 520 ** 40 = do not detect secure element in slot 0. 521 ** 80 = do not detect secure element in slot 1. 522 ** 523 ** config: a sequence of TLV's. 524 ** 525 *******************************************************************************/ 526 void mayDisableSecureElement (StartupConfig& config) 527 { 528 unsigned int bitmask = 0; 529 char valueStr [PROPERTY_VALUE_MAX] = {0}; 530 int len = property_get ("nfc.disable_secure_element", valueStr, ""); 531 if (len > 0) 532 { 533 sscanf (valueStr, "%x", &bitmask); //read system property as a hex octet 534 ALOGD ("%s: disable 0x%02X", __FUNCTION__, (UINT8) bitmask); 535 config.disableSecureElement ((UINT8) (bitmask & 0xC0)); 536 } 537 } 538