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