• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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