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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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