• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2012-2014 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 
19 #include <string.h>
20 #include "nfc_hal_int.h"
21 #include "userial.h"
22 
23 /*****************************************************************************
24 * Definitions
25 *****************************************************************************/
26 
27 /* Internal flags */
28 #define NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF  0x01    /* Application provided patchram in a single buffer */
29 #define NFC_HAL_PRM_FLAGS_RFU               0x02    /* Reserved for future use */
30 #define NFC_HAL_PRM_FLAGS_SIGNATURE_SENT    0x04    /* Signature sent to NFCC */
31 #define NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED  0x08    /* PreI2C patch required */
32 #define NFC_HAL_PRM_FLAGS_BCM20791B3        0x10    /* B3 Patch (no RESET_NTF after patch download) */
33 #define NFC_HAL_PRM_FLAGS_RM_RF             0x20    /* Erase Personality data */
34 
35 /* Secure patch download definitions */
36 #define NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN  7       /* PRJID + MAJORVER + MINORVER + COUNT */
37 
38 /* Enumeration of power modes IDs */
39 #define NFC_HAL_PRM_SPD_POWER_MODE_LPM     0
40 #define NFC_HAL_PRM_SPD_POWER_MODE_FPM     1
41 
42 /* Version string for BCM20791B3 */
43 const UINT8 NFC_HAL_PRM_BCM20791B3_STR[]   = "20791B3";
44 #define NFC_HAL_PRM_BCM20791B3_STR_LEN     (sizeof (NFC_HAL_PRM_BCM20791B3_STR)-1)
45 
46 #define NFC_HAL_PRM_SPD_TOUT                   (6000)  /* timeout for SPD events (in ms)   */
47 #define NFC_HAL_PRM_END_DELAY                  (250)   /* delay before sending any new command (ms)*/
48 
49 #if (NFC_HAL_PRM_DEBUG == TRUE)
50 #define NFC_HAL_PRM_STATE(str)  HAL_TRACE_DEBUG2 ("%s st: %d", str, nfc_hal_cb.prm.state)
51 #else
52 #define NFC_HAL_PRM_STATE(str)
53 #endif
54 
55 void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status);
56 typedef struct
57 {
58     UINT16              offset;
59     UINT8               len;
60 } tNFC_HAL_PRM_RM_RF;
61 
62 const tNFC_HAL_PRM_RM_RF nfc_hal_prm_rm_rf_20795a1 [] =
63 {
64     {0x0000,    0xFB},
65     {0x019C,    0x08},
66     {0x05E8,    0xFB},
67     {0,         0}
68 };
69 static BOOLEAN nfc_hal_prm_nvm_rw_cmd(void);
70 
71 /*****************************************************************************
72 ** Extern variable from nfc_hal_dm_cfg.c
73 *****************************************************************************/
74 extern tNFC_HAL_CFG *p_nfc_hal_cfg;
75 
76 /*******************************************************************************
77 **
78 ** Function         nfc_hal_prm_spd_handle_download_complete
79 **
80 ** Description      Patch download complete (for secure patch download)
81 **
82 ** Returns          void
83 **
84 *******************************************************************************/
nfc_hal_prm_spd_handle_download_complete(UINT8 event)85 void nfc_hal_prm_spd_handle_download_complete (UINT8 event)
86 {
87     nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_IDLE;
88 
89     /* Notify application now */
90     if (nfc_hal_cb.prm.p_cback)
91         (nfc_hal_cb.prm.p_cback) (event);
92 }
93 
94 /*******************************************************************************
95 **
96 ** Function         nfc_hal_prm_spd_send_next_segment
97 **
98 ** Description      Send next patch segment (for secure patch download)
99 **
100 ** Returns          void
101 **
102 *******************************************************************************/
nfc_hal_prm_spd_send_next_segment(void)103 void nfc_hal_prm_spd_send_next_segment (void)
104 {
105     UINT8   *p_src;
106     UINT16  len, offset = nfc_hal_cb.prm.cur_patch_offset;
107     UINT8   hcit, oid, hdr0, type;
108     UINT8   chipverlen;
109     UINT8   chipverstr[NCI_SPD_HEADER_CHIPVER_LEN];
110     UINT8   patch_hdr_size = NCI_MSG_HDR_SIZE + 1; /* 1 is for HCIT */
111 
112     /* Validate that segment is at least big enought to have NCI_MSG_HDR_SIZE + 1 (hcit) */
113     if (nfc_hal_cb.prm.cur_patch_len_remaining < patch_hdr_size)
114     {
115         HAL_TRACE_ERROR0 ("Unexpected end of patch.");
116         nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
117         return;
118     }
119 
120     /* Parse NCI command header */
121     p_src = (UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset);
122     STREAM_TO_UINT8 (hcit, p_src);
123     STREAM_TO_UINT8 (hdr0, p_src);
124     STREAM_TO_UINT8 (oid,  p_src);
125     STREAM_TO_UINT8 (len,  p_src);
126     STREAM_TO_UINT8 (type, p_src);
127 
128 
129     /* Update number of bytes comsumed */
130     nfc_hal_cb.prm.cur_patch_offset += (len + patch_hdr_size);
131     nfc_hal_cb.prm.cur_patch_len_remaining -=  (len + patch_hdr_size);
132 
133     /* Check if sending signature byte */
134     if (  (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD )
135         &&(type == NCI_SPD_TYPE_SIGNATURE)  )
136     {
137         nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
138     }
139     /* Check for header */
140     else if (  (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD )
141              &&(type == NCI_SPD_TYPE_HEADER)  )
142     {
143         /* Check if patch is for BCM20791B3 */
144         p_src += NCI_SPD_HEADER_OFFSET_CHIPVERLEN;
145         STREAM_TO_UINT8 (chipverlen, p_src);
146         if (memcmp (nfc_hal_cb.nvm_cb.chip_ver, p_src, chipverlen) != 0)
147         {
148             HAL_TRACE_ERROR0 ("Unexpected chip ver.");
149             nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
150             return;
151         }
152         STREAM_TO_ARRAY (chipverstr, p_src, NCI_SPD_HEADER_CHIPVER_LEN);
153 
154         if (memcmp (NFC_HAL_PRM_BCM20791B3_STR, chipverstr, NFC_HAL_PRM_BCM20791B3_STR_LEN) == 0)
155         {
156             /* Patch is for BCM2079B3 - do not wait for RESET_NTF after patch download */
157             nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_BCM20791B3;
158         }
159         else
160         {
161             /* Patch is for BCM2079B4 or newer - wait for RESET_NTF after patch download */
162             nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_BCM20791B3;
163         }
164     }
165 
166     /* Send the command (not including HCIT here) */
167     nfc_hal_dm_send_nci_cmd ((UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset + 1), (UINT8) (len + NCI_MSG_HDR_SIZE),
168                              nfc_hal_prm_nci_command_complete_cback);
169 }
170 
171 /*******************************************************************************
172 **
173 ** Function         nfc_hal_prm_spd_handle_next_patch_start
174 **
175 ** Description      Handle start of next patch (for secure patch download)
176 **
177 ** Returns          void
178 **
179 *******************************************************************************/
nfc_hal_prm_spd_handle_next_patch_start(void)180 void nfc_hal_prm_spd_handle_next_patch_start (void)
181 {
182     UINT32  cur_patch_mask;
183     UINT32  cur_patch_len;
184     BOOLEAN found_patch_to_download = FALSE;
185 
186     while (!found_patch_to_download)
187     {
188         /* Get length of current patch */
189         cur_patch_len = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len;
190 
191         /* Check if this is a patch we need to download */
192         cur_patch_mask = ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
193         if (nfc_hal_cb.prm.spd_patch_needed_mask & cur_patch_mask)
194         {
195             found_patch_to_download = TRUE;
196         }
197         else
198         {
199             /* Do not need to download this patch. Skip to next patch */
200             HAL_TRACE_DEBUG1 ("Skipping patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
201 
202             nfc_hal_cb.prm.spd_cur_patch_idx++;
203             if (nfc_hal_cb.prm.spd_cur_patch_idx >= nfc_hal_cb.prm.spd_patch_count)
204             {
205                 /* No more to download */
206                 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
207                 return;
208             }
209             else if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
210             {
211                 /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch header */
212                 (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
213                 return;
214             }
215             else
216             {
217                 /* Patch in buffer. Skip over current patch. Check next patch */
218                 nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) cur_patch_len;
219                 nfc_hal_cb.prm.cur_patch_offset += (UINT16) cur_patch_len;
220             }
221         }
222     }
223 
224 
225     /* Begin downloading patch */
226     HAL_TRACE_DEBUG1 ("Downloading patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
227     nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_DOWNLOADING;
228     nfc_hal_prm_spd_send_next_segment ();
229 }
230 
231 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
232 /*******************************************************************************
233 **
234 ** Function         nfc_hal_prm_spd_download_i2c_fix
235 **
236 ** Description      Start downloading patch for i2c fix
237 **
238 ** Returns          void
239 **
240 *******************************************************************************/
nfc_hal_prm_spd_download_i2c_fix(void)241 void nfc_hal_prm_spd_download_i2c_fix (void)
242 {
243     UINT8 *p, *p_start;
244     UINT16 patchfile_project_id;
245     UINT16 patchfile_ver_major;
246     UINT16 patchfile_ver_minor;
247     UINT16 patchfile_patchsize;
248     UINT8 u8;
249 
250     HAL_TRACE_DEBUG0 ("Downloading I2C fix...");
251 
252     /* Save pointer and offset of patchfile, so we can resume after downloading the i2c fix */
253     nfc_hal_cb.prm.spd_patch_offset = nfc_hal_cb.prm.cur_patch_offset;
254     nfc_hal_cb.prm.spd_patch_len_remaining = nfc_hal_cb.prm.cur_patch_len_remaining;
255 
256     /* Initialize pointers for downloading i2c fix */
257     nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm_i2c.p_patch;
258     nfc_hal_cb.prm.cur_patch_offset = 0;
259     nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm_i2c.len;
260 
261     /* Parse the i2c patchfile */
262     if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN)
263     {
264         /* Parse patchfile header */
265         p = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data;
266         p_start = p;
267         STREAM_TO_UINT16 (patchfile_project_id, p);
268         STREAM_TO_UINT16 (patchfile_ver_major, p);
269         STREAM_TO_UINT16 (patchfile_ver_minor, p);
270 
271         /* RFU */
272         p++;
273 
274         /* Check how many patches are in the patch file */
275         STREAM_TO_UINT8 (u8, p);
276 
277         /* Should only be one patch */
278         if (u8 > 1)
279         {
280             HAL_TRACE_ERROR1 ("Invalid i2c fix: invalid number of patches (%i)", u8);
281             nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
282             return;
283         }
284 
285 
286         /* Get info about the i2c patch*/
287         STREAM_TO_UINT8 (u8, p);                     /* power mode (not needed for i2c patch)    */
288         STREAM_TO_UINT16 (patchfile_patchsize, p);   /* size of patch                            */
289 
290         /* 5 byte RFU */
291         p += 5;
292 
293         /* Adjust length to exclude patchfiloe header */
294         nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start);       /* Adjust size of patchfile                        */
295         nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start);              /* Bytes of patchfile transmitted/processed so far */
296 
297         /* Begin sending patch to the NFCC */
298         nfc_hal_prm_spd_send_next_segment ();
299     }
300     else
301     {
302         /* ERROR: Bad length for patchfile */
303         HAL_TRACE_ERROR0 ("Invalid i2c fix: unexpected end of patch");
304         nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
305     }
306 }
307 #endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
308 
309 /*******************************************************************************
310 **
311 ** Function         nfc_hal_prm_spd_check_version_continue
312 **
313 ** Description      Check patchfile version with current downloaded version
314 **
315 ** Returns          void
316 **
317 *******************************************************************************/
nfc_hal_prm_spd_check_version_continue(void)318 static void nfc_hal_prm_spd_check_version_continue (void)
319 {
320     HAL_TRACE_DEBUG1 ("nfc_hal_prm_spd_check_version_continue 0x%02x", nfc_hal_cb.prm.flags);
321     if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_RM_RF)
322     {
323         HAL_TRACE_DEBUG0("erase relevant blocks in NVM");
324         nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_RM_RF;
325         if (!nfc_hal_prm_nvm_rw_cmd())
326         {
327             /* nvm rw started successfully */
328             return;
329         }
330     }
331 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
332     if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED)
333     {
334         HAL_TRACE_DEBUG0 ("I2C patch fix required.");
335         /* Download i2c fix first */
336         nfc_hal_prm_spd_download_i2c_fix ();
337         return;
338     }
339 #endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
340 
341     /* Download first segment */
342     nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
343     if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
344     {
345         /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch segment */
346         (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
347     }
348     else
349     {
350         nfc_hal_prm_spd_handle_next_patch_start ();
351     }
352 }
353 
354 /*******************************************************************************
355 **
356 ** Function         nfc_hal_prm_spd_check_version
357 **
358 ** Description      Check patchfile version with current downloaded version
359 **
360 ** Returns          void
361 **
362 *******************************************************************************/
nfc_hal_prm_spd_check_version(void)363 void nfc_hal_prm_spd_check_version (void)
364 {
365     UINT8 *p, *p_start, i;
366     UINT32 nvm_patch_present_mask = 0;
367     UINT32 patchfile_patch_present_mask;
368     UINT16 patchfile_project_id = 0;
369     UINT16 patchfile_ver_major = 0;
370     UINT16 patchfile_ver_minor = 0;
371     UINT16 patchfile_patchsize;
372 
373     UINT8  return_code = NFC_HAL_PRM_COMPLETE_EVT;
374 
375     /* Initialize patchfile offset pointers */
376     p = p_start = NULL;
377     patchfile_patchsize = 0;
378 
379     /* the good patches in NVM */
380     if (nfc_hal_cb.nvm_cb.lpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_LPM_BAD)))
381         nvm_patch_present_mask  |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_LPM);
382 
383     if (nfc_hal_cb.nvm_cb.fpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_FPM_BAD)))
384         nvm_patch_present_mask  |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_FPM);
385 
386     /* Get patchfile version */
387     if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN)
388     {
389         /* Parse patchfile header */
390         p       = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data;
391         p_start = p;
392         STREAM_TO_UINT16 (patchfile_project_id, p);
393         STREAM_TO_UINT16 (patchfile_ver_major, p);
394         STREAM_TO_UINT16 (patchfile_ver_minor, p);
395 
396         /* RFU */
397         p++;
398 
399         /* Check how many patches are in the patch file */
400         STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_count, p);
401 
402         if (nfc_hal_cb.prm.spd_patch_count > NFC_HAL_PRM_MAX_PATCH_COUNT)
403         {
404             HAL_TRACE_ERROR2 ("Unsupported patchfile (number of patches (%i) exceeds maximum (%i)",
405                                nfc_hal_cb.prm.spd_patch_count, NFC_HAL_PRM_MAX_PATCH_COUNT);
406         }
407 
408         /* Mask of patches that are present in the patchfile */
409         patchfile_patch_present_mask = 0;
410 
411         /* Get lengths for each patch */
412         for (i = 0; i < nfc_hal_cb.prm.spd_patch_count; i++)
413         {
414             /* Get power mode for this patch */
415             STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_desc[i].power_mode, p);
416 
417             /* Update mask of power-modes present in the patchfile */
418             patchfile_patch_present_mask |= ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[i].power_mode);
419 
420             /* Get length of patch */
421             STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_patch_desc[i].len, p);
422 
423             /* Add total size of patches */
424             patchfile_patchsize += nfc_hal_cb.prm.spd_patch_desc[i].len;
425 
426             /* 5 byte RFU */
427             p += 5;
428         }
429 
430         /* Adjust offset to after the patch file header */
431         nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start);              /* Bytes of patchfile transmitted/processed so far */
432         nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start);       /* Adjust size of patchfile                        */
433 
434 
435         HAL_TRACE_DEBUG4 ("NVM Patch info: flags=0x%04x,   Ver=%i.%i, PatchMask=0x%08x",
436             nfc_hal_cb.nvm_cb.flags, nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor, nvm_patch_present_mask );
437         HAL_TRACE_DEBUG6 ("Patchfile info: ProjID=0x%04x,  Ver=%i.%i, Num patches=%i, PatchMask=0x%08x, PatchSize=%i",
438                            patchfile_project_id, patchfile_ver_major, patchfile_ver_minor,
439                            nfc_hal_cb.prm.spd_patch_count, patchfile_patch_present_mask, patchfile_patchsize);
440 
441         /*********************************************************************
442         * Version check of patchfile against NVM
443         *********************************************************************/
444         /* Download the patchfile if no patches in NVM */
445         if ((nfc_hal_cb.nvm_cb.project_id == 0) || !(nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_PATCH_PRESENT))
446         {
447             /* No patch in NVM, need to download all */
448             nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
449             if (nfc_hal_cb.dev_cb.brcm_hw_id == BRCM_20795A1_ID)
450             {
451                 nfc_hal_cb.prm.flags   |= NFC_HAL_PRM_FLAGS_RM_RF;
452                 nfc_hal_cb.prm.p_param  = (void *)nfc_hal_prm_rm_rf_20795a1;
453                 nfc_hal_cb.prm.param_idx = 0;
454             }
455 
456             HAL_TRACE_DEBUG2 ("No previous patch detected. Downloading patch %i.%i",
457                               patchfile_ver_major, patchfile_ver_minor);
458         }
459         /* Skip download if project ID of patchfile does not match NVM */
460         else if (nfc_hal_cb.nvm_cb.project_id != patchfile_project_id)
461         {
462             /* Project IDs mismatch */
463             HAL_TRACE_DEBUG2 ("Patch download skipped: Mismatched Project ID (NVM ProjId: 0x%04x, Patchfile ProjId: 0x%04x)",
464                               nfc_hal_cb.nvm_cb.project_id, patchfile_project_id);
465 
466             return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
467         }
468         /* Skip download if version of patchfile is equal to version in NVM */
469         /*                  and patches of the power modes are the same as the good patches in NVM */
470         else if (  (nfc_hal_cb.nvm_cb.ver_major == patchfile_ver_major)
471             &&(nfc_hal_cb.nvm_cb.ver_minor == patchfile_ver_minor)
472                  &&((nvm_patch_present_mask | patchfile_patch_present_mask) == nvm_patch_present_mask)  ) /* if the NVM patch include all the patched in file */
473         {
474             HAL_TRACE_DEBUG2 ("Patch download skipped. NVM patch (version %i.%i) is the same than the patchfile ",
475                               nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
476 
477             return_code = NFC_HAL_PRM_COMPLETE_EVT;
478         }
479         /* Remaining cases: Download all patches in the patchfile */
480         else
481         {
482             nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
483 
484             HAL_TRACE_DEBUG4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
485                               patchfile_ver_major, patchfile_ver_minor,
486                               nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
487         }
488 
489     }
490     else
491     {
492         /* Invalid patch file header */
493         HAL_TRACE_ERROR0 ("Invalid patch file header.");
494 
495         return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
496     }
497 
498     /* If we need to download anything, get the first patch to download */
499     if (nfc_hal_cb.prm.spd_patch_needed_mask)
500     {
501         HAL_TRACE_ERROR4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
502                             patchfile_ver_major, patchfile_ver_minor,
503                             nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
504 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
505         /* Check if I2C patch is needed: if                                     */
506         /*      - I2C patch file was provided using HAL_NfcPrmSetI2cPatch, and        */
507         /*      -   current patch in NVM has ProjectID=0, or                    */
508         /*          FPM is not present or corrupted, or                         */
509         /*          or patchfile is major-ver 76+                               */
510         /*          or patchfile is not for B3 (always download for B4 onward)  */
511         if (  (nfc_hal_cb.prm_i2c.p_patch)
512             &&(  (nfc_hal_cb.nvm_cb.project_id == 0)
513                ||(nfc_hal_cb.nvm_cb.fpm_size == 0)
514                ||(nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_FPM_BAD)
515                ||(patchfile_ver_major >= 76)
516                ||(!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3)) ))
517         {
518             HAL_TRACE_DEBUG0 ("I2C patch fix required.");
519             nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
520         }
521 #endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
522         nfc_hal_prm_spd_check_version_continue ();
523     }
524     else
525     {
526         static BOOLEAN firstTime = TRUE;
527         if (firstTime)
528         {
529             HAL_TRACE_ERROR2 ("NVM patch version is %d.%d",
530                               nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
531             firstTime = FALSE;
532         }
533         /* Download complete */
534         nfc_hal_prm_spd_handle_download_complete (return_code);
535     }
536 }
537 
538 #if (NFC_HAL_TRACE_VERBOSE == TRUE)
539 /*******************************************************************************
540 **
541 ** Function         nfc_hal_prm_spd_status_str
542 **
543 ** Description      Return status string for a given spd status code
544 **
545 ** Returns          Status string
546 **
547 *******************************************************************************/
nfc_hal_prm_spd_status_str(UINT8 spd_status_code)548 UINT8 *nfc_hal_prm_spd_status_str (UINT8 spd_status_code)
549 {
550     char *p_str;
551 
552     switch (spd_status_code)
553     {
554     case NCI_STATUS_SPD_ERROR_DEST:
555         p_str = "SPD_ERROR_DEST";
556         break;
557 
558     case NCI_STATUS_SPD_ERROR_PROJECTID:
559         p_str = "SPD_ERROR_PROJECTID";
560         break;
561 
562     case NCI_STATUS_SPD_ERROR_CHIPVER:
563         p_str = "SPD_ERROR_CHIPVER";
564         break;
565 
566     case NCI_STATUS_SPD_ERROR_MAJORVER:
567         p_str = "SPD_ERROR_MAJORVER";
568         break;
569 
570     case NCI_STATUS_SPD_ERROR_INVALID_PARAM:
571         p_str = "SPD_ERROR_INVALID_PARAM";
572         break;
573 
574     case NCI_STATUS_SPD_ERROR_INVALID_SIG:
575         p_str = "SPD_ERROR_INVALID_SIG";
576         break;
577 
578     case NCI_STATUS_SPD_ERROR_NVM_CORRUPTED:
579         p_str = "SPD_ERROR_NVM_CORRUPTED";
580         break;
581 
582     case NCI_STATUS_SPD_ERROR_PWR_MODE:
583         p_str = "SPD_ERROR_PWR_MODE";
584         break;
585 
586     case NCI_STATUS_SPD_ERROR_MSG_LEN:
587         p_str = "SPD_ERROR_MSG_LEN";
588         break;
589 
590     case NCI_STATUS_SPD_ERROR_PATCHSIZE:
591         p_str = "SPD_ERROR_PATCHSIZE";
592         break;
593 
594     default:
595         p_str = "Unspecified Error";
596         break;
597 
598     }
599 
600     return ((UINT8*) p_str);
601 }
602 #endif  /* (NFC_HAL_TRACE_VERBOSE == TRUE) */
603 /*******************************************************************************
604 **
605 ** Function         nfc_hal_prm_nvm_rw_cmd
606 **
607 ** Description      Non Volatile Read Write Command; for now only write zeros
608 **
609 ** Returns          TRUE if done.
610 **
611 *******************************************************************************/
nfc_hal_prm_nvm_rw_cmd(void)612 static BOOLEAN nfc_hal_prm_nvm_rw_cmd(void)
613 {
614     tNFC_HAL_PRM_RM_RF  *p_param = (tNFC_HAL_PRM_RM_RF *)(nfc_hal_cb.prm.p_param);
615     UINT8   *p_buff, *p, *p_end;
616     UINT8   len = 0;
617     UINT16  cmd_len;
618 
619     if (p_param)
620         len     = p_param[nfc_hal_cb.prm.param_idx].len;
621     HAL_TRACE_DEBUG2 ("nfc_hal_prm_nvm_rw_cmd: %d/%d", nfc_hal_cb.prm.param_idx, len);
622     if (len == 0)
623     {
624         return TRUE;
625     }
626     cmd_len = len + 7;
627 
628     if ((p_buff = (UINT8 *) GKI_getbuf(cmd_len)) == NULL)
629     {
630         HAL_TRACE_ERROR0 ("NVM No buffer");
631         nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
632         return TRUE;
633     }
634 
635     p = p_buff;
636 
637     UINT8_TO_STREAM  (p, (NCI_MTS_CMD|NCI_GID_PROP));
638     UINT8_TO_STREAM  (p, NCI_MSG_EEPROM_RW);
639     UINT8_TO_STREAM  (p, (len+4));
640     UINT8_TO_STREAM  (p, 1); /* 1=write 0=read */
641     UINT16_TO_STREAM  (p, p_param[nfc_hal_cb.prm.param_idx].offset);
642     UINT8_TO_STREAM  (p, len);
643     memset (p, 0, len); /* Fill remaining bytes with zeros*/
644 
645     nfc_hal_cb.prm.param_idx++;
646     nfc_hal_dm_send_nci_cmd(p_buff, cmd_len, nfc_hal_prm_nci_command_complete_cback);
647     GKI_freebuf (p_buff);
648     return FALSE;
649 }
650 
651 /*******************************************************************************
652 **
653 ** Function         nfc_hal_prm_nci_command_complete_cback
654 **
655 ** Description      Callback for NCI vendor specific command complete
656 **                  (for secure patch download)
657 **
658 ** Returns          void
659 **
660 *******************************************************************************/
nfc_hal_prm_nci_command_complete_cback(tNFC_HAL_NCI_EVT event,UINT16 data_len,UINT8 * p_data)661 void nfc_hal_prm_nci_command_complete_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
662 {
663     UINT8 status, u8;
664     UINT8 *p;
665     UINT32 post_signature_delay;
666 
667     NFC_HAL_PRM_STATE ("nfc_hal_prm_nci_command_complete_cback");
668 
669     /* Stop the command-timeout timer */
670     nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
671 
672     /* Skip over NCI header */
673     p = p_data + NCI_MSG_HDR_SIZE;
674 
675     /* Handle SECURE_PATCH_DOWNLOAD Rsp */
676     if (event == NFC_VS_SEC_PATCH_DOWNLOAD_EVT)
677     {
678         /* Status and error code */
679         STREAM_TO_UINT8 (status, p);
680         STREAM_TO_UINT8 (u8, p);
681 
682         if (status != NCI_STATUS_OK)
683         {
684 #if (NFC_HAL_TRACE_VERBOSE == TRUE)
685             HAL_TRACE_ERROR2 ("Patch download failed, reason code=0x%X (%s)", status, nfc_hal_prm_spd_status_str (status));
686 #else
687             HAL_TRACE_ERROR1 ("Patch download failed, reason code=0x%X", status);
688 #endif
689 
690             /* Notify application */
691             nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
692             return;
693         }
694 
695         /* If last segment (SIGNATURE) sent */
696         if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_SIGNATURE_SENT)
697         {
698             /* Wait for authentication complete (SECURE_PATCH_DOWNLOAD NTF), including time to commit to NVM (for BCM43341B0) */
699             nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTHENTICATING;
700             nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
701                                             (NFC_HAL_PRM_COMMIT_DELAY * QUICK_TIMER_TICKS_PER_SEC) / 1000);
702             return;
703         }
704         /* Download next segment */
705         else if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
706         {
707             /* If patch is in a buffer, get next patch from buffer */
708             nfc_hal_prm_spd_send_next_segment ();
709         }
710         else
711         {
712             /* Notify adaptation layer to get next patch segment (via HAL_NfcPrmDownloadContinue) */
713             (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_CONTINUE_EVT);
714         }
715     }
716     /* Handle SECURE_PATCH_DOWNLOAD NTF */
717     else if (event == NFC_VS_SEC_PATCH_AUTH_EVT)
718     {
719         HAL_TRACE_DEBUG1 ("prm flags:0x%x.", nfc_hal_cb.prm.flags);
720         /* Status and error code */
721         STREAM_TO_UINT8 (status, p);
722         STREAM_TO_UINT8 (u8, p);
723 
724         /* Sanity check - should only get this NTF while in AUTHENTICATING stage */
725         if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTHENTICATING)
726         {
727             if (status != NCI_STATUS_OK)
728             {
729                 HAL_TRACE_ERROR0 ("Patch authentication failed");
730                 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT);
731                 return;
732             }
733 
734 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
735             if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED)
736             {
737                 HAL_TRACE_DEBUG1 ("PreI2C patch downloaded...waiting %i ms for NFCC to reboot.", nfc_hal_cb.prm_i2c.prei2c_delay);
738 
739                 /* Restore pointers to patchfile */
740                 nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
741                 nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm.p_spd_patch;
742                 nfc_hal_cb.prm.cur_patch_offset = nfc_hal_cb.prm.spd_patch_offset;
743                 nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm.spd_patch_len_remaining;
744 
745                 /* Resume normal patch download */
746                 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
747                 nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
748 
749                 /* Post PreI2C delay */
750                 nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00, (nfc_hal_cb.prm_i2c.prei2c_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000);
751 
752                 return;
753             }
754 #endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
755 
756 
757             /* Wait for NFCC to save the patch to NVM */
758             if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3))
759             {
760                 /* 20791B4 or newer - wait for RESET_NTF; including time to commit to NVM (for BCM20791B4+) */
761                 post_signature_delay = NFC_HAL_PRM_COMMIT_DELAY;
762                 HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for RESET NTF...", post_signature_delay);
763 
764             }
765             else if (nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_NO_NVM)
766             {
767                 /* No NVM. Wait for NFCC to restart */
768                 post_signature_delay = NFC_HAL_PRM_END_DELAY;
769                 HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NFCC to restart...", post_signature_delay);
770             }
771             else
772             {
773                 /* Wait for NFCC to save the patch to NVM (need about 1 ms per byte) */
774                 post_signature_delay = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len;
775                 if (post_signature_delay < nfc_hal_cb.prm.patchram_delay)
776                     post_signature_delay = nfc_hal_cb.prm.patchram_delay;
777                 HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NVM update to complete...", post_signature_delay);
778             }
779 
780             nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTH_DONE;
781 
782             nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
783                                             (post_signature_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000);
784         }
785         else
786         {
787             HAL_TRACE_ERROR0 ("Got unexpected SECURE_PATCH_DOWNLOAD NTF");
788             nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
789         }
790     }
791     /* Handle NCI_MSG_GET_PATCH_VERSION RSP */
792     else if (event == NFC_VS_GET_PATCH_VERSION_EVT)
793     {
794         nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
795     }
796     else if (event == NFC_VS_EEPROM_RW_EVT)
797     {
798         STREAM_TO_UINT8 (status, p);
799         if (status == NCI_STATUS_OK)
800         {
801             if (nfc_hal_prm_nvm_rw_cmd ())
802             {
803                 nfc_hal_prm_spd_check_version_continue ();
804             }
805         }
806         else
807         {
808             HAL_TRACE_ERROR0 ("NVM failed");
809             nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
810         }
811     }
812     else
813     {
814         /* Invalid response from NFCC during patch download */
815         HAL_TRACE_ERROR1 ("Invalid response from NFCC during patch download (opcode=0x%02X)", event);
816         nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
817     }
818 
819     NFC_HAL_PRM_STATE ("prm_nci_command_complete_cback");
820 }
821 
822 /*******************************************************************************
823 **
824 ** Function         nfc_hal_prm_nfcc_ready_to_continue
825 **
826 ** Description      Continue to download patch or notify application completition
827 **
828 ** Returns          void
829 **
830 *******************************************************************************/
nfc_hal_prm_nfcc_ready_to_continue(void)831 void nfc_hal_prm_nfcc_ready_to_continue (void)
832 {
833     UINT8 get_patch_version_cmd [NCI_MSG_HDR_SIZE] =
834     {
835         NCI_MTS_CMD|NCI_GID_PROP,
836         NCI_MSG_GET_PATCH_VERSION,
837         0x00
838     };
839 
840     /* Clear the bit for the patch we just downloaded */
841     nfc_hal_cb.prm.spd_patch_needed_mask &= ~ ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
842 
843     /* Check if another patch to download */
844     nfc_hal_cb.prm.spd_cur_patch_idx++;
845     if ((nfc_hal_cb.prm.spd_patch_needed_mask) && (nfc_hal_cb.prm.spd_cur_patch_idx < nfc_hal_cb.prm.spd_patch_count))
846     {
847         nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
848         nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
849 
850         if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
851         {
852             /* If patch is in a buffer, get next patch from buffer */
853             nfc_hal_prm_spd_handle_next_patch_start ();
854         }
855         else
856         {
857             /* Notify adaptation layer to get next patch header (via HAL_NfcPrmDownloadContinue) */
858             (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
859         }
860 
861     }
862     else
863     {
864         /* Done downloading */
865         HAL_TRACE_DEBUG0 ("Patch downloaded and authenticated. Get new patch version.");
866         /* add get patch info again to verify the effective FW version */
867         nfc_hal_dm_send_nci_cmd (get_patch_version_cmd, NCI_MSG_HDR_SIZE, nfc_hal_prm_nci_command_complete_cback);
868         nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_W4_GET_VERSION;
869     }
870 }
871 
872 /*******************************************************************************
873 **
874 ** Function         nfc_hal_prm_spd_reset_ntf
875 **
876 ** Description      Received RESET NTF from NFCC, indicating it has completed
877 **                  reset after patch download.
878 **
879 ** Returns          void
880 **
881 *******************************************************************************/
nfc_hal_prm_spd_reset_ntf(UINT8 reset_reason,UINT8 reset_type)882 void nfc_hal_prm_spd_reset_ntf (UINT8 reset_reason, UINT8 reset_type)
883 {
884     /* Check if we were expecting a RESET NTF */
885     if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
886     {
887         HAL_TRACE_DEBUG2 ("Received RESET NTF after patch download (reset_reason=%i, reset_type=%i)", reset_reason, reset_type);
888 
889         /* Stop waiting for RESET NTF */
890         nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
891 
892         {
893             /* Continue with patch download */
894             nfc_hal_prm_nfcc_ready_to_continue ();
895         }
896     }
897     else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
898     {
899         HAL_TRACE_DEBUG0 ("Received RESET NTF after pre-I2C patch download. Proceeding with patch download...");
900 
901         /* Stop waiting for RESET NTF */
902         nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
903         nfc_hal_prm_spd_handle_next_patch_start ();
904     }
905     else
906     {
907         HAL_TRACE_ERROR2 ("Received unexpected RESET NTF (reset_reason=%i, reset_type=%i)", reset_reason, reset_type);
908     }
909 }
910 
911 /*******************************************************************************
912 **
913 ** Function:    nfc_post_final_baud_update
914 **
915 ** Description: Called after baud rate udate
916 **
917 ** Returns:     Nothing
918 **
919 *******************************************************************************/
nfc_hal_prm_post_baud_update(tHAL_NFC_STATUS status)920 void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status)
921 {
922     NFC_HAL_PRM_STATE ("nfc_hal_prm_post_baud_update");
923 
924     if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
925     {
926         /* Proceed with next step of patch download sequence */
927         nfc_hal_prm_nfcc_ready_to_continue ();
928     }
929 }
930 
931 /*******************************************************************************
932 **
933 ** Function         nfc_hal_prm_process_timeout
934 **
935 ** Description      Process timer expireation for patch download
936 **
937 ** Returns          void
938 **
939 *******************************************************************************/
nfc_hal_prm_process_timeout(void * p_tle)940 void nfc_hal_prm_process_timeout (void *p_tle)
941 {
942     NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout");
943 
944     if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
945     {
946         if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3))
947         {
948             /* Timeout waiting for RESET NTF after signature sent */
949             HAL_TRACE_ERROR0 ("Timeout waiting for RESET NTF after patch download");
950             nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
951         }
952         else
953         {
954             nfc_hal_prm_nfcc_ready_to_continue ();
955         }
956     }
957     else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
958     {
959         HAL_TRACE_DEBUG0 ("Delay after PreI2C patch download...proceeding to download firmware patch");
960         nfc_hal_prm_spd_handle_next_patch_start ();
961     }
962     else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_W4_GET_VERSION)
963     {
964         HAL_TRACE_DEBUG0 ("get patch version timeout???");
965         nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
966     }
967     else
968     {
969         HAL_TRACE_ERROR1 ("Patch download: command timeout (state=%i)", nfc_hal_cb.prm.state);
970 
971         nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
972     }
973 
974     NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout");
975 }
976 
977 
978 /*******************************************************************************
979 **
980 ** Function         HAL_NfcPrmDownloadStart
981 **
982 ** Description      Initiate patch download
983 **
984 ** Input Params
985 **                  format_type     patch format type
986 **                                  (NFC_HAL_PRM_FORMAT_BIN, NFC_HAL_PRM_FORMAT_HCD, or
987 **                                   NFC_HAL_PRM_FORMAT_NCD)
988 **
989 **                  dest_address    destination adderess (needed for BIN format only)
990 **
991 **                  p_patchram_buf  pointer to patchram buffer. If NULL,
992 **                                  then app must call HAL_NfcPrmDownloadContinue when
993 **                                  NFC_HAL_PRM_CONTINUE_EVT is received, to send the next
994 **                                  segment of patchram
995 **
996 **                  patchram_len    size of p_patchram_buf (if non-NULL)
997 **
998 **                  patchram_delay  The delay after each patch.
999 **                                  If the given value is less than the size of the patchram,
1000 **                                  the size of patchram is used instead.
1001 **
1002 **                  p_cback         callback for download status
1003 **
1004 **
1005 ** Returns          TRUE if successful, otherwise FALSE
1006 **
1007 **
1008 *******************************************************************************/
HAL_NfcPrmDownloadStart(tNFC_HAL_PRM_FORMAT format_type,UINT32 dest_address,UINT8 * p_patchram_buf,UINT32 patchram_len,UINT32 patchram_delay,tNFC_HAL_PRM_CBACK * p_cback)1009 BOOLEAN HAL_NfcPrmDownloadStart (tNFC_HAL_PRM_FORMAT format_type,
1010                                  UINT32              dest_address,
1011                                  UINT8               *p_patchram_buf,
1012                                  UINT32              patchram_len,
1013                                  UINT32              patchram_delay,
1014                                  tNFC_HAL_PRM_CBACK  *p_cback)
1015 {
1016     HAL_TRACE_API0 ("HAL_NfcPrmDownloadStart ()");
1017 
1018     memset (&nfc_hal_cb.prm, 0, sizeof (tNFC_HAL_PRM_CB));
1019 
1020     if (p_patchram_buf)
1021     {
1022         nfc_hal_cb.prm.p_cur_patch_data = p_patchram_buf;
1023         nfc_hal_cb.prm.cur_patch_offset = 0;
1024         nfc_hal_cb.prm.cur_patch_len_remaining = (UINT16) patchram_len;
1025         nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF;
1026 
1027         if (patchram_len == 0)
1028             return FALSE;
1029     }
1030 
1031     nfc_hal_cb.prm.p_cback          = p_cback;
1032     nfc_hal_cb.prm.dest_ram         = dest_address;
1033     nfc_hal_cb.prm.format           = format_type;
1034     nfc_hal_cb.prm.patchram_delay   = patchram_delay;
1035 
1036     nfc_hal_cb.prm.timer.p_cback = nfc_hal_prm_process_timeout;
1037 
1038     if (format_type == NFC_HAL_PRM_FORMAT_NCD)
1039     {
1040         /* Store patch buffer pointer and length */
1041         nfc_hal_cb.prm.p_spd_patch             = p_patchram_buf;
1042         nfc_hal_cb.prm.spd_patch_len_remaining = (UINT16)patchram_len;
1043         nfc_hal_cb.prm.spd_patch_offset        = 0;
1044 
1045         /* If patch download is required, but no NVM is available, then abort */
1046         if ((p_nfc_hal_cfg->nfc_hal_prm_nvm_required) && (nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_NO_NVM))
1047         {
1048             HAL_TRACE_ERROR0 ("This platform requires NVM and the NVM is not available - Abort");
1049             nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_NO_NVM_EVT);
1050             return FALSE;
1051         }
1052 
1053         /* Compare patch version in NVM with version in patchfile */
1054         nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_COMPARE_VERSION;
1055         if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
1056         {
1057             /* If patchfile is in a buffer, get patch version from buffer */
1058             nfc_hal_prm_spd_check_version ();
1059         }
1060         else
1061         {
1062             /* If patchfile is not in a buffer, then request patchfile header from adaptation layer. */
1063             (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_PATCHFILE_HDR_EVT);
1064         }
1065     }
1066     else
1067     {
1068         HAL_TRACE_ERROR0 ("Unexpected patch format.");
1069         return FALSE;
1070     }
1071 
1072     return TRUE;
1073 }
1074 
1075 /*******************************************************************************
1076 **
1077 ** Function         HAL_NfcPrmDownloadContinue
1078 **
1079 ** Description      Send next segment of patchram to controller. Called when
1080 **                  NFC_HAL_PRM_CONTINUE_EVT is received.
1081 **
1082 **                  Only needed if HAL_NfcPrmDownloadStart was called with
1083 **                  p_patchram_buf=NULL
1084 **
1085 ** Input Params     p_patch_data    pointer to patch data
1086 **                  patch_data_len  patch data len
1087 **
1088 ** Returns          TRUE if successful, otherwise FALSE
1089 **
1090 *******************************************************************************/
HAL_NfcPrmDownloadContinue(UINT8 * p_patch_data,UINT16 patch_data_len)1091 BOOLEAN HAL_NfcPrmDownloadContinue (UINT8 *p_patch_data,
1092                                     UINT16 patch_data_len)
1093 {
1094     HAL_TRACE_API2 ("HAL_NfcPrmDownloadContinue ():state = %d, patch_data_len=%d",
1095                      nfc_hal_cb.prm.state, patch_data_len);
1096 
1097     /* Check if we are in a valid state for this API */
1098     if (  (nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_COMPARE_VERSION)
1099         &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
1100         &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_DOWNLOADING)  )
1101         return FALSE;
1102 
1103     if (patch_data_len == 0)
1104         return FALSE;
1105 
1106     nfc_hal_cb.prm.cur_patch_offset = 0;
1107     nfc_hal_cb.prm.p_cur_patch_data = p_patch_data;
1108     nfc_hal_cb.prm.cur_patch_len_remaining = patch_data_len;
1109 
1110     /* Call appropriate handler */
1111     if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_COMPARE_VERSION)
1112     {
1113         nfc_hal_prm_spd_check_version ();
1114     }
1115     else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
1116     {
1117         nfc_hal_prm_spd_handle_next_patch_start ();
1118     }
1119     else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_DOWNLOADING)
1120     {
1121         nfc_hal_prm_spd_send_next_segment ();
1122     }
1123     else
1124     {
1125         HAL_TRACE_ERROR1 ("Unexpected patch state:%d.", nfc_hal_cb.prm.state);
1126     }
1127 
1128     return TRUE;
1129 }
1130 
1131 /*******************************************************************************
1132 **
1133 ** Function         HAL_NfcPrmSetI2cPatch
1134 **
1135 ** Description      Specify patchfile for BCM20791B3 I2C fix. This fix
1136 **                  must be downloaded prior to initial patch download for I2C
1137 **                  transport
1138 **
1139 ** Input Params     p_i2c_patchfile_buf: pointer to patch for i2c fix
1140 **                  i2c_patchfile_len: length of patch
1141 **                  prei2c_delay: the delay before downloading main patch
1142 **                                if 0 is given, NFC_HAL_PRM_POST_I2C_FIX_DELAY is used instead.
1143 **
1144 ** Returns          Nothing
1145 **
1146 **
1147 *******************************************************************************/
HAL_NfcPrmSetI2cPatch(UINT8 * p_i2c_patchfile_buf,UINT16 i2c_patchfile_len,UINT32 prei2c_delay)1148 void HAL_NfcPrmSetI2cPatch (UINT8 *p_i2c_patchfile_buf, UINT16 i2c_patchfile_len, UINT32 prei2c_delay)
1149 {
1150 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
1151     HAL_TRACE_API0 ("HAL_NfcPrmSetI2cPatch ()");
1152 
1153     nfc_hal_cb.prm_i2c.prei2c_delay    = NFC_HAL_PRM_POST_I2C_FIX_DELAY;
1154     if (prei2c_delay)
1155         nfc_hal_cb.prm_i2c.prei2c_delay = prei2c_delay;
1156     nfc_hal_cb.prm_i2c.p_patch = p_i2c_patchfile_buf;
1157     nfc_hal_cb.prm_i2c.len = i2c_patchfile_len;
1158 #endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
1159 }
1160 
1161 /*******************************************************************************
1162 **
1163 ** Function         HAL_NfcPrmSetSpdNciCmdPayloadSize
1164 **
1165 ** Description      Set Host-to-NFCC NCI message size for secure patch download
1166 **
1167 **                  This API must be called before calling HAL_NfcPrmDownloadStart.
1168 **                  If the API is not called, then PRM will use the default
1169 **                  message size.
1170 **
1171 **                  Typically, this API is only called for platforms that have
1172 **                  message-size limitations in the transport/driver.
1173 **
1174 **                  Valid message size range: NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE to 255.
1175 **
1176 ** Returns          HAL_NFC_STATUS_OK if successful
1177 **                  HAL_NFC_STATUS_FAILED otherwise
1178 **
1179 **
1180 *******************************************************************************/
HAL_NfcPrmSetSpdNciCmdPayloadSize(UINT8 max_payload_size)1181 tHAL_NFC_STATUS HAL_NfcPrmSetSpdNciCmdPayloadSize (UINT8 max_payload_size)
1182 {
1183     /* Validate: minimum size is NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE */
1184     if (max_payload_size < NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE)
1185     {
1186         HAL_TRACE_ERROR2 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: invalid size (%i). Must be between %i and 255", max_payload_size, NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE);
1187         return (HAL_NFC_STATUS_FAILED);
1188     }
1189     else
1190     {
1191         HAL_TRACE_API1 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: new message size during download: %i", max_payload_size);
1192         nfc_hal_cb.ncit_cb.nci_ctrl_size = max_payload_size;
1193         return (HAL_NFC_STATUS_OK);
1194     }
1195 }
1196