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 "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)
42 static char sPrePatchFn[MAX_BUFFER+1];
43 static char sPatchFn[MAX_BUFFER+1];
44 static void * sPrmBuf = NULL;
45 static void * sI2cFixPrmBuf = NULL;
46
47 #define NFA_DM_START_UP_CFG_PARAM_MAX_LEN 100
48 static UINT8 nfa_dm_start_up_cfg[NFA_DM_START_UP_CFG_PARAM_MAX_LEN];
49 extern UINT8 *p_nfc_hal_dm_start_up_cfg;
50 static UINT8 nfa_dm_start_up_vsc_cfg[NFA_DM_START_UP_CFG_PARAM_MAX_LEN];
51 extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg;
52 extern UINT8 *p_nfc_hal_dm_lptd_cfg;
53 static UINT8 nfa_dm_lptd_cfg[LPTD_PARAM_LEN];
54 extern tSNOOZE_MODE_CONFIG gSnoozeModeCfg;
55 extern BOOLEAN nfc_hal_prm_nvm_required; //true: don't download firmware if controller cannot detect EERPOM
56 static void HalNciCallback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
57
58
59 tNFC_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 *******************************************************************************/
getFileLength(FILE * fp)86 static 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 *******************************************************************************/
isFileExist(const char * pFilename)105 static 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 *******************************************************************************/
findPatchramFile(const char * pConfigName,char * pBuffer,int bufferLen)126 static 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 *******************************************************************************/
continueAfterSetSnoozeMode(tHAL_NFC_STATUS status)155 static 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 *******************************************************************************/
postDownloadPatchram(tHAL_NFC_STATUS status)173 static 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 *******************************************************************************/
prmCallback(UINT8 event)229 void 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 *******************************************************************************/
getNfaValues()277 static 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 *******************************************************************************/
StartPatchDownload(UINT32 chipid)321 static 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 *******************************************************************************/
nfc_hal_post_reset_init(UINT32 brcm_hw_id,UINT8 nvm_type)431 void 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 *******************************************************************************/
HalNciCallback(tNFC_HAL_NCI_EVT event,UINT16 dataLen,UINT8 * data)466 void 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