summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorburet2007-07-24 13:37:19 +0000
committerburet2007-07-24 13:37:19 +0000
commit444d3c488c7cc4c00004d3f01ec8d332eef78c25 (patch)
tree543e8e53f85a14154773417421e15f79c3bd1dab
parent259c6a06c999a25a68c489abcfdf9990e84bffa1 (diff)
HAL Phy Maximus:
- update tm dma - develop pb dma - develop recv/send chandata + associated tests git-svn-id: svn+ssh://pessac/svn/cesar/trunk@520 017c9cb6-072f-447c-8318-d5b54f68fe89
-rw-r--r--hal/phy/maximus/inc/maximus_phy_ctrl.h8
-rw-r--r--hal/phy/maximus/inc/maximus_phy_ctx.h29
-rw-r--r--hal/phy/maximus/src/maximus_pbdma.c48
-rw-r--r--hal/phy/maximus/src/maximus_phy_ctrl.c799
-rw-r--r--hal/phy/maximus/src/maximus_tmdma.c6
-rw-r--r--hal/phy/maximus/test/src/test_bridgedma.c2
-rw-r--r--hal/phy/maximus/test/src/test_pbdma.c201
-rw-r--r--hal/phy/maximus/test/src/test_phy_ctrl.c305
-rw-r--r--hal/phy/maximus/test/src/test_phy_maximus.c2
-rw-r--r--hal/phy/maximus/test/src/test_tmdma.c6
10 files changed, 1276 insertions, 130 deletions
diff --git a/hal/phy/maximus/inc/maximus_phy_ctrl.h b/hal/phy/maximus/inc/maximus_phy_ctrl.h
index 103d3cd4cc..c7cc13289c 100644
--- a/hal/phy/maximus/inc/maximus_phy_ctrl.h
+++ b/hal/phy/maximus/inc/maximus_phy_ctrl.h
@@ -66,6 +66,14 @@ int maximus_phy_recv_noise (phy_t *ctx, sci_msg_t *msg);
int maximus_phy_recv_spectrum (phy_t *ctx, sci_msg_t *msg);
/**
+ * Maximus TX frame callbacks in case of chandata transfer called when the corresponding netclock message is received.
+ * \param data pointer containing PHY context.
+ */
+void maximus_phy_send_tonemap_cb (void *data);
+void maximus_phy_send_noise_cb (void *data);
+void maximus_phy_send_spectrum_cb (void *data);
+
+/**
* Maximus TX frame first callback called when the corresponding netclock message is received.
* \param data pointer to 'maximus_tx_fc_t' structure, containing argument 'want_conf' of 'phy_tx_frame'.
*/
diff --git a/hal/phy/maximus/inc/maximus_phy_ctx.h b/hal/phy/maximus/inc/maximus_phy_ctx.h
index 9d94809052..ccfa824fc0 100644
--- a/hal/phy/maximus/inc/maximus_phy_ctx.h
+++ b/hal/phy/maximus/inc/maximus_phy_ctx.h
@@ -93,6 +93,16 @@ struct maximus_phy_ctrl_t
};
typedef struct maximus_phy_ctrl_t maximus_phy_ctrl_t;
+enum chandata_type_t
+{
+ MAXIMUS_PHY_CHANDATA_TYPE_NONE = 0x00,
+ MAXIMUS_PHY_CHANDATA_TYPE_FREQUENCY_NOISE = 0x01,
+ MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE = 0x02,
+ MAXIMUS_PHY_CHANDATA_TYPE_SPECTRUM = 0x03,
+ MAXIMUS_PHY_CHANDATA_TYPE_NB = 0x04
+};
+typedef enum chandata_type_t chandata_type_t;
+
/** PB DMA structure for Maximus */
struct maximus_pbdma_t
{
@@ -114,16 +124,19 @@ struct maximus_pbdma_t
uint nb_ready;
/** Number of the PB after which an interrupt is triggered. */
uint nb_pb_it;
+ /** Used to indicate or a chandata transfer (true) or a PB transfer (false).*/
+ bool transfer_mode;
+ /** Indicates if at least one received PB was received with error. */
+ bool pb_crc_error;
/** First PB descriptor. */
phy_pb_t *first_pb;
+ /** Current PB descriptor for Rx. */
+ phy_pb_rx_t *current_pb;
+ /** Indicates if chandata are noise (u16 frequency_noise[PHY_CARRIER_MAX_NB] and u8 time_noise[PHY_SYMBOL_MAX_NB])
+ * or spectrum (u64 spectrum[PHY_CARRIER_MAX_NB]). */
+ chandata_type_t chandata_type;
/** First transfer descriptor. */
- phy_chandata_t *first_chandata;
- /** Frequency noise. */
- u16 frequency_noise[PHY_CARRIER_MAX_NB];
- /** Time noise. */
- u8 time_noise[PHY_SYMBOL_MAX_NB];
- /** Transfer function of channel response. */
- u64 spectrum[PHY_CARRIER_MAX_NB];
+ phy_chandata_t *first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_NB];
};
typedef struct maximus_pbdma_t maximus_pbdma_t;
@@ -143,7 +156,7 @@ struct maximus_tmdma_t
/** Tonemask blocks first descriptor. */
blk_t *tonemask; // tonemask[PHY_CARRIER_MAX_NB] (1 bit per carrier)
/** Tonemap blocks first descriptor. */
- blk_t *tonemap; // tonemap[PHY_CARRIER_MAX_NB] (4 bits per carrier)
+ blk_t *tonemap[PHY_TONEMAP_MAX_NB]; // tonemap[PHY_CARRIER_MAX_NB] (4 bits per carrier)
};
typedef struct maximus_tmdma_t maximus_tmdma_t;
diff --git a/hal/phy/maximus/src/maximus_pbdma.c b/hal/phy/maximus/src/maximus_pbdma.c
index e698460b3a..3a02c5dff2 100644
--- a/hal/phy/maximus/src/maximus_pbdma.c
+++ b/hal/phy/maximus/src/maximus_pbdma.c
@@ -13,6 +13,7 @@
#include "common/std.h"
#include "hal/phy/maximus/inc/maximus_phy_ctx.h"
+#include <errno.h>
/**
@@ -33,7 +34,24 @@ phy_pbdma_start (phy_t *ctx, bool bypass_aes, const u32 iv[3],
const u32 nek[4], uint nb_total, uint nb_ready,
uint nb_pb_it, phy_pb_t *first_pb)
{
-
+ if ((NULL == ctx)
+ || (NULL == first_pb))
+ {
+ errno = EINVAL;
+ }
+ else
+ {
+ ctx->pb_dma.bypass_aes = bypass_aes;
+ memcpy(ctx->pb_dma.iv, iv, 3*sizeof(u32));
+ memcpy(ctx->pb_dma.nek, nek, 4*sizeof(u32));
+ ctx->pb_dma.nb_total = nb_total;
+ ctx->pb_dma.nb_ready = nb_ready;
+ ctx->pb_dma.nb_pb_it = nb_pb_it;
+ ctx->pb_dma.first_pb = first_pb;
+
+ // set PB transfer mode
+ ctx->pb_dma.transfer_mode = false;
+ }
}
@@ -46,7 +64,18 @@ phy_pbdma_start (phy_t *ctx, bool bypass_aes, const u32 iv[3],
void
phy_pbdma_update (phy_t *ctx, uint nb_ready, uint nb_pb_it)
{
-
+ if ((NULL == ctx)
+ || (nb_ready < ctx->pb_dma.nb_ready)
+ || (nb_pb_it > ctx->pb_dma.nb_total)
+ || (nb_ready > ctx->pb_dma.nb_total))
+ {
+ errno = EINVAL;
+ }
+ else
+ {
+ ctx->pb_dma.nb_ready = nb_ready;
+ ctx->pb_dma.nb_pb_it = nb_pb_it;
+ }
}
@@ -61,6 +90,19 @@ phy_pbdma_update (phy_t *ctx, uint nb_ready, uint nb_pb_it)
void
phy_pbdma_start_chandata (phy_t *ctx, phy_chandata_t *first_chandata)
{
-
+ if ((NULL == ctx)
+ || (NULL == first_chandata)
+ || (0 == first_chandata->type)) // (INTERFACE TO BE UPDATED)
+ {
+ errno = EINVAL;
+ }
+ else
+ {
+ ctx->pb_dma.chandata_type = first_chandata->type;
+ ctx->pb_dma.first_chandata[ctx->pb_dma.chandata_type] = first_chandata;
+
+ // set chandata transfer mode
+ ctx->pb_dma.transfer_mode = true;
+ }
}
diff --git a/hal/phy/maximus/src/maximus_phy_ctrl.c b/hal/phy/maximus/src/maximus_phy_ctrl.c
index db0eed50b0..d1c7e67af8 100644
--- a/hal/phy/maximus/src/maximus_phy_ctrl.c
+++ b/hal/phy/maximus/src/maximus_phy_ctrl.c
@@ -164,7 +164,7 @@ maximus_phy_tx_fc_cb (void *data)
// calculate frame control transimission time
bits_per_symbol = maximus_dur_bits_per_symbol(tx_fc_data->ctx->tm_dma.mod,
tx_fc_data->ctx->tm_dma.tonemask,
- tx_fc_data->ctx->tm_dma.tonemap,
+ tx_fc_data->ctx->tm_dma.tonemap[tx_fc_data->ctx->tm_dma.tonemap_index],
tx_fc_data->ctx->tm_dma.carrier_nb); // 4 bits per carrier
if ((PHY_FC_MODE_HYBRID_2 == tx_fc_data->ctx->control.fc_mode)
|| (PHY_FC_MODE_AV_2 == tx_fc_data->ctx->control.fc_mode))
@@ -212,7 +212,8 @@ maximus_phy_tx_frame_cb (void *data)
{
maximus_phy_tx_frame_t *tx_frame_data = (maximus_phy_tx_frame_t*)data;
- if (NULL == tx_frame_data->ctx)
+ if ((NULL == tx_frame_data->ctx)
+ || (NULL == tx_frame_data->ctx->control.pbdma_cb))
{
errno = EINVAL;
}
@@ -224,40 +225,57 @@ maximus_phy_tx_frame_cb (void *data)
// for phy message
unsigned char buffer[SCI_MSG_MAX_SIZE];
sci_msg_t msg;
- unsigned short int msg_nb = 1; // number of phy messages needed to transmit ready PBs
- uint8_t pb_nb = tx_frame_data->ctx->pb_dma.nb_ready;
- uint8_t last_msg_pb_nb = PHY_PB_MAX_NB; // number of PBs to transmit into last phy message
- unsigned short int msg_counter, pb_counter;
-
+
// for phy header
+ uint8_t type = PHY_TYPE_MPDU_PAYLOAD;
uint8_t mpdu_format = PHY_MPDU_FORMAT_NONE;
uint8_t flags = PHY_FLAG_CRC_OK;
uint32_t pb_measurement[PHY_PB_MAX_NB];
- uint32_t pb_header[PHY_PB_MAX_NB];
-
+ uint32_t pb_header[PHY_PB_MAX_NB];
+
+ // for pb dma callback
+ phy_pbdma_status_t status_word;
+
+ // find first descriptor
+ phy_pb_t *current_desc = tx_frame_data->ctx->pb_dma.first_pb;
+
// set flags and pb size
unsigned short int pb_size = 128;
if (PHY_PB_SIZE_520 == tx_frame_data->ctx->pb_dma.pb_size)
{
- flags &= PHY_FLAG_PB512;
+ flags |= PHY_FLAG_PB512;
pb_size = 512;
}
-
+
// set pb measurement
memset(pb_measurement, '\0', PHY_PB_MAX_NB*sizeof(uint32_t));
- // find first pb
- phy_pb_tx_t *current_pb = &tx_frame_data->ctx->pb_dma.first_pb->pb_tx;
+ // initialize pb header
+ memset(pb_header, '\0', PHY_PB_MAX_NB*sizeof(uint32_t));
+
+ // initialize PB DMA status
+ memset(&status_word, '\0', sizeof(phy_pbdma_status_t));
- // calculate number of phy messages needed to transmit ready PBs,
+ unsigned short int msg_nb = 1; // number of phy messages needed to transmit all PBs
+ uint8_t pb_nb = tx_frame_data->ctx->pb_dma.nb_total;
+ uint8_t last_msg_pb_nb = PHY_PB_MAX_NB; // number of PBs to transmit into last phy message
+ unsigned short int msg_counter, pb_counter;
+
+ // reset internal PB counter
+ tx_frame_data->ctx->pb_dma.index_current_pb = 0;
+
+ // calculate number of phy messages needed to transmit all PBs,
// and number of PBs to transmit into last phy message
- if (PHY_PB_MAX_NB < tx_frame_data->ctx->pb_dma.nb_ready)
+ if (PHY_PB_MAX_NB < tx_frame_data->ctx->pb_dma.nb_total)
{
- msg_nb = (unsigned short int)(tx_frame_data->ctx->pb_dma.nb_ready / PHY_PB_MAX_NB);
+ msg_nb = (unsigned short int)(tx_frame_data->ctx->pb_dma.nb_total/PHY_PB_MAX_NB);
pb_nb = PHY_PB_MAX_NB;
- last_msg_pb_nb = (uint8_t)(tx_frame_data->ctx->pb_dma.nb_ready % PHY_PB_MAX_NB);
+ if (0 != (last_msg_pb_nb=(uint8_t)(tx_frame_data->ctx->pb_dma.nb_total % PHY_PB_MAX_NB)))
+ {
+ msg_nb++;
+ }
}
-
+
// for each phy message to send
for (msg_counter=0; msg_counter<msg_nb; msg_counter++)
{
@@ -270,23 +288,68 @@ maximus_phy_tx_frame_cb (void *data)
{
pb_nb = last_msg_pb_nb;
}
-
+
// for each pb to send into current message
for (pb_counter=0; pb_counter<pb_nb; pb_counter++)
{
- // set pb header of current pb
- pb_header[pb_counter] = (uint32_t)current_pb->header;
-
- // fill sci data
- if (pb_size == sci_msg_push(&msg, pb_size))
+ if (tx_frame_data->ctx->pb_dma.index_current_pb == tx_frame_data->ctx->pb_dma.nb_ready)
{
- memcpy(msg.data_begin, current_pb->blk.data, pb_size);
+ /* When index_current_pb = nb_ready,
+ * PB null is sent until the end of the MPDU
+ * (even if, after, index_current_pb <= pb_nb_ready). */
+
+ current_desc = NULL;
+
+ /* If not enough PBs are available in PB DMA,
+ * PB DMA raises an IT by calling 'phy_pbdma_cb' callback. */
+
+ status_word.pb_null = 1;
+ status_word.null_pb_index = tx_frame_data->ctx->pb_dma.index_current_pb;
+ (*tx_frame_data->ctx->control.pbdma_cb)(tx_frame_data->ctx->control.user_data, (*(u32*)(void*)&(status_word)));
+
+ // reset pb dma status
+ memset(&status_word, '\0', sizeof(phy_pbdma_status_t));
+ }
+
+ if (NULL != current_desc)
+ {
+ // set pb header of current pb
+ pb_header[pb_counter] = (uint32_t)current_desc->pb_tx.header;
+
+ // fill sci data
+ if (pb_size == sci_msg_push(&msg, pb_size))
+ {
+ memcpy(msg.data_begin, current_desc->blk.data, pb_size);
+ }
+
+ // find next pb
+ current_desc = PARENT_OF(phy_pb_t, blk, current_desc->blk.next);
+ }
+ else // PB null is sent until the end of the MPDU
+ {
+ // fill sci data
+ if (pb_size == sci_msg_push(&msg, pb_size))
+ {
+ memset(msg.data_begin, '\0', pb_size);
+ }
+ }
+ // increment internal PB counter
+ tx_frame_data->ctx->pb_dma.index_current_pb++;
+
+ if (tx_frame_data->ctx->pb_dma.index_current_pb == tx_frame_data->ctx->pb_dma.nb_pb_it)
+ {
+ /* At the end of the nth PB transfer
+ * (i.e. index_current_pb = nb_pb_it),
+ * a PB end interrupt is simulated by calling phy_pbdma_cb callback. */
+
+ status_word.pb_it = 1;
+ (*tx_frame_data->ctx->control.pbdma_cb)(tx_frame_data->ctx->control.user_data, (*(u32*)(void*)&(status_word)));
+
+ // reset pb dma status
+ memset(&status_word, '\0', sizeof(phy_pbdma_status_t));
}
-
- // find next pb
- current_pb = PARENT_OF(phy_pb_tx_t, blk, current_pb->blk.next);
}
-
+
// set mpdu format
// HomePlug AV specs => delimiter type (DT_AV) is described by bits 0-2 of first fc_av octet:
// 000 Beacon
@@ -296,11 +359,11 @@ maximus_phy_tx_frame_cb (void *data)
// 100 SOUND
// 101 RSOF
mpdu_format = (uint8_t)((tx_frame_data->ctx->control.fc_av[0] & 0x07) + 1); // +1 to have the correspondance with our own mpdu format definition (of 'phy_types.h')
-
+
// fill phy header
maximus_phy_fill_hdr(tx_frame_data->ctx,
&msg,
- PHY_TYPE_MPDU_PAYLOAD,
+ type,
mpdu_format,
pb_nb,
(uint8_t)tx_frame_data->ctx->tm_dma.tonemap_index,
@@ -308,17 +371,375 @@ maximus_phy_tx_frame_cb (void *data)
tx_frame_data->ctx->pb_dma.nek,
pb_measurement,
pb_header);
-
+
// fill the sci header
sci_fill_hdr(my_station.sci, &msg, SCI_MSG_TYPE_PHY, 0 /* flags */);
-
+
// send the message
sci_send(my_station.sci, &msg);
}
}
-
+
// once phy messages have been sent, set medium state to idle
tx_frame_data->ctx->access.medium_state = MAXIMUS_PHY_MEDIUM_IDLE;
+
+ /* At each end of transfer,
+ * a PB end interrupt is simulated by calling phy_pbdma_cb callback. */
+
+ if (tx_frame_data->ctx->pb_dma.index_current_pb == tx_frame_data->ctx->pb_dma.nb_total)
+ {
+ status_word.end_tx_pb = 1; // it is the end of a PB transfer
+ (*tx_frame_data->ctx->control.pbdma_cb)(tx_frame_data->ctx->control.user_data, (*(u32*)(void*)&(status_word)));
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Maximus TX frame callbacks in case of chandata transfer called when the corresponding netclock message is received.
+ * \param data pointer containing PHY context.
+ */
+void
+maximus_phy_send_tonemap_cb (void *data)
+{
+ /* At the corresponding event reception, the transfer really starts,
+ * i.e. this callback has to send a phy message containing tonemap. */
+
+ if (NULL == data)
+ {
+ errno = EINVAL;
+ }
+ else
+ {
+ phy_t *ctx = (phy_t*)data;
+
+ if ((MAXIMUS_PHY_MEDIUM_BUSY == ctx->access.medium_state)
+ && !ctx->control.rx_tx_mode)
+ {
+ // for phy message
+ unsigned char buffer[SCI_MSG_MAX_SIZE];
+ sci_msg_t msg;
+
+ // for phy header
+ uint8_t type = PHY_TYPE_TONEMAP;
+ uint8_t mpdu_format = PHY_MPDU_FORMAT_NONE;
+ uint8_t flags = PHY_FLAG_CRC_OK;
+ uint32_t pb_measurement[PHY_PB_MAX_NB];
+ uint32_t pb_header[PHY_PB_MAX_NB];
+
+ // for pb dma callback
+ phy_pbdma_status_t status_word;
+
+ // set flags
+ if (PHY_PB_SIZE_520 == ctx->pb_dma.pb_size)
+ {
+ flags |= PHY_FLAG_PB512;
+ }
+
+ // set pb measurement
+ memset(pb_measurement, '\0', PHY_PB_MAX_NB*sizeof(uint32_t));
+
+ // initialize pb header
+ memset(pb_header, '\0', PHY_PB_MAX_NB*sizeof(uint32_t));
+
+ // initialize PB DMA status
+ memset(&status_word, '\0', sizeof(phy_pbdma_status_t));
+
+ // init for phy message
+ memset(buffer, '\0', SCI_MSG_MAX_SIZE);
+ if (0 == sci_msg_init(&msg, buffer, SCI_MSG_MAX_SIZE))
+ {
+ /* For a chandata transfer, all data are sent into one SCI message. */
+
+ if ((NULL != ctx->tm_dma.tonemap[ctx->tm_dma.tonemap_index])
+ && (NULL != ctx->tm_dma.tonemap[ctx->tm_dma.tonemap_index]->next))
+ {
+ // fill sci data
+ if (PHY_PB_MAX_SIZE == sci_msg_push(&msg, PHY_PB_MAX_SIZE))
+ {
+ memcpy(msg.data_begin, ctx->tm_dma.tonemap[ctx->tm_dma.tonemap_index]->data, PHY_PB_MAX_SIZE);
+ }
+ if (PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE == sci_msg_push(&msg, PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE))
+ {
+ memcpy(msg.data_begin, ctx->tm_dma.tonemap[ctx->tm_dma.tonemap_index]->next->data, PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE);
+ }
+ }
+ else
+ {
+ if (PHY_CARRIER_MAX_NB/2 == sci_msg_push(&msg, PHY_CARRIER_MAX_NB/2))
+ {
+ memset(msg.data_begin, '\0', PHY_CARRIER_MAX_NB/2);
+ }
+ }
+
+ // fill phy header
+ maximus_phy_fill_hdr(ctx,
+ &msg,
+ type,
+ mpdu_format,
+ 0, // pb_nb
+ (uint8_t)ctx->tm_dma.tonemap_index,
+ flags,
+ ctx->pb_dma.nek,
+ pb_measurement,
+ pb_header);
+
+ // fill the sci header
+ sci_fill_hdr(my_station.sci, &msg, SCI_MSG_TYPE_PHY, 0 /* flags */);
+
+ // send the message
+ sci_send(my_station.sci, &msg);
+
+ // once phy message has been sent, set medium state to idle
+ ctx->access.medium_state = MAXIMUS_PHY_MEDIUM_IDLE;
+ }
+ }
+ }
+}
+
+
+void
+maximus_phy_send_noise_cb (void *data)
+{
+ /* At the corresponding event reception, the transfer really starts,
+ * i.e. this callback has to send a phy message containing frequency noise and time noise. */
+
+ if (NULL == data)
+ {
+ errno = EINVAL;
+ }
+ else
+ {
+ phy_t *ctx = (phy_t*)data;
+
+ if ((MAXIMUS_PHY_MEDIUM_BUSY == ctx->access.medium_state)
+ && !ctx->control.rx_tx_mode)
+ {
+ // for phy message
+ unsigned char buffer[SCI_MSG_MAX_SIZE];
+ sci_msg_t msg;
+
+ // for phy header
+ uint8_t type = PHY_TYPE_NOISE;
+ uint8_t mpdu_format = PHY_MPDU_FORMAT_NONE;
+ uint8_t flags = PHY_FLAG_CRC_OK;
+ uint32_t pb_measurement[PHY_PB_MAX_NB];
+ uint32_t pb_header[PHY_PB_MAX_NB];
+
+ // for pb dma callback
+ phy_pbdma_status_t status_word;
+
+ // find first descriptor
+ phy_pb_t *current_desc = PARENT_OF(phy_pb_t, chandata, ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_FREQUENCY_NOISE]);
+
+ // set flags
+ if (PHY_PB_SIZE_520 == ctx->pb_dma.pb_size)
+ {
+ flags |= PHY_FLAG_PB512;
+ }
+
+ // set pb measurement
+ memset(pb_measurement, '\0', PHY_PB_MAX_NB*sizeof(uint32_t));
+
+ // initialize pb header
+ memset(pb_header, '\0', PHY_PB_MAX_NB*sizeof(uint32_t));
+
+ // initialize PB DMA status
+ memset(&status_word, '\0', sizeof(phy_pbdma_status_t));
+
+ // init for phy message
+ memset(buffer, '\0', SCI_MSG_MAX_SIZE);
+ if (0 == sci_msg_init(&msg, buffer, SCI_MSG_MAX_SIZE))
+ {
+ /* For a chandata transfer, all data are sent into one SCI message. */
+
+ int counter;
+ unsigned short int max_transfer_size = 255*2; // max value on 8 bits * 2 because size is in words => max transfer size in bytes
+ unsigned short int chandata_nb = (unsigned short int)(PHY_CARRIER_MAX_NB*sizeof(uint16_t)/max_transfer_size)+1;
+ unsigned short int last_chandata_size = (PHY_CARRIER_MAX_NB*sizeof(uint16_t)) % max_transfer_size;
+ unsigned short int current_chandata_size = max_transfer_size;
+
+ for (counter=0; counter<chandata_nb; counter++)
+ {
+ if (chandata_nb-1 == counter)
+ {
+ current_chandata_size = last_chandata_size;
+ }
+
+ // fill sci data
+ if (current_chandata_size == sci_msg_push(&msg, current_chandata_size))
+ {
+ if (NULL != current_desc)
+ {
+ memcpy(msg.data_begin, current_desc->blk.data, current_chandata_size);
+
+ // find next chandata
+ current_desc = PARENT_OF(phy_pb_t, blk, current_desc->blk.next);
+ }
+ else
+ {
+ memset(msg.data_begin, '\0', current_chandata_size);
+ }
+ }
+ }
+
+ // SCI message data also contain time noise
+ if (PHY_SYMBOL_MAX_NB*sizeof(uint8_t) == sci_msg_push(&msg, PHY_SYMBOL_MAX_NB*sizeof(uint8_t)))
+ {
+ memcpy(msg.data_begin, ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE]->blk.data, PHY_SYMBOL_MAX_NB*sizeof(uint8_t));
+ }
+
+ // fill phy header
+ maximus_phy_fill_hdr(ctx,
+ &msg,
+ type,
+ mpdu_format,
+ 0, // pb_nb
+ (uint8_t)ctx->tm_dma.tonemap_index,
+ flags,
+ ctx->pb_dma.nek,
+ pb_measurement,
+ pb_header);
+
+ // fill the sci header
+ sci_fill_hdr(my_station.sci, &msg, SCI_MSG_TYPE_PHY, 0 /* flags */);
+
+ // send the message
+ sci_send(my_station.sci, &msg);
+
+ // once phy message has been sent, set medium state to idle
+ ctx->access.medium_state = MAXIMUS_PHY_MEDIUM_IDLE;
+
+ /* At each end of transfer,
+ * a PB end interrupt is simulated by calling phy_pbdma_cb callback. */
+
+ if (ctx->pb_dma.index_current_pb == ctx->pb_dma.nb_total)
+ {
+ status_word.end_chandata = 1; // it is the end of a chandata transfer
+ (*ctx->control.pbdma_cb)(ctx->control.user_data, (*(u32*)(void*)&(status_word)));
+ }
+ }
+ }
+ }
+}
+
+
+void
+maximus_phy_send_spectrum_cb (void *data)
+{
+ /* At the corresponding event reception, the transfer really starts,
+ * i.e. this callback has to send a phy message containing spectrum. */
+
+ if (NULL == data)
+ {
+ errno = EINVAL;
+ }
+ else
+ {
+ phy_t *ctx = (phy_t*)data;
+
+ if ((MAXIMUS_PHY_MEDIUM_BUSY == ctx->access.medium_state)
+ && !ctx->control.rx_tx_mode)
+ {
+ // for phy message
+ unsigned char buffer[SCI_MSG_MAX_SIZE];
+ sci_msg_t msg;
+
+ // for phy header
+ uint8_t type = PHY_TYPE_SPECTRUM;
+ uint8_t mpdu_format = PHY_MPDU_FORMAT_NONE;
+ uint8_t flags = PHY_FLAG_CRC_OK;
+ uint32_t pb_measurement[PHY_PB_MAX_NB];
+ uint32_t pb_header[PHY_PB_MAX_NB];
+
+ // for pb dma callback
+ phy_pbdma_status_t status_word;
+
+ // find first descriptor
+ phy_pb_t *current_desc = PARENT_OF(phy_pb_t, chandata, ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_SPECTRUM]);
+
+ // set flags
+ if (PHY_PB_SIZE_520 == ctx->pb_dma.pb_size)
+ {
+ flags |= PHY_FLAG_PB512;
+ }
+
+ // set pb measurement
+ memset(pb_measurement, '\0', PHY_PB_MAX_NB*sizeof(uint32_t));
+
+ // initialize pb header
+ memset(pb_header, '\0', PHY_PB_MAX_NB*sizeof(uint32_t));
+
+ // initialize PB DMA status
+ memset(&status_word, '\0', sizeof(phy_pbdma_status_t));
+
+ // init for phy message
+ memset(buffer, '\0', SCI_MSG_MAX_SIZE);
+ if (0 == sci_msg_init(&msg, buffer, SCI_MSG_MAX_SIZE))
+ {
+ /* For a chandata transfer, all data are sent into one SCI message. */
+
+ int counter;
+ unsigned short int max_transfer_size = 255*2; // max value on 8 bits * 2 because size is in words => max transfer size in bytes
+ unsigned short int chandata_nb = (unsigned short int)(PHY_CARRIER_MAX_NB*sizeof(uint64_t)/max_transfer_size)+1;
+ unsigned short int last_chandata_size = (PHY_CARRIER_MAX_NB*sizeof(uint64_t)) % max_transfer_size;
+ unsigned short int current_chandata_size = max_transfer_size;
+
+ for (counter=0; counter<chandata_nb; counter++)
+ {
+ if (chandata_nb-1 == counter)
+ {
+ current_chandata_size = last_chandata_size;
+ }
+
+ // fill sci data
+ if (current_chandata_size == sci_msg_push(&msg, current_chandata_size))
+ {
+ if (NULL != current_desc)
+ {
+ memcpy(msg.data_begin, current_desc->blk.data, current_chandata_size);
+
+ // find next chandata
+ current_desc = PARENT_OF(phy_pb_t, blk, current_desc->blk.next);
+ }
+ else
+ {
+ memset(msg.data_begin, '\0', current_chandata_size);
+ }
+ }
+ }
+
+ // fill phy header
+ maximus_phy_fill_hdr(ctx,
+ &msg,
+ type,
+ mpdu_format,
+ 0, // pb_nb
+ (uint8_t)ctx->tm_dma.tonemap_index,
+ flags,
+ ctx->pb_dma.nek,
+ pb_measurement,
+ pb_header);
+
+ // fill the sci header
+ sci_fill_hdr(my_station.sci, &msg, SCI_MSG_TYPE_PHY, 0 /* flags */);
+
+ // send the message
+ sci_send(my_station.sci, &msg);
+
+ // once phy message has been sent, set medium state to idle
+ ctx->access.medium_state = MAXIMUS_PHY_MEDIUM_IDLE;
+
+ /* At each end of transfer,
+ * a PB end interrupt is simulated by calling phy_pbdma_cb callback. */
+
+ if (ctx->pb_dma.index_current_pb == ctx->pb_dma.nb_total)
+ {
+ status_word.end_chandata = 1; // it is the end of a chandata transfer
+ (*ctx->control.pbdma_cb)(ctx->control.user_data, (*(u32*)(void*)&(status_word)));
+ }
}
}
}
@@ -456,6 +877,7 @@ maximus_phy_recv (sci_msg_t *msg, void *phy)
|| (PHY_TYPE_NB <= msg->hdr.phy->type)
|| (PHY_MPDU_FORMAT_NB <= msg->hdr.phy->mpdu_format)
|| (PHY_PB_MAX_NB < msg->hdr.phy->pb_nb)
+ || (PHY_TONEMAP_MAX_NB <= msg->hdr.phy->tonemap_index)
|| ((PHY_FLAG_ENCRYPTED + PHY_FLAG_CRC_OK + PHY_FLAG_PB512) < msg->hdr.phy->flags)
|| (NULL == msg->hdr.phy->nek)
|| (NULL == msg->hdr.phy->pb_measurement)
@@ -466,23 +888,19 @@ maximus_phy_recv (sci_msg_t *msg, void *phy)
else
{
/* Read flags. */
-
+ // message encryption
bool encrypted = (PHY_FLAG_ENCRYPTED == (msg->hdr.phy->flags & PHY_FLAG_ENCRYPTED));
- bool crc_ok = (PHY_FLAG_CRC_OK == (msg->hdr.phy->flags & PHY_FLAG_CRC_OK));
-
- // read pb size
+ // pb size
ctx->pb_dma.pb_size = (PHY_FLAG_PB512 == (msg->hdr.phy->flags & PHY_FLAG_PB512)) ? PHY_PB_SIZE_520 : PHY_PB_SIZE_136;
// update phy context current date
ctx->control.current_date = msg->sci_hdr->netclock_low;
- // check crc, nek and medium state
// handle message only if:
- if (crc_ok // - CRC is correct
- && (!encrypted // - and message is not encrypted
- || (encrypted // or message is encrypted with a correct nek
- && (0 == memcmp(msg->hdr.phy->nek, ctx->pb_dma.nek, 4*sizeof(uint32_t)))))
- && (msg->hdr.phy->tonemap_index == ctx->tm_dma.tonemap_index)) // - and received tonemap index is correct
+ if ((!encrypted // - message is not encrypted
+ || (encrypted // or message is encrypted with a correct nek
+ && (0 == memcmp(msg->hdr.phy->nek, ctx->pb_dma.nek, 4*sizeof(uint32_t)))))
+ && (msg->hdr.phy->tonemap_index == ctx->tm_dma.tonemap_index)) // - and received tonemap index is correct
{
// depending on the phy header type, different actions have to be done
ret = (*(function_array[msg->hdr.phy->type]))(ctx, msg);
@@ -675,22 +1093,84 @@ maximus_phy_recv_mpdu_payload (phy_t *ctx, sci_msg_t *msg)
else
{
unsigned int pb_counter;
- phy_pb_rx_t *current_pb = &ctx->pb_dma.first_pb->pb_rx;
unsigned short int pb_size = (PHY_PB_SIZE_520 == ctx->pb_dma.pb_size) ? 512 : 128;
-
+
+ // read crc
+ ctx->pb_dma.pb_crc_error &= (PHY_FLAG_CRC_OK != (msg->hdr.phy->flags & PHY_FLAG_CRC_OK));
+
+ // for pb dma callback
+ phy_pbdma_status_t status_word;
+ memset(&status_word, '\0', sizeof(phy_pbdma_status_t));
+
for (pb_counter = 0; pb_counter < msg->hdr.phy->pb_nb; pb_counter++)
{
- current_pb->header = msg->hdr.phy->pb_header[pb_counter];
- memcpy(&current_pb->pb_measurement, &msg->hdr.phy->pb_measurement[pb_counter], sizeof(pb_measurement_t));
+ if (ctx->pb_dma.index_current_pb == ctx->pb_dma.nb_ready)
+ {
+ /* When index_current_pb = nb_ready,
+ * PB null is set until the end of the MPDU
+ * (even if, after, index_current_pb <= pb_nb_ready). */
+
+ ctx->pb_dma.current_pb = NULL;
+
+ /* If not enough PBs are available in PB DMA,
+ * PB DMA raises an IT by calling 'phy_pbdma_cb' callback. */
+
+ status_word.pb_null = 1;
+ status_word.null_pb_index = ctx->pb_dma.index_current_pb;
+ (*ctx->control.pbdma_cb)(ctx->control.user_data, (*(u32*)(void*)&(status_word)));
+
+ // reset pb dma status
+ memset(&status_word, '\0', sizeof(phy_pbdma_status_t));
+ }
+
+ if (NULL != ctx->pb_dma.current_pb)
+ {
+ ctx->pb_dma.current_pb->header = msg->hdr.phy->pb_header[pb_counter];
+ memcpy(&ctx->pb_dma.current_pb->pb_measurement, &msg->hdr.phy->pb_measurement[pb_counter], sizeof(pb_measurement_t));
- // when message is received, first PB is read at the end of data
- memcpy(current_pb->blk.data, msg->data_end-(pb_counter+1)*pb_size, pb_size);
+ // when message is received, first PB is read at the end of data
+ memcpy(ctx->pb_dma.current_pb->blk.data, msg->data_end-(pb_counter+1)*pb_size, pb_size);
+ if (1 == ctx->pb_dma.current_pb->pb_measurement.crc_error)
+ {
+ ctx->pb_dma.pb_crc_error = true;
+ }
+
+ // find next pb
+ ctx->pb_dma.current_pb = PARENT_OF(phy_pb_rx_t, blk, ctx->pb_dma.current_pb->blk.next);
+ }
sci_msg_pop(msg, pb_size);
- current_pb = PARENT_OF(phy_pb_rx_t, blk, current_pb->blk.next);
+
+ // increment internal PB counter
+ ctx->pb_dma.index_current_pb++;
+
+ if (ctx->pb_dma.index_current_pb == ctx->pb_dma.nb_pb_it)
+ {
+ /* At the end of the nth PB transfer
+ * (i.e. index_current_pb = nb_pb_it),
+ * a PB end interrupt is simulated by calling phy_pbdma_cb callback. */
+
+ status_word.pb_it = 1;
+ (*ctx->control.pbdma_cb)(ctx->control.user_data, (*(u32*)(void*)&(status_word)));
+
+ // reset pb dma status
+ memset(&status_word, '\0', sizeof(phy_pbdma_status_t));
+ }
}
-
- ret = 0;
+
+ if (ctx->pb_dma.index_current_pb == ctx->pb_dma.nb_total) // end of transfer
+ {
+ if (ctx->pb_dma.pb_crc_error) // CRC is not correct
+ {
+ // at least one received PB was received with error,
+ // or a crc error was introduced by Maximus simulator
+ status_word.pb_crc_error = 1;
+ }
+ status_word.end_rx_pb = 1;
+ (*ctx->control.pbdma_cb)(ctx->control.user_data, (*(u32*)(void*)&(status_word)));
+ }
+
+ ret = 0;
}
return ret;
@@ -705,18 +1185,19 @@ maximus_phy_recv_tonemap (phy_t *ctx, sci_msg_t *msg)
{
errno = EINVAL;
}
- else if (2 != msg->hdr.phy->pb_nb) // tonemap uses two blocks
+ else if ((2 != msg->hdr.phy->pb_nb) // tonemap uses two blocks
+ || (PHY_TONEMAP_MAX_NB <= msg->hdr.phy->tonemap_index))
{
errno = EPROTO;
}
else
{
// when message is received, read second PB first
- memcpy(ctx->tm_dma.tonemap->next->data, msg->data_begin, PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE);
+ memcpy(ctx->tm_dma.tonemap[msg->hdr.phy->tonemap_index]->next->data, msg->data_begin, PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE);
sci_msg_pop(msg, PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE);
// then, read first PB
- memcpy(ctx->tm_dma.tonemap->data, msg->data_begin, PHY_PB_MAX_SIZE);
+ memcpy(ctx->tm_dma.tonemap[msg->hdr.phy->tonemap_index]->data, msg->data_begin, PHY_PB_MAX_SIZE);
sci_msg_pop(msg, PHY_PB_MAX_SIZE);
ret = 0;
@@ -736,17 +1217,62 @@ maximus_phy_recv_noise (phy_t *ctx, sci_msg_t *msg)
}
else
{
- // when message is received, time_noise is read
- memcpy(ctx->pb_dma.time_noise, msg->data_begin, PHY_SYMBOL_MAX_NB*sizeof(u8));
- sci_msg_pop(msg, PHY_SYMBOL_MAX_NB*sizeof(u8));
+ /* For a chandata transfer, all data are received into one SCI message. */
- // then, frequency_noise is read
- memcpy(ctx->pb_dma.frequency_noise, msg->data_begin, PHY_CARRIER_MAX_NB*sizeof(u16));
- sci_msg_pop(msg, PHY_CARRIER_MAX_NB*sizeof(u16));
-
- ret = 0;
+ int counter;
+ unsigned short int max_transfer_size = 255*2; // max value on 8 bits * 2 because size is in words => max transfer size in bytes
+ unsigned short int chandata_nb = (unsigned short int)(PHY_CARRIER_MAX_NB*sizeof(uint16_t)/max_transfer_size)+1;
+ unsigned short int last_chandata_size = (PHY_CARRIER_MAX_NB*sizeof(uint16_t)) % max_transfer_size;
+
+ // set current chandata
+ phy_chandata_t *current_chandata = ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE];
+
+ // read crc
+ bool chandata_crc_error = (PHY_FLAG_CRC_OK != (msg->hdr.phy->flags & PHY_FLAG_CRC_OK));
+
+ if ((NULL != current_chandata)
+ && (!chandata_crc_error))
+ {
+ // when message is received, time_noise is read
+ current_chandata->size = PHY_SYMBOL_MAX_NB*sizeof(uint8_t)/2; // size in words
+ current_chandata->last = 1;
+ current_chandata->type = MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE; // (INTERFACE TO BE UPDATED)
+ memcpy(ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE]->blk.data, msg->data_begin, PHY_SYMBOL_MAX_NB*sizeof(uint8_t));
+ sci_msg_pop(msg, PHY_SYMBOL_MAX_NB*sizeof(uint8_t));
+
+ // then, frequency_noise is read
+ current_chandata = ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_FREQUENCY_NOISE];
+ for (counter=0; counter<chandata_nb; counter++)
+ {
+ if (NULL != current_chandata)
+ {
+ current_chandata->type = MAXIMUS_PHY_CHANDATA_TYPE_FREQUENCY_NOISE; // (INTERFACE TO BE UPDATED)
+ if (counter != chandata_nb-1)
+ {
+ current_chandata->size = max_transfer_size/2; // size in words
+ current_chandata->last = 0;
+ memcpy(current_chandata->blk.data, msg->data_end-((counter+1)*max_transfer_size), max_transfer_size);
+ }
+ else
+ {
+ current_chandata->size = last_chandata_size/2; // size in words
+ current_chandata->last = 1;
+ memcpy(current_chandata->blk.data, msg->data_end-(counter*max_transfer_size+last_chandata_size), last_chandata_size);
+ ret = 0;
+ }
+
+ // find next chandata
+ current_chandata = PARENT_OF(phy_chandata_t, blk, current_chandata->blk.next);
+ }
+ else
+ {
+ errno = EPROTO;
+ }
+ }
+ sci_msg_pop(msg, PHY_CARRIER_MAX_NB*sizeof(uint16_t));
+ }
}
-
+
return ret;
}
@@ -761,11 +1287,55 @@ maximus_phy_recv_spectrum (phy_t *ctx, sci_msg_t *msg)
}
else
{
- memcpy(ctx->pb_dma.spectrum, msg->data_begin, PHY_CARRIER_MAX_NB*sizeof(u64));
- sci_msg_pop(msg, PHY_CARRIER_MAX_NB*sizeof(u64));
- ret = 0;
+ /* For a chandata transfer, all data are received into one SCI message. */
+
+ int counter;
+ unsigned short int max_transfer_size = 255*2; // max value on 8 bits * 2 because size is in words => max transfer size in bytes
+ unsigned short int chandata_nb = (unsigned short int)(PHY_CARRIER_MAX_NB*sizeof(uint64_t)/max_transfer_size)+1;
+ unsigned short int last_chandata_size = (PHY_CARRIER_MAX_NB*sizeof(uint64_t)) % max_transfer_size;
+
+ // set current chandata
+ phy_chandata_t *current_chandata = ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_SPECTRUM];
+
+ // read crc
+ bool chandata_crc_error = (PHY_FLAG_CRC_OK != (msg->hdr.phy->flags & PHY_FLAG_CRC_OK));
+
+ if ((NULL != current_chandata)
+ && (!chandata_crc_error))
+ {
+ // spectrum is read
+ current_chandata = ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_SPECTRUM];
+ for (counter=0; counter<chandata_nb; counter++)
+ {
+ if (NULL != current_chandata)
+ {
+ current_chandata->type = MAXIMUS_PHY_CHANDATA_TYPE_SPECTRUM; // (INTERFACE TO BE UPDATED)
+ if (counter != chandata_nb-1)
+ {
+ current_chandata->size = max_transfer_size/2; // size in words
+ current_chandata->last = 0;
+ memcpy(current_chandata->blk.data, msg->data_end-((counter+1)*max_transfer_size), max_transfer_size);
+ }
+ else
+ {
+ current_chandata->size = last_chandata_size/2; // size in words
+ current_chandata->last = 1;
+ memcpy(current_chandata->blk.data, msg->data_end-(counter*max_transfer_size+last_chandata_size), last_chandata_size);
+ ret = 0;
+ }
+
+ // find next chandata
+ current_chandata = PARENT_OF(phy_chandata_t, blk, current_chandata->blk.next);
+ }
+ else
+ {
+ errno = EPROTO;
+ }
+ }
+ sci_msg_pop(msg, PHY_CARRIER_MAX_NB*sizeof(uint64_t));
+ }
}
-
+
return ret;
}
@@ -801,11 +1371,10 @@ phy_init (void *user_data, phy_rx_fc_cb_t rx_fc_cb, phy_access_cb_t access_cb,
static netclock_callback_t rx_activate_netclock_cb;
static blk_t phy_tonemask; // uses one block
- static blk_t phy_tonemap1; // uses two blocks
- static blk_t phy_tonemap2;
+ static blk_t phy_tonemap[2*PHY_TONEMAP_MAX_NB]; // each tonemap uses two blocks
static u8 phy_tonemask_data[PHY_CARRIER_MAX_NB/8]; // 1 bit per carrier
- static u8 phy_tonemap1_data[PHY_PB_MAX_SIZE];
- static u8 phy_tonemap2_data[PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE]; // 4 bits per carrier
+ static u8 phy_tonemap1_data[PHY_PB_MAX_SIZE][PHY_TONEMAP_MAX_NB];
+ static u8 phy_tonemap2_data[PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE][PHY_TONEMAP_MAX_NB]; // 4 bits per carrier
if ((NULL == user_data)
|| (NULL == rx_fc_cb)
@@ -818,6 +1387,8 @@ phy_init (void *user_data, phy_rx_fc_cb_t rx_fc_cb, phy_access_cb_t access_cb,
}
else
{
+ unsigned short int tonemap_index;
+
memset(&ctx, '\0', sizeof(phy_t));
ctx.control.user_data = user_data;
ctx.control.rx_fc_cb = rx_fc_cb;
@@ -837,12 +1408,15 @@ phy_init (void *user_data, phy_rx_fc_cb_t rx_fc_cb, phy_access_cb_t access_cb,
memset(phy_tonemap2_data, '\0', PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE);
phy_tonemask.next = NULL;
phy_tonemask.data = phy_tonemask_data;
- phy_tonemap1.next = &phy_tonemap2;
- phy_tonemap1.data = phy_tonemap1_data;
- phy_tonemap2.next = NULL;
- phy_tonemap2.data = phy_tonemap2_data;
ctx.tm_dma.tonemask = &phy_tonemask;
- ctx.tm_dma.tonemap = &phy_tonemap1;
+ for (tonemap_index=0; tonemap_index<PHY_TONEMAP_MAX_NB; tonemap_index++)
+ {
+ phy_tonemap[2*tonemap_index].next = &phy_tonemap[2*tonemap_index+1];
+ phy_tonemap[2*tonemap_index].data = &phy_tonemap1_data[0][tonemap_index];
+ phy_tonemap[2*tonemap_index+1].next = NULL;
+ phy_tonemap[2*tonemap_index+1].data = &phy_tonemap2_data[0][tonemap_index];
+ ctx.tm_dma.tonemap[tonemap_index] = &phy_tonemap[2*tonemap_index];
+ }
// register phy_recv to the sci layer
sci_register_callback(my_station.sci, SCI_MSG_TYPE_PHY, maximus_phy_recv, &ctx);
@@ -996,7 +1570,8 @@ phy_tx_param (phy_t *ctx, phy_fc_mode_t fc_mode, bool short_ppdu,
* Set the gil value of PHY context.
* Set the tonemap_index value of PHY context. */
- if (NULL == ctx)
+ if ((NULL == ctx)
+ || (PHY_TONEMAP_MAX_NB <= tonemap_index))
{
errno = EINVAL;
}
@@ -1064,25 +1639,54 @@ phy_tx_frame (phy_t *ctx, u32 date, bool want_conf, bool stop_tx_on_prp_lost,
// set phy context values
ctx->control.stop_tx_on_prp_lost = stop_tx_on_prp_lost;
memcpy(ctx->control.fc_av, fc_av, 4*sizeof(u32));
-
- // fill callback data
- tx_fc_cb_data.isr = maximus_pending_isrs;
- tx_fc_cb_data.ctx = ctx;
- tx_fc_cb_data.want_conf = want_conf;
// set schedule tick
tick_high = my_station.current_tick_tck >> 32;
tick_low = date;
schedule_tick = (((unsigned long long)(tick_high)) << 32) | (unsigned long long)(tick_low);
-
- // send netclock message to Maximus
- netclock_schedule(my_station.netclock,
- ctx->control.tx_frame_netclock_cb,
- NETWORK_CLOCK_TYPE_STATION,
- schedule_tick,
- &maximus_phy_tx_fc_cb,
- (void*)&tx_fc_cb_data,
- &id);
+
+ if (!ctx->pb_dma.transfer_mode) // PB transfer
+ {
+ // fill callback data
+ tx_fc_cb_data.isr = maximus_pending_isrs;
+ tx_fc_cb_data.ctx = ctx;
+ tx_fc_cb_data.want_conf = want_conf;
+
+ // send netclock message to Maximus
+ netclock_schedule(my_station.netclock,
+ ctx->control.tx_frame_netclock_cb,
+ NETWORK_CLOCK_TYPE_STATION,
+ schedule_tick,
+ &maximus_phy_tx_fc_cb,
+ (void*)&tx_fc_cb_data,
+ &id);
+ }
+ else // chandata transfer
+ {
+ if ((MAXIMUS_PHY_CHANDATA_TYPE_FREQUENCY_NOISE == ctx->pb_dma.chandata_type)
+ || (MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE))
+ {
+ // send netclock message to Maximus
+ netclock_schedule(my_station.netclock,
+ ctx->control.tx_frame_netclock_cb,
+ NETWORK_CLOCK_TYPE_STATION,
+ schedule_tick,
+ &maximus_phy_send_noise_cb,
+ (void*)ctx,
+ &id);
+ }
+ else if (MAXIMUS_PHY_CHANDATA_TYPE_SPECTRUM == ctx->pb_dma.chandata_type)
+ {
+ // send netclock message to Maximus
+ netclock_schedule(my_station.netclock,
+ ctx->control.tx_frame_netclock_cb,
+ NETWORK_CLOCK_TYPE_STATION,
+ schedule_tick,
+ &maximus_phy_send_spectrum_cb,
+ (void*)ctx,
+ &id);
+ }
+ }
}
}
@@ -1227,6 +1831,15 @@ phy_rx_prepare (phy_t *ctx, bool short_ppdu, phy_mod_t mod,
// set rx mode
ctx->control.rx_tx_mode = true;
+
+ // reset internal PB counter
+ ctx->pb_dma.index_current_pb = 0;
+
+ // reset current PB descriptor for Rx
+ ctx->pb_dma.current_pb = &ctx->pb_dma.first_pb->pb_rx;
+
+ // reset crc error
+ ctx->pb_dma.pb_crc_error = false;
}
}
diff --git a/hal/phy/maximus/src/maximus_tmdma.c b/hal/phy/maximus/src/maximus_tmdma.c
index b5e35ccadb..27da4e2b44 100644
--- a/hal/phy/maximus/src/maximus_tmdma.c
+++ b/hal/phy/maximus/src/maximus_tmdma.c
@@ -63,7 +63,7 @@ phy_set_tonemap (phy_t *ctx, uint tonemap_index, blk_t *tonemap)
* Copy tonemap contents into PHY context. */
if ((NULL == ctx)
- || (ctx->tm_dma.carrier_nb <= tonemap_index)
+ || (PHY_TONEMAP_MAX_NB <= tonemap_index)
|| (NULL == tonemap)
|| (NULL == tonemap->next) // tonemap uses two blocks
|| (NULL == tonemap->data)
@@ -80,8 +80,8 @@ phy_set_tonemap (phy_t *ctx, uint tonemap_index, blk_t *tonemap)
ctx->tm_dma.tonemap_index = tonemap_index;
// copy tonemap
- memcpy(ctx->tm_dma.tonemap->data, tonemap->data, PHY_PB_MAX_SIZE);
- memcpy(ctx->tm_dma.tonemap->next->data, tonemap->next->data, ctx->tm_dma.carrier_nb/2-PHY_PB_MAX_SIZE);
+ memcpy(ctx->tm_dma.tonemap[tonemap_index]->data, tonemap->data, PHY_PB_MAX_SIZE);
+ memcpy(ctx->tm_dma.tonemap[tonemap_index]->next->data, tonemap->next->data, ctx->tm_dma.carrier_nb/2-PHY_PB_MAX_SIZE);
}
}
}
diff --git a/hal/phy/maximus/test/src/test_bridgedma.c b/hal/phy/maximus/test/src/test_bridgedma.c
index 478e43ef84..80a09305ed 100644
--- a/hal/phy/maximus/test/src/test_bridgedma.c
+++ b/hal/phy/maximus/test/src/test_bridgedma.c
@@ -17,6 +17,7 @@
#include "hal/phy/maximus/inc/maximus_phy_ctx.h"
#include "hal/phy/maximus/inc/maximus_bridgedma_ctx.h"
#include "host/station.h"
+#include <stdio.h> // for 'printf'
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
@@ -243,6 +244,7 @@ void bridgedma_segmentation_test_case(test_t t)
+ (job1.data_len + 10 + job2.data_len + 10 + job3.data_len + 10) / BRIDGEDMA_BYTE_PER_TICK;
max_end_of_dma_tck = min_end_of_dma_tck + BRIDGEDMA_ADD_MAX_TICK;
/* check the netclock tick planned event */
+ printf("bridgedma:\tnetclock hdr type = %d\tend of dma tck = %d\n", netclock_hdr->type, (int)end_of_dma_tck);
test_fail_unless(
(netclock_hdr->type == NETWORK_CLOCK_TYPE_PHY)
&& (end_of_dma_tck >= min_end_of_dma_tck)
diff --git a/hal/phy/maximus/test/src/test_pbdma.c b/hal/phy/maximus/test/src/test_pbdma.c
index 5866968a28..cfd4b489f6 100644
--- a/hal/phy/maximus/test/src/test_pbdma.c
+++ b/hal/phy/maximus/test/src/test_pbdma.c
@@ -11,3 +11,204 @@
* \ingroup hal_phy_maximus
*/
+#include "common/std.h"
+#include "lib/test.h"
+#include "host/station.h"
+#include "hal/phy/maximus/inc/maximus_phy_ctx.h"
+#include "hal/phy/maximus/inc/maximus_interrupts.h"
+#include "hal/phy/maximus/test/inc/test_phy_maximus.h"
+#include <stdio.h> // for 'printf'
+#include <string.h> // for 'memset'
+#include <errno.h>
+
+extern uint32_t maximus_pending_isrs; // used in 'station.c'
+extern station_ctx_t my_station;
+phy_t *ctx;
+
+void phy_pbdma_start_test_case(test_t t)
+{
+ printf("pbdma start\n");
+ test_case_begin(t, "pbdma start");
+
+ bool bypass_aes = false;
+ u32 iv[3];
+ u32 nek[4];
+ uint nb_total = 3;
+ uint nb_ready = 2;
+ uint nb_pb_it = 1;
+ phy_pb_t pb1;
+ phy_pb_t pb2;
+ phy_pb_t pb3;
+ u8 pb1_data[PHY_PB_MAX_SIZE];
+ u8 pb2_data[PHY_PB_MAX_SIZE];
+ u8 pb3_data[PHY_PB_MAX_SIZE];
+
+ memset(iv, 'i', 3*sizeof(u32));
+ memset(nek, 'n', 4*sizeof(u32));
+
+ // set pb size (set by 'phy_rx_prepare' in Rx and 'phy_tx_param' in Tx)
+ ctx->pb_dma.pb_size = PHY_PB_SIZE_520;
+
+ test_begin(t, "pbdma start in Tx")
+ {
+ // fill PBs for Tx
+ memset(pb1_data, 'a', PHY_PB_MAX_SIZE);
+ memset(pb2_data, 'b', PHY_PB_MAX_SIZE);
+ memset(pb3_data, 'c', PHY_PB_MAX_SIZE);
+ pb3.pb_tx.blk.next = NULL;
+ pb3.pb_tx.blk.data = pb3_data;
+ pb3.pb_tx.header = 3;
+ pb2.pb_tx.blk.next = &pb3.pb_tx.blk;
+ pb2.pb_tx.blk.data = pb2_data;
+ pb2.pb_tx.header = 2;
+ pb1.pb_tx.blk.next = &pb2.pb_tx.blk;
+ pb1.pb_tx.blk.data = pb1_data;
+ pb1.pb_tx.header = 1;
+
+ // set Tx mode
+ ctx->control.rx_tx_mode = false;
+
+ phy_pbdma_start (ctx, bypass_aes, iv,
+ nek, nb_total, nb_ready,
+ nb_pb_it, &pb1);
+ test_fail_unless ((EINVAL != errno)
+ && (bypass_aes == ctx->pb_dma.bypass_aes)
+ && (0 == memcmp(iv, ctx->pb_dma.iv, 3*sizeof(u32)))
+ && (0 == memcmp(nek, ctx->pb_dma.nek, 4*sizeof(u32)))
+ && (nb_total == ctx->pb_dma.nb_total)
+ && (nb_ready == ctx->pb_dma.nb_ready)
+ && (nb_pb_it == ctx->pb_dma.nb_pb_it)
+ && (&pb1 == ctx->pb_dma.first_pb)
+ && (0 == memcmp(pb1_data, ctx->pb_dma.first_pb->pb_tx.blk.data, PHY_PB_MAX_SIZE))
+ && (0 == memcmp(pb2_data, ctx->pb_dma.first_pb->pb_tx.blk.next->data, PHY_PB_MAX_SIZE))
+ && (0 == memcmp(pb3_data, ctx->pb_dma.first_pb->pb_tx.blk.next->next->data, PHY_PB_MAX_SIZE))
+ && (!ctx->pb_dma.transfer_mode));
+ } test_end;
+
+ test_begin(t, "pbdma start in Rx")
+ {
+ // reset PBs for Rx
+ memset(pb1_data, '\0', PHY_PB_MAX_SIZE);
+ memset(pb2_data, '\0', PHY_PB_MAX_SIZE);
+ memset(pb3_data, '\0', PHY_PB_MAX_SIZE);
+
+ pb3.pb_rx.blk.next = NULL;
+ pb3.pb_rx.blk.data = pb3_data;
+ pb3.pb_rx.header = 0;
+ memset(&pb3.pb_rx.pb_measurement, '\0', sizeof(pb_measurement_t));
+ pb2.pb_rx.blk.next = &pb3.pb_tx.blk;
+ pb2.pb_rx.blk.data = pb2_data;
+ pb2.pb_rx.header = 0;
+ memset(&pb2.pb_rx.pb_measurement, '\0', sizeof(pb_measurement_t));
+ pb1.pb_rx.blk.next = &pb2.pb_tx.blk;
+ pb1.pb_rx.blk.data = pb1_data;
+ pb1.pb_rx.header = 0;
+ memset(&pb1.pb_rx.pb_measurement, '\0', sizeof(pb_measurement_t));
+
+ // set Rx mode
+ ctx->control.rx_tx_mode = true;
+
+ phy_pbdma_start (ctx, bypass_aes, iv,
+ nek, nb_total, nb_ready,
+ nb_pb_it, &pb1);
+ test_fail_unless ((EINVAL != errno)
+ && (bypass_aes == ctx->pb_dma.bypass_aes)
+ && (0 == memcmp(iv, ctx->pb_dma.iv, 3*sizeof(u32)))
+ && (0 == memcmp(nek, ctx->pb_dma.nek, 4*sizeof(u32)))
+ && (nb_total == ctx->pb_dma.nb_total)
+ && (nb_ready == ctx->pb_dma.nb_ready)
+ && (nb_pb_it == ctx->pb_dma.nb_pb_it)
+ && (&pb1 == ctx->pb_dma.first_pb)
+ && (!ctx->pb_dma.transfer_mode));
+ } test_end;
+}
+
+void phy_pbdma_update_test_case(test_t t)
+{
+ printf("pbdma update\n");
+ test_case_begin(t, "pbdma update");
+
+ test_begin(t, "pbdma update")
+ {
+ uint nb_ready = 3;
+ uint nb_pb_it = 2;
+
+ phy_pbdma_update (ctx, nb_ready, nb_pb_it);
+ test_fail_unless ((EINVAL != errno)
+ && (nb_ready == ctx->pb_dma.nb_ready)
+ && (nb_pb_it == ctx->pb_dma.nb_pb_it));
+ } test_end;
+}
+
+void phy_pbdma_start_chandata_test_case(test_t t)
+{
+ printf("pbdma start chandata\n");
+ test_case_begin(t, "pbdma start chandata");
+
+ phy_chandata_t chandata1;
+ phy_chandata_t chandata2;
+ unsigned short int chandata_size = 255*2; // max value on 8 bits * 2 because size is in words => max transfer size in bytes
+ u8 chandata1_data[chandata_size];
+ u8 chandata2_data[chandata_size];
+
+ test_begin(t, "pbdma start chandata in Tx")
+ {
+ // fill chandata for Tx
+ memset(chandata1_data, 'd', chandata_size);
+ memset(chandata2_data, 'e', chandata_size);
+ chandata2.blk.next = NULL;
+ chandata2.blk.data = chandata2_data;
+ chandata2.size = chandata_size/2; // in words
+ chandata2.last = 1;
+ chandata2.type = MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE;
+ chandata2.address = 0;
+ chandata1.blk.next = &chandata2.blk;
+ chandata1.blk.data = chandata1_data;
+ chandata1.size = chandata_size/2; // in words
+ chandata1.last = 0;
+ chandata1.type = MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE;
+ chandata1.address = 0;
+
+ // set Tx mode
+ ctx->control.rx_tx_mode = false;
+
+ phy_pbdma_start_chandata (ctx, &chandata1);
+ test_fail_unless ((EINVAL != errno)
+ && (&chandata1 == ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE])
+ && (0 == memcmp(chandata1_data, ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE]->blk.data, chandata_size))
+ && (0 == memcmp(chandata2_data, ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE]->blk.next->data, chandata_size))
+ && (ctx->pb_dma.transfer_mode));
+ } test_end;
+
+ test_begin(t, "pbdma start chandata in Rx")
+ {
+ // set Rx mode
+ ctx->control.rx_tx_mode = true;
+
+ phy_pbdma_start_chandata (ctx, &chandata2);
+ test_fail_unless ((EINVAL != errno)
+ && (&chandata2 == ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE])
+ && (ctx->pb_dma.transfer_mode));
+ } test_end;
+}
+
+void pbdma_test_suite(test_t t)
+{
+ int user_data = 1234567890;
+
+ station_init (&my_station);
+ ctx = phy_init ((void*)&user_data,
+ &phy_rx_fc_cb,
+ &phy_access_cb,
+ &phy_access_conf_cb,
+ &phy_pbdma_cb,
+ &phy_deferred_cb);
+
+ test_suite_begin(t, "pb dma");
+ phy_pbdma_start_test_case(t);
+ phy_pbdma_update_test_case(t);
+ phy_pbdma_start_chandata_test_case(t);
+
+ phy_uninit (ctx);
+ station_down (&my_station);
+}
diff --git a/hal/phy/maximus/test/src/test_phy_ctrl.c b/hal/phy/maximus/test/src/test_phy_ctrl.c
index 18314af458..0b8e988781 100644
--- a/hal/phy/maximus/test/src/test_phy_ctrl.c
+++ b/hal/phy/maximus/test/src/test_phy_ctrl.c
@@ -126,6 +126,21 @@ void maximus_phy_fill_hdr_test_case(test_t t)
void maximus_phy_recv_test_case(test_t t)
{
+ // for PHY_TYPE_NOISE
+ static u16 frequency_noise[PHY_CARRIER_MAX_NB];
+ static u8 time_noise[PHY_SYMBOL_MAX_NB];
+ const unsigned short int max_transfer_size = 255*2; // max value on 8 bits * 2 because size is in words => max transfer size in bytes
+ const unsigned short int frequency_noise_nb = 7;
+ static phy_chandata_t frequency_noise_chandata[7];
+ static phy_chandata_t time_noise_chandata;
+ static u8 frequency_noise_data[7][510];
+ static u8 time_noise_data[510];
+ // for PHY_TYPE_SPECTRUM
+ static u64 spectrum[PHY_CARRIER_MAX_NB];
+ const unsigned short int spectrum_nb = 25;
+ static phy_chandata_t spectrum_chandata[25];
+ static u8 spectrum_data[SCI_MSG_MAX_SIZE];
+
sci_msg_t msg;
unsigned char buffer[SCI_MSG_MAX_SIZE];
@@ -179,10 +194,6 @@ void maximus_phy_recv_test_case(test_t t)
// for PHY_TYPE_TONEMAP
u8 tonemap1_data[PHY_PB_MAX_SIZE];
u8 tonemap2_data[PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE];
- // for PHY_TYPE_NOISE
- u16 frequency_noise[PHY_CARRIER_MAX_NB];
- u8 time_noise[PHY_SYMBOL_MAX_NB];
- u64 spectrum[PHY_CARRIER_MAX_NB]; // for PHY_TYPE_SPECTRUM
// initialize sci data
char c = '1';
@@ -191,8 +202,11 @@ void maximus_phy_recv_test_case(test_t t)
memset(pb_header, '0', PHY_PB_MAX_NB*sizeof(u32));
memset(fc_av, 'b', 4*sizeof(u32));
memset(frequency_noise, 'c', PHY_CARRIER_MAX_NB*sizeof(u16));
+ memset(frequency_noise_data, '\0', frequency_noise_nb*max_transfer_size);
memset(time_noise, 'd', PHY_SYMBOL_MAX_NB*sizeof(u8));
+ memset(time_noise_data, '\0', max_transfer_size);
memset(spectrum, 'e', PHY_CARRIER_MAX_NB*sizeof(u64));
+ memset(spectrum_data, '\0', SCI_MSG_MAX_SIZE);
for (pb_counter = 0; pb_counter < PHY_PB_NB; pb_counter++)
{
memset(&pb_measurement[pb_counter], c, sizeof(pb_measurement_t));
@@ -266,7 +280,12 @@ void maximus_phy_recv_test_case(test_t t)
phy_pb[pb_counter].pb_rx.blk.next = NULL;
}
}
+ // set pb dma
ctx->pb_dma.first_pb = phy_pb;
+ ctx->pb_dma.current_pb = &ctx->pb_dma.first_pb->pb_rx;
+ ctx->pb_dma.nb_total = PHY_PB_NB;
+ ctx->pb_dma.nb_ready = PHY_PB_NB;
+ ctx->pb_dma.nb_pb_it = PHY_PB_NB-1;
}
// tonemap
if (PHY_TYPE_TONEMAP == phy_hdr.type)
@@ -289,6 +308,31 @@ void maximus_phy_recv_test_case(test_t t)
// noise
if (PHY_TYPE_NOISE == phy_hdr.type)
{
+ // for frequency noise
+ unsigned int i=0;
+ phy_chandata_t *current_chandata = frequency_noise_chandata;
+
+ // reset SCI message
+ memset(buffer, '\0', SCI_MSG_MAX_SIZE);
+ test_fail_unless (0 == sci_msg_init(&msg, buffer, SCI_MSG_MAX_SIZE));
+ msg.length = 0;
+
+ // frequency noise
+ for (i=0; i<frequency_noise_nb; i++)
+ {
+ current_chandata->blk.data = &frequency_noise_data[i][0];
+ current_chandata->blk.next = &(frequency_noise_chandata[i+1].blk);
+ current_chandata = PARENT_OF(phy_chandata_t, blk, current_chandata->blk.next);
+ }
+ current_chandata->blk.next = NULL; // for last chandata
+ ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_FREQUENCY_NOISE] = frequency_noise_chandata;
+
+ // time noise
+ time_noise_chandata.blk.data = time_noise_data;
+ time_noise_chandata.blk.next = NULL;
+ ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE] = &time_noise_chandata;
+
+ // fill sci data
test_fail_unless ((PHY_CARRIER_MAX_NB*sizeof(u16) == sci_msg_push(&msg, PHY_CARRIER_MAX_NB*sizeof(u16)))
&& (EINVAL != errno)
&& (ENOSPC != errno));
@@ -297,10 +341,29 @@ void maximus_phy_recv_test_case(test_t t)
&& (EINVAL != errno)
&& (ENOSPC != errno));
memcpy(msg.data_begin, time_noise, PHY_SYMBOL_MAX_NB*sizeof(u8));
+
}
// spectrum
if (PHY_TYPE_SPECTRUM == phy_hdr.type)
{
+ unsigned int i=0;
+ phy_chandata_t *current_chandata = spectrum_chandata;
+
+ // reset SCI message
+ memset(buffer, '\0', SCI_MSG_MAX_SIZE);
+ test_fail_unless (0 == sci_msg_init(&msg, buffer, SCI_MSG_MAX_SIZE));
+ msg.length = 0;
+
+ for (i=0; i<spectrum_nb; i++)
+ {
+ current_chandata->blk.data = &spectrum_data[i*max_transfer_size];
+ current_chandata->blk.next = &(spectrum_chandata[i+1].blk);
+ current_chandata = PARENT_OF(phy_chandata_t, blk, current_chandata->blk.next);
+ }
+ current_chandata->blk.next = NULL;
+ ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_SPECTRUM] = spectrum_chandata;
+
+ // fill sci data
test_fail_unless ((PHY_CARRIER_MAX_NB*sizeof(u64) == sci_msg_push(&msg, PHY_CARRIER_MAX_NB*sizeof(u64)))
&& (EINVAL != errno)
&& (ENOSPC != errno));
@@ -373,19 +436,61 @@ void maximus_phy_recv_test_case(test_t t)
if (PHY_TYPE_TONEMAP == phy_hdr.type)
{
// tonemap uses 2 blocks
- test_fail_unless (0 == memcmp(tonemap1_data, ctx->tm_dma.tonemap->data, PHY_PB_MAX_SIZE));
- test_fail_unless (0 == memcmp(tonemap2_data, ctx->tm_dma.tonemap->next->data, PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE));
+ test_fail_unless (0 == memcmp(tonemap1_data, ctx->tm_dma.tonemap[phy_hdr.tonemap_index]->data, PHY_PB_MAX_SIZE));
+ test_fail_unless (0 == memcmp(tonemap2_data, ctx->tm_dma.tonemap[phy_hdr.tonemap_index]->next->data, PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE));
}
// test noise
if (PHY_TYPE_NOISE == phy_hdr.type)
- {
- test_fail_unless (0 == memcmp(frequency_noise, ctx->pb_dma.frequency_noise, PHY_CARRIER_MAX_NB*sizeof(u16)));
- test_fail_unless (0 == memcmp(time_noise, ctx->pb_dma.time_noise, PHY_SYMBOL_MAX_NB*sizeof(u8)));
+ {
+ // for frequency noise
+ int counter;
+ unsigned short int last_chandata_size = 12;
+ phy_chandata_t *current_chandata;
+
+ // test time noise
+ //printf("\ttime noise length = %d\n", strlen((char*)ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE]->blk.data));
+ //printf("\ttime noise = %s\n", ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE]->blk.data);
+ test_fail_unless (0 == memcmp(time_noise, ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE]->blk.data, PHY_SYMBOL_MAX_NB*sizeof(u8)));
+
+ // test frequency noise
+ // set current chandata
+ current_chandata = ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_FREQUENCY_NOISE];
+ for (counter=0; counter<frequency_noise_nb; counter++)
+ {
+ //printf("\tfrequency noise %d length = %d\n", counter, strlen((char*)current_chandata->blk.data));
+ //printf("\tfrequency noise = %s\n", current_chandata->blk.data);
+ if (frequency_noise_nb-1 != counter)
+ {
+ test_fail_unless (0 == memcmp(&frequency_noise[counter*max_transfer_size/2], current_chandata->blk.data, max_transfer_size));
+ current_chandata = PARENT_OF(phy_chandata_t, blk, current_chandata->blk.next);
+ }
+ else
+ {
+ test_fail_unless (0 == memcmp(&frequency_noise[counter*max_transfer_size/2], current_chandata->blk.data, last_chandata_size));
+ }
+ }
}
// test spectrum
if (PHY_TYPE_SPECTRUM == phy_hdr.type)
{
- test_fail_unless (0 == memcmp(spectrum, ctx->pb_dma.spectrum, PHY_CARRIER_MAX_NB*sizeof(u64)));
+ int counter;
+ unsigned short int last_chandata_size = 48;
+ // set current chandata
+ phy_chandata_t *current_chandata = ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_SPECTRUM];
+ for (counter=0; counter<spectrum_nb; counter++)
+ {
+ //printf("\tspectrum %d length = %d\n", counter, strlen((char*)current_chandata->blk.data));
+ //printf("\tspectrum = %s\n", current_chandata->blk.data);
+ if (spectrum_nb-1 != counter)
+ {
+ test_fail_unless (0 == memcmp(&spectrum[counter*max_transfer_size/8], ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_SPECTRUM]->blk.data, max_transfer_size));
+ current_chandata = PARENT_OF(phy_chandata_t, blk, current_chandata->blk.next);
+ }
+ else
+ {
+ test_fail_unless (0 == memcmp(&spectrum[counter*max_transfer_size/8], ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_SPECTRUM]->blk.data, last_chandata_size));
+ }
+ }
}
}
} test_end;
@@ -522,7 +627,7 @@ void phy_tx_param_test_case(test_t t)
phy_fecrate_t fecrate = PHY_FEC_RATE_1_2;
phy_pb_size_t pb_size = PHY_PB_SIZE_136;
phy_gil_t gil = PHY_GIL_417;
- uint tonemap_index = 9;
+ uint tonemap_index = 3;
phy_tx_param (ctx, fc_mode, short_ppdu,
mod, fecrate, pb_size,
@@ -565,7 +670,7 @@ void phy_tx_frame_test_case(test_t t)
uint carrier_nb = PHY_CARRIER_MAX_NB;
u8 tonemap1_data[PHY_PB_MAX_SIZE];
u8 tonemap2_data[PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE];
- uint tonemap_index = 10;
+ uint tonemap_index = 3;
printf("tx frame\n");
test_case_begin(t, "tx frame");
@@ -716,7 +821,7 @@ void phy_tx_frame_test_case(test_t t)
// calculate frame control transimission time
bits_per_symbol = maximus_dur_bits_per_symbol(ctx->tm_dma.mod,
ctx->tm_dma.tonemask,
- ctx->tm_dma.tonemap,
+ ctx->tm_dma.tonemap[tonemap_index],
ctx->tm_dma.carrier_nb);
if ((PHY_FC_MODE_HYBRID_2 == ctx->control.fc_mode)
|| (PHY_FC_MODE_AV_2 == ctx->control.fc_mode))
@@ -781,6 +886,7 @@ void phy_tx_frame_test_case(test_t t)
pb1.pb_tx.header = 1;
ctx->pb_dma.pb_size = PHY_PB_SIZE_520;
+ ctx->pb_dma.nb_total = 3;
ctx->pb_dma.nb_ready = 3;
ctx->pb_dma.first_pb = &pb1;
@@ -845,12 +951,169 @@ void phy_tx_frame_test_case(test_t t)
return;
}
-void phy_clock_set_test_case(test_t t)
+void maximus_phy_send_test_case(test_t t)
+{
+ // for tonemap
+ blk_t tonemap1;
+ blk_t tonemap2;
+ u8 tonemap1_data[PHY_PB_MAX_SIZE];
+ u8 tonemap2_data[PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE];
+ uint tonemap_index = 3;
+
+ printf("maximus phy send\n");
+ test_case_begin(t, "maximus phy send");
+
+ // set tonemap
+ memset(tonemap1_data, '1', PHY_PB_MAX_SIZE*sizeof(u8));
+ memset(tonemap2_data, '2', (PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE)*sizeof(u8));
+ tonemap2.next = NULL;
+ tonemap2.data = tonemap2_data;
+ tonemap1.next = &tonemap2;
+ tonemap1.data = tonemap1_data;
+ ctx->tm_dma.mod = PHY_MOD_TM;
+ phy_set_tonemap (ctx, tonemap_index, &tonemap1);
+
+ // set tx param
+ ctx->access.medium_state = MAXIMUS_PHY_MEDIUM_BUSY;
+ ctx->control.rx_tx_mode = false;
+
+ // test the tonemap callback
+ test_begin(t, "maximus phy send tonemap cb")
+ {
+ maximus_phy_send_tonemap_cb ((void*)ctx);
+ test_fail_unless (EINVAL != errno);
+ } test_end;
+
+ // check that the correct phy message has been sent to Maximus
+ test_begin(t, "tonemap phy message")
+ {
+ unsigned char data[SCI_MSG_MAX_SIZE];
+ sci_msg_hdr_t *sci_hdr;
+ phy_msg_hdr_t *phy_hdr;
+ int fd_in = -1;
+
+ // open pipe
+ fd_in = open(my_station.pipe_out_name, O_RDONLY);
+
+ // read sci and phy headers
+ memset(data, '\0', SCI_MSG_MAX_SIZE);
+ test_fail_unless ((-1 != fd_in)
+ && (sizeof(sci_msg_hdr_t) == read(fd_in, data, sizeof(sci_msg_hdr_t)))
+ && (sizeof(phy_msg_hdr_t) == read(fd_in, data+sizeof(sci_msg_hdr_t), sizeof(phy_msg_hdr_t))));
+
+ // set sci and phy headers pointers
+ sci_hdr = (sci_msg_hdr_t *)(data);
+ phy_hdr = (phy_msg_hdr_t *)(data+sizeof(sci_msg_hdr_t));
+
+ // check phy header
+ test_fail_unless (PHY_TYPE_TONEMAP == phy_hdr->type);
+
+ // read the remaining part of message
+ test_fail_unless (PHY_CARRIER_MAX_NB/2 == read(fd_in, data+sizeof(sci_msg_hdr_t)+sizeof(phy_msg_hdr_t), PHY_CARRIER_MAX_NB/2));
+
+ // check phy data
+ test_fail_unless (0 == memcmp(tonemap2_data, data+sizeof(sci_msg_hdr_t)+sizeof(phy_msg_hdr_t), PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE));
+ test_fail_unless (0 == memcmp(tonemap1_data, data+sizeof(sci_msg_hdr_t)+sizeof(phy_msg_hdr_t)+PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE, PHY_PB_MAX_SIZE));
+
+ // close pipe
+ close(fd_in);
+ } test_end;
+
+ // set medium state
+ ctx->access.medium_state = MAXIMUS_PHY_MEDIUM_BUSY;
+
+ // test the tonemap callback
+ test_begin(t, "maximus phy send noise cb")
+ {
+ maximus_phy_send_noise_cb ((void*)ctx);
+ test_fail_unless (EINVAL != errno);
+ } test_end;
+
+ // check that the correct phy message has been sent to Maximus
+ test_begin(t, "noise phy message")
+ {
+ unsigned char data[SCI_MSG_MAX_SIZE];
+ sci_msg_hdr_t *sci_hdr;
+ phy_msg_hdr_t *phy_hdr;
+ int fd_in = -1;
+
+ // open pipe
+ fd_in = open(my_station.pipe_out_name, O_RDONLY);
+
+ // read sci and phy headers
+ memset(data, '\0', SCI_MSG_MAX_SIZE);
+ test_fail_unless ((-1 != fd_in)
+ && (sizeof(sci_msg_hdr_t) == read(fd_in, data, sizeof(sci_msg_hdr_t)))
+ && (sizeof(phy_msg_hdr_t) == read(fd_in, data+sizeof(sci_msg_hdr_t), sizeof(phy_msg_hdr_t))));
+
+ // set sci and phy headers pointers
+ sci_hdr = (sci_msg_hdr_t *)(data);
+ phy_hdr = (phy_msg_hdr_t *)(data+sizeof(sci_msg_hdr_t));
+
+ // check phy header
+ test_fail_unless (PHY_TYPE_NOISE == phy_hdr->type);
+
+ // read time noise
+ test_fail_unless (PHY_SYMBOL_MAX_NB*sizeof(uint8_t) == read(fd_in, data+sizeof(sci_msg_hdr_t)+sizeof(phy_msg_hdr_t), PHY_SYMBOL_MAX_NB*sizeof(uint8_t)));
+
+ // read frequency noise
+ test_fail_unless (PHY_CARRIER_MAX_NB*sizeof(uint16_t) == read(fd_in, data+sizeof(sci_msg_hdr_t)+sizeof(phy_msg_hdr_t)+PHY_SYMBOL_MAX_NB*sizeof(uint8_t), PHY_CARRIER_MAX_NB*sizeof(uint16_t)));
+
+ // check phy data
+ test_fail_unless (0 == memcmp(data+sizeof(sci_msg_hdr_t)+sizeof(phy_msg_hdr_t), ctx->pb_dma.first_chandata[MAXIMUS_PHY_CHANDATA_TYPE_TIME_NOISE]->blk.data, PHY_SYMBOL_MAX_NB*sizeof(uint8_t)));
+
+ // close pipe
+ close(fd_in);
+ } test_end;
+
+ // set medium state
+ ctx->access.medium_state = MAXIMUS_PHY_MEDIUM_BUSY;
+
+ // test the tonemap callback
+ test_begin(t, "maximus phy send spectrum cb")
+ {
+ maximus_phy_send_spectrum_cb ((void*)ctx);
+ test_fail_unless (EINVAL != errno);
+ } test_end;
+
+ // check that the correct phy message has been sent to Maximus
+ test_begin(t, "spectrum phy message")
+ {
+ unsigned char data[SCI_MSG_MAX_SIZE];
+ sci_msg_hdr_t *sci_hdr;
+ phy_msg_hdr_t *phy_hdr;
+ int fd_in = -1;
+
+ // open pipe
+ fd_in = open(my_station.pipe_out_name, O_RDONLY);
+
+ // read sci and phy headers
+ memset(data, '\0', SCI_MSG_MAX_SIZE);
+ test_fail_unless ((-1 != fd_in)
+ && (sizeof(sci_msg_hdr_t) == read(fd_in, data, sizeof(sci_msg_hdr_t)))
+ && (sizeof(phy_msg_hdr_t) == read(fd_in, data+sizeof(sci_msg_hdr_t), sizeof(phy_msg_hdr_t))));
+
+ // set sci and phy headers pointers
+ sci_hdr = (sci_msg_hdr_t *)(data);
+ phy_hdr = (phy_msg_hdr_t *)(data+sizeof(sci_msg_hdr_t));
+
+ // check phy header
+ test_fail_unless (PHY_TYPE_SPECTRUM == phy_hdr->type);
+
+ // read the remaining part of message
+ test_fail_unless (PHY_CARRIER_MAX_NB*sizeof(uint64_t) == read(fd_in, data+sizeof(sci_msg_hdr_t)+sizeof(phy_msg_hdr_t), PHY_CARRIER_MAX_NB*sizeof(uint64_t)));
+
+ // close pipe
+ close(fd_in);
+ } test_end;
+}
+
+void phy_set_clock_test_case(test_t t)
{
- printf("clock set\n");
- test_case_begin(t, "clock set");
+ printf("set clock\n");
+ test_case_begin(t, "set clock");
- test_begin(t, "clock set")
+ test_begin(t, "set clock")
{
uint phy_clock = 1234567890;
@@ -957,7 +1220,10 @@ void phy_rx_prepare_test_case(test_t t)
test_fail_unless ((EINVAL != errno)
&& (NULL != ctx)
&& (tonemap_index == ctx->tm_dma.tonemap_index)
- && (pb_size == ctx->pb_dma.pb_size));
+ && (pb_size == ctx->pb_dma.pb_size)
+ && (0 == ctx->pb_dma.index_current_pb)
+ && (ctx->pb_dma.current_pb == &ctx->pb_dma.first_pb->pb_rx)
+ && (!ctx->pb_dma.pb_crc_error));
} test_end;
return;
@@ -975,7 +1241,8 @@ void phy_ctrl_test_suite(test_t t)
phy_tx_fc10_test_case(t);
phy_tx_param_test_case(t);
phy_tx_frame_test_case(t);
- phy_clock_set_test_case(t);
+ maximus_phy_send_test_case(t);
+ phy_set_clock_test_case(t);
phy_rx_param_test_case(t);
phy_rx_activate_test_case(t);
phy_rx_prepare_test_case(t);
diff --git a/hal/phy/maximus/test/src/test_phy_maximus.c b/hal/phy/maximus/test/src/test_phy_maximus.c
index 940d789cd9..7fb371de29 100644
--- a/hal/phy/maximus/test/src/test_phy_maximus.c
+++ b/hal/phy/maximus/test/src/test_phy_maximus.c
@@ -57,7 +57,7 @@ main (int argc, char **argv)
test_init(t, argc, argv);
bridgedma_test_suite(t);
- //pbdma_test_suite(t);
+ pbdma_test_suite(t);
phy_access_test_suite(t);
phy_ctrl_test_suite(t);
tmdma_test_suite(t);
diff --git a/hal/phy/maximus/test/src/test_tmdma.c b/hal/phy/maximus/test/src/test_tmdma.c
index 22108b841c..d91545e1af 100644
--- a/hal/phy/maximus/test/src/test_tmdma.c
+++ b/hal/phy/maximus/test/src/test_tmdma.c
@@ -53,7 +53,7 @@ void phy_set_tonemap_test_case(test_t t)
blk_t tonemap2;
u8 tonemap1_data[PHY_PB_MAX_SIZE];
u8 tonemap2_data[PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE]; // 4 bits per carrier
- uint tonemap_index = 10;
+ uint tonemap_index = 3;
memset(tonemap1_data, 'b', PHY_PB_MAX_SIZE*sizeof(u8));
memset(tonemap2_data, 'c', (PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE)*sizeof(u8));
@@ -66,8 +66,8 @@ void phy_set_tonemap_test_case(test_t t)
phy_set_tonemap (ctx, tonemap_index, &tonemap1);
test_fail_unless ((EINVAL != errno)
&& (tonemap_index == ctx->tm_dma.tonemap_index)
- && (0 == memcmp(tonemap1.data, ctx->tm_dma.tonemap->data, PHY_PB_MAX_SIZE))
- && (0 == memcmp(tonemap2.data, ctx->tm_dma.tonemap->next->data, PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE)));
+ && (0 == memcmp(tonemap1.data, ctx->tm_dma.tonemap[ctx->tm_dma.tonemap_index]->data, PHY_PB_MAX_SIZE))
+ && (0 == memcmp(tonemap2.data, ctx->tm_dma.tonemap[ctx->tm_dma.tonemap_index]->next->data, PHY_CARRIER_MAX_NB/2-PHY_PB_MAX_SIZE)));
} test_end;
}