summaryrefslogtreecommitdiff
path: root/cesar/cp/eoc/cco/bw/src/bw.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/cp/eoc/cco/bw/src/bw.c')
-rw-r--r--cesar/cp/eoc/cco/bw/src/bw.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/cesar/cp/eoc/cco/bw/src/bw.c b/cesar/cp/eoc/cco/bw/src/bw.c
new file mode 100644
index 0000000000..a858521474
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/src/bw.c
@@ -0,0 +1,174 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/bw/src/bw.c
+ * \brief Create the alloctions for beacon period and create CCo schedule
+ * \ingroup cp_eoc_cco_bw
+ *
+*/
+#include "common/std.h"
+
+/* Private headers. */
+#include "cp/inc/context.h"
+#include "cp/cco/bw/inc/context.h"
+#include "cp/eoc/cco/bw/inc/bw.h"
+
+/* Public headers. */
+#include "cp/eoc/cco/bw/bw.h"
+#include "cp/eoc/cco/bw/service.h"
+#include "cp/cco/bw/bw.h"
+#include "cp/sta/mgr/sta.h"
+
+static uint cp_eoc_cco_bw_csma_duration = MAC_US_TO_TCK (4300);
+static uint cp_eoc_cco_bw_central_tck = MIN_SPC_CENTRAL_TCK;
+
+void
+cp_eoc_cco_bw_allocations_adjust (cp_t *ctx, bool adjust)
+{
+ dbg_assert (ctx);
+ if (!adjust)
+ {
+ cp_eoc_cco_bw_csma_duration = MIN_CSMA_EOC_TCK;
+ cp_eoc_cco_bw_central_tck = MIN_SPC_CENTRAL_TCK;
+ }
+ else
+ {
+ cp_eoc_cco_bw_csma_duration = MAC_MS_TO_TCK (7);
+ cp_eoc_cco_bw_central_tck = MAC_MS_TO_TCK (2);
+ }
+ dbg_assert ((cp_eoc_cco_bw_csma_duration - cp_eoc_cco_bw_central_tck)
+ >= MAC_MS_TO_TCK (3));
+}
+
+/**
+ * Create schedule bentry to be transmitted in EOC beacon
+ * \param ctx the module context
+ */
+void
+cp_eoc_cco_bw_bp_allocations (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ cp_cco_bw_alloc_t *alloc;
+ static bool startup_period = true;
+ static bool update_end_date = true;
+ static u32 startup_date_end;
+ if (update_end_date)
+ {
+#if MODULE_INCLUDED (hal_phy_maximus)
+ startup_date_end = phy_date () + MAC_MS_TO_TCK (3000);
+#else
+ startup_date_end = phy_date () + CP_EOC_CCO_STARTUP_PERIOD;
+#endif
+ update_end_date = false;
+ }
+
+ if (startup_period && !less_mod2p32 (phy_date (), startup_date_end))
+ startup_period = false;
+
+ cp_cco_bw_alloc_clean (ctx, &ctx->bw.alloc_list);
+
+ alloc = cp_cco_bw_alloc_init (ctx);
+ alloc->stpf = false;
+ alloc->glid = MAC_LID_SPC_CENTRAL;
+ alloc->end_time_atu = MAC_TCK_TO_ATU(cp_eoc_cco_bw_central_tck);
+ alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
+ cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
+ slab_release (alloc);
+
+ alloc = cp_cco_bw_alloc_init (ctx);
+ alloc->stpf = false;
+ alloc->glid = MAC_LID_LOCAL_CSMA;
+ if (startup_period)
+ {
+ alloc->end_time_atu = MAC_TCK_TO_ATU(CP_EOC_CSMA_STARTUP_PERIOD);
+ }
+ else
+ {
+ alloc->end_time_atu = MAC_TCK_TO_ATU(cp_eoc_cco_bw_csma_duration);
+ }
+ alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
+ cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
+ slab_release (alloc);
+
+ alloc = cp_cco_bw_alloc_init (ctx);
+ alloc->stpf = false;
+ alloc->glid = MAC_LID_CFPI;
+ alloc->end_time_atu = MAC_TCK_TO_ATU(BSU_ACLF_BP_CABLE_TCK);
+ alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
+ cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
+ slab_release (alloc);
+}
+
+/** Create allocations at CCo startup or for station that has missed some
+ * beacons
+ * \param ctx module context
+ */
+void
+cp_eoc_cco_bw_sta_allocations (cp_t *ctx)
+{
+ cp_cco_bw_alloc_t *alloc;
+ dbg_assert (ctx);
+
+ cp_cco_bw_alloc_clean (ctx, &ctx->bw.alloc_list);
+
+ alloc = cp_cco_bw_alloc_init (ctx);
+ alloc->stpf = false;
+ alloc->glid = MAC_LID_SPC_CENTRAL;
+ alloc->end_time_atu = MAC_TCK_TO_ATU(BSU_ACLF_BP_CABLE_TCK);
+ alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
+ cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
+ slab_release (alloc);
+}
+
+#if CONFIG_CP_EOC_IS_MASTER
+void
+cp_eoc_cco_bw_sched_init (cp_t * ctx)
+{
+ dbg_assert (ctx);
+ cp_eoc_cco_services_init (ctx);
+}
+
+void
+cp_eoc_cco_bw_scheduler (cp_t *ctx)
+{
+ sta_t *sta = NULL;
+ uint i;
+
+ dbg_assert ((sizeof (sta->poll_off) * 8) > CP_EOC_CCO_RELEASE_LIMIT);
+
+ for (i = MAC_TEI_STA_MIN_EOC; i < MAC_TEI_STA_MAX; i++)
+ {
+ sta = mac_store_sta_get (ctx->mac_store, i);
+ if (sta)
+ {
+ /* Manage stations not replying to poll. */
+ if (sta->poll_off & 1)
+ sta->poll_off <<= 1;
+ else
+ sta->poll_off = 0;
+
+ if (sta->poll_off & (1 << CP_EOC_CCO_RELEASE_LIMIT))
+ {
+ sta->tdma_poll = false;
+ sta->poll_off = 0;
+ ca_sta_update (ctx->ca, sta);
+ }
+ /* Release previously polled stations. */
+ blk_release (sta);
+ }
+ }
+}
+
+void
+cp_eoc_cco_bw_sched_uninit (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ cp_eoc_cco_services_uninit (ctx);
+}
+
+#endif /* CONFIG_CP_EOC_IS_MASTER */