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