nfc_hal_hci.c revision a24be4f06674b2707b57904deaa0dff5a95823bd
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 */
57const 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 */
61const 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 */
65const UINT8 NFC_HAL_DM_BCM43341B0_STR[]   = "43341B0";
66#define NFC_HAL_DM_BCM43341B0_STR_LEN     (sizeof (NFC_HAL_DM_BCM43341B0_STR)-1)
67
68extern tNFC_HAL_CFG *p_nfc_hal_cfg;
69/****************************************************************************
70** Internal function prototypes
71****************************************************************************/
72static void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block);
73static void nfc_hal_hci_remove_dyn_pipe_to_uicc1 (void);
74static void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size);
75static void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status);
76static 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*******************************************************************************/
87void 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*******************************************************************************/
124void 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*******************************************************************************/
195void 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*******************************************************************************/
229void 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*******************************************************************************/
298void 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*******************************************************************************/
346BOOLEAN 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*******************************************************************************/
428void 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*******************************************************************************/
518void 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*******************************************************************************/
613void 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*******************************************************************************/
656void 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*******************************************************************************/
690void 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*******************************************************************************/
760static 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*******************************************************************************/
803void 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