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 
     20 /******************************************************************************
     21  *
     22  *  Vendor-specific handler for HCI events
     23  *
     24  ******************************************************************************/
     25 #include "gki.h"
     26 #include "nfc_hal_api.h"
     27 #include "nfc_hal_int.h"
     28 #include "nfc_hal_nv_ci.h"
     29 #include "nfc_hal_nv_co.h"
     30 
     31 #include <string.h>
     32 #include "nfc_hal_nv_co.h"
     33 
     34 #ifndef NFC_HAL_HCI_NV_READ_TIMEOUT
     35 #define NFC_HAL_HCI_NV_READ_TIMEOUT    1000
     36 #endif
     37 
     38 #ifndef NFC_HAL_HCI_NFCC_RSP_TIMEOUT
     39 #define NFC_HAL_HCI_NFCC_RSP_TIMEOUT   3000
     40 #endif
     41 
     42 #define NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET    0x0C
     43 #define NFC_HAL_HCI_NETWK_CMD_TYPE_B_CE_PIPE_INFO_OFFSET    0x32
     44 #define NFC_HAL_HCI_NETWK_CMD_TYPE_BP_CE_PIPE_INFO_OFFSET   0x7F
     45 #define NFC_HAL_HCI_NETWK_CMD_TYPE_F_CE_PIPE_INFO_OFFSET    0xB4
     46 
     47 #define NFC_HAL_HCI_PIPE_VALID_MASK                         0x80
     48 
     49 extern tNFC_HAL_CFG *p_nfc_hal_cfg;
     50 /****************************************************************************
     51 ** Internal function prototypes
     52 ****************************************************************************/
     53 static void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block);
     54 static void nfc_hal_hci_remove_dyn_pipe_to_uicc1 (void);
     55 static void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size);
     56 static void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status);
     57 static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
     58 
     59 /*******************************************************************************
     60 **
     61 ** Function         nfc_hal_hci_evt_hdlr
     62 **
     63 ** Description      Processing event for NFA HCI
     64 **
     65 ** Returns          None
     66 **
     67 *******************************************************************************/
     68 void nfc_hal_hci_evt_hdlr (tNFC_HAL_HCI_EVENT_DATA *p_evt_data)
     69 {
     70     HAL_TRACE_DEBUG0 ("nfc_hal_hci_evt_hdlr ()");
     71 
     72     switch (p_evt_data->hdr.event)
     73     {
     74     case NFC_HAL_HCI_RSP_NV_READ_EVT:
     75         if (  (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf && (p_evt_data->nv_read.block == HC_F3_NV_BLOCK || p_evt_data->nv_read.block == HC_F4_NV_BLOCK))
     76             ||(nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf && p_evt_data->nv_read.block == HC_F2_NV_BLOCK)  )
     77         {
     78         nfc_hal_hci_handle_nv_read (p_evt_data->nv_read.block, p_evt_data->nv_read.status, p_evt_data->nv_read.size);
     79         }
     80         else
     81         {
     82             /* Invalid block or no buffer, Ignore */
     83             HAL_TRACE_ERROR1 ("nfc_hal_hci_evt_hdlr: No buffer for handling read NV block: 0x%02x", p_evt_data->nv_read.block);
     84         }
     85         break;
     86 
     87     case NFC_HAL_HCI_RSP_NV_WRITE_EVT:
     88         /* NV Ram write completed - nothing to do... */
     89         break;
     90 
     91     default:
     92         break;
     93     }
     94 }
     95 
     96 /*******************************************************************************
     97 **
     98 ** Function         nfc_hal_hci_enable
     99 **
    100 ** Description      Program nv data on to controller
    101 **
    102 ** Returns          void
    103 **
    104 *******************************************************************************/
    105 void nfc_hal_hci_enable (void)
    106 {
    107 
    108     UINT8 *p_hci_netwk_cmd;
    109 
    110     HAL_TRACE_DEBUG0 ("nfc_hal_hci_enable ()");
    111 
    112     if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE)
    113     {
    114         HAL_TRACE_DEBUG1 ("nfc_hal_hci_enable (): No HCI NETWK CMD to send for NVM Type: 0x%02x", nfc_hal_cb.nvm_cb.nvm_type);
    115         nfc_hal_hci_init_complete (HAL_NFC_STATUS_OK);
    116         return;
    117     }
    118 
    119     if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
    120     {
    121         p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
    122         GKI_freebuf (p_hci_netwk_cmd);
    123         nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
    124     }
    125 
    126     if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
    127     {
    128         p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
    129         GKI_freebuf (p_hci_netwk_cmd);
    130         nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
    131     }
    132 
    133     if (  (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC0_HOST)
    134         ||((p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC1_HOST) && ((!nfc_hal_cb.hci_cb.hci_fw_workaround) || (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_EEPROM)))  )
    135     {
    136         if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_NETWK_INFO_SIZE)) == NULL)
    137         {
    138             HAL_TRACE_ERROR0 ("nfc_hal_hci_enable: unable to allocate buffer for reading hci network info from nvram");
    139             nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
    140         }
    141         else
    142         {
    143             nfc_hal_cb.hci_cb.p_hci_netwk_info_buf   = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
    144             nfc_hal_cb.hci_cb.hci_netwk_config_block = 0;
    145             if (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC0_HOST)
    146             {
    147                 memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
    148                 nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F3_NV_BLOCK);
    149                 nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
    150             }
    151             else
    152             {
    153                 HAL_TRACE_DEBUG1 ("nfc_hal_hci_enable (): Skip send F3 HCI NETWK CMD for UICC Mask: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support);
    154                 nfc_hal_hci_set_next_hci_netwk_config (HC_F3_NV_BLOCK);
    155             }
    156 
    157         }
    158     }
    159     else
    160     {
    161         HAL_TRACE_DEBUG2 ("nfc_hal_hci_enable (): No HCI NETWK CMD to send for UICC Mask: 0x%02x & NVM Type: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
    162         nfc_hal_hci_set_next_hci_netwk_config (HC_F2_NV_BLOCK);
    163     }
    164 }
    165 
    166 /*******************************************************************************
    167 **
    168 ** Function         nfc_hal_hci_handle_hci_netwk_info
    169 **
    170 ** Description      Handler function for HCI Network Notification
    171 **
    172 ** Returns          None
    173 **
    174 *******************************************************************************/
    175 void nfc_hal_hci_handle_hci_netwk_info (UINT8 *p_data)
    176 {
    177     UINT8  *p = p_data;
    178     UINT16 data_len;
    179     UINT8  target_handle;
    180     UINT8   hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
    181 
    182     HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_hci_netwk_info ()");
    183 
    184     /* skip NCI header byte0 (MT,GID), byte1 (OID) */
    185     p += 2;
    186 
    187     STREAM_TO_UINT8 (data_len, p);
    188     target_handle = *(UINT8 *) p;
    189 
    190     if (target_handle == NFC_HAL_HCI_DH_TARGET_HANDLE)
    191         nfc_hal_nv_co_write (p, data_len, HC_F2_NV_BLOCK);
    192 
    193     else if (target_handle == NFC_HAL_HCI_UICC0_TARGET_HANDLE)
    194     {
    195         if (  (!nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd)
    196             ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
    197             ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_B_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
    198             ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_BP_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
    199             ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_F_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)  )
    200         {
    201             /* HCI Network notification received for UICC 0, Update nv data */
    202             nfc_hal_nv_co_write (p, data_len,HC_F3_NV_BLOCK);
    203         }
    204         else
    205         {
    206             HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, Reset nv file: 0x%02x", p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET]);
    207             hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
    208             memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
    209             nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F3_NV_BLOCK);
    210         }
    211     }
    212     else if (target_handle == NFC_HAL_HCI_UICC1_TARGET_HANDLE)
    213     {
    214         if (  (!nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd)
    215             ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
    216             ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_B_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
    217             ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_BP_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
    218             ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_F_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)  )
    219         {
    220             /* HCI Network notification received for UICC 1, Update nv data */
    221             nfc_hal_nv_co_write (p, data_len,HC_F4_NV_BLOCK);
    222         }
    223         else
    224         {
    225             HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, Reset nv file: 0x%02x", p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET]);
    226             hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
    227             /* Reset Session ID */
    228             memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
    229             nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F4_NV_BLOCK);
    230         }
    231     }
    232 }
    233 
    234 /*******************************************************************************
    235 **
    236 ** Function         nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh
    237 **
    238 ** Description      Fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to nfc task
    239 **
    240 ** Returns          None
    241 **
    242 *******************************************************************************/
    243 void nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh (void)
    244 {
    245     NFC_HDR  *p_msg;
    246     UINT8 *p, *ps;
    247 
    248     HAL_TRACE_DEBUG1 ("nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh (): Fake ADM_NOTIFY_ALL_PIPE_CLEARED (0x%02x) from HAL", NFC_HAL_HCI_HOST_ID_UICC1);
    249 
    250     /* Start of new message. Allocate a buffer for message */
    251     if ((p_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
    252     {
    253         /* Initialize NFC_HDR */
    254         p_msg->len    = NCI_DATA_HDR_SIZE + 0x03;
    255         p_msg->event  = 0;
    256         p_msg->offset = 0;
    257         p_msg->layer_specific = 0;
    258 
    259         p = (UINT8 *) (p_msg + 1) + p_msg->offset;
    260         ps = p;
    261         NCI_DATA_BLD_HDR (p, nfc_hal_cb.hci_cb.hcp_conn_id, 0x03);
    262         /* HCP header with ADMIN pipe id and chaining bit set */
    263         *p++ = ((1 << 0x07) | (NFC_HAL_HCI_ADMIN_PIPE & 0x7F));
    264         /* HCP Message header with Command type instruction and ADM_NOTIFY_ALL_PIPE_CLEARED command */
    265         *p++ = ((NFC_HAL_HCI_COMMAND_TYPE << 6) | (NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED & 0x3F));
    266         /* HCP Data with UICC1 host id */
    267         *p = NFC_HAL_HCI_HOST_ID_UICC1;
    268 
    269 #ifdef DISP_NCI
    270         DISP_NCI (ps, (UINT16) p_msg->len, TRUE);
    271 #endif
    272         nfc_hal_send_nci_msg_to_nfc_task (p_msg);
    273 
    274     }
    275     else
    276     {
    277         HAL_TRACE_ERROR0 ("Unable to allocate buffer for faking ADM_NOTIFY_ALL_PIPE_CLEARED cmd from HAL to stack");
    278     }
    279 }
    280 
    281 /*******************************************************************************
    282 **
    283 ** Function         nfc_hal_hci_handle_hcp_pkt_to_hc
    284 **
    285 ** Description      Handle HCP Packet from NFC task to Host Controller
    286 **
    287 ** Returns          FALSE to send the packet to host controller
    288 **                  TRUE to drop the packet and fake credit ntf for hcp connection
    289 **
    290 *******************************************************************************/
    291 BOOLEAN nfc_hal_hci_handle_hcp_pkt_to_hc (UINT8 *p_data)
    292 {
    293     UINT8   chaining_bit;
    294     UINT8   pipe;
    295     UINT8   type;
    296     UINT8   inst;
    297     UINT8   index;
    298 
    299     HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_hcp_pkt_to_hc ()");
    300 
    301     if (  (!nfc_hal_cb.hci_cb.hci_fw_workaround)
    302         ||(nfc_hal_cb.nvm_cb.nvm_type != NCI_SPD_NVM_TYPE_UICC)  )
    303     {
    304         /* Do nothing, just forward the stack hcp packet to host controller */
    305         return FALSE;
    306     }
    307 
    308     chaining_bit = ((*p_data) >> 0x07) & 0x01;
    309     pipe = (*p_data++) & 0x7F;
    310 
    311     if (  (chaining_bit)
    312         &&(pipe == NFC_HAL_HCI_ADMIN_PIPE)  )
    313     {
    314         type  = ((*p_data) >> 0x06) & 0x03;
    315 
    316         if (type == NFC_HAL_HCI_COMMAND_TYPE)
    317         {
    318             inst  = (*p_data++ & 0x3F);
    319             if (inst == NFC_HAL_HCI_ANY_SET_PARAMETER)
    320             {
    321                 index = *(p_data++);
    322                 if (index == NFC_HAL_HCI_WHITELIST_INDEX)
    323                 {
    324                     /* Set flag to fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to nfc task after
    325                      * response from host controller to set whitelist cmd
    326                      */
    327                     nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1 = TRUE;
    328                 }
    329             }
    330         }
    331         else if (type == NFC_HAL_HCI_RESPONSE_TYPE)
    332         {
    333             if (nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1)
    334             {
    335                 /* Got response to the fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd sent by HAL to nfc task */
    336                 nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1 =  FALSE;
    337                 /* return TRUE to drop this hcp without forwarding to host controller */
    338                 return TRUE;
    339             }
    340         }
    341     }
    342 
    343     return FALSE;
    344 }
    345 
    346 /*******************************************************************************
    347 **
    348 ** Function         nfc_hal_hci_handle_hcp_pkt_from_hc
    349 **
    350 ** Description      Handle HCP Packet from Host controller to Terminal Host
    351 **
    352 ** Returns          None
    353 **
    354 *******************************************************************************/
    355 void nfc_hal_hci_handle_hcp_pkt_from_hc (UINT8 *p_data)
    356 {
    357     UINT8   chaining_bit;
    358     UINT8   pipe;
    359     UINT8   type;
    360     UINT8   inst;
    361     UINT8   hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
    362     UINT8   source_host;
    363 
    364     HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_hcp_pkt_from_hc ()");
    365 
    366     if (!nfc_hal_cb.hci_cb.hci_fw_workaround)
    367         return;
    368 
    369     chaining_bit = ((*p_data) >> 0x07) & 0x01;
    370     pipe = (*p_data++) & 0x7F;
    371 
    372     if (  (chaining_bit)
    373         &&(pipe == NFC_HAL_HCI_ADMIN_PIPE)  )
    374     {
    375         type  = ((*p_data) >> 0x06) & 0x03;
    376 
    377         if (type == NFC_HAL_HCI_COMMAND_TYPE)
    378         {
    379             inst  = (*p_data++ & 0x3F);
    380 
    381             if (inst == NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED)
    382             {
    383 
    384                 STREAM_TO_UINT8 (source_host, p_data);
    385 
    386                 HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt_from_hc (): Received ADM_NOTIFY_ALL_PIPE_CLEARED command for UICC: 0x%02x", source_host);
    387                 if (source_host == NFC_HAL_HCI_HOST_ID_UICC0)
    388                 {
    389                     hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
    390                     /* Reset Session ID */
    391                     memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
    392                     nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F3_NV_BLOCK);
    393                     HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt_from_hc (): Sent command to reset nv file for block: 0x%02x", HC_F3_NV_BLOCK);
    394                 }
    395                 else if (source_host == NFC_HAL_HCI_HOST_ID_UICC1)
    396                 {
    397                     hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
    398                     /* Reset Session ID */
    399                     memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
    400                     nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F4_NV_BLOCK);
    401                     HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt_from_hc (): Sent command to reset nv file for block: 0x%02x", HC_F4_NV_BLOCK);
    402                 }
    403             }
    404         }
    405         else if (type == NFC_HAL_HCI_RESPONSE_TYPE)
    406         {
    407             if (nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1)
    408             {
    409                 /* NVM Type is UICC and got response from host controller
    410                  * to Set whitelist command. Now fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to
    411                  * NFC Task and then forward the whitelist cmd response
    412                  */
    413                 nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh ();
    414             }
    415         }
    416     }
    417 }
    418 
    419 /*******************************************************************************
    420 **
    421 ** Function         nfc_hal_hci_handle_nv_read
    422 **
    423 ** Description      handler function for nv read complete event
    424 **
    425 ** Returns          None
    426 **
    427 *******************************************************************************/
    428 void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size)
    429 {
    430     UINT8   *p;
    431     UINT8   *p_hci_netwk_info = NULL;
    432 
    433     HAL_TRACE_DEBUG3 ("nfc_hal_hci_handle_nv_read (): Block: [0x%02x], Status: [0x%02x], Size: [0x%04x]", block, status, size);
    434 
    435     /* Stop timer as NVDATA Read Completed */
    436     nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer);
    437 
    438     switch (block)
    439     {
    440     case HC_F3_NV_BLOCK:
    441     case HC_F4_NV_BLOCK:
    442         if (  (status != HAL_NFC_STATUS_OK)
    443             ||(size > NFC_HAL_HCI_NETWK_INFO_SIZE)
    444             ||(size < NFC_HAL_HCI_MIN_NETWK_INFO_SIZE)
    445             ||((nfc_hal_cb.hci_cb.hci_fw_workaround) && (block == HC_F4_NV_BLOCK) && (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC))  )
    446         {
    447             HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set DEFAULT Configuration for block:0x%02x", block);
    448             memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
    449             nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = (block == HC_F3_NV_BLOCK) ? NFC_HAL_HCI_UICC0_TARGET_HANDLE : NFC_HAL_HCI_UICC1_TARGET_HANDLE;
    450             memset (&nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
    451             size = NFC_HAL_HCI_NETWK_INFO_SIZE;
    452         }
    453 
    454         p_hci_netwk_info = (UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE;
    455         break;
    456 
    457     case HC_F2_NV_BLOCK:
    458 
    459         if (  (status != HAL_NFC_STATUS_OK)
    460             ||(size > NFC_HAL_HCI_DH_NETWK_INFO_SIZE)
    461             ||(size < NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE)  )
    462         {
    463             HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set DEFAULT Configuration for block:0x%02x", block);
    464             memset (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, 0, NFC_HAL_HCI_DH_NETWK_INFO_SIZE);
    465             nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[0] = NFC_HAL_HCI_DH_TARGET_HANDLE;
    466             memset (&nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
    467             size = NFC_HAL_HCI_DH_NETWK_INFO_SIZE;
    468             p_hci_netwk_info = (UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE;
    469         }
    470         else
    471         {
    472             if ((nfc_hal_cb.hci_cb.hci_fw_workaround) && (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC))
    473             {
    474                 /* if NVM Type is UICC, then UICC1 will find session id mismatch when activated for patch download,
    475                  * and will remove pipes connected to DH even before DH is enabled, So DH will update NFCC
    476                  * control block by removing all dynamic pipes connected to UICC1 */
    477 
    478                 nfc_hal_hci_remove_dyn_pipe_to_uicc1 ();
    479                 size = NFC_HAL_HCI_DH_NETWK_INFO_SIZE;
    480             }
    481             p_hci_netwk_info = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
    482         }
    483         break;
    484 
    485     default:
    486         return;
    487     }
    488 
    489         p = p_hci_netwk_info;
    490         /* Send HCI Network ntf command using nv data */
    491         NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_PROP);
    492         NCI_MSG_BLD_HDR1 (p, NCI_MSG_HCI_NETWK);
    493         UINT8_TO_STREAM (p, (UINT8) size);
    494 
    495         nfc_hal_dm_send_nci_cmd (p_hci_netwk_info, (UINT16) (NCI_MSG_HDR_SIZE + size), nfc_hal_hci_vsc_cback);
    496 
    497         nfc_hal_cb.hci_cb.hci_netwk_config_block = block;
    498 }
    499 
    500 /*******************************************************************************
    501 **
    502 ** Function         nfc_hal_hci_remove_dyn_pipe_to_uicc1
    503 **
    504 ** Description      Prepare hci network command read from nv file removing
    505 **                  all pipes connected to UICC1
    506 **
    507 ** Returns          None
    508 **
    509 *******************************************************************************/
    510 void nfc_hal_hci_remove_dyn_pipe_to_uicc1 (void)
    511 {
    512     UINT8 *p, *np;
    513     UINT8 num_dyn_pipes = 0, new_num_dyn_pipes = 0;
    514     UINT8 xx;
    515     UINT8 source_host, dest_host, pipe_id;
    516 
    517     HAL_TRACE_DEBUG0 ("nfc_hal_hci_remove_dyn_pipe_to_uicc1 ()");
    518 
    519     p  = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf + NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE);
    520     np = p;
    521     num_dyn_pipes = *(p - 1);
    522 
    523     for (xx = 0; xx < num_dyn_pipes; xx++,p += NFC_HAL_HCI_PIPE_INFO_SIZE)
    524     {
    525         source_host = *(UINT8 *) (p);
    526         dest_host   = *(UINT8 *) (p + 1);
    527         pipe_id     = *(UINT8 *) (p + 4);
    528 
    529         if ((source_host != NFC_HAL_HCI_HOST_ID_UICC1) && (dest_host != NFC_HAL_HCI_HOST_ID_UICC1))
    530         {
    531             memcpy (np, p, NFC_HAL_HCI_PIPE_INFO_SIZE);
    532             np += NFC_HAL_HCI_PIPE_INFO_SIZE;
    533             new_num_dyn_pipes++;
    534         }
    535     }
    536 
    537     memset ((UINT8 *) (np), 0, NFC_HAL_HCI_PIPE_INFO_SIZE * (20 - new_num_dyn_pipes));
    538 
    539     /* Update number of pipes after removing pipes connected to UICC1 */
    540     p = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf + NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE);
    541     *(p - 1) = new_num_dyn_pipes;
    542 }
    543 
    544 /*******************************************************************************
    545 **
    546 ** Function         nfc_hal_hci_init_complete
    547 **
    548 ** Description      Notify VSC initialization is complete
    549 **
    550 ** Returns          None
    551 **
    552 *******************************************************************************/
    553 void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status)
    554 {
    555     UINT8 *p_hci_netwk_cmd;
    556 
    557     HAL_TRACE_DEBUG1 ("nfc_hal_hci_init_complete (): Status: [0x%02x]", status);
    558 
    559     if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
    560     {
    561         p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
    562         GKI_freebuf (p_hci_netwk_cmd);
    563         nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
    564     }
    565 
    566     if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
    567     {
    568         p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
    569         GKI_freebuf (p_hci_netwk_cmd);
    570         nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
    571     }
    572 
    573     NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
    574 
    575     nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, status);
    576 }
    577 
    578 /*******************************************************************************
    579 **
    580 ** Function         nfc_hal_hci_set_next_hci_netwk_config
    581 **
    582 ** Description      set next hci network configuration
    583 **
    584 ** Returns          None
    585 **
    586 *******************************************************************************/
    587 void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block)
    588 {
    589     UINT8 *p_hci_netwk_cmd;
    590 
    591     HAL_TRACE_DEBUG1 ("nfc_hal_hci_set_next_hci_netwk_config (): Block: [0x%02x]", block);
    592 
    593     switch (block)
    594     {
    595     case HC_F3_NV_BLOCK:
    596         if (  (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC1_HOST)
    597             &&(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
    598             &&((!nfc_hal_cb.hci_cb.hci_fw_workaround) || (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_EEPROM))  )
    599         {
    600             /* Send command to read nvram data for 0xF4 */
    601             memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
    602             nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F4_NV_BLOCK);
    603             nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
    604             break;
    605         }
    606         HAL_TRACE_DEBUG2 ("nfc_hal_hci_set_next_hci_netwk_config (): Skip send F4 HCI NETWK CMD for UICC Mask: 0x%02x & NVM Type: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
    607 
    608     case HC_F4_NV_BLOCK:
    609         if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_DH_NETWK_INFO_SIZE)) == NULL)
    610         {
    611             HAL_TRACE_ERROR0 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer for reading hci network info from nvram");
    612             nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
    613         }
    614         else
    615         {
    616             nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf   = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
    617             /* Send command to read nvram data for 0xF2 */
    618             memset (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, 0, NFC_HAL_HCI_DH_NETWK_INFO_SIZE);
    619             nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, NFC_HAL_HCI_DH_NETWK_INFO_SIZE, HC_F2_NV_BLOCK);
    620             nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
    621         }
    622         break;
    623 
    624     case HC_F2_NV_BLOCK:
    625         nfc_hal_hci_init_complete (HAL_NFC_STATUS_OK);
    626         break;
    627 
    628     default:
    629         HAL_TRACE_ERROR1 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer to send VSC 0x%02x", block);
    630         /* Brcm initialization failed */
    631         nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
    632         break;
    633     }
    634 }
    635 
    636 /*******************************************************************************
    637 **
    638 ** Function         nfc_hal_hci_vsc_cback
    639 **
    640 ** Description      process VS callback event from stack
    641 **
    642 ** Returns          none
    643 **
    644 *******************************************************************************/
    645 static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
    646 {
    647     UINT8 *p_ret = NULL;
    648     UINT8 status;
    649 
    650     p_ret  = p_data + NCI_MSG_HDR_SIZE;
    651     status = *p_ret;
    652 
    653     HAL_TRACE_DEBUG3 ("nfc_hal_hci_vsc_cback (): Event: [0x%02x], Data length: [0x%04x], Status: [0x%02x]", event, data_len, status);
    654 
    655     if (event  != NFC_VS_HCI_NETWK_RSP)
    656         return;
    657 
    658     if (status != HAL_NFC_STATUS_OK)
    659     {
    660         nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
    661         return;
    662     }
    663 
    664     switch (nfc_hal_cb.hci_cb.hci_netwk_config_block)
    665     {
    666     case HC_F3_NV_BLOCK:
    667     case HC_F4_NV_BLOCK:
    668     case HC_F2_NV_BLOCK:
    669         nfc_hal_hci_set_next_hci_netwk_config (nfc_hal_cb.hci_cb.hci_netwk_config_block);
    670         break;
    671 
    672     default:
    673         /* Ignore the event */
    674         break;
    675     }
    676 }
    677 
    678 /*******************************************************************************
    679 **
    680 ** Function         nfc_hal_nci_cmd_timeout_cback
    681 **
    682 ** Description      callback function for timeout
    683 **
    684 ** Returns          void
    685 **
    686 *******************************************************************************/
    687 void nfc_hal_hci_timeout_cback (void *p_tle)
    688 {
    689     TIMER_LIST_ENT  *p_tlent = (TIMER_LIST_ENT *)p_tle;
    690 
    691     HAL_TRACE_DEBUG0 ("nfc_hal_hci_timeout_cback ()");
    692 
    693     if (p_tlent->event == NFC_HAL_HCI_VSC_TIMEOUT_EVT)
    694     {
    695         HAL_TRACE_ERROR0 ("nfc_hal_hci_timeout_cback: Timeout - NFC HAL HCI BRCM Initialization Failed!");
    696         nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
    697     }
    698 }
    699 
    700