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