summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyril Jourdan2013-03-05 16:21:55 +0100
committerCyril Jourdan2013-03-06 11:30:39 +0100
commit55b0b14083d9890ecb9d878acf84f12073ae2b1b (patch)
tree12e134451cfcd12c0bb2793fd23bdf0f406362b8
parent16809075e991c746d457656be020b99c31b50a98 (diff)
cesar/mac/pbproc: handle received RSOF frames, closes #3803
For the moment, they are handled as frames not for us. This first implementation is done to unify code with EoC and set the basis to a clean management of this kind of frames.
-rw-r--r--cesar/mac/pbproc/inc/fc.h13
-rw-r--r--cesar/mac/pbproc/src/fsm_handle_fc.c42
-rw-r--r--cesar/mac/pbproc/test/pbproc/src/rx_data.c42
3 files changed, 96 insertions, 1 deletions
diff --git a/cesar/mac/pbproc/inc/fc.h b/cesar/mac/pbproc/inc/fc.h
index 11a63f6098..6c6b004307 100644
--- a/cesar/mac/pbproc/inc/fc.h
+++ b/cesar/mac/pbproc/inc/fc.h
@@ -15,8 +15,21 @@
* Be careful to bit order.
*/
+#include "mac/common/timings.h"
+
#include "mac/pbproc/inc/sacki_dec.h"
+/* See ยง4.4.1.5.6.11 in HPAV specification for RSOF_FL_AV computation. */
+/* Convert RSOF_FL_AV value to tick. */
+#define PBPROC_FC_RSOF_FL_AV_TO_TCK(fl) \
+ ((fl) > 512 ? MAC_FL_TO_TCK ((fl) - 512) * 2 + MAC_FL_TO_TCK (512) \
+ : MAC_FL_TO_TCK (fl))
+/* Convert tick to RSOF_FL_AV value. */
+#define PBPROC_FC_TCK_TO_RSOF_FL_AV(tck) \
+ ((tck) > MAC_FL_TO_TCK (512) ? CEIL_DIV ((tck) - MAC_FL_TO_TCK (512), \
+ 2 * MAC_TCK_PER_FL) + 512 \
+ : MAC_TCK_TO_FL (tck))
+
/** Delimiter type. */
enum pbproc_fc_dt_t
{
diff --git a/cesar/mac/pbproc/src/fsm_handle_fc.c b/cesar/mac/pbproc/src/fsm_handle_fc.c
index 3db4e5d467..bf149db18f 100644
--- a/cesar/mac/pbproc/src/fsm_handle_fc.c
+++ b/cesar/mac/pbproc/src/fsm_handle_fc.c
@@ -42,6 +42,15 @@ static void
pbproc_fhfc_sof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av);
/**
+ * Handle RSOF FC.
+ * \param ctx pbproc context
+ * \param rx_date start of preamble date
+ * \param fc_av generic FC
+ */
+static void
+pbproc_fhfc_rsof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t * fc_av);
+
+/**
* Handle RTS/CTS.
* \param ctx pbproc context
* \param rx_date start of preamble date
@@ -128,6 +137,9 @@ pbproc_fhfc_handle_fc (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av)
case PBPROC_FC_DT_SOF:
pbproc_fhfc_sof (ctx, rx_date, fc_av);
break;
+ case PBPROC_FC_DT_RSOF:
+ pbproc_fhfc_rsof (ctx, rx_date, fc_av);
+ break;
case PBPROC_FC_DT_SACK:
pbproc_fhfc_ignore (ctx, rx_date, ctx->times.pre_fcs_tck
+ MAC_CIFS_TCK);
@@ -218,6 +230,15 @@ pbproc_fhfc_parse_sof (pbproc_t *ctx, const pbproc_fc_t *fc_av)
return fc_ok;
}
+static bool ARCH_ILRAM
+pbproc_fhfc_parse_rsof (pbproc_t *ctx, const pbproc_fc_t *fc_av)
+{
+ bool fc_ok = false;
+ /* For the moment, this function returns an error everytime because we do
+ * not handle RSOFs. So they will be processed as frames not for us. */
+ return fc_ok;
+}
+
static void ARCH_ILRAM
pbproc_fhfc_sof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av)
{
@@ -245,6 +266,27 @@ pbproc_fhfc_sof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av)
}
}
+static void ARCH_ILRAM
+pbproc_fhfc_rsof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av)
+{
+ if (pbproc_fhfc_parse_rsof (ctx, fc_av))
+ {
+ pbproc_frda__handle (ctx, rx_date);
+ }
+ else
+ {
+ /* Not for us. We have to wait for next frame, as we do not know if
+ * it will be a SACK or a SOF. */
+ ctx->stats.rx_nfu++;
+ phy_rx_prepare_short (ctx->phy);
+ u32 next_date = rx_date + ctx->times.pre_fcs_tck
+ + PBPROC_FC_RSOF_FL_AV_TO_TCK (fc_av->rsof.rsof_fl_av);
+ ca_access_vcs_restart_eifs (ctx->ca, next_date);
+ phy_rx_activate (ctx->phy, false, next_date, true);
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
+ }
+}
+
static __attribute__ ((noinline)) void
pbproc_fhfc_rts_cts (pbproc_t *ctx, u32 rx_date,
const pbproc_fc_rts_cts_t *fc)
diff --git a/cesar/mac/pbproc/test/pbproc/src/rx_data.c b/cesar/mac/pbproc/test/pbproc/src/rx_data.c
index 7bc2f7eb11..d82892b20f 100644
--- a/cesar/mac/pbproc/test/pbproc/src/rx_data.c
+++ b/cesar/mac/pbproc/test/pbproc/src/rx_data.c
@@ -907,6 +907,7 @@ rx_data_burst_test_case (test_t t)
enum rx_data_nfu_t
{
NFU_SACK,
+ NFU_RSOF,
NFU_SOF_ACCESS,
NFU_SOF_SNID,
NFU_SOF_TEI,
@@ -928,6 +929,8 @@ rx_data_nfu_test (test_t t, test_pbproc_t *tp, u32 date, rx_data_nfu_t nfu)
pbproc_fc_t fc;
const uint sof_fl_tck = MAC_PAYLOAD_TCK (45, MAC_DX417_TCK)
+ MAC_RIFS_DEFAULT_TCK;
+ const uint rsof_fl_tck = MAC_PAYLOAD_TCK (15, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK;
bool eifs;
uint dtei;
if (nfu == NFU_SOF_UNASSOC_SNID)
@@ -971,6 +974,31 @@ rx_data_nfu_test (test_t t, test_pbproc_t *tp, u32 date, rx_data_nfu_t nfu)
.bm_sacki = 0xf,
.fccs_av = 0,
};
+ pbproc_fc_rsof_t rsof_fc = {
+ .dt_av = PBPROC_FC_DT_RSOF,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = dtei,
+ .cfs = false,
+ .bdf = true,
+ .svn = 0,
+ .rrtf = false,
+ .mfs_rsp_mgmt = MFS_FSM_RSP_ACK,
+ .mfs_rsp_data = MFS_FSM_RSP_ACK,
+ .sackt3 = 0,
+ .sackt2 = 0,
+ .sackt1 = 0,
+ .sackt0 = 0,
+ .sacki_lsb = 0,
+ .sacki_msb = 0,
+ .rsof_fl_av = PBPROC_FC_TCK_TO_RSOF_FL_AV (rsof_fl_tck),
+ .tmi_av = PHY_MOD_ROBO,
+ .pbsz = false,
+ .num_sym = MIN (15u, 3u),
+ .mfs_cmd_mgmt = MFS_FSM_CMD_NOP,
+ .mfs_cmd_data = MFS_FSM_CMD_NOP,
+ .fccs_av = 0,
+ };
pbproc_fc_sack_t sack_fc = {
.dt_av = PBPROC_FC_DT_SACK,
.access = false,
@@ -995,6 +1023,13 @@ rx_data_nfu_test (test_t t, test_pbproc_t *tp, u32 date, rx_data_nfu_t nfu)
fc.sack = sack_fc;
length_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK;
}
+ else if (nfu == NFU_RSOF)
+ {
+ fc.rsof = rsof_fc;
+ length_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + PBPROC_FC_RSOF_FL_AV_TO_TCK (
+ PBPROC_FC_TCK_TO_RSOF_FL_AV (rsof_fl_tck));
+ }
else
{
fc.sof = sof_fc;
@@ -1015,7 +1050,8 @@ rx_data_nfu_test (test_t t, test_pbproc_t *tp, u32 date, rx_data_nfu_t nfu)
{
restart_date = date;
}
- eifs = (nfu == NFU_SOF_TEI_BURST) || (nfu == NFU_SOF_TEI_BIDIR_BURST);
+ eifs = (nfu == NFU_SOF_TEI_BURST) || (nfu == NFU_SOF_TEI_BIDIR_BURST)
+ || (nfu == NFU_RSOF);
uint our_tei_saved = tp->config.tei;
if (nfu == NFU_SOF_UNASSOC_SNID)
tp->config.tei = 0;
@@ -1497,6 +1533,10 @@ rx_data_errors_test_case (test_t t)
{
rx_data_nfu_test (t, &tp, 123546, NFU_SACK);
} test_end;
+ test_begin (t, "nfu rsof")
+ {
+ rx_data_nfu_test (t, &tp, 123, NFU_RSOF);
+ } test_end;
test_begin (t, "nfu sof")
{
rx_data_nfu_test (t, &tp, 12354, NFU_SOF_ACCESS);