nfc_hal_hci.c revision df5080d7feca9827fd0306471c54f52ecf185c22
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 49extern tNFC_HAL_CFG *p_nfc_hal_cfg; 50/**************************************************************************** 51** Internal function prototypes 52****************************************************************************/ 53static void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block); 54static void nfc_hal_hci_remove_dyn_pipe_to_uicc1 (void); 55static void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size); 56static void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status); 57static 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*******************************************************************************/ 68void 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*******************************************************************************/ 105void 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*******************************************************************************/ 175void 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*******************************************************************************/ 243void 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*******************************************************************************/ 291BOOLEAN 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*******************************************************************************/ 355void 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*******************************************************************************/ 428void 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*******************************************************************************/ 510void 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*******************************************************************************/ 553void 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*******************************************************************************/ 587void 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*******************************************************************************/ 645static 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*******************************************************************************/ 687void 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