summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Schodet2011-08-12 14:31:27 +0200
committerNicolas Schodet2011-09-16 14:58:08 +0200
commit83ef436d13bdbb8681eee93208750ac2332d1dac (patch)
tree601d33928952e7e4b866c5a5bda173a8db746f8e
parentff83932aff7c5031e7080ba1ca81005fa6f18345 (diff)
cesar/mac/pbproc: decode ack data in byte aligned structure, refs #1431
In order to improve CPU performance, received FC acknowledgement data is parsed into a byte aligned structure used by the software instead of FCs bitfield structures. The same structure is used, independent from the FC type which was used to store acknowledgement data (SACK/SOF/RSOF).
-rw-r--r--cesar/mac/pbproc/inc/fc.h21
-rw-r--r--cesar/mac/pbproc/inc/prep_mpdu.h6
-rw-r--r--cesar/mac/pbproc/src/fsm_tx_data.c73
-rw-r--r--cesar/mac/pbproc/src/prep_mpdu.c31
4 files changed, 93 insertions, 38 deletions
diff --git a/cesar/mac/pbproc/inc/fc.h b/cesar/mac/pbproc/inc/fc.h
index 56885997e4..11a63f6098 100644
--- a/cesar/mac/pbproc/inc/fc.h
+++ b/cesar/mac/pbproc/inc/fc.h
@@ -15,6 +15,8 @@
* Be careful to bit order.
*/
+#include "mac/pbproc/inc/sacki_dec.h"
+
/** Delimiter type. */
enum pbproc_fc_dt_t
{
@@ -241,6 +243,9 @@ enum pbproc_fc_sacki_uniform_t
/** Maximum number of bits in a SACK. */
#define PBPROC_FC_SACK_SACKI_BITS 72
+/** Number of possible RRTL values. */
+#define PBPROC_FC_SACK_RRTL_NB 16
+
/** Selective Acknowledgment frame control. */
struct pbproc_fc_sack_t
{
@@ -558,6 +563,22 @@ union pbproc_fc_t
};
typedef union pbproc_fc_t pbproc_fc_t;
+/** Byte aligned structure for ACK data (SOF/RSOF/SACK FC).*/
+struct pbproc_fc_ack_data_t
+{
+ /** SACK type table. */
+ u8 sackt[4];
+ /** SACK decompression informations. */
+ pbproc_sacki_dec_t sacki_dec;
+ /** Request reverse transmission length. */
+ uint rrtl_tck;
+ /** RX window size. */
+ u8 rxwsz;
+ /** MFS response. */
+ u8 mfs_rsp;
+};
+typedef struct pbproc_fc_ack_data_t pbproc_fc_ack_data_t;
+
BEGIN_DECLS
/**
diff --git a/cesar/mac/pbproc/inc/prep_mpdu.h b/cesar/mac/pbproc/inc/prep_mpdu.h
index 038d1c6ba6..3a9007247b 100644
--- a/cesar/mac/pbproc/inc/prep_mpdu.h
+++ b/cesar/mac/pbproc/inc/prep_mpdu.h
@@ -225,16 +225,16 @@ pbproc_prep_mpdu_ack_uniform (pbproc_t *ctx, uint mpdu_count, uint sacki);
* \param sacki_dec SACKI decompression context
*/
void
-pbproc_prep_mpdu_ack (pbproc_t *ctx, const uint sackt[],
+pbproc_prep_mpdu_ack (pbproc_t *ctx, const u8 sackt[],
pbproc_sacki_dec_t *sacki_dec);
/**
* Update FSM response and window size and launch acknowledge handling.
* \param ctx pbproc context
- * \param fc SACK frame control
+ * \param ack_data data extracted from SACK frame control
*/
void
-pbproc_prep_mpdu_handle_sack (pbproc_t *ctx, const pbproc_fc_t *fc);
+pbproc_prep_mpdu_handle_sack (pbproc_t *ctx, pbproc_fc_ack_data_t *ack_data);
/**
* Commit burst.
diff --git a/cesar/mac/pbproc/src/fsm_tx_data.c b/cesar/mac/pbproc/src/fsm_tx_data.c
index 7b1e6e717a..c2a8af9348 100644
--- a/cesar/mac/pbproc/src/fsm_tx_data.c
+++ b/cesar/mac/pbproc/src/fsm_tx_data.c
@@ -166,24 +166,79 @@ pbproc_ftda__tx_wait_access_conf__access_conf (pbproc_t *ctx)
- ctx->prep_mpdu.ifs_tck);
}
+static bool ARCH_ILRAM
+pbproc_ftda_parse_ack_data (pbproc_t *ctx, const pbproc_fc_t *fc_av,
+ pbproc_fc_ack_data_t *ack_data)
+{
+ dbg_claim (ack_data);
+ pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
+ bool fc_ok;
+ u32 sack_w0 = fc_av->words[0];
+ if (fc_av
+ && ((sack_w0
+ & BF_MASKS (PBPROC_FC_SACK_W0, DT_AV, ACCESS, SNID, DTEI))
+ == (u32) BF_FILL (PBPROC_FC_SACK_W0, (DT_AV, PBPROC_FC_DT_SACK),
+ (ACCESS, false), (SNID, ctx->alloc.snid),
+ (DTEI, prep->stei)))
+ )
+ {
+ /** FC is for us, parse the data. */
+ ack_data->sackt[0] = BF_GET (PBPROC_FC_SACK_W0__SACKT0, sack_w0);
+ ack_data->sackt[1] = BF_GET (PBPROC_FC_SACK_W0__SACKT1, sack_w0);
+ ack_data->sackt[2] = BF_GET (PBPROC_FC_SACK_W0__SACKT2, sack_w0);
+ ack_data->sackt[3] = BF_GET (PBPROC_FC_SACK_W0__SACKT3, sack_w0);
+ uint sacki_length = PBPROC_FC_SACK_SACKI_BITS;
+ u32 sacki_last = fc_av->sack.sacki_last;
+ u32 sacki_msb = sacki_last;
+ if (sack_w0 & BF_MASK (PBPROC_FC_SACK_W0__RRTF))
+ {
+ static const uint rrtl_map_tck[PBPROC_FC_SACK_RRTL_NB] = {
+ 4096, 5120, 6144, 7168, 8192, 10240, 12288, 14336, 16384,
+ 20480, 24576, 28672, 32768, 40960, 49152, 57344 };
+ ack_data->rrtl_tck = rrtl_map_tck[sacki_msb >> 4];
+ sacki_msb <<= 4;
+ sacki_length -= 4;
+ }
+ else
+ ack_data->rrtl_tck = 0;
+ if (MAC_LID_IS_PLID (prep->main_mfs->common.lid))
+ {
+ ack_data->rxwsz = sacki_msb >> 4;
+ sacki_length -= 4;
+ }
+ pbproc_sacki_dec_init (&ack_data->sacki_dec, fc_av->sack.sacki[0],
+ fc_av->sack.sacki[1], sacki_last,
+ sacki_length);
+ if (prep->main_mfs->common.mme)
+ ack_data->mfs_rsp = BF_GET (PBPROC_FC_SACK_W0__MFS_RSP_MGMT,
+ sack_w0);
+ else
+ ack_data->mfs_rsp = BF_GET (PBPROC_FC_SACK_W0__MFS_RSP_DATA,
+ sack_w0);
+ fc_ok = true;
+ }
+ else
+ {
+ /** FC is not for us, it will be ignored. */
+ fc_ok = false;
+ }
+ return fc_ok;
+}
+
void ARCH_ILRAM
pbproc_ftda__tx_wait_sackd__rx_fc (pbproc_t *ctx, u32 rx_date,
const pbproc_fc_t *fc_av)
{
dbg_claim (ctx);
- pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
+ pbproc_fc_ack_data_t ack_data;
/* 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->alloc.snid
- && fc_av->sack.dtei == prep->stei
- && less_mod2p32 (rx_date, ctx->prep_mpdu.tx_date
- + ctx->prep_mpdu.flp_tck + MAC_TOLERANCE_TCK))
+ if (less_mod2p32 (rx_date, ctx->prep_mpdu.tx_date
+ + ctx->prep_mpdu.flp_tck + MAC_TOLERANCE_TCK)
+ && pbproc_ftda_parse_ack_data (ctx, fc_av, &ack_data))
{
phy_rx_prepare_short (ctx->phy);
/* Update MFS parameters and handle SACKD. */
- pbproc_prep_mpdu_handle_sack (ctx, fc_av);
+ pbproc_prep_mpdu_handle_sack (ctx, &ack_data);
/* Next. */
if (!ctx->access.cfp)
{
diff --git a/cesar/mac/pbproc/src/prep_mpdu.c b/cesar/mac/pbproc/src/prep_mpdu.c
index 411ba4707d..8d4c68fa03 100644
--- a/cesar/mac/pbproc/src/prep_mpdu.c
+++ b/cesar/mac/pbproc/src/prep_mpdu.c
@@ -1060,7 +1060,7 @@ pbproc_prep_mpdu_ack_uniform (pbproc_t *ctx, uint mpdu_count, uint sacki)
}
void ARCH_ILRAM
-pbproc_prep_mpdu_ack (pbproc_t *ctx, const uint sackt[],
+pbproc_prep_mpdu_ack (pbproc_t *ctx, const u8 sackt[],
pbproc_sacki_dec_t *sacki_dec)
{
int mpdu_count;
@@ -1098,42 +1098,21 @@ pbproc_prep_mpdu_ack (pbproc_t *ctx, const uint sackt[],
}
void ARCH_ILRAM
-pbproc_prep_mpdu_handle_sack (pbproc_t *ctx, const pbproc_fc_t *fc)
+pbproc_prep_mpdu_handle_sack (pbproc_t *ctx, pbproc_fc_ack_data_t *ack_data)
{
dbg_claim (ctx);
pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
dbg_claim (prep->valid);
- const pbproc_fc_sack_t *sack_fc = &fc->sack;
/* Update MFS response (only one MFS for the moment). */
- prep->main_mfs_rsp = prep->main_mfs->common.mme
- ? sack_fc->mfs_rsp_mgmt : sack_fc->mfs_rsp_data;
+ prep->main_mfs_rsp = ack_data->mfs_rsp;
/* Update RX window size. */
if (MAC_LID_IS_PLID (prep->main_mfs->common.lid))
- {
- uint window_size_index;
- if (sack_fc->rrtf)
- window_size_index = sack_fc->sacki_last & 0x0F;
- else
- window_size_index = sack_fc->sacki_last >> 4;
- prep->main_mfs->window_size = mfs_window_size[window_size_index];
- }
+ prep->main_mfs->window_size = mfs_window_size[ack_data->rxwsz];
/* Handle SACKD. */
if (prep->main_mfs_rsp == MFS_FSM_RSP_ACK)
- {
- pbproc_sacki_dec_t sacki_dec;
- pbproc_sacki_dec_init (
- &sacki_dec, sack_fc->sacki[0], sack_fc->sacki[1],
- sack_fc->sacki_last, PBPROC_FC_SACK_SACKI_BITS
- - (MAC_LID_IS_PLID (prep->main_mfs->common.lid) ? 4 : 0)
- - (sack_fc->rrtf ? 4 : 0));
- uint st[4] = { sack_fc->sackt0, sack_fc->sackt1,
- sack_fc->sackt2, sack_fc->sackt3 };
- pbproc_prep_mpdu_ack (ctx, st, &sacki_dec);
- }
+ pbproc_prep_mpdu_ack (ctx, ack_data->sackt, &ack_data->sacki_dec);
else
- {
pbproc_prep_mpdu_cancel_burst(ctx);
- }
}
void ARCH_ILRAM