summaryrefslogtreecommitdiff
path: root/cesar/mac/sar
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/mac/sar')
-rw-r--r--cesar/mac/sar/src/expiration.c36
-rw-r--r--cesar/mac/sar/src/tx.c4
-rw-r--r--cesar/mac/sar/test/utest/host/src/expiration.c35
-rw-r--r--cesar/mac/sar/test/utest/host/src/segmentation.c43
4 files changed, 110 insertions, 8 deletions
diff --git a/cesar/mac/sar/src/expiration.c b/cesar/mac/sar/src/expiration.c
index abe5f5c2bb..c01a66f629 100644
--- a/cesar/mac/sar/src/expiration.c
+++ b/cesar/mac/sar/src/expiration.c
@@ -159,20 +159,39 @@ sar_expiration_mfs_rx (sar_t *ctx, mfs_rx_t *mfs)
sar_expiration_mfs_purge_rx (ctx, mfs, now);
}
+/** Context used for expiration MFS travel. */
+struct sar_expiration_mfs_t
+{
+ /** SAR context. */
+ sar_t *sar;
+ /** Number of active MFS. */
+ int active;
+};
+typedef struct sar_expiration_mfs_t sar_expiration_mfs_t;
+
/**
* Clean a MFS.
* \param mac_store the mac store.
* \param mfs the MFS concerned.
- * \param ctx the callback context.
+ * \param user the callback context.
*/
static void
-sar_expiration_mfs_found (mac_store_t *mac_store, mfs_t *mfs, void *ctx)
+sar_expiration_mfs_found (mac_store_t *mac_store, mfs_t *mfs, void *user)
{
+ sar_expiration_mfs_t *cbctx = user;
arch_dsr_lock ();
if (mfs->common.tx)
- sar_expiration_mfs_tx (ctx, &mfs->tx);
+ {
+ sar_expiration_mfs_tx (cbctx->sar, &mfs->tx);
+ if (mfs->tx.head && !mfs->tx.beacon)
+ cbctx->active++;
+ }
else
- sar_expiration_mfs_rx (ctx, &mfs->rx);
+ {
+ sar_expiration_mfs_rx (cbctx->sar, &mfs->rx);
+ if (mfs->rx.head)
+ cbctx->active++;
+ }
arch_dsr_unlock ();
}
@@ -180,7 +199,10 @@ void
sar_expiration_mfs (sar_t *ctx)
{
dbg_assert (ctx);
- mac_store_mfs_travel (ctx->mac_store,
- sar_expiration_mfs_found,
- ctx);
+ sar_expiration_mfs_t sar_expiration_mfs_ctx;
+ sar_expiration_mfs_ctx.sar = ctx;
+ sar_expiration_mfs_ctx.active = 0;
+ mac_store_mfs_travel (ctx->mac_store, sar_expiration_mfs_found,
+ &sar_expiration_mfs_ctx);
+ mfs_tx_max_seg_nb_update (sar_expiration_mfs_ctx.active);
}
diff --git a/cesar/mac/sar/src/tx.c b/cesar/mac/sar/src/tx.c
index 102022ecc3..00bb681552 100644
--- a/cesar/mac/sar/src/tx.c
+++ b/cesar/mac/sar/src/tx.c
@@ -317,8 +317,10 @@ sar_msdu_process (sar_t *ctx, u8 *buffer, u16 length, mfs_tx_t *mfs,
/* Check sequence. */
lib_seq_check_packet (&ctx->seq, buffer, length);
- /* Enough block available to send a frame and SAR is activated ? */
+ /* Enough block available to send a frame, enough room in MFS, and SAR is
+ * activated? */
if (ctx->activate
+ && mfs->seg_nb < mfs_tx_max_seg_nb
&& (blk_slack () || mfs->seg_nb <= MAC_SAR_EM_MAX_PB_ALLOWED))
{
if (mfs->fsm_state == MFS_FSM_CMD_RELEASE)
diff --git a/cesar/mac/sar/test/utest/host/src/expiration.c b/cesar/mac/sar/test/utest/host/src/expiration.c
index 7fd452e5e9..8711ddcf68 100644
--- a/cesar/mac/sar/test/utest/host/src/expiration.c
+++ b/cesar/mac/sar/test/utest/host/src/expiration.c
@@ -112,6 +112,41 @@ test_case_expiration (test_t test)
}
test_end;
sar_cleanup (t.sar);
+ /* Here constants in MFS limiting are unknown to this testing code.
+ * Behaviour will depend on MFS limit constants, code, and current blk
+ * allocator configuration. The test tries to mimic a typical behaviour
+ * but it might have to be changed if context is changed. */
+ test_begin (test, "MFS TX max seg nb update")
+ {
+ int limit, initial;
+ uint i;
+ mfs_tx_max_seg_nb_update (0);
+ initial = limit = mfs_tx_max_seg_nb;
+ phy_date = 0;
+ /* Expiration without MFS, limit should not change. */
+ sar_expiration_mfs (t.sar);
+ test_fail_unless (mfs_tx_max_seg_nb == initial);
+ /* Expiration with TX MFS, limit should be lower. */
+ for (i = 1; i <= COUNT (expiration_ntb); i++)
+ test_case_expiration__add (&t, i, 1, true, expiration_ntb[i - 1]);
+ sar_expiration_mfs (t.sar);
+ test_fail_unless (mfs_tx_max_seg_nb < limit);
+ limit = mfs_tx_max_seg_nb;
+ /* Expiration with RX MFS, limit should be even lower. */
+ for (i = 1; i <= COUNT (expiration_ntb); i++)
+ test_case_expiration__add (&t, i, 1, false, expiration_ntb[i - 1]);
+ sar_expiration_mfs (t.sar);
+ test_fail_unless (mfs_tx_max_seg_nb < limit);
+ /* Expire segments, empty MFS are not counted. */
+ phy_date = expiration_ntb[COUNT (expiration_ntb) - 1] + 10;
+ sar_expiration_mfs (t.sar);
+ test_fail_unless (mfs_tx_max_seg_nb == initial);
+ /* OK, cleanup, limit should return to initial value after
+ * expiration. */
+ sar_cleanup (t.sar);
+ sar_expiration_mfs (t.sar);
+ test_fail_unless (mfs_tx_max_seg_nb == initial);
+ } test_end;
sar_test_uninit (&t);
}
diff --git a/cesar/mac/sar/test/utest/host/src/segmentation.c b/cesar/mac/sar/test/utest/host/src/segmentation.c
index dfd0947f09..72f2b223c9 100644
--- a/cesar/mac/sar/test/utest/host/src/segmentation.c
+++ b/cesar/mac/sar/test/utest/host/src/segmentation.c
@@ -312,6 +312,48 @@ test_case_segmentation_em_max_pb_allowed (test_t test)
}
void
+test_case_segmentation_mfs_tx_max_seg_nb_test (test_t test, sar_test_t ctx,
+ mfs_tx_t *mfs)
+{
+ u8 *buffer = NULL;
+ test_within (test);
+ buffer = bufmgr_get (ctx.sar->bufmgr);
+ sar_msdu_process (ctx.sar, buffer, ETH_PACKET_MIN_SIZE_ALLOWED, mfs,
+ 0x0);
+ sar_bridge_dma_free_head (ctx.sar);
+ test_fail_unless (mfs->seg_nb == mfs_tx_max_seg_nb);
+ bufmgr_give_back (ctx.sar->bufmgr, buffer);
+}
+
+void
+test_case_segmentation_mfs_tx_max_seg_nb (test_t test)
+{
+ sar_test_t ctx;
+ bool added;
+ test_case_begin (test, "Test mfs_tx_max_seg_nb");
+ sar_test_init (&ctx, INVALID_PTR, INVALID_PTR);
+ mfs_tx_t *mfs = mac_store_mfs_add_tx (ctx.mac_store, false, false, 1,
+ 1, &added);
+ sar_activate (ctx.sar, true);
+ test_begin (test, "less than limit")
+ {
+ mfs->seg_nb = mfs_tx_max_seg_nb - 1;
+ test_case_segmentation_mfs_tx_max_seg_nb_test (test, ctx, mfs);
+ }
+ test_end;
+ test_begin (test, "more than limit")
+ {
+ mfs->seg_nb = mfs_tx_max_seg_nb;
+ test_case_segmentation_mfs_tx_max_seg_nb_test (test, ctx, mfs);
+ }
+ test_end;
+ sar_mfs_remove (ctx.sar, PARENT_OF (mfs_t, tx, mfs));
+ blk_release (mfs);
+ sar_sta_remove (ctx.sar, 1);
+ sar_test_uninit (&ctx);
+}
+
+void
test_suite_segmentation (test_t test)
{
test_suite_begin (test, "Segmentation");
@@ -320,6 +362,7 @@ test_suite_segmentation (test_t test)
test_case_segmentation (test);
test_case_segmentation_mfs_release (test);
test_case_segmentation_em_max_pb_allowed (test);
+ test_case_segmentation_mfs_tx_max_seg_nb (test);
test_begin (test, "Memory")
{