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