Home | History | Annotate | Download | only in hal
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2012 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  *  Vendor-specific handler for HCI events
     22  *
     23  ******************************************************************************/
     24 #include "gki.h"
     25 #include "nfc_hal_api.h"
     26 #include "nfc_hal_int.h"
     27 #include "nfc_hal_nv_ci.h"
     28 #include "nfc_hal_nv_co.h"
     29 
     30 #include <string.h>
     31 #include "nfc_hal_nv_co.h"
     32 
     33 #ifndef NFC_HAL_HCI_NV_READ_TIMEOUT
     34 #define NFC_HAL_HCI_NV_READ_TIMEOUT    1000
     35 #endif
     36 
     37 #ifndef NFC_HAL_HCI_NFCC_RSP_TIMEOUT
     38 #define NFC_HAL_HCI_NFCC_RSP_TIMEOUT   3000
     39 #endif
     40 
     41 static void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block);
     42 static void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size);
     43 static void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status);
     44 static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
     45 
     46 /*******************************************************************************
     47 **
     48 ** Function         nfc_hal_hci_evt_hdlr
     49 **
     50 ** Description      Processing event for NFA HCI
     51 **
     52 ** Returns          None
     53 **
     54 *******************************************************************************/
     55 void nfc_hal_hci_evt_hdlr (tNFC_HAL_HCI_EVENT_DATA *p_evt_data)
     56 {
     57     switch (p_evt_data->hdr.event)
     58     {
     59     case NFC_HAL_HCI_RSP_NV_READ_EVT:
     60         nfc_hal_hci_handle_nv_read (p_evt_data->nv_read.block, p_evt_data->nv_read.status, p_evt_data->nv_read.size);
     61         break;
     62 
     63     case NFC_HAL_HCI_RSP_NV_WRITE_EVT:
     64         /* NV Ram write completed - nothing to do... */
     65         break;
     66 
     67     default:
     68         break;
     69     }
     70 }
     71 
     72 /*******************************************************************************
     73 **
     74 ** Function         nfc_hal_hci_enable
     75 **
     76 ** Description      Program nv data on to controller
     77 **
     78 ** Returns          void
     79 **
     80 *******************************************************************************/
     81 void nfc_hal_hci_enable (void)
     82 {
     83 
     84     UINT8 *p_hci_netwk_cmd;
     85 
     86     if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
     87     {
     88         p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
     89         GKI_freebuf (p_hci_netwk_cmd);
     90         nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
     91     }
     92 
     93     if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
     94     {
     95         p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
     96         GKI_freebuf (p_hci_netwk_cmd);
     97         nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
     98     }
     99 
    100     if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_NETWK_INFO_SIZE)) == NULL)
    101     {
    102         NCI_TRACE_ERROR0 ("nfc_hal_hci_enable: unable to allocate buffer for reading hci network info from nvram");
    103         nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
    104     }
    105     else
    106     {
    107         nfc_hal_cb.hci_cb.p_hci_netwk_info_buf   = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
    108         nfc_hal_cb.hci_cb.hci_netwk_config_block = 0;
    109         memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
    110         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);
    111         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);
    112     }
    113 }
    114 
    115 /*******************************************************************************
    116 **
    117 ** Function         nfc_hal_hci_handle_hci_netwk_info
    118 **
    119 ** Description      Handler function for HCI Network Notification
    120 **
    121 ** Returns          None
    122 **
    123 *******************************************************************************/
    124 void nfc_hal_hci_handle_hci_netwk_info (UINT8 *p_data)
    125 {
    126     UINT8  *p = p_data;
    127     UINT16 data_len;
    128     UINT8  target_handle;
    129     UINT8   hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
    130 
    131     NCI_TRACE_DEBUG0 ("nfc_hal_hci_handle_hci_netwk_info()");
    132 
    133     /* skip NCI header byte0 (MT,GID), byte1 (OID) */
    134     p += 2;
    135 
    136     STREAM_TO_UINT8 (data_len, p);
    137     target_handle = *(UINT8 *) p;
    138 
    139     if (target_handle == NFC_HAL_HCI_DH_TARGET_HANDLE)
    140         nfc_hal_nv_co_write (p, data_len,HC_DH_NV_BLOCK);
    141 
    142     else if (target_handle == NFC_HAL_HCI_UICC0_TARGET_HANDLE)
    143     {
    144         if (p[12] & 0x80)
    145         {
    146             /* HCI Network notification received for UICC 0, Update nv data */
    147             nfc_hal_nv_co_write (p, data_len,HC_F3_NV_BLOCK);
    148         }
    149         else
    150         {
    151             NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, Reset nv file: 0x%02x", p[15]);
    152             hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
    153             memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
    154             nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F3_NV_BLOCK);
    155         }
    156     }
    157     else if (target_handle == NFC_HAL_HCI_UICC1_TARGET_HANDLE)
    158     {
    159         if (p[12] & 0x80)
    160         {
    161             /* HCI Network notification received for UICC 1, Update nv data */
    162             nfc_hal_nv_co_write (p, data_len,HC_F4_NV_BLOCK);
    163         }
    164         else
    165         {
    166             NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, Reset nv file: 0x%02x", p[15]);
    167             hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
    168             /* Reset Session ID */
    169             memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
    170             nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F4_NV_BLOCK);
    171         }
    172     }
    173 }
    174 
    175 /*******************************************************************************
    176 **
    177 ** Function         nfc_hal_hci_handle_hcp_pkt
    178 **
    179 ** Description      Handle HCP Packet
    180 **
    181 ** Returns          None
    182 **
    183 *******************************************************************************/
    184 void nfc_hal_hci_handle_hcp_pkt (UINT8 *p_data)
    185 {
    186     UINT8   chaining_bit;
    187     UINT8   pipe;
    188     UINT8   type;
    189     UINT8   inst;
    190     UINT8   hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
    191     UINT8   source_host;
    192 
    193     chaining_bit = ((*p_data) >> 0x07) & 0x01;
    194     pipe = (*p_data++) & 0x7F;
    195 
    196     if (  (chaining_bit)
    197         &&(pipe == NFC_HAL_HCI_ADMIN_PIPE)  )
    198     {
    199         type  = ((*p_data) >> 0x06) & 0x03;
    200 
    201         if (type == NFC_HAL_HCI_COMMAND_TYPE)
    202         {
    203             inst  = (*p_data++ & 0x3F);
    204 
    205             if (inst == NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED)
    206             {
    207 
    208                 STREAM_TO_UINT8 (source_host, p_data);
    209 
    210                 NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt(): Received Clear All pipe command for UICC: 0x%02x", source_host);
    211                 if (source_host == NFC_HAL_HCI_HOST_ID_UICC0)
    212                 {
    213                     hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
    214                     /* Reset Session ID */
    215                     memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
    216                     nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F3_NV_BLOCK);
    217                     NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt(): Sent command to reset nv file for block: 0x%02x", HC_F3_NV_BLOCK);
    218                 }
    219                 else if (source_host == NFC_HAL_HCI_HOST_ID_UICC1)
    220                 {
    221                     hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
    222                     /* Reset Session ID */
    223                     memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
    224                     nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F4_NV_BLOCK);
    225                     NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt(): Sent command to reset nv file for block: 0x%02x", HC_F4_NV_BLOCK);
    226                 }
    227             }
    228         }
    229     }
    230 }
    231 
    232 /*******************************************************************************
    233 **
    234 ** Function         nfc_hal_hci_handle_nv_read
    235 **
    236 ** Description      handler function for nv read complete event
    237 **
    238 ** Returns          None
    239 **
    240 *******************************************************************************/
    241 void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size)
    242 {
    243     NFC_HDR *p_data = NULL;
    244     UINT8   *p;
    245     UINT8   *p_hci_netwk_info = NULL;
    246 
    247     /* Stop timer as NVDATA Read Completed */
    248     nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer);
    249 
    250     switch (block)
    251     {
    252     case HC_F3_NV_BLOCK:
    253     case HC_F4_NV_BLOCK:
    254         if (  (status != HAL_NFC_STATUS_OK)
    255             ||(size > NFC_HAL_HCI_NETWK_INFO_SIZE)  )
    256         {
    257             NCI_TRACE_DEBUG0 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set DEFAULT Configuration!");
    258             memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
    259             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;
    260             memset (&nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
    261             size = NFC_HAL_HCI_NETWK_INFO_SIZE;
    262         }
    263 
    264         p_hci_netwk_info = (UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE;
    265         break;
    266 
    267     case HC_DH_NV_BLOCK:
    268         if (  (status == HAL_NFC_STATUS_OK)
    269             &&(size <= NFC_HAL_HCI_DH_NETWK_INFO_SIZE)  )
    270         {
    271             p_hci_netwk_info = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
    272         }
    273         else
    274         {
    275             NCI_TRACE_ERROR0 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Skip DH Configuration!");
    276         }
    277         break;
    278 
    279     default:
    280         return;
    281     }
    282 
    283     if (p_hci_netwk_info)
    284     {
    285         p = p_hci_netwk_info;
    286         /* Send HCI Network ntf command using nv data */
    287         NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_PROP);
    288         NCI_MSG_BLD_HDR1 (p, NCI_MSG_HCI_NETWK);
    289         UINT8_TO_STREAM (p, (UINT8) size);
    290 
    291         nfc_hal_dm_send_nci_cmd (p_hci_netwk_info, (UINT16) (NCI_MSG_HDR_SIZE + size), nfc_hal_hci_vsc_cback);
    292 
    293         nfc_hal_cb.hci_cb.hci_netwk_config_block = block;
    294     }
    295     else
    296     {
    297         /* Set next HCI Network configuration */
    298         nfc_hal_hci_set_next_hci_netwk_config (block);
    299     }
    300 }
    301 
    302 /*******************************************************************************
    303 **
    304 ** Function         nfc_hal_hci_init_complete
    305 **
    306 ** Description      Notify VSC initialization is complete
    307 **
    308 ** Returns          None
    309 **
    310 *******************************************************************************/
    311 void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status)
    312 {
    313     UINT8 *p_hci_netwk_cmd;
    314 
    315     if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
    316     {
    317         p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
    318         GKI_freebuf (p_hci_netwk_cmd);
    319         nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
    320     }
    321 
    322     if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
    323     {
    324         p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
    325         GKI_freebuf (p_hci_netwk_cmd);
    326         nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
    327     }
    328 
    329     NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
    330     nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
    331 }
    332 
    333 /*******************************************************************************
    334 **
    335 ** Function         nfc_hal_hci_set_next_hci_netwk_config
    336 **
    337 ** Description      set next hci network configuration
    338 **
    339 ** Returns          None
    340 **
    341 *******************************************************************************/
    342 void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block)
    343 {
    344     UINT8 *p_hci_netwk_cmd;
    345 
    346     switch (block)
    347     {
    348     case HC_F3_NV_BLOCK:
    349         /* Send command to read nvram data for 0xF4 */
    350         memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
    351         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);
    352         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);
    353         break;
    354 
    355     case HC_F4_NV_BLOCK:
    356         if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_DH_NETWK_INFO_SIZE)) == NULL)
    357         {
    358             NCI_TRACE_ERROR0 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer for reading hci network info from nvram");
    359             nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
    360         }
    361         else
    362         {
    363             nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf   = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
    364             /* Send command to read nvram data for 0xF2 */
    365             memset (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, 0, NFC_HAL_HCI_DH_NETWK_INFO_SIZE);
    366             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_DH_NV_BLOCK);
    367             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);
    368         }
    369         break;
    370 
    371     case HC_DH_NV_BLOCK:
    372         nfc_hal_hci_init_complete (HAL_NFC_STATUS_OK);
    373         break;
    374 
    375     default:
    376         NCI_TRACE_ERROR1 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer to send VSC 0x%02x", block);
    377         /* Brcm initialization failed */
    378         nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
    379         break;
    380     }
    381 }
    382 
    383 /*******************************************************************************
    384 **
    385 ** Function         nfc_hal_hci_vsc_cback
    386 **
    387 ** Description      process VS callback event from stack
    388 **
    389 ** Returns          none
    390 **
    391 *******************************************************************************/
    392 static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
    393 {
    394     UINT8 *p_ret = NULL;
    395     UINT8 status;
    396 
    397     p_ret  = p_data + NCI_MSG_HDR_SIZE;
    398     status = *p_ret;
    399 
    400     if (event  != NFC_VS_HCI_NETWK_RSP)
    401         return;
    402 
    403     if (status != HAL_NFC_STATUS_OK)
    404         nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
    405 
    406     switch (nfc_hal_cb.hci_cb.hci_netwk_config_block)
    407     {
    408     case HC_F3_NV_BLOCK:
    409     case HC_F4_NV_BLOCK:
    410     case HC_DH_NV_BLOCK:
    411         nfc_hal_hci_set_next_hci_netwk_config (nfc_hal_cb.hci_cb.hci_netwk_config_block);
    412         break;
    413 
    414     default:
    415         /* Ignore the event */
    416         break;
    417     }
    418 }
    419 
    420 /*******************************************************************************
    421 **
    422 ** Function         nfc_hal_nci_cmd_timeout_cback
    423 **
    424 ** Description      callback function for timeout
    425 **
    426 ** Returns          void
    427 **
    428 *******************************************************************************/
    429 void nfc_hal_hci_timeout_cback (void *p_tle)
    430 {
    431     TIMER_LIST_ENT  *p_tlent = (TIMER_LIST_ENT *)p_tle;
    432 
    433     NCI_TRACE_DEBUG0 ("nfc_hal_hci_timeout_cback ()");
    434 
    435     if (p_tlent->event == NFC_HAL_HCI_VSC_TIMEOUT_EVT)
    436     {
    437         NCI_TRACE_ERROR0 ("nfc_hal_hci_timeout_cback: Timeout - NFC HAL HCI BRCM Initialization Failed!");
    438         nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
    439     }
    440 }
    441 
    442