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