summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
authorschodet2010-05-11 15:22:06 +0000
committerschodet2010-05-11 15:22:06 +0000
commit661056e685f0edf486efeebca721d394ebf883e9 (patch)
tree2d6d58e3b7bd189d92e447701ae2bc76357920bc /cesar
parent36a76e8a1f3c0ce561a28196bdde3e1de74e4296 (diff)
cesar/mac/pbproc: handle RX pool shortage, closes #335
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@7010 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar')
-rw-r--r--cesar/mac/pbproc/inc/context.h2
-rw-r--r--cesar/mac/pbproc/src/fsm_rx_beacon.c11
-rw-r--r--cesar/mac/pbproc/src/fsm_rx_data.c9
-rw-r--r--cesar/mac/pbproc/src/fsm_rx_sound.c18
-rw-r--r--cesar/mac/pbproc/src/pbproc.c1
-rw-r--r--cesar/mac/pbproc/test/pbproc/src/rx_data.c34
-rw-r--r--cesar/mac/pbproc/test/pbproc/src/rx_sound.c43
-rw-r--r--cesar/mac/pbproc/test/pbproc/src/test_pbproc.c1
8 files changed, 87 insertions, 32 deletions
diff --git a/cesar/mac/pbproc/inc/context.h b/cesar/mac/pbproc/inc/context.h
index 0f199457dd..c7889e49e2 100644
--- a/cesar/mac/pbproc/inc/context.h
+++ b/cesar/mac/pbproc/inc/context.h
@@ -149,6 +149,8 @@ struct pbproc_stat_t
uint aifs;
/** RX: out of an allocation or too near AIFS. */
uint rx_out_of_alloc;
+ /** RX: no enough PB in pool. */
+ uint rx_pool_shortage;
/** RX: handle FC. */
uint rx_handle_fc;
/** RX: beacon. */
diff --git a/cesar/mac/pbproc/src/fsm_rx_beacon.c b/cesar/mac/pbproc/src/fsm_rx_beacon.c
index e577febb3d..a050160980 100644
--- a/cesar/mac/pbproc/src/fsm_rx_beacon.c
+++ b/cesar/mac/pbproc/src/fsm_rx_beacon.c
@@ -45,11 +45,15 @@ pbproc_frbe__handle (pbproc_t *ctx, u32 rx_date,
+ MAC_PAYLOAD_TCK (symb_nb, MAC_DX567_TCK)
+ MAC_B2BIFS_TCK;
ctx->recv_mpdu.ack_date = rx_date + flp_tck;
- /* Ignore frames ending after the allocation. */
- if (less_mod2p32 (ctx->alloc.end_date, ctx->recv_mpdu.ack_date))
+ /* Ignore frames ending after the allocation, handle pool exhaustion. */
+ if (less_mod2p32 (ctx->alloc.end_date, ctx->recv_mpdu.ack_date)
+ || ctx->rx_pool_size < 1)
{
/* Ignore. */
- ctx->stats.rx_out_of_alloc++;
+ if (ctx->rx_pool_size < 1)
+ ctx->stats.rx_pool_shortage++;
+ else
+ ctx->stats.rx_out_of_alloc++;
phy_rx_prepare_short (ctx->phy);
ca_access_vcs_restart (ctx->ca, ctx->recv_mpdu.ack_date, 0,
PBPROC_ANTICIP_TCK, false);
@@ -61,7 +65,6 @@ pbproc_frbe__handle (pbproc_t *ctx, u32 rx_date,
PHY_MOD_MINI_ROBO, PHY_FEC_RATE_1_2, PHY_PB_SIZE_136),
PHY_GIL_567, symb_nb, tm->tcc_halfit);
/* Program PB DMA. */
- dbg_assert (ctx->rx_pool_size >= 1);
phy_pbdma_start (ctx->phy, true, NULL, 1, 1, 1,
&ctx->rx_pool_head->phy_pb, NULL, true);
/* Save received beacon parameters. */
diff --git a/cesar/mac/pbproc/src/fsm_rx_data.c b/cesar/mac/pbproc/src/fsm_rx_data.c
index 44e1dba2ca..0fcf3197ff 100644
--- a/cesar/mac/pbproc/src/fsm_rx_data.c
+++ b/cesar/mac/pbproc/src/fsm_rx_data.c
@@ -217,6 +217,14 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
PBPROC_FC_SACKI_UNIFORM_NEK_ERROR);
return;
}
+ /* Check for PB Pool shortage. */
+ if (ctx->rx_pool_size < 1 + ctx->chandata_nb + pb_nb)
+ {
+ ctx->stats.rx_pool_shortage++;
+ pbproc_frda_error (ctx, rx_date, sof, wack,
+ PBPROC_FC_SACKI_UNIFORM_ALL_ERROR);
+ return;
+ }
/* First thing to do: unblock the hardware. */
if (tmi >= PHY_MOD_ROBO_NB)
phy_set_tonemap (ctx->phy, tm->tmdma_desc_head);
@@ -247,7 +255,6 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
ctx->recv_mpdu.ack_date = rx_date + ctx->times.pre_fcs_tck + fl_tck;
ctx->recv_mpdu.drop = !nek_ok;
/* Keep a block to store received MPDU parameters. */
- dbg_assert (ctx->rx_pool_size >= 1 + ctx->chandata_nb + pb_nb);
pb_t *pool = ctx->rx_pool_head;
ctx->recv_mpdu.rx_desc = (pbproc_rx_desc_t *) pool;
pool = pool->next;
diff --git a/cesar/mac/pbproc/src/fsm_rx_sound.c b/cesar/mac/pbproc/src/fsm_rx_sound.c
index 0bd9ce1833..543dd1b60c 100644
--- a/cesar/mac/pbproc/src/fsm_rx_sound.c
+++ b/cesar/mac/pbproc/src/fsm_rx_sound.c
@@ -54,12 +54,17 @@ pbproc_frso__handle (pbproc_t *ctx, u32 rx_date,
/* Save early needed received MPDU parameters. */
ctx->recv_mpdu.mpdu_cnt = sound->mpdu_cnt;
ctx->recv_mpdu.ack_date = rx_date + ctx->times.pre_fcs_tck + fl_tck;
- /* Ignore frames ending after the allocation. */
- if (less_mod2p32 (ctx->alloc.end_date,
- rx_date + 2 * ctx->times.pre_fcs_tck + fl_tck
- + MAC_CIFS_TCK))
+ /* Ignore frames ending after the allocation, handle pool exhaustion. */
+ bool pool_shortage = ctx->rx_pool_size < 1 + ctx->chandata_nb;
+ if (pool_shortage
+ || less_mod2p32 (ctx->alloc.end_date,
+ rx_date + 2 * ctx->times.pre_fcs_tck + fl_tck
+ + MAC_CIFS_TCK))
{
- ctx->stats.rx_out_of_alloc++;
+ if (pool_shortage)
+ ctx->stats.rx_pool_shortage++;
+ else
+ ctx->stats.rx_out_of_alloc++;
/* Unblock hardware. */
phy_rx_prepare_short (ctx->phy);
/* Prepare for next. */
@@ -68,8 +73,7 @@ pbproc_frso__handle (pbproc_t *ctx, u32 rx_date,
return;
}
/* May skip channel data reception. */
- bool chandata = ctx->chandata_nb
- && ctx->rx_pool_size >= 1 + ctx->chandata_nb;
+ bool chandata = ctx->chandata_nb != 0;
/* Default to true to keep the sender to flood with SOUND frames. */
bool sound_complete = true;
if (chandata)
diff --git a/cesar/mac/pbproc/src/pbproc.c b/cesar/mac/pbproc/src/pbproc.c
index a19b7bcc19..18ae9b0e6b 100644
--- a/cesar/mac/pbproc/src/pbproc.c
+++ b/cesar/mac/pbproc/src/pbproc.c
@@ -150,6 +150,7 @@ pbproc_stats_init (pbproc_t *ctx)
PBPROC_STAT (cw_lost);
PBPROC_STAT (aifs);
PBPROC_STAT (rx_out_of_alloc);
+ PBPROC_STAT (rx_pool_shortage);
PBPROC_STAT (rx_handle_fc);
PBPROC_STAT (rx_beacon);
PBPROC_STAT (rx_data);
diff --git a/cesar/mac/pbproc/test/pbproc/src/rx_data.c b/cesar/mac/pbproc/test/pbproc/src/rx_data.c
index c2d89fabbc..52e894d988 100644
--- a/cesar/mac/pbproc/test/pbproc/src/rx_data.c
+++ b/cesar/mac/pbproc/test/pbproc/src/rx_data.c
@@ -832,6 +832,7 @@ enum rx_data_nfu_t
NFU_SOF_SNID,
NFU_SOF_TEI,
NFU_OUT_OF_ALLOC,
+ NFU_POOL_SHORTAGE,
};
typedef enum rx_data_nfu_t rx_data_nfu_t;
@@ -959,7 +960,6 @@ rx_data_nfu_test (test_t t, test_pbproc_t *tp, u32 date, rx_data_nfu_t nfu)
static void
rx_beacon_nfu_test (test_t t, test_pbproc_t *tp, rx_data_nfu_t nfu)
{
- dbg_assert (nfu == NFU_OUT_OF_ALLOC);
test_within (t);
/* Prepare FC. */
pbproc_fc_beacon_t beacon_fc = {
@@ -976,11 +976,15 @@ rx_beacon_nfu_test (test_t t, test_pbproc_t *tp, rx_data_nfu_t nfu)
.bto3_msb8 = 0x34,
.fccs_av = 0,
};
- /* Date to overshoot allocation. */
- u32 date = 0x80000000 - MAC_PREAMBLE_HYBRID_TCK / 2;;
+ u32 date = 12345;
+ if (nfu == NFU_OUT_OF_ALLOC)
+ /* Date to overshoot allocation. */
+ date = 0x80000000 - MAC_PREAMBLE_HYBRID_TCK / 2;
const uint pre_fc_fl_tck = MAC_PREAMBLE_HYBRID_TCK + MAC_FC_10_TCK
+ MAC_FC_AV_TCK + MAC_PAYLOAD_TCK (6, MAC_DX567_TCK)
+ MAC_B2BIFS_TCK;
+ if (nfu != NFU_POOL_SHORTAGE)
+ tp->pbproc->rx_pool_size = 1;
/* Use another state to test return to IDLE. */
tp->pbproc->fsm.current_state = PBPROC_FSM_STATE_RX_BURST;
/* Reset stats. */
@@ -1010,9 +1014,13 @@ rx_beacon_nfu_test (test_t t, test_pbproc_t *tp, rx_data_nfu_t nfu)
t, tp,
.rx_handle_fc = 1,
.rx_beacon = 1,
- .rx_out_of_alloc = 1);
+ .rx_out_of_alloc = nfu == NFU_OUT_OF_ALLOC ? 1 : 0,
+ .rx_pool_shortage = nfu == NFU_POOL_SHORTAGE ? 1 : 0);
/* Check PBProc state. */
test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+ test_fail_unless (tp->pbproc->rx_pool_size == (nfu != NFU_POOL_SHORTAGE
+ ? 1 : 0));
+ tp->pbproc->rx_pool_size = 0;
}
enum rx_data_sack_error_t
@@ -1024,6 +1032,7 @@ enum rx_data_sack_error_t
SACK_ERROR_ENC_STA_NO_NEK,
SACK_ERROR_ENC_NO_EKS,
SACK_ERROR_ENC_UNASSOCIATED,
+ SACK_ERROR_POOL_SHORTAGE,
WOACK_ERROR_TM,
WOACK_ERROR_ENC,
};
@@ -1043,6 +1052,7 @@ rx_data_sack_error_test (test_t t, test_pbproc_t *tp,
PBPROC_FC_SACKI_UNIFORM_NEK_ERROR,
PBPROC_FC_SACKI_UNIFORM_NEK_ERROR,
PBPROC_FC_SACKI_UNIFORM_NEK_ERROR,
+ PBPROC_FC_SACKI_UNIFORM_ALL_ERROR,
};
const uint fl_tck = MAC_PAYLOAD_TCK (45, MAC_DX417_TCK)
+ MAC_RIFS_DEFAULT_TCK;
@@ -1063,6 +1073,11 @@ rx_data_sack_error_test (test_t t, test_pbproc_t *tp,
tmi = 5;
eks = 0xf;
}
+ else if (sack_error == SACK_ERROR_POOL_SHORTAGE)
+ {
+ tmi = PHY_MOD_ROBO;
+ eks = 0xf;
+ }
else
{
tmi = PHY_MOD_ROBO;
@@ -1140,7 +1155,8 @@ rx_data_sack_error_test (test_t t, test_pbproc_t *tp,
.prp_lost = 1,
.rx_handle_fc = 1,
.rx_data = 1,
- .rx_data_error = 1);
+ .rx_data_error = 1,
+ .rx_pool_shortage = sack_error == SACK_ERROR_POOL_SHORTAGE ? 1 : 0);
/* Check SACK. */
if (wack)
{
@@ -1279,6 +1295,10 @@ rx_data_errors_test_case (test_t t)
rx_data_sack_error_test (t, &tp, SACK_ERROR_ENC_NO_EKS);
rx_data_sack_error_test (t, &tp, SACK_ERROR_ENC_UNASSOCIATED);
} test_end;
+ test_begin (t, "pool shortage")
+ {
+ rx_data_sack_error_test (t, &tp, SACK_ERROR_POOL_SHORTAGE);
+ } test_end;
test_begin (t, "woack error invalid tm")
{
rx_data_sack_error_test (t, &tp, WOACK_ERROR_TM);
@@ -1291,6 +1311,10 @@ rx_data_errors_test_case (test_t t)
{
rx_beacon_nfu_test (t, &tp, NFU_OUT_OF_ALLOC);
} test_end;
+ test_begin (t, "beacon nfu pool shortage")
+ {
+ rx_beacon_nfu_test (t, &tp, NFU_POOL_SHORTAGE);
+ } test_end;
test_pbproc_uninit (&tp);
}
diff --git a/cesar/mac/pbproc/test/pbproc/src/rx_sound.c b/cesar/mac/pbproc/test/pbproc/src/rx_sound.c
index edd8e5bcdd..1edc045744 100644
--- a/cesar/mac/pbproc/test/pbproc/src/rx_sound.c
+++ b/cesar/mac/pbproc/test/pbproc/src/rx_sound.c
@@ -224,20 +224,13 @@ rx_sound_basic_test_case (test_t t)
rx_sound_test (t, &tp, 123456, 0, 1, PHY_MOD_ROBO, 1, true);
rx_sound_test (t, &tp, 123456, 0, 1, PHY_MOD_MINI_ROBO, 1, true);
} test_end;
- test_begin (t, "no enough pool blocks")
- {
- rx_sound_test (t, &tp, 123456, 11, 5, PHY_MOD_ROBO, 0, true);
- } test_end;
- test_begin (t, "woack no enough pool blocks")
- {
- rx_sound_test (t, &tp, 123456, 6, 0, PHY_MOD_ROBO, 1, true);
- } test_end;
test_pbproc_uninit (&tp);
}
enum rx_sound_nfu_t
{
NFU_OUT_OF_ALLOC,
+ NFU_POOL_SHORTAGE,
};
typedef enum rx_sound_nfu_t rx_sound_nfu_t;
@@ -247,6 +240,15 @@ 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;
+ /* Prepare channel data configuration. */
+ const uint chandata_nb = 3;
+ u32 chandata_conf[chandata_nb];
+ uint i;
+ for (i = 0; i < chandata_nb; i++)
+ chandata_conf[i] = i;
+ pbproc_set_chandata_conf (tp->pbproc,
+ (phy_chandata_conf_t *) chandata_conf,
+ chandata_nb);
/* 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]
@@ -276,14 +278,15 @@ rx_sound_nfu_test (test_t t, test_pbproc_t *tp, u32 date, rx_sound_nfu_t nfu)
.reserved2 = 0,
.fccs_av = 0,
};
- dbg_assert (nfu == NFU_OUT_OF_ALLOC);
- date += 0x80000000;
+ if (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;
+ tp->pbproc->rx_pool_size = nfu != NFU_POOL_SHORTAGE ? 4 : 3;
test_pbproc_check_stats_reset (tp);
scenario_entry_t entries[] = {
SCENARIO_ACTION (phy_rx_fc, .rx_date = date, .prp_won = false,
@@ -305,12 +308,18 @@ rx_sound_nfu_test (test_t t, test_pbproc_t *tp, u32 date, rx_sound_nfu_t nfu)
.tp = tp,
};
scenario_run (t, entries, &globals);
- test_pbproc_check_stats (t, tp,
- .prp_lost = 1,
- .rx_handle_fc = 1,
- .rx_sound = 1,
- .rx_out_of_alloc = 1);
+ test_pbproc_check_stats (
+ t, tp,
+ .prp_lost = 1,
+ .rx_handle_fc = 1,
+ .rx_sound = 1,
+ .rx_out_of_alloc = nfu == NFU_OUT_OF_ALLOC ? 1 : 0,
+ .rx_pool_shortage = nfu == NFU_POOL_SHORTAGE ? 1 : 0);
test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+ test_fail_unless (tp->pbproc->rx_pool_size == (nfu != NFU_POOL_SHORTAGE
+ ? 4 : 3));
+ tp->pbproc->rx_pool_size = 0;
+ pbproc_set_chandata_conf (tp->pbproc, NULL, 0);
}
void
@@ -323,6 +332,10 @@ rx_sound_error_test_case (test_t t)
{
rx_sound_nfu_test (t, &tp, 123456, NFU_OUT_OF_ALLOC);
} test_end;
+ test_begin (t, "nfu pool shortage")
+ {
+ rx_sound_nfu_test (t, &tp, 123456, NFU_POOL_SHORTAGE);
+ } test_end;
test_pbproc_uninit (&tp);
}
diff --git a/cesar/mac/pbproc/test/pbproc/src/test_pbproc.c b/cesar/mac/pbproc/test/pbproc/src/test_pbproc.c
index f3fd74d873..905e066c0c 100644
--- a/cesar/mac/pbproc/test/pbproc/src/test_pbproc.c
+++ b/cesar/mac/pbproc/test/pbproc/src/test_pbproc.c
@@ -137,6 +137,7 @@ test_pbproc_check_stats_ (test_t t, test_pbproc_t *ctx,
TEST_PBPROC_CHECK_STAT(cw_lost);
TEST_PBPROC_CHECK_STAT(aifs);
TEST_PBPROC_CHECK_STAT(rx_out_of_alloc);
+ TEST_PBPROC_CHECK_STAT(rx_pool_shortage);
TEST_PBPROC_CHECK_STAT(rx_handle_fc);
TEST_PBPROC_CHECK_STAT(rx_beacon);
TEST_PBPROC_CHECK_STAT(rx_data);