summaryrefslogtreecommitdiff
path: root/cesar/hal/phy/maximus
diff options
context:
space:
mode:
authorburet2008-10-10 13:54:15 +0000
committerburet2008-10-10 13:54:15 +0000
commit2d2816cdc6f798d649b9f826c3155054e484f3c4 (patch)
treec3c5943000cf9d7eab2375cd58c0155fc8cdbd37 /cesar/hal/phy/maximus
parent6efa942de48f4d23fec7a02ba2d3c845bd8a5427 (diff)
[maximus] hal phy: evolution to handle rx collisions
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@3252 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/hal/phy/maximus')
-rw-r--r--cesar/hal/phy/maximus/inc/maximus_phy_ctx.h2
-rw-r--r--cesar/hal/phy/maximus/src/maximus_phy_ctrl.c147
-rw-r--r--cesar/hal/phy/maximus/src/maximus_phy_ctrl_cb.c3
-rw-r--r--cesar/hal/phy/maximus/test/src/test_phy_ctrl.c120
4 files changed, 214 insertions, 58 deletions
diff --git a/cesar/hal/phy/maximus/inc/maximus_phy_ctx.h b/cesar/hal/phy/maximus/inc/maximus_phy_ctx.h
index c992ff7592..d51fee3d15 100644
--- a/cesar/hal/phy/maximus/inc/maximus_phy_ctx.h
+++ b/cesar/hal/phy/maximus/inc/maximus_phy_ctx.h
@@ -190,6 +190,8 @@ struct maximus_phy_ctrl_t
bool pre_detection;
/** Used to indicate if the RX has been prepared. */
bool rx_prepared;
+ /** Indicate if there is a RX collision. */
+ bool rx_collision;
/** Date of last zero-cross. */
u32 zero_cross_date;
/** Phy RX parameters. */
diff --git a/cesar/hal/phy/maximus/src/maximus_phy_ctrl.c b/cesar/hal/phy/maximus/src/maximus_phy_ctrl.c
index b43228991b..0d6a16c59c 100644
--- a/cesar/hal/phy/maximus/src/maximus_phy_ctrl.c
+++ b/cesar/hal/phy/maximus/src/maximus_phy_ctrl.c
@@ -559,6 +559,9 @@ maximus_phy_recv_preamble (phy_t *ctx, sci_msg_t *msg)
station_log(&my_station, STATION_LOG_WARNING, STATION_LOGTYPE_PHY,
"%s: recv a PREAMBLE but does not process it because one is already being received", __FUNCTION__);
+ // indicate that there is a RX collision
+ ctx->control.rx_collision = true;
+
ret = 0;
}
}
@@ -637,79 +640,106 @@ maximus_phy_recv_fc_av_only_mode (phy_t *ctx, sci_msg_t *msg)
{
if (MAXIMUS_PHY_MEDIUM_BUSY_RX == ctx->access.medium_state)
{
- // check transmission ID and station ID of the received frame control
- dbg_assert(ctx->control.rx_param.src_tx_id == ntohs(msg->hdr.phy->tx_id));
- dbg_assert(ctx->control.rx_param.src_station_id == ntohs(msg->sci_hdr->station_id));
- if ((ctx->control.rx_param.src_tx_id == ntohs(msg->hdr.phy->tx_id))
- && (ctx->control.rx_param.src_station_id == ntohs(msg->sci_hdr->station_id)))
+ // check that there is no RX collision
+ if (!ctx->control.rx_collision)
{
- MAXIMUS_PHY_TRACE (M_FC_DETECT, my_station.current_tick_tck);
-
- u32 pre_duration = MAC_PREAMBLE_TCK; // in AV mode
- u32 fc_duration = MAC_FC_AV_TCK; // in AV mode on 1 symbol
-
- memcpy(ctx->control.rx_param.fc_av, msg->data_begin, 16);
- if (16 != sci_msg_pop(msg, 16))
- {
- station_log(&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_PHY,
- "%s: errno = %d", __FUNCTION__, errno);
- dbg_assert_print(false, "errno = %d when poping SCI message", errno);
- }
- else
+ // check transmission ID and station ID of the received frame control
+ dbg_assert(ctx->control.rx_param.src_tx_id == ntohs(msg->hdr.phy->tx_id));
+ dbg_assert(ctx->control.rx_param.src_station_id == ntohs(msg->sci_hdr->station_id));
+ if ((ctx->control.rx_param.src_tx_id == ntohs(msg->hdr.phy->tx_id))
+ && (ctx->control.rx_param.src_station_id == ntohs(msg->sci_hdr->station_id)))
{
- /* rx_date should be the date of preamble start, not current date. */
- /* => Calculate rx_date. */
+ MAXIMUS_PHY_TRACE (M_FC_DETECT, my_station.current_tick_tck);
- // calculate frame control duration and preamble duration,
- // depending on AV/Hybrid mode and number of symbols
- if ((PHY_FC_MODE_HYBRID_2 == msg->hdr.phy->fc_mode)
- || (PHY_FC_MODE_AV_2 == msg->hdr.phy->fc_mode))
+ u32 pre_duration = MAC_PREAMBLE_TCK; // in AV mode
+ u32 fc_duration = MAC_FC_AV_TCK; // in AV mode on 1 symbol
+
+ memcpy(ctx->control.rx_param.fc_av, msg->data_begin, 16);
+ if (16 != sci_msg_pop(msg, 16))
{
- fc_duration *= 2; // on 2 symbols
+ station_log(&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_PHY,
+ "%s: errno = %d", __FUNCTION__, errno);
+ dbg_assert_print(false, "errno = %d when poping SCI message", errno);
}
- if ((PHY_FC_MODE_HYBRID_1 == msg->hdr.phy->fc_mode)
- || (PHY_FC_MODE_HYBRID_2 == msg->hdr.phy->fc_mode))
+ else
{
- pre_duration = MAC_PREAMBLE_HYBRID_TCK; // in Hybrid mode
- fc_duration += MAC_FC_10_TCK; // in Hybrid mode
- }
+ /* rx_date should be the date of preamble start, not current date. */
+ /* => Calculate rx_date. */
- // compute rx_date
- ctx->control.rx_fc_param.rx_date = ntohl(msg->sci_hdr->netclock_low) - MAXIMUS_PHY_FC_RECEPTION_DELAY_TCK - fc_duration - pre_duration;
+ // calculate frame control duration and preamble duration,
+ // depending on AV/Hybrid mode and number of symbols
+ if ((PHY_FC_MODE_HYBRID_2 == msg->hdr.phy->fc_mode)
+ || (PHY_FC_MODE_AV_2 == msg->hdr.phy->fc_mode))
+ {
+ fc_duration *= 2; // on 2 symbols
+ }
+ if ((PHY_FC_MODE_HYBRID_1 == msg->hdr.phy->fc_mode)
+ || (PHY_FC_MODE_HYBRID_2 == msg->hdr.phy->fc_mode))
+ {
+ pre_duration = MAC_PREAMBLE_HYBRID_TCK; // in Hybrid mode
+ fc_duration += MAC_FC_10_TCK; // in Hybrid mode
+ }
- // PHY raises an IT_RX_FC by calling 'phy_rx_fc_cb'
+ // compute rx_date
+ ctx->control.rx_fc_param.rx_date = ntohl(msg->sci_hdr->netclock_low) - MAXIMUS_PHY_FC_RECEPTION_DELAY_TCK - fc_duration - pre_duration;
- // if the RX FC mode is hybrid and the TX FC mode is AV only, the FC 1.0 FCCS should be wrong => set fc_10 = (u32)-1
- if (((PHY_FC_MODE_HYBRID_1 == ctx->control.rx_param.fc_mode)
- || (PHY_FC_MODE_HYBRID_2 == ctx->control.rx_param.fc_mode))
- && ((PHY_FC_MODE_AV_1 == msg->hdr.phy->fc_mode)
- || (PHY_FC_MODE_AV_2 == msg->hdr.phy->fc_mode)))
- {
- ctx->control.rx_param.fc_10 = (u32)-1;
- }
+ // PHY raises an IT_RX_FC by calling 'phy_rx_fc_cb'
- // if the RX FC mode is different from the TX FC mode, the FC AV FCCS_AV should be wrong => send fc_av = NULL
- if (ctx->control.rx_param.fc_mode != msg->hdr.phy->fc_mode)
- {
- ctx->control.rx_fc_param.fc_av = NULL;
- }
- else
- {
- ctx->control.rx_fc_param.fc_av = ctx->control.rx_param.fc_av;
- }
+ // if the RX FC mode is hybrid and the TX FC mode is AV only, the FC 1.0 FCCS should be wrong => set fc_10 = (u32)-1
+ if (((PHY_FC_MODE_HYBRID_1 == ctx->control.rx_param.fc_mode)
+ || (PHY_FC_MODE_HYBRID_2 == ctx->control.rx_param.fc_mode))
+ && ((PHY_FC_MODE_AV_1 == msg->hdr.phy->fc_mode)
+ || (PHY_FC_MODE_AV_2 == msg->hdr.phy->fc_mode)))
+ {
+ ctx->control.rx_param.fc_10 = (u32)-1;
+ }
- // set callback function to call
- ctx->control.current_cb = ctx->control.rx_fc_cb;
- maximus_pending_isrs |= (1 << PHY_HAL_INTERRUPT_PHY);
+ // if the RX FC mode is different from the TX FC mode, the FC AV FCCS_AV should be wrong => send fc_av = NULL
+ if (ctx->control.rx_param.fc_mode != msg->hdr.phy->fc_mode)
+ {
+ ctx->control.rx_fc_param.fc_av = NULL;
+ }
+ else
+ {
+ ctx->control.rx_fc_param.fc_av = ctx->control.rx_param.fc_av;
+ }
- ret = 0;
+ // set callback function to call
+ ctx->control.current_cb = ctx->control.rx_fc_cb;
+ maximus_pending_isrs |= (1 << PHY_HAL_INTERRUPT_PHY);
+
+ ret = 0;
+ }
+ }
+ else
+ {
+ errno = EPROTO;
+ station_log(&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_PHY,
+ "%s: recv a FC with incorrect TX ID and/or station ID", __FUNCTION__);
}
}
else
{
- errno = EPROTO;
- station_log(&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_PHY,
- "%s: recv a FC with incorrect TX ID and/or station ID", __FUNCTION__);
+ /* In case of RX collision. */
+
+ // 1st case: if receiving the expected FC,
+ // the FC 1.0 FCCS and the FC AV FCCS_AV should be wrong,
+ // and PHY raises an IT_RX_FC
+ if ((ctx->control.rx_param.src_tx_id == ntohs(msg->hdr.phy->tx_id))
+ && (ctx->control.rx_param.src_station_id == ntohs(msg->sci_hdr->station_id)))
+ {
+ ctx->control.rx_param.fc_10 = (u32)-1;
+ ctx->control.rx_fc_param.fc_av = NULL;
+
+ // set callback function to call
+ ctx->control.current_cb = ctx->control.rx_fc_cb;
+ maximus_pending_isrs |= (1 << PHY_HAL_INTERRUPT_PHY);
+ }
+
+ // 2nd case: if receiving an unexpected FC, PHY does not raise the IT_RX_FC
+ // => nothing to do
+
+ ret = 0;
}
}
else if (ctx->warning_assert)
@@ -2568,6 +2598,9 @@ phy_rx_activate (phy_t *ctx, bool now, u32 date, bool pre_detection)
{
// reset prp result to 'true'
ctx->access.prp_result = true;
+
+ // reset RX collision to 'false'
+ ctx->control.rx_collision = false;
}
else if ( (MAXIMUS_PHY_MEDIUM_PRS0 == ctx->access.medium_state)
|| (MAXIMUS_PHY_MEDIUM_PRS1 == ctx->access.medium_state)
diff --git a/cesar/hal/phy/maximus/src/maximus_phy_ctrl_cb.c b/cesar/hal/phy/maximus/src/maximus_phy_ctrl_cb.c
index 3ae563b0ef..9023fa6951 100644
--- a/cesar/hal/phy/maximus/src/maximus_phy_ctrl_cb.c
+++ b/cesar/hal/phy/maximus/src/maximus_phy_ctrl_cb.c
@@ -914,6 +914,9 @@ maximus_phy_rx_activate_cb (void *data)
{
// reset prp result to 'true'
ctx->access.prp_result = true;
+
+ // reset RX collision to 'false'
+ ctx->control.rx_collision = false;
}
// reset RX activate netclock message id
diff --git a/cesar/hal/phy/maximus/test/src/test_phy_ctrl.c b/cesar/hal/phy/maximus/test/src/test_phy_ctrl.c
index f24ffe0328..05f0834c51 100644
--- a/cesar/hal/phy/maximus/test/src/test_phy_ctrl.c
+++ b/cesar/hal/phy/maximus/test/src/test_phy_ctrl.c
@@ -739,6 +739,45 @@ void maximus_phy_recv_test_case(test_t t)
// reset netclock id
ctx->control.rx_param.recv_preamble_netclock_id = 0;
+ /* Test RX collision. */
+
+ // reset rx collision
+ ctx->control.rx_collision = false;
+
+ // phy header
+ test_fail_unless (((int)sizeof(phy_msg_hdr_t) == sci_msg_push(&msg, sizeof(phy_msg_hdr_t)))
+ && (EINVAL != errno)
+ && (ENOSPC != errno));
+ memcpy(msg.data_begin, &phy_hdr, sizeof(phy_msg_hdr_t));
+
+ test_fail_unless ((0 <= (maximus_phy_recv(&msg, ctx)))
+ && (EINVAL != errno)
+ && (EPROTO != errno));
+
+ test_fail_unless ((phy_hdr.version == msg.hdr.phy->version)
+ && (phy_hdr.type == msg.hdr.phy->type)
+ && (phy_hdr.mpdu_format == msg.hdr.phy->mpdu_format)
+ && (phy_hdr.pb_nb == msg.hdr.phy->pb_nb)
+ && (phy_hdr.fc_mode == msg.hdr.phy->fc_mode)
+ && (phy_hdr.short_ppdu == msg.hdr.phy->short_ppdu)
+ && (phy_hdr.mod == msg.hdr.phy->mod)
+ && (phy_hdr.fecrate == msg.hdr.phy->fecrate)
+ && (phy_hdr.gil == msg.hdr.phy->gil)
+ && (phy_hdr.tonemap_index == msg.hdr.phy->tonemap_index)
+ && (phy_hdr.tx_id == msg.hdr.phy->tx_id)
+ && (phy_hdr.flags == msg.hdr.phy->flags)
+ && (phy_hdr.reserved == msg.hdr.phy->reserved)
+ && (phy_hdr.symbol_nb == msg.hdr.phy->symbol_nb)
+ && (0 == memcmp(phy_hdr.iv, msg.hdr.phy->iv, 3*sizeof(uint32_t)))
+ && (0 == memcmp(phy_hdr.nek, msg.hdr.phy->nek, 4*sizeof(uint32_t)))
+ && (0 == memcmp(phy_hdr.pb_measurement, msg.hdr.phy->pb_measurement, msg.hdr.phy->pb_nb*sizeof(uint32_t)))
+ && (0 == memcmp(phy_hdr.pb_header, msg.hdr.phy->pb_header, msg.hdr.phy->pb_nb*sizeof(uint32_t))));
+
+ test_fail_unless (ctx->control.rx_collision);
+
+ // reset rx collision
+ ctx->control.rx_collision = false;
+
/* Test callback:
* - with a wrong preamble;
* - then, with a correct preamble. */
@@ -771,7 +810,7 @@ void maximus_phy_recv_test_case(test_t t)
{
test_fail_unless ((maximus_pending_isrs & (1 << PHY_HAL_INTERRUPT_PHY))
&& (ctx->control.current_cb == ctx->control.rx_fc_cb)
- && (0 == memcmp(fc_av, ctx->control.rx_param.fc_av, 4*sizeof(u32))));
+ && (0 == memcmp(fc_av, ctx->control.rx_fc_param.fc_av, 4*sizeof(u32))));
(*ctx->control.rx_fc_cb)(ctx->control.user_data, ctx->control.rx_fc_param.rx_date, ctx->control.rx_fc_param.fc_av);
maximus_pending_isrs &= (0 << PHY_HAL_INTERRUPT_PHY);
}
@@ -780,6 +819,85 @@ void maximus_phy_recv_test_case(test_t t)
{
test_fail_unless (fc_10 == ctx->control.rx_param.fc_10);
}
+ // test RX collision
+ if (PHY_TYPE_FC_AV_ONLY_MODE == phy_hdr.type)
+ {
+ // set rx collision
+ ctx->control.rx_collision = true;
+
+ // phy header
+ test_fail_unless (((int)sizeof(phy_msg_hdr_t) == sci_msg_push(&msg, sizeof(phy_msg_hdr_t)))
+ && (EINVAL != errno)
+ && (ENOSPC != errno));
+ memcpy(msg.data_begin, &phy_hdr, sizeof(phy_msg_hdr_t));
+
+ test_fail_unless ((0 <= (maximus_phy_recv(&msg, ctx)))
+ && (EINVAL != errno)
+ && (EPROTO != errno));
+
+ test_fail_unless ((phy_hdr.version == msg.hdr.phy->version)
+ && (phy_hdr.type == msg.hdr.phy->type)
+ && (phy_hdr.mpdu_format == msg.hdr.phy->mpdu_format)
+ && (phy_hdr.pb_nb == msg.hdr.phy->pb_nb)
+ && (phy_hdr.fc_mode == msg.hdr.phy->fc_mode)
+ && (phy_hdr.short_ppdu == msg.hdr.phy->short_ppdu)
+ && (phy_hdr.mod == msg.hdr.phy->mod)
+ && (phy_hdr.fecrate == msg.hdr.phy->fecrate)
+ && (phy_hdr.gil == msg.hdr.phy->gil)
+ && (phy_hdr.tonemap_index == msg.hdr.phy->tonemap_index)
+ && (phy_hdr.tx_id == msg.hdr.phy->tx_id)
+ && (phy_hdr.flags == msg.hdr.phy->flags)
+ && (phy_hdr.reserved == msg.hdr.phy->reserved)
+ && (phy_hdr.symbol_nb == msg.hdr.phy->symbol_nb)
+ && (0 == memcmp(phy_hdr.iv, msg.hdr.phy->iv, 3*sizeof(uint32_t)))
+ && (0 == memcmp(phy_hdr.nek, msg.hdr.phy->nek, 4*sizeof(uint32_t)))
+ && (0 == memcmp(phy_hdr.pb_measurement, msg.hdr.phy->pb_measurement, msg.hdr.phy->pb_nb*sizeof(uint32_t)))
+ && (0 == memcmp(phy_hdr.pb_header, msg.hdr.phy->pb_header, msg.hdr.phy->pb_nb*sizeof(uint32_t))));
+
+ test_fail_unless ((maximus_pending_isrs & (1 << PHY_HAL_INTERRUPT_PHY))
+ && (ctx->control.current_cb == ctx->control.rx_fc_cb)
+ && (NULL == ctx->control.rx_fc_param.fc_av)
+ && ((u32)-1 == ctx->control.rx_param.fc_10));
+ (*ctx->control.rx_fc_cb)(ctx->control.user_data, ctx->control.rx_fc_param.rx_date, ctx->control.rx_fc_param.fc_av);
+ maximus_pending_isrs &= (0 << PHY_HAL_INTERRUPT_PHY);
+
+ // sci header => FC coming from another station
+ sci_hdr.station_id = my_station.id + 1;
+
+ // phy header
+ test_fail_unless (((int)sizeof(phy_msg_hdr_t) == sci_msg_push(&msg, sizeof(phy_msg_hdr_t)))
+ && (EINVAL != errno)
+ && (ENOSPC != errno));
+ memcpy(msg.data_begin, &phy_hdr, sizeof(phy_msg_hdr_t));
+
+ test_fail_unless ((0 <= (maximus_phy_recv(&msg, ctx)))
+ && (EINVAL != errno)
+ && (EPROTO != errno));
+
+ test_fail_unless ((phy_hdr.version == msg.hdr.phy->version)
+ && (phy_hdr.type == msg.hdr.phy->type)
+ && (phy_hdr.mpdu_format == msg.hdr.phy->mpdu_format)
+ && (phy_hdr.pb_nb == msg.hdr.phy->pb_nb)
+ && (phy_hdr.fc_mode == msg.hdr.phy->fc_mode)
+ && (phy_hdr.short_ppdu == msg.hdr.phy->short_ppdu)
+ && (phy_hdr.mod == msg.hdr.phy->mod)
+ && (phy_hdr.fecrate == msg.hdr.phy->fecrate)
+ && (phy_hdr.gil == msg.hdr.phy->gil)
+ && (phy_hdr.tonemap_index == msg.hdr.phy->tonemap_index)
+ && (phy_hdr.tx_id == msg.hdr.phy->tx_id)
+ && (phy_hdr.flags == msg.hdr.phy->flags)
+ && (phy_hdr.reserved == msg.hdr.phy->reserved)
+ && (phy_hdr.symbol_nb == msg.hdr.phy->symbol_nb)
+ && (0 == memcmp(phy_hdr.iv, msg.hdr.phy->iv, 3*sizeof(uint32_t)))
+ && (0 == memcmp(phy_hdr.nek, msg.hdr.phy->nek, 4*sizeof(uint32_t)))
+ && (0 == memcmp(phy_hdr.pb_measurement, msg.hdr.phy->pb_measurement, msg.hdr.phy->pb_nb*sizeof(uint32_t)))
+ && (0 == memcmp(phy_hdr.pb_header, msg.hdr.phy->pb_header, msg.hdr.phy->pb_nb*sizeof(uint32_t))));
+
+ test_fail_unless (0 == maximus_pending_isrs);
+
+ // reset rx collision
+ ctx->control.rx_collision = false;
+ }
// test PBs
if (PHY_TYPE_MPDU_PAYLOAD == phy_hdr.type)
{