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