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