From 10f48a2779ee7baad125d6926ef265e549996555 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Fri, 12 Aug 2011 14:35:34 +0200 Subject: cesar/mac/pbproc: decode FC data in byte aligned structure, refs #1431 In order to improve CPU performance, received FC data is directly parsed into RX parameters structure used by the software instead of FCs bitfield structures. The same structure is used, independent from the FC type which was used to transmit data (SOF/RSOF). --- cesar/mac/pbproc/inc/fsm_rx_data.h | 3 +- cesar/mac/pbproc/pbproc.h | 14 ++++ cesar/mac/pbproc/src/fsm_handle_fc.c | 76 +++++++++++++++++++--- cesar/mac/pbproc/src/fsm_rx_data.c | 120 ++++++++++++++--------------------- 4 files changed, 129 insertions(+), 84 deletions(-) (limited to 'cesar/mac') diff --git a/cesar/mac/pbproc/inc/fsm_rx_data.h b/cesar/mac/pbproc/inc/fsm_rx_data.h index 6e9eddf707..6de044bc55 100644 --- a/cesar/mac/pbproc/inc/fsm_rx_data.h +++ b/cesar/mac/pbproc/inc/fsm_rx_data.h @@ -26,10 +26,9 @@ pbproc_frda_init (pbproc_t *ctx); * Handle a RX data, called from handle_fc. * \param ctx pbproc context * \param rx_date start of preamble date - * \param sof SOF frame control */ void -pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof); +pbproc_frda__handle (pbproc_t *ctx, u32 rx_date); /** * RX DATA WACK =PBDMA=>. diff --git a/cesar/mac/pbproc/pbproc.h b/cesar/mac/pbproc/pbproc.h index 0cf54548a4..fd008a610f 100644 --- a/cesar/mac/pbproc/pbproc.h +++ b/cesar/mac/pbproc/pbproc.h @@ -38,6 +38,8 @@ struct pbproc_rx_params_t uint fl_tck; /** TEI of the transmitter. */ u8 tei; + /** TEI of the receiver. */ + u8 dtei; /** Link ID of this MPDU. */ u8 lid; /** Short network identifier. */ @@ -58,10 +60,22 @@ struct pbproc_rx_params_t u8 ble; /** PB size (PHY_PB_SIZE_136 or PHY_PB_SIZE_520). */ u8 pb_size; + /** Number of symbols, 0, 1, 2 or more. */ + u8 num_sym; /** Tone map index. */ u8 tmi_av; /** MPDU count. */ u8 mpdu_cnt; + /** Burst count. */ + u8 burst_cnt; + /** Bidirectional burst flag. */ + bool bbf; + /** Max reverse transmission frame length. */ + u8 mrtfl; + /** Different CP PHY clock flag. */ + bool dcppcf; + /** Request SACK retransmission. */ + bool rsr; /** Beacon detect flag. */ bool bdf; /** Homeplug 1.0.1 detect flag. */ diff --git a/cesar/mac/pbproc/src/fsm_handle_fc.c b/cesar/mac/pbproc/src/fsm_handle_fc.c index a6fd63d8cc..a72d2479a6 100644 --- a/cesar/mac/pbproc/src/fsm_handle_fc.c +++ b/cesar/mac/pbproc/src/fsm_handle_fc.c @@ -36,10 +36,10 @@ pbproc_fhfc_beacon (pbproc_t *ctx, u32 rx_date, * Handle SOF FC. * \param ctx pbproc context * \param rx_date start of preamble date - * \param sof SOF FC + * \param fc_av frame control */ static void -pbproc_fhfc_sof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof); +pbproc_fhfc_sof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av); /** * Handle RTS/CTS. @@ -126,7 +126,7 @@ pbproc_fhfc_handle_fc (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av) pbproc_fhfc_beacon (ctx, rx_date, &fc_av->beacon); break; case PBPROC_FC_DT_SOF: - pbproc_fhfc_sof (ctx, rx_date, &fc_av->sof); + pbproc_fhfc_sof (ctx, rx_date, fc_av); break; case PBPROC_FC_DT_SACK: pbproc_fhfc_ignore (ctx, rx_date, ctx->times.pre_fcs_tck @@ -153,19 +153,77 @@ pbproc_fhfc_beacon (pbproc_t *ctx, u32 rx_date, pbproc_frbe__handle (ctx, rx_date, beacon); } +static bool ARCH_ILRAM +pbproc_fhfc_parse_sof (pbproc_t *ctx, const pbproc_fc_t *fc_av) +{ + dbg_claim (fc_av->sof.clst == false); + /* TODO features. */ + dbg_claim (fc_av->sof.bbf == false); + dbg_claim (fc_av->sof.dcppcf == false); + dbg_claim (fc_av->sof.rsr == false); + pbproc_rx_params_t *rx_params = &ctx->recv_mpdu.rx_params; + bool fc_ok; + u32 sof_w0 = fc_av->words[0]; + rx_params->snid = BF_GET (PBPROC_FC_SOF_W0__SNID, sof_w0); + rx_params->dtei = BF_GET (PBPROC_FC_SOF_W0__DTEI, sof_w0); + u32 sof_w2 = fc_av->words[2]; + rx_params->bcast = BF_GET (PBPROC_FC_SOF_W2__MCF, sof_w2); + rx_params->multi_net_bcast = BF_GET (PBPROC_FC_SOF_W2__MNBF, sof_w2); + if (!BF_GET (PBPROC_FC_SOF_W0__ACCESS, sof_w0) + && ((ctx->config->tei && rx_params->snid == ctx->alloc.snid) + || rx_params->multi_net_bcast) + && (rx_params->dtei == ctx->config->tei || rx_params->bcast)) + { + rx_params->sound = false; + /** FC is for us, parse the data. */ + rx_params->tei = BF_GET (PBPROC_FC_SOF_W0__STEI, sof_w0); + rx_params->lid = BF_GET (PBPROC_FC_SOF_W0__LID, sof_w0); + u32 sof_w1 = fc_av->words[1]; + rx_params->cfp = BF_GET (PBPROC_FC_SOF_W1__CFS, sof_w1); + rx_params->bdf = BF_GET (PBPROC_FC_SOF_W1__BDF, sof_w1); + rx_params->hp10df = BF_GET (PBPROC_FC_SOF_W1__HP10DF, sof_w1); + rx_params->hp11df = BF_GET (PBPROC_FC_SOF_W1__HP11DF, sof_w1); + rx_params->eks = BF_GET (PBPROC_FC_SOF_W1__EKS, sof_w1); + rx_params->pending_seg_nb = BF_GET (PBPROC_FC_SOF_W1__PPB, sof_w1); + rx_params->ble = BF_GET (PBPROC_FC_SOF_W1__BLE, sof_w1); + rx_params->pb_size = BF_GET (PBPROC_FC_SOF_W1__PBSZ, sof_w1) + ? PHY_PB_SIZE_136 : PHY_PB_SIZE_520; + rx_params->num_sym = BF_GET (PBPROC_FC_SOF_W1__NUM_SYM, sof_w1); + rx_params->tmi_av = BF_GET (PBPROC_FC_SOF_W1__TMI_AV, sof_w1); + u32 sof_w2 = fc_av->words[2]; + rx_params->fl_tck = MAC_FL_TO_TCK ( + BF_GET (PBPROC_FC_SOF_W2__FL_AV, sof_w2)); + rx_params->mpdu_cnt = BF_GET (PBPROC_FC_SOF_W2__MPDU_CNT, sof_w2); + rx_params->burst_cnt = BF_GET (PBPROC_FC_SOF_W2__BURST_CNT, sof_w2); + rx_params->bbf = BF_GET (PBPROC_FC_SOF_W2__BBF, sof_w2); + rx_params->mrtfl = BF_GET (PBPROC_FC_SOF_W2__MRTFL, sof_w2); + rx_params->dcppcf = BF_GET (PBPROC_FC_SOF_W2__DCPPCF, sof_w2); + rx_params->rsr = BF_GET (PBPROC_FC_SOF_W2__RSR, sof_w2); + rx_params->mfs_cmd_mme = + BF_GET (PBPROC_FC_SOF_W2__MFS_CMD_MGMT, sof_w2); + rx_params->mfs_cmd_data = + BF_GET (PBPROC_FC_SOF_W2__MFS_CMD_DATA, sof_w2); + fc_ok = true; + } + else + { + /** FC is not for us, it will be ignored. */ + fc_ok = false; + } + return fc_ok; +} + static void ARCH_ILRAM -pbproc_fhfc_sof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) +pbproc_fhfc_sof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av) { - if (sof->access == false - && ((ctx->config->tei && sof->snid == ctx->alloc.snid) || sof->mnbf) - && (sof->dtei == ctx->config->tei || sof->mcf)) + if (pbproc_fhfc_parse_sof (ctx, fc_av)) { - pbproc_frda__handle (ctx, rx_date, sof); + pbproc_frda__handle (ctx, rx_date); } else { /* Not for us, count the expected following SACK. */ - pbproc_fhfc_ignore (ctx, rx_date, MAC_FL_TO_TCK (sof->fl_av) + pbproc_fhfc_ignore (ctx, rx_date, MAC_FL_TO_TCK (fc_av->sof.fl_av) + 2 * ctx->times.pre_fcs_tck + MAC_CIFS_TCK); } diff --git a/cesar/mac/pbproc/src/fsm_rx_data.c b/cesar/mac/pbproc/src/fsm_rx_data.c index 9fb87b0131..ad3620d778 100644 --- a/cesar/mac/pbproc/src/fsm_rx_data.c +++ b/cesar/mac/pbproc/src/fsm_rx_data.c @@ -46,24 +46,21 @@ pbproc_frda_send_sack (pbproc_t *ctx); /** * Initialise SACKD, reset if not part of last burst. * \param ctx pbproc context - * \param sof received MPDU SOF */ static void -pbproc_frda_sackd_init (pbproc_t *ctx, const pbproc_fc_sof_t *sof); +pbproc_frda_sackd_init (pbproc_t *ctx); /** * Give up reception and eventually prepare a SACK to signal the problem. * \param ctx pbproc context * \param rx_date start of preamble date - * \param sof SOF FC * \param wack with acknowledge * \param sacki_uniform uniform SACK information * * Go to next FSM state. */ static void -pbproc_frda_error (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof, - bool wack, uint sacki_uniform); +pbproc_frda_error (pbproc_t *ctx, u32 rx_date, bool wack, uint sacki_uniform); /** * Unchain received PB, and give them to the upper layer. @@ -89,40 +86,37 @@ pbproc_frda_init (pbproc_t *ctx) } void ARCH_ILRAM -pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) +pbproc_frda__handle (pbproc_t *ctx, u32 rx_date) { bool wack, unassociated; phy_pb_size_t pb_size; dbg_claim (ctx); - dbg_claim (sof); - /* TODO features. */ - dbg_claim (sof->bbf == false); - dbg_claim (sof->dcppcf == false); - dbg_claim (sof->rsr == false); + pbproc_rx_params_t *rx_params = &ctx->recv_mpdu.rx_params; /* Update stats. */ ctx->stats.rx_data++; /* Unassociated? */ - unassociated = sof->stei == 0 || sof->mnbf; + unassociated = rx_params->tei == 0 || rx_params->multi_net_bcast; /* With ACK? */ - wack = sof->snid == ctx->alloc.snid && sof->dtei == ctx->config->tei; + wack = rx_params->snid == ctx->alloc.snid + && rx_params->dtei == ctx->config->tei; /* Burst? */ - ctx->recv_mpdu.mpdu_cnt = sof->mpdu_cnt; + ctx->recv_mpdu.mpdu_cnt = rx_params->mpdu_cnt; /* PB Size. */ - pb_size = sof->pbsz ? PHY_PB_SIZE_136 : PHY_PB_SIZE_520; + pb_size = rx_params->pb_size; /* Ignore frames ending after the allocation. */ - uint fl_tck = MAC_FL_TO_TCK (sof->fl_av); + uint fl_tck = rx_params->fl_tck; if (!ctx->alloc.merge && 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++; - pbproc_frda_error (ctx, rx_date, sof, false, + pbproc_frda_error (ctx, rx_date, false, PBPROC_FC_SACKI_UNIFORM_ALL_ERROR); return; } /* Get tonemap. */ - uint tmi = sof->tmi_av; + uint tmi = rx_params->tmi_av; tonemap_t *tm; uint rifs_tck; if (tmi < PHY_MOD_ROBO_NB) @@ -130,9 +124,9 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) tm = &ctx->config->tonemask_info.tonemap_robo[tmi]; rifs_tck = MAC_RIFS_DEFAULT_TCK; } - else if (sof->mcf || unassociated) + else if (rx_params->bcast || unassociated) { - pbproc_frda_error (ctx, rx_date, sof, wack, + pbproc_frda_error (ctx, rx_date, wack, PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_ROBO); return; } @@ -140,7 +134,7 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) { dbg_claim (wack); dbg_claim (tmi < TONEMAP_INDEX_NB); - sta_t *sta = mac_store_sta_get (ctx->store, sof->stei); + sta_t *sta = mac_store_sta_get (ctx->store, rx_params->tei); if (sta) { tm = sta->rx_tonemaps->tm[tmi]; @@ -148,14 +142,14 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) rifs_tck = MAC_RIFS_SPC_ANY_TCK; if (!tm) { - pbproc_frda_error (ctx, rx_date, sof, true, + pbproc_frda_error (ctx, rx_date, true, PBPROC_FC_SACKI_UNIFORM_TMI_RESTART); return; } } else { - pbproc_frda_error (ctx, rx_date, sof, true, + pbproc_frda_error (ctx, rx_date, true, PBPROC_FC_SACKI_UNIFORM_TMI_RESTART); return; } @@ -165,8 +159,8 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) rifs_tck = MAC_BIFS_TCK; /* Compute symbol and PB number. */ uint symb_nb; - if (sof->num_sym <= 2) - symb_nb = sof->num_sym; + if (rx_params->num_sym <= 2) + symb_nb = rx_params->num_sym; else symb_nb = ((fl_tck - rifs_tck - 2 * MAC_DX567_TCK) / ctx->symbol_tck[tm->gil] + 2); @@ -183,7 +177,7 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) if (!pb_nb) { ctx->stats.rx_data_empty++; - pbproc_frda_error (ctx, rx_date, sof, wack, + pbproc_frda_error (ctx, rx_date, wack, PBPROC_FC_SACKI_UNIFORM_ALL_ERROR); return; } @@ -201,11 +195,11 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) bool nek_ok = false; do { - if (sof->eks < MAC_EKS_NB) + if (rx_params->eks < MAC_EKS_NB) { if (unassociated) break; - sta_t *sta = mac_store_sta_get (ctx->store, sof->stei); + sta_t *sta = mac_store_sta_get (ctx->store, rx_params->tei); mac_nek_t (*nek)[2]; if (sta) { @@ -216,24 +210,24 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) } else nek = &ctx->config->nek; - if ((*nek)[0].eks == sof->eks) + if ((*nek)[0].eks == rx_params->eks) key = (*nek)[0].nek_dec; - else if ((*nek)[1].eks == sof->eks) + else if ((*nek)[1].eks == rx_params->eks) key = (*nek)[1].nek_dec; else break; bypass_aes = false; nek_ok = true; } - else if (sof->eks == MAC_EKS_CLEAR) + else if (rx_params->eks == MAC_EKS_CLEAR) { nek_ok = true; } } while (0); /* Acknowledge multicast frame even if it can not be decrypted. */ - if (!nek_ok && !(wack && sof->mcf)) + if (!nek_ok && !(wack && rx_params->bcast)) { - pbproc_frda_error (ctx, rx_date, sof, wack, + pbproc_frda_error (ctx, rx_date, wack, PBPROC_FC_SACKI_UNIFORM_NEK_ERROR); return; } @@ -241,12 +235,12 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) 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_frda_error (ctx, rx_date, wack, PBPROC_FC_SACKI_UNIFORM_ALL_ERROR); return; } /* First thing to do: unblock the hardware. */ - if (tmi >= PHY_MOD_ROBO_NB) + if (rx_params->tmi_av >= PHY_MOD_ROBO_NB) phy_set_tonemap (ctx->phy, tm->tmdma_desc_head); phy_rx_prepare (ctx->phy, pb_nb, tm->phy_combo_params[pb_size], tm->gil, symb_nb, tm->tcc_halfit); @@ -255,25 +249,6 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) + ctx->config->ntb_offset_tck; ctx->recv_mpdu.rx_params.beacon_period_start_ntb = ctx->alloc.beacon_period_start_date + ctx->config->ntb_offset_tck; - ctx->recv_mpdu.rx_params.fl_tck = fl_tck; - ctx->recv_mpdu.rx_params.tei = sof->stei; - ctx->recv_mpdu.rx_params.lid = sof->lid; - ctx->recv_mpdu.rx_params.snid = sof->snid; - ctx->recv_mpdu.rx_params.bcast = sof->mcf; - ctx->recv_mpdu.rx_params.cfp = sof->cfs; - ctx->recv_mpdu.rx_params.multi_net_bcast = sof->mnbf; - ctx->recv_mpdu.rx_params.sound = false; - ctx->recv_mpdu.rx_params.eks = sof->eks; - ctx->recv_mpdu.rx_params.pending_seg_nb = sof->ppb; - ctx->recv_mpdu.rx_params.ble = sof->ble; - ctx->recv_mpdu.rx_params.pb_size = pb_size; - ctx->recv_mpdu.rx_params.tmi_av = sof->tmi_av; - ctx->recv_mpdu.rx_params.mpdu_cnt = sof->mpdu_cnt; - ctx->recv_mpdu.rx_params.bdf = sof->bdf; - ctx->recv_mpdu.rx_params.hp10df = sof->hp10df; - ctx->recv_mpdu.rx_params.hp11df = sof->hp11df; - ctx->recv_mpdu.rx_params.mfs_cmd_data = sof->mfs_cmd_data; - ctx->recv_mpdu.rx_params.mfs_cmd_mme = sof->mfs_cmd_mgmt; ctx->recv_mpdu.pb_nb = pb_nb; ctx->recv_mpdu.ack_date = rx_date + ctx->times.pre_fcs_tck + fl_tck; ctx->recv_mpdu.drop = !nek_ok; @@ -319,7 +294,7 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof) if (wack) { /* Initialise SACKD. */ - pbproc_frda_sackd_init (ctx, sof); + pbproc_frda_sackd_init (ctx); /* Wait. */ pbproc_fsm_change_state (ctx, sack_last_pb ? PBPROC_FSM_STATE_RX_DATA_WACK @@ -474,19 +449,19 @@ pbproc_frda__rx_burst__access (pbproc_t *ctx) } static void ARCH_ILRAM -pbproc_frda_sackd_init (pbproc_t *ctx, const pbproc_fc_sof_t *sof) +pbproc_frda_sackd_init (pbproc_t *ctx) { dbg_claim (ctx); - dbg_claim (sof); + pbproc_rx_params_t *rx_params = &ctx->recv_mpdu.rx_params; /* Clear current SACKD if this frame is not part of the previous burst. */ bool reinit = false; pbproc_sackd_t *sackd = &ctx->recv_mpdu.sackd; if (!sackd->valid - || sackd->tei != sof->stei - || sackd->lid != sof->lid - || sackd->bcast != sof->mcf - || sackd->burst_cnt != sof->burst_cnt - || sackd->last_mpdu_cnt <= sof->mpdu_cnt) + || sackd->tei != rx_params->tei + || sackd->lid != rx_params->lid + || sackd->bcast != rx_params->bcast + || sackd->burst_cnt != rx_params->burst_cnt + || sackd->last_mpdu_cnt <= rx_params->mpdu_cnt) { sackd->sackt[0] = PBPROC_FC_SACKT_NOT_RECEIVED; sackd->sackt[1] = PBPROC_FC_SACKT_NOT_RECEIVED; @@ -496,37 +471,36 @@ pbproc_frda_sackd_init (pbproc_t *ctx, const pbproc_fc_sof_t *sof) } /* Record SACKD parameters. */ sackd->valid = true; - sackd->tei = sof->stei; - sackd->lid = sof->lid; - sackd->bcast = sof->mcf; - sackd->cfp = sof->cfs; - sackd->burst_cnt = sof->burst_cnt; - sackd->last_mpdu_cnt = sof->mpdu_cnt; + sackd->tei = rx_params->tei; + sackd->lid = rx_params->lid; + sackd->bcast = rx_params->bcast; + sackd->cfp = rx_params->cfp; + sackd->burst_cnt = rx_params->burst_cnt; + sackd->last_mpdu_cnt = rx_params->mpdu_cnt; /* Initialise SACKD preparation. */ sackd->any_pb_crc_error = false; pbproc_sacki_enc_init (&sackd->sacki_enc, PBPROC_FC_SACK_SACKI_BITS - - (MAC_LID_IS_PLID (sof->lid) ? 4 : 0), + - (MAC_LID_IS_PLID (rx_params->lid) ? 4 : 0), reinit); } static void ARCH_ILRAM -pbproc_frda_error (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof, +pbproc_frda_error (pbproc_t *ctx, u32 rx_date, bool wack, uint sacki_uniform) { dbg_claim (ctx); - dbg_claim (sof); dbg_claim (sacki_uniform < PBPROC_FC_SACKI_UNIFORM_NB); /* First thing to do: unblock the hardware. */ phy_rx_prepare_short (ctx->phy); /* ACK date. */ ctx->recv_mpdu.ack_date = rx_date + ctx->times.pre_fcs_tck - + MAC_FL_TO_TCK (sof->fl_av); + + ctx->recv_mpdu.rx_params.fl_tck; /* With acknowledge? */ if (wack) { /* Prepare SACKD. */ - pbproc_frda_sackd_init (ctx, sof); + pbproc_frda_sackd_init (ctx); ctx->recv_mpdu.sackd.sackt[ctx->recv_mpdu.mpdu_cnt] = PBPROC_FC_SACKT_UNIFORM; pbproc_sacki_enc_copy (&ctx->recv_mpdu.sackd.sacki_enc, -- cgit v1.2.3