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