nfc_hal_hci.c revision 5c65c3a0f42e174e47fecd4e569606003217ff4e
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
49extern tNFC_HAL_CFG *p_nfc_hal_cfg;
50/****************************************************************************
51** Internal function prototypes
52****************************************************************************/
53static void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block);
54static void nfc_hal_hci_remove_dyn_pipe_to_uicc1 (void);
55static void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size);
56static void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status);
57static 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*******************************************************************************/
68void 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*******************************************************************************/
103void 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*******************************************************************************/
171void 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*******************************************************************************/
239void 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*******************************************************************************/
287BOOLEAN 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*******************************************************************************/
351void 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*******************************************************************************/
422void 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*******************************************************************************/
502void 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*******************************************************************************/
543void 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*******************************************************************************/
575void 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*******************************************************************************/
630static 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*******************************************************************************/
667void 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