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