nfa_sys_main.c revision e29968cf3e053557a9c2efc5a7a42d0767c51d9d
1/***************************************************************************** 2** 3** Name: nfa_sys_main.c 4** 5** Description: This is the main implementation file for the NFA 6** system manager. 7** 8** Copyright (c) 2010, Broadcom Corp., All Rights Reserved. 9** Broadcom Bluetooth Core. Proprietary and confidential. 10** 11*****************************************************************************/ 12#include <string.h> 13#include "nfa_api.h" 14#include "nfa_sys.h" 15#include "nfa_sys_int.h" 16#include "nfa_sys_ptim.h" 17#include "nfa_dm_int.h" 18 19/* protocol timer update period, in milliseconds */ 20#ifndef NFA_SYS_TIMER_PERIOD 21#define NFA_SYS_TIMER_PERIOD 10 22#endif 23 24/* system manager control block definition */ 25#if NFA_DYNAMIC_MEMORY == FALSE 26tNFA_SYS_CB nfa_sys_cb = {0}; /* nfa_sys control block. statically initialize 'flags' field to 0 */ 27#endif 28 29/******************************************************************************* 30** 31** Function nfa_sys_init 32** 33** Description NFA initialization; called from task initialization. 34** 35** 36** Returns void 37** 38*******************************************************************************/ 39void nfa_sys_init (void) 40{ 41 memset (&nfa_sys_cb, 0, sizeof (tNFA_SYS_CB)); 42 nfa_sys_cb.flags |= NFA_SYS_FL_INITIALIZED; 43 nfa_sys_ptim_init (&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD, p_nfa_sys_cfg->timer); 44 nfa_sys_cb.trace_level = p_nfa_sys_cfg->trace_level; 45} 46 47 48 49 50/******************************************************************************* 51** 52** Function nfa_sys_event 53** 54** Description BTA event handler; called from task event handler. 55** 56** 57** Returns void 58** 59*******************************************************************************/ 60void nfa_sys_event (BT_HDR *p_msg) 61{ 62 UINT8 id; 63 BOOLEAN freebuf = TRUE; 64 65 NFA_TRACE_EVENT1 ("NFA got event 0x%04X", p_msg->event); 66 67 /* get subsystem id from event */ 68 id = (UINT8) (p_msg->event >> 8); 69 70 /* verify id and call subsystem event handler */ 71 if ((id < NFA_ID_MAX) && (nfa_sys_cb.is_reg[id])) 72 { 73 freebuf = (*nfa_sys_cb.reg[id]->evt_hdlr) (p_msg); 74 } 75 else 76 { 77 NFA_TRACE_WARNING1 ("NFA got unregistered event id %d", id); 78 } 79 80 if (freebuf) 81 { 82 GKI_freebuf (p_msg); 83 } 84} 85 86/******************************************************************************* 87** 88** Function nfa_sys_timer_update 89** 90** Description Update the BTA timer list and handle expired timers. 91** 92** Returns void 93** 94*******************************************************************************/ 95void nfa_sys_timer_update (void) 96{ 97 if (!nfa_sys_cb.timers_disabled) 98 { 99 nfa_sys_ptim_timer_update (&nfa_sys_cb.ptim_cb); 100 } 101} 102 103/******************************************************************************* 104** 105** Function nfa_sys_register 106** 107** Description Called by other BTA subsystems to register their event 108** handler. 109** 110** 111** Returns void 112** 113*******************************************************************************/ 114void nfa_sys_register (UINT8 id, const tNFA_SYS_REG *p_reg) 115{ 116 nfa_sys_cb.reg[id] = (tNFA_SYS_REG *) p_reg; 117 nfa_sys_cb.is_reg[id] = TRUE; 118 119 if ((id != NFA_ID_DM) && (id != NFA_ID_SYS)) 120 nfa_sys_cb.enable_cplt_mask |= (0x0001 << id); 121 122 if (id != NFA_ID_SYS) 123 { 124 if (p_reg->proc_nfcc_pwr_mode) 125 nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask |= (0x0001 << id); 126 } 127 128 NFA_TRACE_DEBUG2 ("nfa_sys_register () id=%i, enable_cplt_mask=0x%x", 129 id, nfa_sys_cb.enable_cplt_mask); 130} 131 132 133/******************************************************************************* 134** 135** Function nfa_sys_check_disabled 136** 137** Description If all subsystems above DM have been disabled, then 138** disable DM. Called during NFA shutdown 139** 140** Returns void 141** 142*******************************************************************************/ 143void nfa_sys_check_disabled (void) 144{ 145 UINT8 id; 146 UINT8 done = TRUE; 147 148 /* Check if all subsystems above DM have been disabled. */ 149 for (id = (NFA_ID_DM+1); id < NFA_ID_MAX; id++) 150 { 151 if (nfa_sys_cb.is_reg[id]) 152 { 153 /* as long as one subsystem is not done */ 154 done = FALSE; 155 break; 156 } 157 } 158 159 /* All subsystems disabled. disable DM */ 160 if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM])) 161 { 162 (*nfa_sys_cb.reg[NFA_ID_DM]->disable) (); 163 } 164} 165 166 167/******************************************************************************* 168** 169** Function nfa_sys_deregister 170** 171** Description Called by other BTA subsystems to de-register 172** handler. 173** 174** 175** Returns void 176** 177*******************************************************************************/ 178void nfa_sys_deregister (UINT8 id) 179{ 180 NFA_TRACE_DEBUG1 ("nfa_sys: deregistering subsystem %i", id); 181 182 nfa_sys_cb.is_reg[id] = FALSE; 183 184 /* If not deregistering DM, then check if any other subsystems above DM are still */ 185 /* registered. */ 186 if (id != NFA_ID_DM) 187 { 188 /* If all subsystems above NFA_DM have been disabled, then okay to disable DM */ 189 nfa_sys_check_disabled (); 190 } 191 else 192 { 193 /* DM (the final sub-system) is deregistering. Clear pending timer events in nfa_sys. */ 194 nfa_sys_ptim_init (&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD, p_nfa_sys_cfg->timer); 195 } 196} 197 198/******************************************************************************* 199** 200** Function nfa_sys_is_register 201** 202** Description Called by other BTA subsystems to get registeration 203** status. 204** 205** 206** Returns void 207** 208*******************************************************************************/ 209BOOLEAN nfa_sys_is_register (UINT8 id) 210{ 211 return nfa_sys_cb.is_reg[id]; 212} 213 214/******************************************************************************* 215** 216** Function nfa_sys_is_graceful_disable 217** 218** Description Called by other BTA subsystems to get disable 219** parameter. 220** 221** 222** Returns void 223** 224*******************************************************************************/ 225BOOLEAN nfa_sys_is_graceful_disable (void) 226{ 227 return nfa_sys_cb.graceful_disable; 228} 229 230/******************************************************************************* 231** 232** Function nfa_sys_enable_subsystems 233** 234** Description Call on NFA Start up 235** 236** Returns void 237** 238*******************************************************************************/ 239void nfa_sys_enable_subsystems (void) 240{ 241 UINT8 id; 242 243 NFA_TRACE_DEBUG0 ("nfa_sys: enabling subsystems"); 244 245 /* Disable all subsystems above NFA_DM. (NFA_DM and NFA_SYS will be disabled last) */ 246 for (id = NFA_ID_VS_PRE; id < NFA_ID_MAX; id++) 247 { 248 if (nfa_sys_cb.is_reg[id]) 249 { 250 if (nfa_sys_cb.reg[id]->enable != NULL) 251 { 252 /* Subsytem has a Disable funciton. Call it now */ 253 (*nfa_sys_cb.reg[id]->enable) (); 254 } 255 else 256 { 257 /* Subsytem does not have a Enable function. Report Enable on behalf of subsystem */ 258 nfa_sys_cback_notify_enable_complete (id); 259 } 260 } 261 } 262} 263 264/******************************************************************************* 265** 266** Function nfa_sys_disable_subsystems 267** 268** Description Call on NFA shutdown. Disable all subsystems above NFA_DM 269** 270** Returns void 271** 272*******************************************************************************/ 273void nfa_sys_disable_subsystems (BOOLEAN graceful) 274{ 275 UINT8 id; 276 BOOLEAN done = TRUE; 277 278 NFA_TRACE_DEBUG1 ("nfa_sys: disabling subsystems:%d", graceful); 279 nfa_sys_cb.graceful_disable = graceful; 280 281 /* Disable all subsystems above NFA_DM. (NFA_DM and NFA_SYS will be disabled last) */ 282 for (id = (NFA_ID_DM+1); id < NFA_ID_MAX; id++) 283 { 284 if (nfa_sys_cb.is_reg[id]) 285 { 286 done = FALSE; 287 if (nfa_sys_cb.reg[id]->disable != NULL) 288 { 289 /* Subsytem has a Disable funciton. Call it now */ 290 (*nfa_sys_cb.reg[id]->disable) (); 291 } 292 else 293 { 294 /* Subsytem does not have a Disable function. Deregister on behalf of subsystem */ 295 nfa_sys_deregister (id); 296 } 297 } 298 } 299 300 /* If All subsystems disabled. disable DM */ 301 if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM])) 302 { 303 (*nfa_sys_cb.reg[NFA_ID_DM]->disable) (); 304 } 305} 306 307/******************************************************************************* 308** 309** Function nfa_sys_notify_nfcc_power_mode 310** 311** Description Call to notify NFCC power mode to NFA sub-modules 312** 313** Returns void 314** 315*******************************************************************************/ 316void nfa_sys_notify_nfcc_power_mode (UINT8 nfcc_power_mode) 317{ 318 UINT8 id; 319 320 NFA_TRACE_DEBUG1 ("nfa_sys: notify NFCC power mode(%d) to subsystems", nfcc_power_mode); 321 322 /* Notify NFCC power state to all subsystems except NFA_SYS */ 323 for (id = NFA_ID_VS_PRE; id < NFA_ID_MAX; id++) 324 { 325 if ((nfa_sys_cb.is_reg[id]) && (nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode)) 326 { 327 /* Subsytem has a funciton for processing NFCC power mode. Call it now */ 328 (*nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode) (nfcc_power_mode); 329 } 330 } 331} 332 333/******************************************************************************* 334** 335** Function nfa_sys_sendmsg 336** 337** Description Send a GKI message to BTA. This function is designed to 338** optimize sending of messages to BTA. It is called by BTA 339** API functions and call-in functions. 340** 341** 342** Returns void 343** 344*******************************************************************************/ 345void nfa_sys_sendmsg (void *p_msg) 346{ 347 GKI_send_msg (NFC_TASK, p_nfa_sys_cfg->mbox, p_msg); 348} 349 350/******************************************************************************* 351** 352** Function nfa_sys_start_timer 353** 354** Description Start a protocol timer for the specified amount 355** of time in milliseconds. 356** 357** Returns void 358** 359*******************************************************************************/ 360void nfa_sys_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout) 361{ 362 nfa_sys_ptim_start_timer (&nfa_sys_cb.ptim_cb, p_tle, type, timeout); 363} 364 365/******************************************************************************* 366** 367** Function nfa_sys_stop_timer 368** 369** Description Stop a BTA timer. 370** 371** Returns void 372** 373*******************************************************************************/ 374void nfa_sys_stop_timer (TIMER_LIST_ENT *p_tle) 375{ 376 nfa_sys_ptim_stop_timer (&nfa_sys_cb.ptim_cb, p_tle); 377} 378 379 380/******************************************************************************* 381** 382** Function nfa_sys_disable_timers 383** 384** Description Disable sys timer event handling 385** 386** Returns void 387** 388*******************************************************************************/ 389void nfa_sys_disable_timers (void) 390{ 391 nfa_sys_cb.timers_disabled = TRUE; 392} 393 394/******************************************************************************* 395** 396** Function nfa_sys_set_trace_level 397** 398** Description Set trace level for BTA 399** 400** Returns void 401** 402*******************************************************************************/ 403void nfa_sys_set_trace_level (UINT8 level) 404{ 405 nfa_sys_cb.trace_level = level; 406} 407