summaryrefslogtreecommitdiff
path: root/cesar/hal/phy/maximus/src/maximus_pbdma.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/hal/phy/maximus/src/maximus_pbdma.c')
-rw-r--r--cesar/hal/phy/maximus/src/maximus_pbdma.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/cesar/hal/phy/maximus/src/maximus_pbdma.c b/cesar/hal/phy/maximus/src/maximus_pbdma.c
new file mode 100644
index 0000000000..7da493ca4d
--- /dev/null
+++ b/cesar/hal/phy/maximus/src/maximus_pbdma.c
@@ -0,0 +1,187 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file hal/phy/maximus/src/maximus_pbdma.c
+ * \brief HAL Phy PB DMA functions for Maximus.
+ * \ingroup hal_phy_maximus
+ */
+
+#include "common/std.h"
+#include "hal/phy/maximus/inc/maximus_phy_ctx.h"
+#include "mac/common/defs.h" // for 'MAC_MAX_PB_PER_MPDU'
+#include <errno.h>
+
+
+/**
+ * Start a PB transfer.
+ * \param ctx phy context
+ * \param bypass_aes do not encrypt or decrypt using AES
+ * \param iv three first AES initialisation vector words
+ * \param nek AES network encryption key
+ * \param nb_total total number of PB
+ * \param nb_ready number of ready descriptors
+ * \param nb_pb_it number of the PB after which an interrupt is triggered
+ * \param first_pb first PB descriptor
+ * set errno to:
+ * - EINVAL if ctx or first_pb are null, or if arguments are out-of-range or incoherent
+ *
+ * The transfer will start when the reception or the transmission starts.
+ */
+void
+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)
+{
+ dbg_assert_ptr(ctx);
+ dbg_assert(MAC_MAX_PB_PER_MPDU >= nb_total);
+ dbg_assert(nb_total >= nb_ready);
+ dbg_assert(nb_total >= nb_pb_it);
+ dbg_assert_ptr(first_pb);
+ MAXIMUS_PHY_TRACE (PBDMA_START, bypass_aes, nb_total, nb_ready, nb_pb_it);
+ if ((NULL == ctx)
+ || (MAC_MAX_PB_PER_MPDU < nb_total)
+ || (nb_total < nb_ready)
+ || (nb_total < nb_pb_it)
+ || (NULL == first_pb))
+ {
+ errno = EINVAL;
+ station_log(&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_PHY,
+ "%s: errno = %d", __FUNCTION__, errno);
+ }
+ else
+ {
+ ctx->pbdma.bypass_aes = bypass_aes;
+ if (!bypass_aes)
+ {
+ memcpy(ctx->pbdma.iv, iv, 3*sizeof(u32));
+ memcpy(ctx->pbdma.nek, nek, 4*sizeof(u32));
+ }
+ else
+ {
+ memset(ctx->pbdma.iv, '\0', 3*sizeof(u32));
+ memset(ctx->pbdma.nek, '\0', 4*sizeof(u32));
+ }
+ ctx->pbdma.nb_total = nb_total;
+ ctx->pbdma.nb_ready = nb_ready;
+ ctx->pbdma.nb_pb_it = nb_pb_it;
+ ctx->pbdma.first_pb = first_pb;
+
+ // reset current PB descriptor in case of Rx
+ ctx->pbdma.current_pb = &ctx->pbdma.first_pb->pb_rx;
+ }
+}
+
+
+/**
+ * Update PB transfer counters.
+ * \param ctx phy context
+ * \param nb_ready number of ready descriptors
+ * \param nb_pb_it number of the PB after which an interrupt is triggered
+ * set errno to:
+ * - EINVAL if ctx is null, or if arguments are incoherent
+ */
+void
+phy_pbdma_update (phy_t *ctx, uint nb_ready, uint nb_pb_it)
+{
+ dbg_assert_ptr(ctx);
+ dbg_assert(nb_ready >= ctx->pbdma.nb_ready);
+ dbg_assert(nb_pb_it <= ctx->pbdma.nb_total);
+ dbg_assert(nb_ready <= ctx->pbdma.nb_total);
+ MAXIMUS_PHY_TRACE (PBDMA_UPDATE, nb_ready, nb_pb_it);
+ if ((NULL == ctx)
+ || (nb_ready < ctx->pbdma.nb_ready)
+ || (nb_pb_it > ctx->pbdma.nb_total)
+ || (nb_ready > ctx->pbdma.nb_total))
+ {
+ errno = EINVAL;
+ station_log(&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_PHY,
+ "%s: errno = %d", __FUNCTION__, errno);
+ }
+ else
+ {
+ ctx->pbdma.nb_ready = nb_ready;
+ ctx->pbdma.nb_pb_it = nb_pb_it;
+ }
+}
+
+
+/**
+ * Retrieve last used PB descriptor.
+ * \param ctx phy context
+ * \return last used PB descriptor
+ * set errno to:
+ * - EINVAL if ctx is null
+ */
+phy_pb_t *
+phy_pbdma_get_tail (phy_t *ctx)
+{
+ phy_pb_t * tail = NULL;
+
+ dbg_assert_ptr(ctx);
+ if (NULL == ctx)
+ {
+ errno = EINVAL;
+ station_log(&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_PHY,
+ "%s: errno = %d", __FUNCTION__, errno);
+ }
+ else
+ {
+ // PHY context current PB points to the last valid received PB
+ tail = PARENT_OF(phy_pb_t, pb_rx, ctx->pbdma.current_pb);
+ }
+
+ return tail;
+}
+
+
+/**
+ * Start a channel data transfer.
+ * \param ctx phy context
+ * \param first_chandata first transfer descriptor
+ * set errno to:
+ * - EINVAL if ctx or first_chandata are null, or if first_chandata->type equals 0
+ *
+ * If a PB transfer is set up, this transfer will only start after PB transfer
+ * completion.
+ */
+void
+phy_pbdma_start_chandata (phy_t *ctx, phy_chandata_t *first_chandata)
+{
+ dbg_assert_ptr(ctx);
+ dbg_assert_ptr(first_chandata);
+ dbg_assert((PHY_CHANDATA_TYPE_NO_MEMORY_READ < first_chandata->type) && (PHY_CHANDATA_TYPE_NRJ_SYMBOL >= first_chandata->type));
+ MAXIMUS_PHY_TRACE (PBDMA_START_CHANDATA);
+ if ((NULL == ctx)
+ || (NULL == first_chandata)
+ || (PHY_CHANDATA_TYPE_NO_MEMORY_READ >= first_chandata->type) || (PHY_CHANDATA_TYPE_NRJ_SYMBOL < first_chandata->type))
+ {
+ errno = EINVAL;
+ station_log(&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_PHY,
+ "%s: errno = %d", __FUNCTION__, errno);
+ }
+ else
+ {
+ ctx->pbdma.first_chandata = first_chandata;
+
+ // set chandata transfer
+ ctx->pbdma.chandata_transfer = true;
+ }
+}
+
+
+/**
+ * Return the address of the CRC bitmap registers.
+ * \param ctx phy context
+ * \return address of the first of the eight CRC bitmap registers
+ */
+volatile const u32 *
+phy_pbdma_get_crc_bitmap (phy_t *ctx)
+{
+ return ctx->pbdma.crc_bitmap;
+}
+