summaryrefslogtreecommitdiff
path: root/cesar/mac/pbproc/src/fsm_tx_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/mac/pbproc/src/fsm_tx_data.c')
-rw-r--r--cesar/mac/pbproc/src/fsm_tx_data.c251
1 files changed, 251 insertions, 0 deletions
diff --git a/cesar/mac/pbproc/src/fsm_tx_data.c b/cesar/mac/pbproc/src/fsm_tx_data.c
new file mode 100644
index 0000000000..88cb27662f
--- /dev/null
+++ b/cesar/mac/pbproc/src/fsm_tx_data.c
@@ -0,0 +1,251 @@
+/* Maria project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file mac/pbproc/src/fsm_tx_data.c
+ * \brief FSM TX data part.
+ * \ingroup mac_pbproc
+ */
+#include "common/std.h"
+
+#include "inc/context.h"
+#include "inc/fc.h"
+
+#include "inc/fsm_top.h"
+#include "inc/fsm_handle_fc.h"
+#include "inc/prep_mpdu.h"
+
+#include "inc/fsm_tx_data.h"
+
+void
+pbproc_ftda_init (pbproc_t *ctx)
+{
+ dbg_assert (ctx);
+ ctx->fsm.states[PBPROC_FSM_STATE_TX_WAIT_ACCESS_CONF].rx_fc_cb =
+ pbproc_ftda__tx_wait_access_conf__rx_fc;
+ ctx->fsm.states[PBPROC_FSM_STATE_TX_WAIT_ACCESS_CONF].access_cb =
+ pbproc_ftda__tx_wait_access_conf__access;
+ ctx->fsm.states[PBPROC_FSM_STATE_TX_WAIT_ACCESS_CONF].access_conf_cb =
+ pbproc_ftda__tx_wait_access_conf__access_conf;
+ ctx->fsm.states[PBPROC_FSM_STATE_TX_WAIT_SACKD].rx_fc_cb =
+ pbproc_ftda__tx_wait_sackd__rx_fc;
+ ctx->fsm.states[PBPROC_FSM_STATE_TX_WAIT_SACKD].access_cb =
+ pbproc_ftda__tx_wait_sackd__access;
+ ctx->fsm.states[PBPROC_FSM_STATE_TX_WAIT_TX_END].access_cb =
+ pbproc_ftda__tx_wait_tx_end__access;
+ ctx->fsm.states[PBPROC_FSM_STATE_TX_BURST].access_cb =
+ pbproc_ftda__tx_burst__access;
+}
+
+void
+pbproc_ftda__handle (pbproc_t *ctx)
+{
+ dbg_assert (ctx);
+ if (PHY_FC_MODE_IS_HYBRID (ctx->prep_mpdu.fc_mode))
+ phy_tx_fc10 (ctx->phy, ctx->prep_mpdu.fc_10);
+ phy_pbdma_start (ctx->phy, ctx->prep_mpdu.bypass_aes, ctx->prep_mpdu.iv,
+ ctx->prep_mpdu.nek, ctx->prep_mpdu.pb_nb_total,
+ ctx->prep_mpdu.main_seg_nb, 0,
+ &ctx->prep_mpdu.head->phy_pb);
+ if (ctx->prep_mpdu.mod == PHY_MOD_TM)
+ phy_set_tonemap (ctx->phy, 0, ctx->prep_mpdu.tonemap);
+ phy_tx_param (ctx->phy, ctx->prep_mpdu.fc_mode, false, ctx->prep_mpdu.mod,
+ ctx->prep_mpdu.fecrate, ctx->prep_mpdu.pb_size,
+ ctx->prep_mpdu.gil, 0);
+ bool content = !ctx->access.cfp && !ctx->prep_mpdu.rts_cts;
+ phy_tx_frame (ctx->phy, ctx->prep_mpdu.tx_date, true, content,
+ ctx->prep_mpdu.fc_av.words);
+ if (content)
+ {
+ ca_access_vcs_restart (ctx->ca, ctx->prep_mpdu.tx_date,
+ ctx->times[ctx->access.hybrid].eifs_tck,
+ PBPROC_ANTICIP_TCK, true);
+ }
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_TX_WAIT_ACCESS_CONF);
+}
+
+void
+pbproc_ftda__tx_wait_access_conf__rx_fc (pbproc_t *ctx, u32 rx_date,
+ const pbproc_fc_t *fc_av)
+{
+ dbg_assert (ctx);
+ /* Update backoff. */
+ if (phy_access_backoff_prp_won (ctx->phy))
+ {
+ ca_backoff_deferred (ctx->ca,
+ phy_access_backoff_slot_count (ctx->phy) - 2);
+ ctx->stats.cw_lost++;
+ }
+ else
+ {
+ ca_backoff_cancel (ctx->ca);
+ ctx->stats.prp_lost++;
+ }
+ /* Handle FC. */
+ pbproc_fhfc_handle_fc (ctx, rx_date, fc_av);
+ /* Now, we have time, cancel transmission. */
+ pbproc_prep_mpdu_cancel (ctx);
+}
+
+void
+pbproc_ftda__tx_wait_access_conf__access (pbproc_t *ctx)
+{
+ dbg_assert (ctx);
+ pbproc_prep_mpdu_cancel (ctx);
+ dbg_assert (!phy_access_backoff_prp_won (ctx->phy));
+ pbproc_ftop__idle__access (ctx);
+}
+
+void
+pbproc_ftda__tx_wait_access_conf__access_conf (pbproc_t *ctx)
+{
+ dbg_assert (ctx);
+ pbproc_prep_mpdu_chain (ctx);
+ if (ctx->prep_mpdu.burst)
+ {
+ /* Burst. */
+ phy_pbdma_update (ctx->phy, ctx->prep_mpdu.main_seg_nb, 0);
+ ca_access_program (ctx->ca, ctx->prep_mpdu.tx_date +
+ ctx->prep_mpdu.flp_tck, PBPROC_ANTICIP_TCK);
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_TX_BURST);
+ }
+ else
+ {
+ if (ctx->prep_mpdu.wack)
+ {
+ /* With ACK. */
+ phy_pbdma_update (ctx->phy, ctx->prep_mpdu.main_seg_nb, 0);
+ ca_backoff_deferred (ctx->ca,
+ phy_access_backoff_slot_count (ctx->phy)
+ - 2);
+ ca_access_vcs_restart (ctx->ca, ctx->prep_mpdu.tx_date
+ + ctx->prep_mpdu.flp_tck,
+ ctx->times[ctx->access.hybrid].eifs_tck,
+ PBPROC_ANTICIP_TCK, true);
+ phy_rx_activate (ctx->phy, false, ctx->prep_mpdu.tx_date
+ + ctx->prep_mpdu.flp_tck, true);
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_TX_WAIT_SACKD);
+ }
+ else
+ {
+ /* Without ACK. */
+ phy_pbdma_update (ctx->phy, ctx->prep_mpdu.main_seg_nb,
+ ctx->prep_mpdu.pb_nb_total);
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_TX_WAIT_TX_END);
+ }
+ }
+}
+
+void
+pbproc_ftda__tx_wait_sackd__rx_fc (pbproc_t *ctx, u32 rx_date,
+ const pbproc_fc_t *fc_av)
+{
+ pbproc_times_t *times;
+ dbg_assert (ctx);
+ times = &ctx->times[ctx->access.hybrid];
+ pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
+ /* Is it our SACK. */
+ if (fc_av
+ && fc_av->generic.dt_av == PBPROC_FC_DT_SACK
+ && fc_av->generic.access == false
+ && fc_av->generic.snid == ctx->config->snid
+ && fc_av->sack.dtei == ctx->config->tei
+ && less_mod2p32 (rx_date, ctx->prep_mpdu.tx_date
+ + ctx->prep_mpdu.flp_tck + MAC_TOLERANCE_TCK))
+ {
+ phy_rx_prepare_short (ctx->phy);
+ /* Handle SACKD. */
+ if (fc_av->sack.sackt0 == PBPROC_FC_SACKT_MIXED)
+ {
+ pbproc_prep_mpdu_ack_bitmap (
+ ctx, fc_av->sack.sacki, 0, PBPROC_FC_SACK_SACKI_BITS
+ - (MAC_LID_IS_PLID (prep->main_mfs->common.lid) ? 4 : 0));
+ }
+ else if (fc_av->sack.sackt0 == PBPROC_FC_SACKT_MIXED_COMPRESSED)
+ {
+ u32 si[3];
+ si[0] = fc_av->sack.sacki[0];
+ si[1] = fc_av->sack.sacki[1];
+ si[2] = fc_av->sack.sacki_last;
+ pbproc_prep_mpdu_ack_encoded (
+ ctx, si, PBPROC_FC_SACK_SACKI_BITS
+ - (MAC_LID_IS_PLID (prep->main_mfs->common.lid) ? 4 : 0));
+ }
+ else if (fc_av->sack.sackt0 == PBPROC_FC_SACKT_NOT_RECEIVED)
+ {
+ pbproc_prep_mpdu_cancel (ctx);
+ }
+ else
+ {
+ uint sacki = fc_av->sack.sacki[0] & 0xf;
+ if (sacki == PBPROC_FC_SACKI_UNIFORM_ALL_OK)
+ pbproc_prep_mpdu_ack_all (ctx);
+ else
+ pbproc_prep_mpdu_cancel (ctx);
+ }
+ /* Next. */
+ if (!ctx->access.cfp)
+ {
+ ca_backoff_success (ctx->ca);
+ ca_access_vcs_restart (ctx->ca, rx_date,
+ times->pre_fcs_tck + MAC_CIFS_TCK,
+ PBPROC_ANTICIP_TCK, false);
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
+ }
+ else
+ {
+ //handle_access ();
+ }
+ }
+ else
+ {
+ /* Not our SACK, may contain our SACKD. */
+#if 0
+ if (our sackd)
+ {
+ if (ctx->access.content)
+ ca_backoff_success (ctx->ca);
+ }
+ else
+#endif
+ {
+ pbproc_prep_mpdu_cancel (ctx);
+ ctx->stats.data_fail++;
+ }
+ pbproc_fhfc_handle_fc (ctx, rx_date, fc_av);
+ }
+}
+
+void
+pbproc_ftda__tx_wait_sackd__access (pbproc_t *ctx)
+{
+ dbg_assert (ctx);
+ pbproc_prep_mpdu_cancel (ctx);
+ ctx->stats.data_fail++;
+ pbproc_ftop__idle__access (ctx);
+}
+
+void
+pbproc_ftda__tx_wait_tx_end__access (pbproc_t *ctx)
+{
+ dbg_assert (ctx);
+ pbproc_prep_mpdu_ack_all (ctx);
+ ca_backoff_success (ctx->ca);
+ ca_access_vcs_restart (ctx->ca, ctx->prep_mpdu.tx_date
+ + ctx->prep_mpdu.flp_tck,
+ 0, PBPROC_ANTICIP_TCK, false);
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
+}
+
+void
+pbproc_ftda__tx_burst__access (pbproc_t *ctx)
+{
+ dbg_assert (ctx);
+ // TODO pbproc_prep_mpdu_burst_next (ctx);
+ pbproc_ftda__handle (ctx);
+}
+