summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Schodet2011-03-22 11:07:48 +0100
committerNicolas Schodet2011-05-25 16:45:04 +0200
commit4135eb9d6c84d8ba662e520daa94e51dd43e098b (patch)
tree54d8fe8a798473c2e9e5d8d8798c8a6a218cedab
parent16dfa301d1b3c34c5fd6a40c09ac3253798ad174 (diff)
cesar/mac/pbproc: handle burst acknowledgement, refs #362
-rw-r--r--cesar/mac/pbproc/inc/prep_mpdu.h52
-rw-r--r--cesar/mac/pbproc/src/fsm_top.c2
-rw-r--r--cesar/mac/pbproc/src/fsm_tx_data.c10
-rw-r--r--cesar/mac/pbproc/src/prep_mpdu.c199
-rw-r--r--cesar/mac/pbproc/test/pbproc/src/prep_mpdu.c22
5 files changed, 200 insertions, 85 deletions
diff --git a/cesar/mac/pbproc/inc/prep_mpdu.h b/cesar/mac/pbproc/inc/prep_mpdu.h
index 7295fe8b98..2224f54fa2 100644
--- a/cesar/mac/pbproc/inc/prep_mpdu.h
+++ b/cesar/mac/pbproc/inc/prep_mpdu.h
@@ -106,6 +106,12 @@ struct pbproc_prep_mpdu_t
/** Pointer to current MPDU data, should be synchronised with
* mpdu_count. */
pbproc_prep_mpdu_single_t *current;
+ /** First segment to be returned to main MFS. */
+ pb_t *main_commit_return_head;
+ /** Last segment to be returned to main MFS. */
+ pb_t *main_commit_return_tail;
+ /** Number of segments to be returned to main MFS. */
+ uint main_commit_return_seg_nb;
};
typedef struct pbproc_prep_mpdu_t pbproc_prep_mpdu_t;
@@ -142,42 +148,63 @@ void
pbproc_prep_mpdu_chain (pbproc_t *ctx);
/**
- * Cancel a MPDU preparation and repair MFS.
+ * Cancel a burst preparation and repair MFS.
* \param ctx pbproc context
*/
void
-pbproc_prep_mpdu_cancel (pbproc_t *ctx);
+pbproc_prep_mpdu_cancel_burst (pbproc_t *ctx);
+
+/**
+ * Cancel a MPDU preparation.
+ * \param ctx pbproc context
+ * \param mpdu_count MPDU index in burst
+ */
+void
+pbproc_prep_mpdu_cancel (pbproc_t *ctx, uint mpdu_count);
+
+/**
+ * Acknowledge every PB in burst.
+ * \param ctx pbproc context
+ */
+void
+pbproc_prep_mpdu_ack_all_burst (pbproc_t *ctx);
/**
* Acknowledge every PB.
* \param ctx pbproc context
+ * \param mpdu_count MPDU index in burst
*/
void
-pbproc_prep_mpdu_ack_all (pbproc_t *ctx);
+pbproc_prep_mpdu_ack_all (pbproc_t *ctx, uint mpdu_count);
/**
* Acknowledge a selection of PBs based on bitmap information.
* \param ctx pbproc context
+ * \param mpdu_count MPDU index in burst
* \param sacki_dec SACKI decompression context
*/
void
-pbproc_prep_mpdu_ack_bitmap (pbproc_t *ctx, pbproc_sacki_dec_t *sacki_dec);
+pbproc_prep_mpdu_ack_bitmap (pbproc_t *ctx, uint mpdu_count,
+ pbproc_sacki_dec_t *sacki_dec);
/**
* Acknowledge a selection of PBs based on compressed bitmap information.
* \param ctx pbproc context
+ * \param mpdu_count MPDU index in burst
* \param sacki_dec SACKI decompression context
*/
void
-pbproc_prep_mpdu_ack_encoded (pbproc_t *ctx, pbproc_sacki_dec_t *sacki_dec);
+pbproc_prep_mpdu_ack_encoded (pbproc_t *ctx, uint mpdu_count,
+ pbproc_sacki_dec_t *sacki_dec);
/**
* Uniform acknowledge.
* \param ctx pbproc context
+ * \param mpdu_count MPDU index in burst
* \param sacki SACKI uniform information
*/
void
-pbproc_prep_mpdu_ack_uniform (pbproc_t *ctx, uint sacki);
+pbproc_prep_mpdu_ack_uniform (pbproc_t *ctx, uint mpdu_count, uint sacki);
/**
* Handle acknowledge.
@@ -200,6 +227,19 @@ pbproc_prep_mpdu_fsm_response (pbproc_t *ctx, mfs_fsm_rsp_t mfs_rsp_data,
mfs_fsm_rsp_t mfs_rsp_mgmt);
/**
+ * Commit burst.
+ * \param ctx pbproc context
+ *
+ * Commit the whole access:
+ * - return unacknowledged segments to MFS.
+ * - commit FSM.
+ * - update MFS in CA.
+ * - clear prepared burst.
+ */
+void
+pbproc_prep_mpdu_commit_burst (pbproc_t *ctx);
+
+/**
* Acknowledge or cancel a SOUND frame.
* \param ctx pbproc context
* \param scf true if a acknowledgement has been received and SCF was set
diff --git a/cesar/mac/pbproc/src/fsm_top.c b/cesar/mac/pbproc/src/fsm_top.c
index 9221014b18..582d630528 100644
--- a/cesar/mac/pbproc/src/fsm_top.c
+++ b/cesar/mac/pbproc/src/fsm_top.c
@@ -157,7 +157,7 @@ pbproc_ftop__idle__access (pbproc_t *ctx)
if (ctx->prep_mpdu.sound_reason_code != TONEMAP_SRC_NULL)
pbproc_prep_mpdu_sound_ack (ctx, false);
else
- pbproc_prep_mpdu_cancel (ctx);
+ pbproc_prep_mpdu_cancel_burst (ctx);
ctx->stats.tx_late++;
}
/* Test if TX can be done. */
diff --git a/cesar/mac/pbproc/src/fsm_tx_data.c b/cesar/mac/pbproc/src/fsm_tx_data.c
index b96e94f237..cc83050f04 100644
--- a/cesar/mac/pbproc/src/fsm_tx_data.c
+++ b/cesar/mac/pbproc/src/fsm_tx_data.c
@@ -77,7 +77,7 @@ pbproc_ftda__tx_wait_access_conf__rx_fc (pbproc_t *ctx, u32 rx_date,
/* Handle FC. */
pbproc_fhfc_handle_fc (ctx, rx_date, fc_av);
/* Now, we have time, cancel transmission. */
- pbproc_prep_mpdu_cancel (ctx);
+ pbproc_prep_mpdu_cancel_burst (ctx);
ctx->stats.tx_data_cancel++;
}
@@ -85,7 +85,7 @@ void ARCH_ILRAM
pbproc_ftda__tx_wait_access_conf__access (pbproc_t *ctx)
{
dbg_claim (ctx);
- pbproc_prep_mpdu_cancel (ctx);
+ pbproc_prep_mpdu_cancel_burst (ctx);
pbproc_ftop__idle__access (ctx);
ctx->stats.prp_lost++;
ctx->stats.tx_data_cancel++;
@@ -200,7 +200,7 @@ pbproc_ftda__tx_wait_sackd__rx_fc (pbproc_t *ctx, u32 rx_date,
else
#endif
{
- pbproc_prep_mpdu_cancel (ctx);
+ pbproc_prep_mpdu_cancel_burst (ctx);
ctx->stats.tx_data_wack_noack++;
}
pbproc_fhfc_handle_fc (ctx, rx_date, fc_av);
@@ -211,7 +211,7 @@ void ARCH_ILRAM
pbproc_ftda__tx_wait_sackd__access (pbproc_t *ctx)
{
dbg_claim (ctx);
- pbproc_prep_mpdu_cancel (ctx);
+ pbproc_prep_mpdu_cancel_burst (ctx);
pbproc_ftop__idle__access (ctx);
ctx->stats.tx_data_wack_noack++;
}
@@ -222,7 +222,7 @@ pbproc_ftda__tx_wait_tx_end__pbdma (pbproc_t *ctx)
dbg_claim (ctx);
uint sack_tck = !ctx->prep_mpdu.main_mfs->beacon
? ctx->times.pre_fcs_tck + MAC_CIFS_TCK : 0;
- pbproc_prep_mpdu_ack_all (ctx);
+ pbproc_prep_mpdu_ack_all_burst (ctx);
ca_backoff_success (ctx->ca);
ca_access_vcs_restart (ctx->ca, ctx->prep_mpdu.tx_date
+ ctx->prep_mpdu.flp_tck + sack_tck);
diff --git a/cesar/mac/pbproc/src/prep_mpdu.c b/cesar/mac/pbproc/src/prep_mpdu.c
index 3fd009d706..208faa3b1e 100644
--- a/cesar/mac/pbproc/src/prep_mpdu.c
+++ b/cesar/mac/pbproc/src/prep_mpdu.c
@@ -27,6 +27,7 @@
/**
* Commit MPDU.
* \param ctx pbproc context
+ * \param mpdu_count MPDU index in burst
* \param release_head segments to release list head
* \param release_tail segments to release list tail
* \param return_head segments to return to MFS list head
@@ -35,12 +36,11 @@
*
* This means:
* - release acknowledged segments.
- * - give unacknowledged segments to MFS.
+ * - enqueue unacknowledged segments for return to MFS.
* - clear prepared MPDU.
- * - update MFS in CA.
*/
static void
-pbproc_prep_mpdu_commit (pbproc_t *ctx,
+pbproc_prep_mpdu_commit (pbproc_t *ctx, uint mpdu_count,
pb_t *release_head, pb_t *release_tail,
pb_t *return_head, pb_t *return_tail,
uint return_nb);
@@ -73,6 +73,7 @@ pbproc_prep_mpdu_init (pbproc_t *ctx)
dbg_invalid_ptr (prep->mpdu[i].main_head);
dbg_invalid_ptr (prep->mpdu[i].main_tail);
}
+ slist_init (prep->main_commit_return_);
}
void ARCH_ILRAM
@@ -646,30 +647,62 @@ pbproc_prep_mpdu_chain (pbproc_t *ctx)
}
void ARCH_ILRAM
-pbproc_prep_mpdu_cancel (pbproc_t *ctx)
+pbproc_prep_mpdu_cancel_burst (pbproc_t *ctx)
{
+ int mpdu_count;
/* Check inputs. */
dbg_claim (ctx);
pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
- pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[0];
+ dbg_claim (prep->valid);
+ /* Cancel all MPDU. */
+ for (mpdu_count = prep->burst_mpdu_nb - 1; mpdu_count >= 0; mpdu_count--)
+ if (prep->mpdu[mpdu_count].pb_nb_total)
+ pbproc_prep_mpdu_cancel (ctx, mpdu_count);
+ pbproc_prep_mpdu_commit_burst (ctx);
+}
+
+void ARCH_ILRAM
+pbproc_prep_mpdu_cancel (pbproc_t *ctx, uint mpdu_count)
+{
+ /* Check inputs. */
+ dbg_claim (ctx);
+ dbg_claim (mpdu_count < PBPROC_PREP_MPDU_NB_MAX);
+ pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
+ pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[mpdu_count];
dbg_claim (prep->valid);
dbg_claim_ptr (prep->main_mfs);
dbg_claim_ptr (mpdu->main_head);
dbg_claim_ptr (mpdu->main_tail);
dbg_claim (mpdu->main_seg_nb);
/* Commit. */
- pbproc_prep_mpdu_commit (ctx, NULL, NULL,
+ pbproc_prep_mpdu_commit (ctx, mpdu_count, NULL, NULL,
mpdu->main_head, mpdu->main_tail,
mpdu->main_seg_nb + prep->main_seg_nb_reserved);
}
void ARCH_ILRAM
-pbproc_prep_mpdu_ack_all (pbproc_t *ctx)
+pbproc_prep_mpdu_ack_all_burst (pbproc_t *ctx)
{
+ int mpdu_count;
/* Check inputs. */
dbg_claim (ctx);
pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
- pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[0];
+ dbg_claim (prep->valid);
+ /* Commit all MPDU. */
+ for (mpdu_count = prep->burst_mpdu_nb - 1; mpdu_count >= 0; mpdu_count--)
+ if (prep->mpdu[mpdu_count].pb_nb_total)
+ pbproc_prep_mpdu_ack_all (ctx, mpdu_count);
+ pbproc_prep_mpdu_commit_burst (ctx);
+}
+
+void ARCH_ILRAM
+pbproc_prep_mpdu_ack_all (pbproc_t *ctx, uint mpdu_count)
+{
+ /* Check inputs. */
+ dbg_claim (ctx);
+ dbg_claim (mpdu_count < PBPROC_PREP_MPDU_NB_MAX);
+ pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
+ pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[mpdu_count];
dbg_claim (prep->valid);
dbg_claim_ptr (prep->main_mfs);
dbg_claim_ptr (mpdu->main_head);
@@ -678,18 +711,21 @@ pbproc_prep_mpdu_ack_all (pbproc_t *ctx)
dbg_claim (prep->main_seg_nb_reserved == 0);
dbg_claim (mpdu->pb_nb_total >= mpdu->main_seg_nb);
/* Commit. */
- pbproc_prep_mpdu_commit (ctx, mpdu->main_head, mpdu->main_tail,
+ pbproc_prep_mpdu_commit (ctx, mpdu_count,
+ mpdu->main_head, mpdu->main_tail,
NULL, NULL, 0);
}
void ARCH_ILRAM
-pbproc_prep_mpdu_ack_bitmap (pbproc_t *ctx, pbproc_sacki_dec_t *sacki_dec)
+pbproc_prep_mpdu_ack_bitmap (pbproc_t *ctx, uint mpdu_count,
+ pbproc_sacki_dec_t *sacki_dec)
{
/* Check inputs. */
dbg_claim (ctx);
+ dbg_claim (mpdu_count < PBPROC_PREP_MPDU_NB_MAX);
dbg_claim (sacki_dec);
pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
- pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[0];
+ pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[mpdu_count];
dbg_claim (prep->valid);
dbg_claim_ptr (prep->main_mfs);
dbg_claim_ptr (mpdu->main_head);
@@ -732,8 +768,8 @@ pbproc_prep_mpdu_ack_bitmap (pbproc_t *ctx, pbproc_sacki_dec_t *sacki_dec)
slist_push_back_range (nok_, p, mpdu->main_tail,
mpdu->main_seg_nb - is, paste_size);
/* Commit. */
- pbproc_prep_mpdu_commit (ctx, ok_head, ok_tail, nok_head, nok_tail,
- nok_size);
+ pbproc_prep_mpdu_commit (ctx, mpdu_count,
+ ok_head, ok_tail, nok_head, nok_tail, nok_size);
}
/** Structure used to handle encoded acknowledgement information. */
@@ -797,13 +833,15 @@ pbproc_prep_mpdu_ack_encoded_nok_cb (void *user, uint first, uint nb)
}
void ARCH_ILRAM
-pbproc_prep_mpdu_ack_encoded (pbproc_t *ctx, pbproc_sacki_dec_t *sacki_dec)
+pbproc_prep_mpdu_ack_encoded (pbproc_t *ctx, uint mpdu_count,
+ pbproc_sacki_dec_t *sacki_dec)
{
/* Check inputs. */
dbg_claim (ctx);
+ dbg_claim (mpdu_count < PBPROC_PREP_MPDU_NB_MAX);
dbg_claim (sacki_dec);
pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
- pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[0];
+ pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[mpdu_count];
dbg_claim (prep->valid);
dbg_claim_ptr (prep->main_mfs);
dbg_claim_ptr (mpdu->main_head);
@@ -827,24 +865,26 @@ pbproc_prep_mpdu_ack_encoded (pbproc_t *ctx, pbproc_sacki_dec_t *sacki_dec)
if (enc.p_i != mpdu->main_seg_nb)
slist_push_back_range (enc.ok_, enc.p, mpdu->main_tail);
/* Commit. */
- pbproc_prep_mpdu_commit (ctx, enc.ok_head, enc.ok_tail, enc.nok_head,
- enc.nok_tail, enc.nok_nb);
+ pbproc_prep_mpdu_commit (ctx, mpdu_count, enc.ok_head, enc.ok_tail,
+ enc.nok_head, enc.nok_tail, enc.nok_nb);
}
/**
* Handle tone maps changes after SACKI reception.
* \param ctx pbproc context
+ * \param mpdu_count MPDU index in burst
* \param sacki SACKI uniform information
*
* Part of pbproc_prep_mpdu_ack_uniform not in local ram.
*/
static __attribute__ ((noinline)) void
-pbproc_prep_mpdu_ack_uniform_tmi (pbproc_t *ctx, uint sacki)
+pbproc_prep_mpdu_ack_uniform_tmi (pbproc_t *ctx, uint mpdu_count, uint sacki)
{
/* Check inputs. */
dbg_claim (ctx);
+ dbg_claim (mpdu_count < PBPROC_PREP_MPDU_NB_MAX);
pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
- pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[0];
+ pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[mpdu_count];
dbg_claim (prep->valid);
dbg_claim_ptr (prep->main_mfs);
/* If valid default TMI or ROBO was used, change default TMI or intervals
@@ -878,20 +918,21 @@ pbproc_prep_mpdu_ack_uniform_tmi (pbproc_t *ctx, uint sacki)
}
void ARCH_ILRAM
-pbproc_prep_mpdu_ack_uniform (pbproc_t *ctx, uint sacki)
+pbproc_prep_mpdu_ack_uniform (pbproc_t *ctx, uint mpdu_count, uint sacki)
{
/* Check inputs. */
dbg_claim (ctx);
+ dbg_claim (mpdu_count < PBPROC_PREP_MPDU_NB_MAX);
/* Handle SACKI. */
if (sacki == PBPROC_FC_SACKI_UNIFORM_ALL_OK)
- pbproc_prep_mpdu_ack_all (ctx);
+ pbproc_prep_mpdu_ack_all (ctx, mpdu_count);
else
{
if (sacki == PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_ROBO
|| sacki == PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_RESTART
|| sacki == PBPROC_FC_SACKI_UNIFORM_TMI_RESTART)
- pbproc_prep_mpdu_ack_uniform_tmi (ctx, sacki);
- pbproc_prep_mpdu_cancel (ctx);
+ pbproc_prep_mpdu_ack_uniform_tmi (ctx, mpdu_count, sacki);
+ pbproc_prep_mpdu_cancel (ctx, mpdu_count);
}
}
@@ -899,28 +940,35 @@ void ARCH_ILRAM
pbproc_prep_mpdu_ack (pbproc_t *ctx, const uint sackt[],
pbproc_sacki_dec_t *sacki_dec)
{
+ int mpdu_count;
/* Check inputs. */
dbg_claim (ctx);
dbg_claim (sackt);
dbg_claim (sacki_dec);
- /* Handle SACKD. */
- if (sackt[0] == PBPROC_FC_SACKT_MIXED)
- {
- pbproc_prep_mpdu_ack_bitmap (ctx, sacki_dec);
- }
- else if (sackt[0] == PBPROC_FC_SACKT_MIXED_COMPRESSED)
- {
- pbproc_prep_mpdu_ack_encoded (ctx, sacki_dec);
- }
- else if (sackt[0] == PBPROC_FC_SACKT_NOT_RECEIVED)
- {
- pbproc_prep_mpdu_cancel (ctx);
- }
- else
+ pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
+ dbg_claim (prep->valid);
+ /* Handle SACKD for each MPDU. */
+ for (mpdu_count = prep->burst_mpdu_nb - 1; mpdu_count >= 0; mpdu_count--)
{
- uint sacki = pbproc_sacki_dec_read (sacki_dec, 4);
- pbproc_prep_mpdu_ack_uniform (ctx, sacki);
+ if (sackt[mpdu_count] == PBPROC_FC_SACKT_MIXED)
+ {
+ pbproc_prep_mpdu_ack_bitmap (ctx, mpdu_count, sacki_dec);
+ }
+ else if (sackt[mpdu_count] == PBPROC_FC_SACKT_MIXED_COMPRESSED)
+ {
+ pbproc_prep_mpdu_ack_encoded (ctx, mpdu_count, sacki_dec);
+ }
+ else if (sackt[mpdu_count] == PBPROC_FC_SACKT_NOT_RECEIVED)
+ {
+ pbproc_prep_mpdu_cancel (ctx, mpdu_count);
+ }
+ else
+ {
+ uint sacki = pbproc_sacki_dec_read (sacki_dec, 4);
+ pbproc_prep_mpdu_ack_uniform (ctx, mpdu_count, sacki);
+ }
}
+ pbproc_prep_mpdu_commit_burst (ctx);
}
void ARCH_ILRAM
@@ -936,14 +984,14 @@ pbproc_prep_mpdu_fsm_response (pbproc_t *ctx, mfs_fsm_rsp_t mfs_rsp_data,
}
void ARCH_ILRAM
-pbproc_prep_mpdu_commit (pbproc_t *ctx,
+pbproc_prep_mpdu_commit (pbproc_t *ctx, uint mpdu_count,
pb_t *release_head, pb_t *release_tail,
pb_t *return_head, pb_t *return_tail, uint return_nb)
{
dbg_claim (ctx);
PBPROC_TRACE (PREP_MPDU_COMMIT, return_nb);
pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
- pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[0];
+ pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[mpdu_count];
dbg_claim (prep->valid);
mfs_tx_t *mfs = prep->main_mfs;
/* Release acknowledged PB in DSR. */
@@ -953,23 +1001,12 @@ pbproc_prep_mpdu_commit (pbproc_t *ctx,
release_head, release_tail);
pbproc_fsm_schedule_deferred (ctx);
}
- /* Change MFS. */
+ /* Keep returning PB to be put in MFS. */
if (return_head)
{
- /* If the MFS has been removed, do not give PB back. Do not put more
- * than one PB in a beacon MFS. */
- if (mfs->ca_state == CA_MFS_STATE_REMOVED
- || (mfs->beacon && mfs->seg_nb))
- {
- slist_push_back_range (ctx->commit.release_,
- return_head, return_tail);
- pbproc_fsm_schedule_deferred (ctx);
- }
- else
- {
- slist_push_front_range (mfs->, return_head, return_tail, bare);
- mfs->seg_nb += return_nb;
- }
+ slist_push_back_range (prep->main_commit_return_, return_head,
+ return_tail);
+ prep->main_commit_return_seg_nb += return_nb;
}
/* Update link stats. */
mfs->stats.num_segs_suc += mpdu->main_seg_nb + prep->main_seg_nb_reserved
@@ -979,17 +1016,9 @@ pbproc_prep_mpdu_commit (pbproc_t *ctx,
dbg_invalid_ptr (mpdu->main_head);
dbg_invalid_ptr (mpdu->main_tail);
mpdu->main_seg_nb = prep->main_seg_nb_reserved = 0;
- /* Handle MFS FSM. */
- pbproc_prep_mpdu_commit_fsm (ctx);
- /* Inform CA. */
- ca_access_done (ctx->ca);
- /* No longer valid. */
- blk_release (prep->main_mfs);
- prep->main_mfs = NULL;
- prep->valid = false;
}
-void ARCH_ILRAM
+inline void
pbproc_prep_mpdu_commit_fsm (pbproc_t *ctx)
{
dbg_claim (ctx);
@@ -1041,6 +1070,46 @@ pbproc_prep_mpdu_commit_fsm (pbproc_t *ctx)
}
}
+void ARCH_ILRAM
+pbproc_prep_mpdu_commit_burst (pbproc_t *ctx)
+{
+ dbg_claim (ctx);
+ pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
+ dbg_claim (prep->valid);
+ mfs_tx_t *mfs = prep->main_mfs;
+ /* Change MFS. */
+ if (prep->main_commit_return_head)
+ {
+ /* If the MFS has been removed, do not give PB back. Do not put more
+ * than one PB in a beacon MFS. */
+ if (mfs->ca_state == CA_MFS_STATE_REMOVED
+ || (mfs->beacon && mfs->seg_nb))
+ {
+ slist_push_back_range (ctx->commit.release_,
+ prep->main_commit_return_head,
+ prep->main_commit_return_tail);
+ pbproc_fsm_schedule_deferred (ctx);
+ }
+ else
+ {
+ slist_push_front_range (mfs->, prep->main_commit_return_head,
+ prep->main_commit_return_tail, bare);
+ mfs->seg_nb += prep->main_commit_return_seg_nb;
+ }
+ /* Empty commit list. */
+ slist_init (prep->main_commit_return_);
+ prep->main_commit_return_seg_nb = 0;
+ }
+ /* Commit FSM change. */
+ pbproc_prep_mpdu_commit_fsm (ctx);
+ /* Inform CA. */
+ ca_access_done (ctx->ca);
+ /* No longer valid. */
+ blk_release (prep->main_mfs);
+ prep->main_mfs = NULL;
+ prep->valid = false;
+}
+
static void
pbproc_prep_mpdu_sound (pbproc_t *ctx, mfs_tx_t *mfs, uint fl_tck)
{
diff --git a/cesar/mac/pbproc/test/pbproc/src/prep_mpdu.c b/cesar/mac/pbproc/test/pbproc/src/prep_mpdu.c
index de2ca90e84..41e100375e 100644
--- a/cesar/mac/pbproc/test/pbproc/src/prep_mpdu.c
+++ b/cesar/mac/pbproc/test/pbproc/src/prep_mpdu.c
@@ -412,7 +412,8 @@ prep_mpdu_test_f (test_t t, test_pbproc_t *tp, u32 date,
tonemaps_t *tms = sta->tx_tonemaps;
if (params->tmi_update)
tms->default_tmi = params->tmi_update;
- pbproc_prep_mpdu_ack_uniform (tp->pbproc, params->sacki);
+ pbproc_prep_mpdu_ack_uniform (
+ tp->pbproc, prep->mpdu_count, params->sacki);
test_fail_unless (
tms->default_tmi == params->tmi_sacki);
if (params->intervals)
@@ -422,12 +423,13 @@ prep_mpdu_test_f (test_t t, test_pbproc_t *tp, u32 date,
blk_release (sta);
}
else
- pbproc_prep_mpdu_ack_uniform (tp->pbproc, params->sacki);
+ pbproc_prep_mpdu_ack_uniform (
+ tp->pbproc, prep->mpdu_count, params->sacki);
}
else if (!params->all_ok)
- pbproc_prep_mpdu_cancel (tp->pbproc);
+ pbproc_prep_mpdu_cancel (tp->pbproc, prep->mpdu_count);
else
- pbproc_prep_mpdu_ack_all (tp->pbproc);
+ pbproc_prep_mpdu_ack_all (tp->pbproc, prep->mpdu_count);
}
else
{
@@ -440,7 +442,8 @@ prep_mpdu_test_f (test_t t, test_pbproc_t *tp, u32 date,
params->crc_error[2] & 0xff,
MIN (params->main_seg_nb_total,
PREP_MPDU_TEST_CRC_BITMAP_SIZE));
- pbproc_prep_mpdu_ack_bitmap (tp->pbproc, &sacki_dec);
+ pbproc_prep_mpdu_ack_bitmap (tp->pbproc, prep->mpdu_count,
+ &sacki_dec);
}
else
{
@@ -448,9 +451,11 @@ prep_mpdu_test_f (test_t t, test_pbproc_t *tp, u32 date,
pbproc_sacki_dec_init (
&sacki_dec, params->encoded_sack & 0xffffffff,
(params->encoded_sack >> 32) & 0xffffffff, 0, 64);
- pbproc_prep_mpdu_ack_encoded (tp->pbproc, &sacki_dec);
+ pbproc_prep_mpdu_ack_encoded (tp->pbproc, prep->mpdu_count,
+ &sacki_dec);
}
}
+ pbproc_prep_mpdu_commit_burst (tp->pbproc);
/* Call DSR if requested. */
if (tp->pbproc->fsm.schedule_deferred)
pbproc_fsm_handle_deferred (tp->pbproc);
@@ -1032,7 +1037,7 @@ prep_beacon_test (test_t t, test_pbproc_t *tp, u32 date, bool prepared,
| params.bpsto[2] << 16;
test_fail_unless (bpsto == date - beacon_period_start_date);
/* Cancel preparation. */
- pbproc_prep_mpdu_cancel (tp->pbproc);
+ pbproc_prep_mpdu_cancel_burst (tp->pbproc);
/* Check result. */
test_fail_unless (mfs->seg_nb == 1);
test_fail_unless (mfs->head == seg);
@@ -1104,6 +1109,7 @@ prep_mpdu_fsm_test (test_t t, test_pbproc_t *tp, mfs_fsm_cmd_t cmd,
prep->main_mfs = mfs;
blk_addref (mfs);
pb_t *pb = PARENT_OF (pb_t, blk, blk_alloc_desc ());
+ prep->burst_mpdu_nb = 1;
prep->mpdu[0].main_head = prep->mpdu[0].main_tail = pb;
prep->mpdu[0].main_seg_nb = 1;
prep->main_seg_nb_reserved = 0;
@@ -1111,7 +1117,7 @@ prep_mpdu_fsm_test (test_t t, test_pbproc_t *tp, mfs_fsm_cmd_t cmd,
prep->main_mfs_cmd = cmd;
/* Test. */
pbproc_prep_mpdu_fsm_response (tp->pbproc, rsp, MFS_FSM_RSP_ACK);
- pbproc_prep_mpdu_ack_all (tp->pbproc);
+ pbproc_prep_mpdu_ack_all_burst (tp->pbproc);
/* Call DSR if requested. */
if (tp->pbproc->fsm.schedule_deferred)
pbproc_fsm_handle_deferred (tp->pbproc);