summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
authorschodet2009-12-01 15:15:48 +0000
committerschodet2009-12-01 15:15:48 +0000
commitf43123c6a94c49c3dfbedfd5906306151b48558a (patch)
tree6f09aab8204c37a07aa262049f495acf0422eb6e /cesar
parent20d3445b4bd7e1120b73e96b525ed5a61d8ea073 (diff)
cesar/mac/pbproc: ignore out of alloc SOUND frames, closes #839
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@6503 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar')
-rw-r--r--cesar/mac/pbproc/src/fsm_rx_sound.c43
-rw-r--r--cesar/mac/pbproc/test/pbproc/src/rx_sound.c86
2 files changed, 121 insertions, 8 deletions
diff --git a/cesar/mac/pbproc/src/fsm_rx_sound.c b/cesar/mac/pbproc/src/fsm_rx_sound.c
index 90822674e9..b3778ef721 100644
--- a/cesar/mac/pbproc/src/fsm_rx_sound.c
+++ b/cesar/mac/pbproc/src/fsm_rx_sound.c
@@ -18,6 +18,13 @@
#include "hal/phy/pbdma.h"
+/**
+ * Restart VCS for next MPDU and go to next state.
+ * \param ctx pbproc context
+ */
+static void
+pbproc_frso_next (pbproc_t *ctx);
+
void
pbproc_frso_init (pbproc_t *ctx)
{
@@ -43,12 +50,25 @@ pbproc_frso__handle (pbproc_t *ctx, u32 rx_date,
uint bits_per_pb = tm->bits_per_pb[pb_size];
uint symb_nb = (1 * bits_per_pb + tm->bits_per_symbol - 1) /
tm->bits_per_symbol;
+ /* Save early needed received MPDU parameters. */
+ ctx->recv_mpdu.mpdu_cnt = sound->mpdu_cnt;
+ ctx->recv_mpdu.ack_date = rx_date + ctx->times[hybrid].pre_fcs_tck
+ + fl_tck;
+ /* Ignore frames ending after the allocation. */
+ if (less_mod2p32 (ctx->alloc.end_date,
+ rx_date + 2 * ctx->times[hybrid].pre_fcs_tck + fl_tck
+ + MAC_CIFS_TCK))
+ {
+ /* Unblock hardware. */
+ phy_rx_prepare_short (ctx->phy);
+ /* Prepare for next. */
+ pbproc_frso_next (ctx);
+ /* Stop now. */
+ return;
+ }
/* May skip channel data reception. */
bool chandata = ctx->chandata_nb
- && ctx->rx_pool_size >= 1 + ctx->chandata_nb
- && !less_mod2p32 (ctx->alloc.end_date,
- rx_date + 2 * ctx->times[hybrid].pre_fcs_tck
- + fl_tck + MAC_CIFS_TCK);
+ && ctx->rx_pool_size >= 1 + ctx->chandata_nb;
if (chandata)
{
/* Unblock hardware. */
@@ -57,7 +77,7 @@ pbproc_frso__handle (pbproc_t *ctx, u32 rx_date,
}
else
{
- /* Ignore frame. */
+ /* Skip frame. */
phy_rx_prepare_short (ctx->phy);
}
/* Is sound completed? */
@@ -93,9 +113,6 @@ pbproc_frso__handle (pbproc_t *ctx, u32 rx_date,
ctx->recv_mpdu.rx_params.sound_req_tm = sound->req_tm;
ctx->recv_mpdu.rx_params.sound_complete = sound_complete;
ctx->recv_mpdu.pb_nb = 0;
- ctx->recv_mpdu.mpdu_cnt = sound->mpdu_cnt;
- ctx->recv_mpdu.ack_date = rx_date + ctx->times[hybrid].pre_fcs_tck
- + fl_tck;
/* Keep a block to store received MPDU parameters. */
dbg_assert (ctx->rx_pool_size >= 1);
pb_t *last = ctx->rx_pool_head;
@@ -183,6 +200,15 @@ pbproc_frso__rx_sound__pbdma (pbproc_t *ctx)
pbproc_fsm_schedule_deferred (ctx);
dbg_invalid_ptr (ctx->recv_mpdu.chandata_head);
/* Prepare for next. */
+ pbproc_frso_next (ctx);
+}
+
+static void ARCH_ILRAM
+pbproc_frso_next (pbproc_t *ctx)
+{
+ dbg_claim (ctx);
+ const bool hybrid = ctx->alloc.hybrid;
+ /* Restart VCS. */
if (ctx->recv_mpdu.mpdu_cnt == 0)
{
ca_access_vcs_restart (ctx->ca, ctx->recv_mpdu.ack_date,
@@ -196,6 +222,7 @@ pbproc_frso__rx_sound__pbdma (pbproc_t *ctx)
PBPROC_ANTICIP_TCK, true);
phy_rx_activate (ctx->phy, false, ctx->recv_mpdu.ack_date, true);
}
+ /* Return to IDLE. */
pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
}
diff --git a/cesar/mac/pbproc/test/pbproc/src/rx_sound.c b/cesar/mac/pbproc/test/pbproc/src/rx_sound.c
index 9fb7074efa..ce8f646314 100644
--- a/cesar/mac/pbproc/test/pbproc/src/rx_sound.c
+++ b/cesar/mac/pbproc/test/pbproc/src/rx_sound.c
@@ -225,11 +225,97 @@ rx_sound_basic_test_case (test_t t)
test_pbproc_uninit (&tp);
}
+enum rx_sound_nfu_t
+{
+ NFU_OUT_OF_ALLOC,
+};
+typedef enum rx_sound_nfu_t rx_sound_nfu_t;
+
+void
+rx_sound_nfu_test (test_t t, test_pbproc_t *tp, u32 date, rx_sound_nfu_t nfu)
+{
+ test_within (t);
+ u32 restart_date;
+ uint length_tck;
+ /* Compute frame size. */
+ tonemap_t *tm = &tp->config.tonemask_info.tonemap_robo[PHY_MOD_ROBO];
+ uint symb_nb = (1 * tm->bits_per_pb[PHY_PB_SIZE_520]
+ + tm->bits_per_symbol - 1) / tm->bits_per_symbol;
+ const uint fl_tck = MAC_PAYLOAD_TCK (symb_nb, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK;
+ /* Prepare FC. */
+ pbproc_fc_sound_t sound_fc = {
+ .dt_av = PBPROC_FC_DT_SOUND,
+ .access = false,
+ .snid = tp->snid,
+ .stei = 2,
+ .dtei = tp->config.tei,
+ .lid = 1,
+ .cfs = false,
+ .pbsz = false,
+ .bdf = true,
+ .saf = false,
+ .scf = false,
+ .req_tm = 7,
+ .fl_av = MAC_TCK_TO_FL (fl_tck),
+ .mpdu_cnt = 0,
+ .reserved0 = 0,
+ .ppb = 42,
+ .src = TONEMAP_SRC_INITIAL,
+ .reserved1 = 0,
+ .reserved2 = 0,
+ .fccs_av = 0,
+ };
+ dbg_assert (nfu == NFU_OUT_OF_ALLOC);
+ date += 0x80000000;
+ length_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_FL_TO_TCK (MAC_TCK_TO_FL (fl_tck))
+ + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK;
+ restart_date = date + length_tck - MAC_PREAMBLE_TCK - MAC_FC_AV_TCK
+ - MAC_CIFS_TCK;
+ length_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK;
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date, .prp_won = false,
+ .slot_count = 2,
+ .fc_av = PARENT_OF (pbproc_fc_t, sound,
+ &sound_fc)->words),
+ SCENARIO_EVENT (ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare, .short_ppdu = true),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .start_date = restart_date,
+ .length_tck = length_tck,
+ .anticipation_tck = PBPROC_ANTICIP_TCK,
+ .eifs = false),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+}
+
+void
+rx_sound_error_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "error");
+ test_pbproc_init (&tp);
+ test_begin (t, "nfu out of alloc")
+ {
+ rx_sound_nfu_test (t, &tp, 123456, NFU_OUT_OF_ALLOC);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
void
rx_sound_test_suite (test_t t)
{
test_suite_begin (t, "rx sound");
rx_sound_basic_test_case (t);
+ rx_sound_error_test_case (t);
test_case_begin (t, "memory");
test_begin (t, "memory")
{