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