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