/* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file cl/src/cl.c * \brief private function for the Convergence Layer * \ingroup cl * */ #include "common/std.h" #include "lib/seq_check.h" #include "lib/stats.h" #include "hal/arch/arch.h" #include "hal/gpio/gpio.h" #include "cl/cl.h" #include "cl/cl_mactotei.h" #include "cl/bridge_table.h" #include "cl/inc/context.h" #include "cl/inc/trace.h" #include "cl/inc/send.h" #include "cl/inc/receive.h" #include "config/cl.h" #include "config/cl/eoc.h" #include "config/mac/common.h" #include "config.h" #include static struct cl_t cl_global; /** * Initialise CL stats. * \param ctx cl context */ static void cl_stats_init (cl_t *ctx) { # define CL_STAT(s) \ lib_stats_set_stat_value_notype ("cl_" #s, &ctx->stats.s, \ LIB_STATS_ACCESS_READ_ONLY, \ LIB_STATS_DEBUG) CL_STAT (rx_data); CL_STAT (rx_data_multicast); CL_STAT (rx_mme); CL_STAT (tx_data); CL_STAT (tx_data_drop_auth); CL_STAT (tx_data_drop_prio); CL_STAT (tx_data_drop_mfs); CL_STAT (tx_data_multicast); CL_STAT (tx_mme); } cl_t * cl_init (mac_store_t *mac_store, sar_t *sar, mac_config_t *mac_config, ipmbox_t *ipmbox, bufmgr_t *bufmgr) { cl_t *ctx; /* Check parameters. */ dbg_assert (mac_config); memset (&cl_global, 0, sizeof (cl_t)); ctx = &cl_global; /* Initialize MAC store. */ cl_global.mac_store = mac_store; /* Initialize IPMbox. */ cl_global.ipmbox = ipmbox; ipmbox_register_rx_data_cb ( ipmbox, &cl_global, (ipmbox_rx_cb_t) cl_ipmbox_data_recv); /* Initialise Mbx cl sub module. */ cl_global.mbx = cl_mbx_init (ipmbox); /* Initialize buffer manager. */ cl_global.bufmgr = bufmgr; /* Initialize SAR */ cl_global.sar = sar; sar_init_reassembly_callbacks (cl_global.sar, (sar_reassembly_cb_t) cl_sar_data_recv, (sar_reassembly_cb_t) cl_sar_mme_recv, &cl_global); /* Initialize the cl_mactotei table */ cl_global.mactotei = NULL; /* Add the mac_config */ cl_global.mac_config = mac_config; /* Initialize the trace system. */ cl_trace_init (ctx); /* Initialize the local bridge table module. */ bridge_table_init (ctx); ctx->brg_rx = NULL; #if CONFIG_CL_EOC_ROUTE cl_eoc_mactotei_init (ctx); ctx->groups.nb = 0; #endif /* Initialize the data link. */ ctx->data_send_link.mfs = NULL; CL_TRACE (INIT, phy_date ()); /* Initialize packet sequence check. */ lib_seq_check_init (&ctx->seq_check_rx_ctx, cl_lib_seq_check_rx_cb, ctx); lib_seq_check_init (&ctx->seq_check_tx_ctx, cl_lib_seq_check_tx_cb, ctx); /* Register statistics. */ cl_stats_init (ctx); /* Debug LEDs. */ GPIO_SETUP (LED_CL_RX, GPIO_DIRECTION_OUT); GPIO_SET (LED_CL_RX, 0); GPIO_SETUP (LED_CL_TX, GPIO_DIRECTION_OUT); GPIO_SET (LED_CL_TX, 0); return &cl_global; } /** * Uninit the Convergence layer context. * * \param ctx the convergence layer context */ void cl_uninit (cl_t *ctx) { dbg_assert (ctx); CL_TRACE (UNINIT, phy_date ()); if (ctx->mactotei) cl_mactotei_release_table (ctx); cl_brg_rx_release (ctx); /* De-initialize the local bridge table module. */ bridge_table_deinit (ctx); cl_data_send_link_clear (ctx); cl_trace_uninit(ctx); } void cl_data_send_link_clear (cl_t *ctx) { arch_dsr_lock (); if (ctx->data_send_link.mfs) blk_release (ctx->data_send_link.mfs); ctx->data_send_link.mfs = NULL; ctx->data_send_link.dmac = MAC_ZERO; ctx->data_send_link.smac = MAC_ZERO; ctx->data_send_link.tag = 0; arch_dsr_unlock (); } #if CONFIG_CL_DATA_RATE void cl_compute_datarate_on_sta_ (cl_t *ctx, mfs_t *mfs, uint length) { if (MAC_TEI_IS_STA (mfs->common.tei)) { sta_t *sta = mac_store_sta_get (ctx->mac_store, mfs->common.tei); if (sta) { data_rate_update_info ( mfs->common.tx ? &sta->tx_data_rate : &sta->rx_data_rate, length); blk_release (sta); } } } #endif cl_mbx_t* cl_mbx_get (cl_t *ctx) { dbg_assert (ctx); return ctx->mbx; }