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