summaryrefslogtreecommitdiff
path: root/cesar/mac
diff options
context:
space:
mode:
authorjelisavcic2009-08-05 11:00:09 +0000
committerjelisavcic2009-08-05 11:00:09 +0000
commit5783e1b66c64c8bf17bc6c6178386a0387a53651 (patch)
tree702db7cc1c2add657ecab1a643ed3c384c671f2d /cesar/mac
parent6bed3e6b086080612bb41ea280380ebbb9b10016 (diff)
[EOC][MAC][PBPROC]:Changes for EOC. SOF,RSOF format changed.
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@5158 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/mac')
-rw-r--r--cesar/mac/ca/ca.h18
-rw-r--r--cesar/mac/ca/src/access.c21
-rw-r--r--cesar/mac/common/defs.h36
-rw-r--r--cesar/mac/pbproc/inc/context.h8
-rw-r--r--cesar/mac/pbproc/inc/fc.h7
-rw-r--r--cesar/mac/pbproc/inc/fsm_rx_data.h4
-rw-r--r--cesar/mac/pbproc/inc/prep_mpdu.h16
-rw-r--r--cesar/mac/pbproc/src/fsm_handle_fc.c51
-rw-r--r--cesar/mac/pbproc/src/fsm_rx_data.c153
-rw-r--r--cesar/mac/pbproc/src/fsm_tx_data.c29
-rw-r--r--cesar/mac/pbproc/src/prep_mpdu.c147
11 files changed, 462 insertions, 28 deletions
diff --git a/cesar/mac/ca/ca.h b/cesar/mac/ca/ca.h
index 18a5c73c1c..d7c6cfd9ce 100644
--- a/cesar/mac/ca/ca.h
+++ b/cesar/mac/ca/ca.h
@@ -120,6 +120,8 @@ struct ca_access_param_t
uint beacon_period_start_date;
/** Available time. */
uint duration_tck;
+ /** Available time for reverse transmission. */
+ uint reverse_duration_tck;
/** Is there a PRP? */
bool prp:1;
/** Does it occurs during a contention free period? This flag is used to
@@ -227,6 +229,22 @@ void
ca_access_program (ca_t *ctx, u32 date, uint anticipation_tck);
/**
+ * Reprogram access structure.
+ * \param ctx ca context
+ * \param date expiration date
+ * \param duration_tck grant duration
+ * \param lid lid to find proper mfs
+ * \param tei TEI fo find proper mfs
+ *
+ * Reprograme ca->access structure. This is done when you send RSOF instead
+ * of SOF. Use this artificial feeding of CA to bypass schedule structures in
+ * CA. After this FSM could behave as usual.
+ */
+void
+ca_access_reprogram (ca_t *ctx, u32 date, uint duration_tck,
+ uint lid, uint tei);
+
+/**
* Update next ACCESS information for the given grant.
* \param ctx ca context
* \param mfs granted MFS or NULL for any MFS
diff --git a/cesar/mac/ca/src/access.c b/cesar/mac/ca/src/access.c
index 50577c8ee8..47dc64c412 100644
--- a/cesar/mac/ca/src/access.c
+++ b/cesar/mac/ca/src/access.c
@@ -380,6 +380,26 @@ ca_access_program (ca_t *ctx, u32 date, uint anticipation_tck)
}
void
+ca_access_reprogram (ca_t *ctx, u32 date, uint duration_tck,
+ uint lid, uint tei)
+{
+ /* Find proper mfs: examine heap and if mme mfs OK, else orig mfs. */
+ mfs_tx_t * mfs;
+ mfs = mac_store_mfs_get_tx (ctx->store, false, false, lid, tei);
+ /* If mfs is found program CA */
+ if (mfs)
+ {
+ /* Feed CA with data about frame that has to be sent in */
+ ca_access_grant (ctx, mfs, date, duration_tck);
+ blk_release (mfs); /* previous call increment reference, avoid dbl */
+ }
+ else
+ {
+ /* TODO Error handling, no mfs. Should't be here */
+ }
+}
+
+void
ca_access_grant (ca_t *ctx, mfs_tx_t *mfs, u32 date, uint duration_tck)
{
dbg_assert (ctx && ctx->state != CA_STATE_IDLE);
@@ -407,6 +427,7 @@ ca_access_grant (ca_t *ctx, mfs_tx_t *mfs, u32 date, uint duration_tck)
blk_addref (mfs);
ctx->access_param.access_date = date;
ctx->access_param.duration_tck = duration_tck;
+ ctx->access_param.reverse_duration_tck = 0;
ctx->access_param.prp = false;
ctx->access_param.cfp = true;
ctx->access_param.hybrid = false; /* TODO */
diff --git a/cesar/mac/common/defs.h b/cesar/mac/common/defs.h
index 681e2644ab..4571e80ba1 100644
--- a/cesar/mac/common/defs.h
+++ b/cesar/mac/common/defs.h
@@ -25,6 +25,8 @@
/** Maximum number of physical PHY blocks per MPDU. */
#define MAC_MAX_PB_PER_MPDU 236
+#include "config/pbproc/fc/eoc.h"
+
/** Link identifiers. */
enum mac_lid_t
{
@@ -74,22 +76,41 @@ enum mac_lid_t
enum mac_tei_t
{
MAC_TEI_UNASSOCIATED = 0,
- MAC_TEI_STA_MIN = 1,
- MAC_TEI_STA_MAX = 0xfe,
- MAC_TEI_STA_NB = MAC_TEI_STA_MAX - MAC_TEI_STA_MIN + 1,
MAC_TEI_BCAST = 0xff,
/** Used to request unicast transmission to all stations in the AVLN. */
MAC_TEI_MULTI_UNICAST = 0x100,
/** Used for peers not present on the medium (HLE driver or other bridged
* address). */
MAC_TEI_FOREIGN = 0x200,
+#if CONFIG_PBPROC_FC_EOC
+ MAC_TEI_CCO_MIN = 1,
+ MAC_TEI_CCO_MAX = 2,
+ MAC_TEI_STA_MIN = MAC_TEI_CCO_MAX + 1,
+ MAC_TEI_STA_NB = 128,
+ MAC_TEI_STA_MAX = MAC_TEI_STA_MIN + MAC_TEI_STA_NB - 1,
+ MAC_TEI_MCAST_MAX = MAC_TEI_BCAST - 1,
+ MAC_TEI_MCAST_NB = 5,
+ MAC_TEI_MCAST_MIN = MAC_TEI_MCAST_MAX - MAC_TEI_MCAST_NB + 1,
+#else
+ MAC_TEI_STA_MIN = 1,
+ MAC_TEI_STA_MAX = 0xfe,
+ MAC_TEI_STA_NB = MAC_TEI_STA_MAX - MAC_TEI_STA_MIN + 1,
+#endif
};
/** Test if a TEI is between STA_MIN and STA_MAX.
* \warning This is a macro, the argument may be evaluated several time. */
+#if CONFIG_PBPROC_FC_EOC
+#define MAC_TEI_IS_EOC_CCO(tei) \
+ ((tei) >= MAC_TEI_CCO_MIN && (tei) <= MAC_TEI_CCO_MAX)
+#define MAC_TEI_IS_EOC_STA(tei) \
+ ((tei) >= MAC_TEI_CCO_MAX+1 && (tei) <= MAC_TEI_STA_MAX)
+#define MAC_TEI_IS_STA(tei) \
+ ((tei) >= MAC_TEI_CCO_MIN && (tei) <= MAC_TEI_MCAST_MAX)
+#else
#define MAC_TEI_IS_STA(tei) \
((tei) >= MAC_TEI_STA_MIN && (tei) <= MAC_TEI_STA_MAX)
-
+#endif
/** Coexistence modes.
* \warning Full Hybrid mode is also used in CSMA-Only with HomePlug 1.0
* compatible frame length. This maps directly to beacon HM field. */
@@ -107,9 +128,14 @@ typedef enum mac_coexistence_mode_t mac_coexistence_mode_t;
enum mac_eks_t
{
MAC_EKS_MIN = 0,
+#if CONFIG_PBPROC_FC_EOC
+ MAC_EKS_CLEAR = 0x3,
+ MAC_EKS_MAX = 2,
+#else
+ MAC_EKS_CLEAR = 0xf,
MAC_EKS_MAX = 7,
+#endif
MAC_EKS_NB = MAC_EKS_MAX - MAC_EKS_MIN + 1,
- MAC_EKS_CLEAR = 0xf,
};
#endif /* mac_common_defs_h */
diff --git a/cesar/mac/pbproc/inc/context.h b/cesar/mac/pbproc/inc/context.h
index 35973d6edc..8a2feed235 100644
--- a/cesar/mac/pbproc/inc/context.h
+++ b/cesar/mac/pbproc/inc/context.h
@@ -88,6 +88,14 @@ struct pbproc_recv_mpdu_t
bool drop;
/** SACK data. */
pbproc_sackd_t sackd;
+#if CONFIG_PBPROC_FC_EOC
+ /** Bidirectional flag */
+ bool bbf;
+ /** all_ok */
+ bool all_ok;
+ /** Duration of RSOF frame */
+ u32 mrtfl;
+#endif
};
typedef struct pbproc_recv_mpdu_t pbproc_recv_mpdu_t;
diff --git a/cesar/mac/pbproc/inc/fc.h b/cesar/mac/pbproc/inc/fc.h
index c374930dd4..5c1a0bc49e 100644
--- a/cesar/mac/pbproc/inc/fc.h
+++ b/cesar/mac/pbproc/inc/fc.h
@@ -206,6 +206,13 @@ struct pbproc_fc_sof_t
/** FCCS. */
uint fccs_av:24;)
};
+
+/** EOC SACK Size. */
+enum pbproc_fc_sackt_eoc_size_t
+{
+ PBPROC_FC_SACKT_EOC_SOF_SIZE = 32+8,
+ PBPROC_FC_SACKT_EOC_RSOF_SIZE = 32+19+8,
+};
#endif
typedef struct pbproc_fc_sof_t pbproc_fc_sof_t;
diff --git a/cesar/mac/pbproc/inc/fsm_rx_data.h b/cesar/mac/pbproc/inc/fsm_rx_data.h
index 6e9eddf707..ca8ceb4346 100644
--- a/cesar/mac/pbproc/inc/fsm_rx_data.h
+++ b/cesar/mac/pbproc/inc/fsm_rx_data.h
@@ -26,10 +26,10 @@ 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
+ * \param fc_av 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, const pbproc_fc_t *fc_av);
/**
* RX DATA WACK =PBDMA=>.
diff --git a/cesar/mac/pbproc/inc/prep_mpdu.h b/cesar/mac/pbproc/inc/prep_mpdu.h
index 88d0c5c05f..cb9fed27cf 100644
--- a/cesar/mac/pbproc/inc/prep_mpdu.h
+++ b/cesar/mac/pbproc/inc/prep_mpdu.h
@@ -104,6 +104,10 @@ struct pbproc_prep_mpdu_t
bool bypass_aes;
/** AES network encryption key. */
u32 *nek;
+ /** Network encryption key select, RSOF */
+ uint eks:2;
+ /** bidirection transmission, RSOF */
+ bool bbf;
};
typedef struct pbproc_prep_mpdu_t pbproc_prep_mpdu_t;
@@ -181,6 +185,18 @@ void
pbproc_prep_mpdu_fsm_response (pbproc_t *ctx, mfs_fsm_rsp_t mfs_rsp_data,
mfs_fsm_rsp_t mfs_rsp_mgmt);
+
+#if CONFIG_PBPROC_FC_EOC
+/**
+ * Ack contained in SOF/RSOF.
+ * \param ctx pbproc context
+ * \param fc_av FC generic pointer (SOF or RSOF)
+ */
+/* Handling of SACK field in SOF/RSOF */
+void
+pbproc_prep_mpdu_ack (pbproc_t *ctx, const pbproc_fc_t *fc_av);
+#endif
+
END_DECLS
#endif /* mac_pbproc_inc_prep_mpdu_h */
diff --git a/cesar/mac/pbproc/src/fsm_handle_fc.c b/cesar/mac/pbproc/src/fsm_handle_fc.c
index 4c6a5fc2d0..1932b3103a 100644
--- a/cesar/mac/pbproc/src/fsm_handle_fc.c
+++ b/cesar/mac/pbproc/src/fsm_handle_fc.c
@@ -31,13 +31,13 @@ pbproc_fhfc_beacon (pbproc_t *ctx, u32 rx_date,
const pbproc_fc_beacon_t *beacon);
/**
- * Handle SOF FC.
+ * Handle SOF/RSOF FC.
* \param ctx pbproc context
* \param rx_date start of preamble date
- * \param sof SOF FC
+ * \param fc_av generic FC
*/
-static void
-pbproc_fhfc_sof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof);
+static void
+pbproc_fhfc_sof_rsof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t * fc_av);
/**
* Handle SOUND FC.
@@ -93,7 +93,8 @@ 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);
+ case PBPROC_FC_DT_RSOF:
+ pbproc_fhfc_sof_rsof (ctx, rx_date, fc_av);
break;
case PBPROC_FC_DT_SACK:
pbproc_fhfc_ignore (ctx, rx_date, ctx->times[hybrid].pre_fcs_tck +
@@ -123,20 +124,44 @@ pbproc_fhfc_beacon (pbproc_t *ctx, u32 rx_date,
}
static void ARCH_ILRAM
-pbproc_fhfc_sof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
+pbproc_fhfc_sof_rsof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t * fc_av)
{
const bool hybrid = ctx->alloc.hybrid;
- PBPROC_TRACE (FHFC_SOF, sof->dtei, sof->lid);
- if (sof->access == false
- && (sof->snid == ctx->alloc.snid || sof->mnbf)
- && (sof->dtei == ctx->config->tei || sof->mcf))
+ bool accept_frame = false;
+ /* TODO PBPROC_TRACE (FHFC_RSOF, sof->dtei, sof->lid); */
+ /* Accept RSOF */
+ if (fc_av->generic.dt_av == PBPROC_FC_DT_RSOF
+ && fc_av->rsof.access == false
+ && (fc_av->rsof.snid == ctx->alloc.snid)
+ && ctx->prep_mpdu.valid
+ && ctx->prep_mpdu.bbf)
+ accept_frame = true;
+ /* Accept SOF */
+ if (fc_av->generic.dt_av == PBPROC_FC_DT_SOF
+ && !accept_frame
+ && fc_av->sof.access == false
+ && (fc_av->sof.snid == ctx->alloc.snid || fc_av->sof.mnbf)
+#if CONFIG_PBPROC_FC_EOC
+ && ((fc_av->sof.dtei == ctx->config->tei)
+ || fc_av->sof.mcf
+ || (fc_av->sof.direction
+ && MAC_TEI_IS_EOC_CCO(ctx->config->tei))))
+#else
+ && (fc_av->sof.dtei == ctx->config->tei || fc_av->sof.mcf))
+#endif
+ accept_frame = true;
+ /* What is the decision? */
+ if (accept_frame)
{
- pbproc_frda__handle (ctx, rx_date, sof);
+ pbproc_frda__handle (ctx, rx_date, fc_av); /* Handle SOF/RSOF FC */
}
else
{
- /* Not for us, count the expected following SACK. */
- pbproc_fhfc_ignore (ctx, rx_date, MAC_FL_TO_TCK (sof->fl_av)
+ /* Not for us */
+ pbproc_fhfc_ignore (ctx, rx_date,
+ MAC_FL_TO_TCK ((fc_av->generic.dt_av == PBPROC_FC_DT_SOF)?
+ fc_av->sof.fl_av:
+ fc_av->rsof.rsof_fl_av)
+ 2 * ctx->times[hybrid].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 ce6b341144..3bcf7b1a08 100644
--- a/cesar/mac/pbproc/src/fsm_rx_data.c
+++ b/cesar/mac/pbproc/src/fsm_rx_data.c
@@ -62,7 +62,6 @@ pbproc_frda_error (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof,
*/
static void
pbproc_frda_commit (pbproc_t *ctx);
-
void
pbproc_frda_init (pbproc_t *ctx)
{
@@ -80,26 +79,48 @@ 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, const pbproc_fc_t *fc_av)
{
const bool hybrid = ctx->alloc.hybrid;
bool wack, unassociated;
+ const pbproc_fc_sof_t *sof = &fc_av->sof;
dbg_assert (ctx);
dbg_assert (sof);
/* TODO features. */
dbg_assert (sof->pbsz == false);
dbg_assert (sof->num_sym != 0);
dbg_assert (sof->bbf == false);
+#if !CONFIG_PBPROC_FC_EOC
dbg_assert (sof->dcppcf == false);
dbg_assert (sof->rsr == false);
/* Unassociated? */
unassociated = sof->stei == 0 || sof->mnbf;
/* With ACK? */
wack = sof->snid == ctx->alloc.snid && sof->dtei == ctx->config->tei;
+#else
+ if (fc_av->generic.dt_av == PBPROC_FC_DT_SOF)
+ {
+ /* Unassociated? */
+ unassociated = sof->dtei == 0 || sof->mnbf;
+ }
+ /* Unassociated? Not true if RSOF in EOC */
+ else if (fc_av->generic.dt_av == PBPROC_FC_DT_RSOF)
+ {
+ unassociated = false;
+ }
+ /* ACK: C->S if there is no bursting, S->C if SOF always (its CSMA) */
+ wack = sof->snid == ctx->alloc.snid
+ && !sof->bbf
+ && ((sof->dtei == ctx->config->tei && !sof->direction)
+ || (MAC_TEI_IS_EOC_CCO(ctx->config->tei)
+ && sof->direction
+ && sof->dtei != MAC_TEI_BCAST));
+#endif
/* Burst? */
ctx->recv_mpdu.mpdu_cnt = sof->mpdu_cnt;
/* Get tonemap. */
- uint tmi = sof->tmi_av;
+ uint tmi = (fc_av->generic.dt_av == PBPROC_FC_DT_SOF)?sof->tmi_av:
+ ((pbproc_fc_rsof_t *)fc_av)->tmi_av;
tonemap_t *tm;
uint rifs_tck;
if (tmi < PHY_MOD_ROBO_NB)
@@ -117,7 +138,24 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
{
dbg_assert (wack);
dbg_assert (tmi < TONEMAP_INDEX_NB);
+#if !CONFIG_PBPROC_FC_EOC
sta_t *sta = mac_store_sta_get (ctx->store, sof->stei);
+#else
+ sta_t *sta;
+ uint tei;
+ if (fc_av->generic.dt_av == PBPROC_FC_DT_SOF)
+ {
+ if (sof->direction == 1)
+ tei = sof->dtei;
+ else
+ tei = 1; /*TODO put define */
+ }
+ else if (fc_av->generic.dt_av == PBPROC_FC_DT_RSOF)
+ {
+ tei = ((pbproc_fc_rsof_t *)fc_av)->dtei;
+ }
+ sta = mac_store_sta_get (ctx->store, tei);
+#endif
if (sta)
{
tm = sta->rx_tonemaps->tm[tmi];
@@ -162,7 +200,24 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
{
if (unassociated)
break;
+#if !CONFIG_PBPROC_FC_EOC
sta_t *sta = mac_store_sta_get (ctx->store, sof->stei);
+#else
+ sta_t *sta;
+ uint tei;
+ if (fc_av->generic.dt_av == PBPROC_FC_DT_SOF)
+ {
+ if (sof->direction == 1)
+ tei = sof->dtei;
+ else
+ tei = 1; /*TODO put define */
+ }
+ else if (fc_av->generic.dt_av == PBPROC_FC_DT_RSOF)
+ {
+ tei = ((pbproc_fc_rsof_t *)fc_av)->dtei;
+ }
+ sta = mac_store_sta_get (ctx->store, tei);
+#endif
mac_nek_t (*nek)[2];
if (sta)
{
@@ -202,6 +257,7 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
/* Save received MPDU parameters. */
ctx->recv_mpdu.rx_params.preamble_ntb = rx_date
+ ctx->config->ntb_offset_tck;
+#if !CONFIG_PBPROC_FC_EOC
ctx->recv_mpdu.rx_params.tei = sof->stei;
ctx->recv_mpdu.rx_params.lid = sof->lid;
ctx->recv_mpdu.rx_params.snid = sof->snid;
@@ -218,6 +274,53 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
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;
+#else
+ if (fc_av->generic.dt_av == PBPROC_FC_DT_SOF)
+ {
+ ctx->recv_mpdu.rx_params.tei = sof->direction?sof->dtei:1;/*TODO chk*/
+ 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 = true; /* TODO check */
+ 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 = 0;
+ ctx->recv_mpdu.rx_params.ble = 0;
+ ctx->recv_mpdu.rx_params.tmi_av = sof->tmi_av;
+ ctx->recv_mpdu.rx_params.bdf = 0;
+ ctx->recv_mpdu.rx_params.hp10df = false;
+ ctx->recv_mpdu.rx_params.hp11df = false;
+ ctx->recv_mpdu.rx_params.mfs_cmd_data = MFS_FSM_CMD_NOP;
+ ctx->recv_mpdu.rx_params.mfs_cmd_mme = MFS_FSM_CMD_NOP;
+ /* Store bbf and mrtlf for RSOF */
+ ctx->recv_mpdu.bbf = sof->bbf;
+ ctx->recv_mpdu.mrtfl = sof->mrtfl;
+ }
+ else
+ {
+ const pbproc_fc_rsof_t *rsof = &fc_av->rsof;
+ ctx->recv_mpdu.rx_params.tei = rsof->dtei;
+ ctx->recv_mpdu.rx_params.lid = ctx->prep_mpdu.lid;
+ ctx->recv_mpdu.rx_params.eks = ctx->prep_mpdu.eks;
+ ctx->recv_mpdu.rx_params.snid = rsof->snid;
+ ctx->recv_mpdu.rx_params.bcast = false; /* No bcast while RSOF */
+ ctx->recv_mpdu.rx_params.cfp = true; /* TODO check */
+ ctx->recv_mpdu.rx_params.multi_net_bcast = false; /* Same as bcast */
+ ctx->recv_mpdu.rx_params.sound = false;
+ /* ctx->recv_mpdu.rx_params.eks = ctx->prep_mpdu.eks; */
+ ctx->recv_mpdu.rx_params.pending_seg_nb = 0;
+ ctx->recv_mpdu.rx_params.ble = 0;
+ ctx->recv_mpdu.rx_params.tmi_av = rsof->tmi_av;
+ ctx->recv_mpdu.rx_params.bdf = 0;
+ ctx->recv_mpdu.rx_params.hp10df = false;
+ ctx->recv_mpdu.rx_params.hp11df = false;
+ ctx->recv_mpdu.rx_params.mfs_cmd_data = MFS_FSM_CMD_NOP;
+ ctx->recv_mpdu.rx_params.mfs_cmd_mme = MFS_FSM_CMD_NOP;
+ ctx->recv_mpdu.bbf = false;
+ ctx->recv_mpdu.mrtfl = 0;
+ }
+#endif
ctx->recv_mpdu.pb_nb = pb_nb;
ctx->recv_mpdu.ack_date = rx_date + ctx->times[hybrid].pre_fcs_tck
+ fl_tck;
@@ -300,6 +403,32 @@ pbproc_frda__rx_data_wack_last_pb__pbdma (pbproc_t *ctx)
dbg_assert (ctx);
/* Prepare SACKD. */
bool all_ok = !ctx->pbdma_status.pb_crc_error;
+
+#if CONFIG_PBPROC_FC_EOC
+ /* Check if this is for reverse transmission
+ * else do ordinary sack confirmation, only STA context could use */
+ /* TODO this could be used in both releases, check */
+ if (ctx->recv_mpdu.bbf)
+ {
+ if (!all_ok)
+ {
+ pbproc_sacki_enc_process (&ctx->recv_mpdu.sackd.sacki_enc,
+ phy_pbdma_get_crc_bitmap (ctx->phy),
+ ctx->recv_mpdu.pb_nb, true);
+ }
+ ca_access_reprogram (ctx->ca, ctx->recv_mpdu.ack_date,
+ ctx->recv_mpdu.mrtfl,
+ ctx->recv_mpdu.rx_params.lid,
+ ctx->recv_mpdu.rx_params.tei);
+ /* Save received frame status */
+ ctx->recv_mpdu.all_ok = all_ok;
+ /* prepare for next access */
+ pbproc_ftop__idle__access (ctx);
+ /* Unchain and give received frame to upper layer, NO vcs restart */
+ pbproc_frda_commit (ctx);
+ return;
+ }
+#endif
if (all_ok)
{
/* All OK, use uniform encoding. */
@@ -379,6 +508,7 @@ pbproc_frda_commit (pbproc_t *ctx)
rx->rx->chandata_nb = ctx->recv_mpdu.chandata_nb;
slist_push_back (ctx->commit.rx_, rx);
pbproc_fsm_schedule_deferred (ctx);
+ /* TODO EOC handle received SACK information from */
}
dbg_invalid_ptr (ctx->recv_mpdu.pb_head);
dbg_invalid_ptr (ctx->recv_mpdu.pb_tail);
@@ -411,10 +541,14 @@ pbproc_frda_sackd_init (pbproc_t *ctx, const pbproc_fc_sof_t *sof)
bool reinit = false;
pbproc_sackd_t *sackd = &ctx->recv_mpdu.sackd;
if (!sackd->valid
+#if !CONFIG_PBPROC_FC_EOC
|| sackd->tei != sof->stei
- || sackd->lid != sof->lid
- || sackd->burst_cnt != sof->burst_cnt
- || sackd->last_mpdu_cnt <= sof->mpdu_cnt)
+#else
+ || sackd->tei != ((sof->direction)?sof->dtei:1)
+#endif
+ || sackd->lid != (u8)sof->lid
+ || sackd->burst_cnt != (u8)sof->burst_cnt
+ || sackd->last_mpdu_cnt <= (u8)sof->mpdu_cnt)
{
sackd->sackt[0] = PBPROC_FC_SACKT_NOT_RECEIVED;
sackd->sackt[1] = PBPROC_FC_SACKT_NOT_RECEIVED;
@@ -424,9 +558,14 @@ pbproc_frda_sackd_init (pbproc_t *ctx, const pbproc_fc_sof_t *sof)
}
/* Record SACKD parameters. */
sackd->valid = true;
+#if !CONFIG_PBPROC_FC_EOC
sackd->tei = sof->stei;
- sackd->lid = sof->lid;
sackd->cfp = sof->cfs;
+#else
+ sackd->tei = sof->direction?sof->dtei:1;
+ sackd->cfp = ctx->access.cfp;
+#endif
+ sackd->lid = sof->lid;
sackd->burst_cnt = sof->burst_cnt;
sackd->last_mpdu_cnt = sof->mpdu_cnt;
/* Initialise SACKD preparation. */
diff --git a/cesar/mac/pbproc/src/fsm_tx_data.c b/cesar/mac/pbproc/src/fsm_tx_data.c
index 6f8da8b386..2b20df2cfc 100644
--- a/cesar/mac/pbproc/src/fsm_tx_data.c
+++ b/cesar/mac/pbproc/src/fsm_tx_data.c
@@ -157,7 +157,7 @@ pbproc_ftda__tx_wait_sackd__rx_fc (pbproc_t *ctx, u32 rx_date,
&& 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
+ && less_mod2p32 (rx_date, ctx->prep_mpdu.tx_date
+ ctx->prep_mpdu.flp_tck + MAC_TOLERANCE_TCK))
{
phy_rx_prepare_short (ctx->phy);
@@ -209,6 +209,32 @@ pbproc_ftda__tx_wait_sackd__rx_fc (pbproc_t *ctx, u32 rx_date,
}
else
{
+#if CONFIG_PBPROC_FC_EOC
+ /* Place for EOC SACKD encapsulated in next frame
+ * if CCO and RSOF it is our SACKD else if SOF and STA
+ * and valid mpdu that it is our SACKD */
+ if (fc_av
+ && fc_av->generic.access == false
+ && fc_av->generic.snid == ctx->alloc.snid
+ && ctx->prep_mpdu.valid
+ && less_mod2p32 (rx_date, ctx->prep_mpdu.tx_date /* TODO chk timeval*/
+ + ctx->prep_mpdu.flp_tck + MAC_TOLERANCE_TCK)
+ && ((fc_av->generic.dt_av == PBPROC_FC_DT_SOF
+ && MAC_TEI_IS_EOC_STA(ctx->config->tei))
+ || (fc_av->generic.dt_av == PBPROC_FC_DT_RSOF
+ && MAC_TEI_IS_EOC_CCO(ctx->config->tei))))
+ {
+ pbproc_prep_mpdu_ack (ctx, fc_av);
+ }
+ else
+ { /* Time expired, noise on line */
+ if (ctx->prep_mpdu.valid)
+ {
+ pbproc_prep_mpdu_cancel (ctx);
+ ctx->stats.data_fail++;
+ }
+ }
+#else
/* Not our SACK, may contain our SACKD. */
#if 0
if (our sackd)
@@ -222,6 +248,7 @@ pbproc_ftda__tx_wait_sackd__rx_fc (pbproc_t *ctx, u32 rx_date,
pbproc_prep_mpdu_cancel (ctx);
ctx->stats.data_fail++;
}
+#endif
pbproc_fhfc_handle_fc (ctx, rx_date, fc_av);
}
}
diff --git a/cesar/mac/pbproc/src/prep_mpdu.c b/cesar/mac/pbproc/src/prep_mpdu.c
index 17398771c9..ac910b3221 100644
--- a/cesar/mac/pbproc/src/prep_mpdu.c
+++ b/cesar/mac/pbproc/src/prep_mpdu.c
@@ -194,6 +194,7 @@ pbproc_prep_mpdu (pbproc_t *ctx)
prep->wack = !mfs->common.bcast;
prep->unassociated = mfs->common.unassociated;
prep->burst = false; /* TODO */
+ prep->bbf = false; /* TODO */
prep->fc_mode = PHY_FC_MODE (access->hybrid, ctx->config->fc_symbols_nb);
prep->stei = (!mfs->common.bcast && prep->unassociated) ? 0 : ctx->config->tei;
/* Should we use RTS CTS?
@@ -432,10 +433,13 @@ pbproc_prep_mpdu (pbproc_t *ctx)
}
}
prep->bypass_aes = eks == MAC_EKS_CLEAR;
+ prep->eks = eks; /* Easy life */
+
// TODO: dbg_assert (mfs->common.mme || !prep->bypass_aes);
/* Data FC. */
prep->main_mfs_cmd = mfs->fsm_state;
prep->main_mfs_rsp = MFS_FSM_RSP_NB;
+#if !CONFIG_PBPROC_FC_EOC
if (1 /* TODO */)
{
pbproc_fc_sof_t *sof_fc = &prep->fc_av.sof;
@@ -479,6 +483,101 @@ pbproc_prep_mpdu (pbproc_t *ctx)
sof_fc->mfs_rsp_data = MFS_FSM_RSP_ACK; /* TODO */
sof_fc->bm_sacki = 0xf; /* TODO */
}
+#else
+ /* decision what to choose SOF or RSOF depend on position,
+ * SOF = cco or BCAST/MCAST, RSOF = sta only */
+ int s_r_decision=0;
+ /* Recv is valid and RSOF is requested */
+ if (/*ctx->recv_mpdu.valid && */ctx->recv_mpdu.bbf)
+ {
+ s_r_decision = 1;
+ }
+ /* prepare RSOF/SOF by EOC specification */
+ if (s_r_decision)
+ {
+ pbproc_fc_rsof_t *rsof_fc = &prep->fc_av.rsof;
+ rsof_fc->dt_av = PBPROC_FC_DT_RSOF;
+ rsof_fc->access = false;
+ rsof_fc->snid = ctx->alloc.snid;
+ rsof_fc->dtei = ctx->config->tei;
+ rsof_fc->pbsz = false;
+ rsof_fc->num_sym = symb_nb < 3 ? symb_nb : 3;
+ rsof_fc->tmi_av = tmi;
+ rsof_fc->bdf = true; /* TODO */
+ rsof_fc->rsof_fl_av = MAC_TCK_TO_FL (data_tck + rifs_tck);
+ rsof_fc->ppb = 0; /* TODO num pending blocks */
+ if (1/*ctx->recv_mpdu.valid*/)
+ {
+ if (!ctx->recv_mpdu.all_ok)
+ {
+ rsof_fc->sackt0 = PBPROC_FC_SACKT_MIXED_COMPRESSED;
+ rsof_fc->sacki0 = ctx->recv_mpdu.sackd.sacki_enc.si[0];
+ rsof_fc->sacki1 = ctx->recv_mpdu.sackd.sacki_enc.si[1];
+ rsof_fc->sacki2 = ctx->recv_mpdu.sackd.sacki_enc.si[1] >> 19;
+ }
+ else
+ {
+ rsof_fc->sackt0 = PBPROC_FC_SACKT_UNIFORM;
+ rsof_fc->sacki0 = PBPROC_FC_SACKI_UNIFORM_ALL_OK;
+ }
+ }
+ else
+ { /* Could be also ALL_ERROR */
+ rsof_fc->sackt0 = PBPROC_FC_SACKT_UNIFORM;
+ rsof_fc->sacki0 = PBPROC_FC_SACKI_UNIFORM_NOT_AVAILABLE;
+ }
+ }
+ else
+ {
+ pbproc_fc_sof_t *sof_fc = &prep->fc_av.sof;
+ prep->bbf = !mfs->common.mme && !sof_fc->mcf
+ && MAC_TEI_IS_EOC_CCO(prep->stei)
+ && access->cfp
+ && access->reverse_duration_tck;
+ /* Set the fields */
+ sof_fc->dt_av = PBPROC_FC_DT_SOF;
+ sof_fc->access = false;
+ sof_fc->snid = ctx->alloc.snid;
+ sof_fc->dtei = prep->dtei;
+ sof_fc->direction = MAC_TEI_IS_EOC_STA(prep->stei);
+ sof_fc->lid = prep->lid;
+ sof_fc->eks = eks;
+ sof_fc->pbsz = false;
+ sof_fc->num_sym = symb_nb < 3 ? symb_nb : 3;
+ sof_fc->tmi_av = tmi;
+ sof_fc->mcf = mfs->common.bcast;
+ sof_fc->mnbf = mfs->common.bcast && prep->unassociated;
+ sof_fc->fl_av = MAC_TCK_TO_FL (data_tck + rifs_tck);
+ /* no burst for mme or bcast/mcast */
+ sof_fc->bbf = prep->bbf;
+ sof_fc->mrtfl = (sof_fc->bbf)?access->reverse_duration_tck:0;
+ /* TODO EOC essential, duration of reverse frame */
+ sof_fc->mpdu_cnt = 0;
+ sof_fc->burst_cnt = 0;
+ /* write SACK info for previous reception */
+ if (1/*ctx->recv_mpdu.valid*/)
+ {
+ if (!ctx->recv_mpdu.all_ok)
+ {
+ sof_fc->sackt0 = PBPROC_FC_SACKT_MIXED_COMPRESSED;
+ sof_fc->sacki0 = ctx->recv_mpdu.sackd.sacki_enc.si[0];
+ sof_fc->sacki1 = ctx->recv_mpdu.sackd.sacki_enc.si[1];
+ }
+ else
+ {
+ sof_fc->sackt0 = PBPROC_FC_SACKT_UNIFORM;
+ sof_fc->sacki0 = PBPROC_FC_SACKI_UNIFORM_ALL_OK;
+ }
+ }
+ else
+ {
+ sof_fc->sackt0 = PBPROC_FC_SACKT_UNIFORM;
+ sof_fc->sacki0 = PBPROC_FC_SACKI_UNIFORM_NOT_AVAILABLE;
+ }
+ }
+ ctx->recv_mpdu.bbf = 0; /* Reset dangerous fields */
+ ctx->recv_mpdu.all_ok = 0;
+#endif
/* Invalid FC 1.0, HP 1.0 stations will defer (20 symbols and ROBO). */
prep->fc10 = 0x200000;
/* Prepare PB. */
@@ -863,3 +962,51 @@ pbproc_prep_mpdu_commit_fsm (pbproc_t *ctx)
}
}
+#if CONFIG_PBPROC_FC_EOC
+/* Handling of SACK field in SOF/RSOF */
+void ARCH_ILRAM
+pbproc_prep_mpdu_ack (pbproc_t *ctx, const pbproc_fc_t *fc_av)
+{
+ dbg_assert (ctx);
+ pbproc_prep_mpdu_t *prep = &ctx->prep_mpdu;
+ dbg_assert (prep->valid);
+ uint sackt0, si[3], sil;
+ /* Compute bitmap and size */
+ switch(fc_av->generic.dt_av)
+ {
+ case PBPROC_FC_DT_SOF:
+ sackt0 = fc_av->sof.sackt0;
+ si[0] = fc_av->sof.sacki0;
+ si[1] = fc_av->sof.sacki1;
+ sil = PBPROC_FC_SACKT_EOC_SOF_SIZE;
+ break;
+ case PBPROC_FC_DT_RSOF:
+ sackt0 = fc_av->rsof.sackt0;
+ si[0] = fc_av->rsof.sacki0;
+ si[1] = (fc_av->rsof.sacki1 << 19) | fc_av->rsof.sacki2;
+ sil = PBPROC_FC_SACKT_EOC_RSOF_SIZE;
+ break;
+ }
+ /* Decide what to do, copied from other files */
+ if (sackt0 == PBPROC_FC_SACKT_MIXED)
+ {
+ pbproc_prep_mpdu_ack_bitmap (ctx, si, 0, sil);
+ }
+ else if (sackt0 == PBPROC_FC_SACKT_MIXED_COMPRESSED)
+ {
+ pbproc_prep_mpdu_ack_encoded (ctx, si, sil);
+ }
+ else if (sackt0 == PBPROC_FC_SACKT_NOT_RECEIVED)
+ {
+ pbproc_prep_mpdu_cancel (ctx);
+ }
+ else
+ {
+ uint sacki = si[0] & 0xf;
+ if (sacki == PBPROC_FC_SACKI_UNIFORM_ALL_OK)
+ pbproc_prep_mpdu_ack_all (ctx);
+ else
+ pbproc_prep_mpdu_cancel (ctx);
+ }
+}
+#endif