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         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 *******************************************************************************/
    159 void 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 *******************************************************************************/
    220 void 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 *******************************************************************************/
    297 void 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 *******************************************************************************/
    489 UINT8 *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 *******************************************************************************/
    555 void 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 *******************************************************************************/
    715 void 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 *******************************************************************************/
    766 void 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 *******************************************************************************/
    804 void 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 *******************************************************************************/
    824 void 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 *******************************************************************************/
    893 BOOLEAN 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 *******************************************************************************/
    975 BOOLEAN 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 *******************************************************************************/
   1032 void 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 *******************************************************************************/
   1065 tHAL_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