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