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