#ifndef hal_phy_pbdma_h #define hal_phy_pbdma_h /* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file hal/phy/pbdma.h * \brief HAL Phy PB DMA public interface. * \ingroup hal_phy */ #include "lib/blk.h" #include "hal/phy/forward.h" /** PB descriptor for TX. */ struct phy_pb_tx_t { /** Common block descriptor. */ blk_t blk; /** PB header to sent. */ u32 header; }; typedef struct phy_pb_tx_t phy_pb_tx_t; /** PB measurement description */ struct pb_measurement_t { BITFIELDS_WORD( /** Received Bit Error Rate from TCC. */ u32 ber:16;, /** Number of half iterations from TCC. */ u32 halfit:5;, /** Whether this PB's CRC is erroneous. */ u32 crc_error:1;, u32 :10;) }; typedef struct pb_measurement_t pb_measurement_t; /** PB descriptor for RX. */ struct phy_pb_rx_t { /** Common block descriptor. */ blk_t blk; /** Received PB header. */ u32 header; /** Pb measurement value */ pb_measurement_t pb_measurement; }; typedef struct phy_pb_rx_t phy_pb_rx_t; /** Control data of pbdma to define transfered memory type. * Cf DATA_CHANNEL_MUX SPECIFICATIONS. * PLEASE, if any changement appears here, adapt initialisation of * mpdu_measure_store.c in mpdu_measurement_store_init about * mpdu_measure_chandata_blk_nb[PHY_CHANDATZ_TYPE_NB]. */ enum phy_chandata_type_t { PHY_CHANDATA_TYPE_NO_MEMORY_READ, PHY_CHANDATA_TYPE_NRJ, PHY_CHANDATA_TYPE_NRJ_SYMBOL, PHY_CHANDATA_TYPE_SPECTRUM_TRUNC, PHY_CHANDATA_TYPE_SPECTRUM_RE, PHY_CHANDATA_TYPE_SPECTRUM_IM, PHY_CHANDATA_TYPE_DATA_LLR, PHY_CHANDATA_TYPE_COPY_I_LLR, PHY_CHANDATA_TYPE_COPY_Q_LLR, PHY_CHANDATA_TYPE_COPY_VOTE_COEF, PHY_CHANDATA_TYPE_NB }; typedef enum phy_chandata_type_t phy_chandata_type_t; /** Channel data transfer descriptor. */ struct phy_chandata_t { /** Common block descriptor. */ blk_t blk; BITFIELDS_WORD( /** Transfer size in words. */ u32 size:8;, /** Set to 1 if this is the last descriptor. */ u32 last:1;, /** Transfer type cf enum phy_chandata_type_t. */ u32 type:4;, u32 :7;, /** Start address. */ u32 address:12;) }; typedef struct phy_chandata_t phy_chandata_t; /** Type to point to any PB or chandata descriptor. */ union phy_pb_t { /** Common block descriptor. */ blk_t blk; /** TX descriptor. */ phy_pb_tx_t pb_tx; /** RX descriptor. */ phy_pb_rx_t pb_rx; /** Channel data transfer descriptor. */ phy_chandata_t chandata; }; typedef union phy_pb_t phy_pb_t; /** PB DMA status given back after a interrupt. */ struct phy_pbdma_status_t { BITFIELDS_WORD( /** The right number of descriptors was not ready, when TX, the PB DMA * generated null PBs. */ u32 pb_null:1;, /** This is for us, poor software developers, a dark PB DMA internal * error. This indicate an internal unexpected error while receiving, * just drop the data, or assert. This should not happen. */ u32 rx_header_load_error:1;, /** Problem when accessing the bus, our descriptors must have been * garbaged. This should not happen. */ u32 ahb_response_error:1;, /** At least one received PB was received with error. */ u32 pb_crc_error:1;, /** Currently transfered PB index, for debug only. */ u32 current_pb_index:8;, /** Channel data type forbidden. This should not happen. */ u32 chandata_type_forbidden:1;, /** Channel data size forbidden. This should not happen. */ u32 chandata_size_forbidden:1;, /** Total number of PB null. This should not happen. */ u32 pb_nb_total_null:1;, u32 :1;, /** Internal FSM state, for debug only. */ u32 fsm_state:2;, /** The PB interrupt occurs, the one configured with nb_pb_it. */ u32 pb_it:1;, u32 :1;, /** A RX transfer has finished. */ u32 end_rx_pb:1;, /** A TX transfer has finished. */ u32 end_tx_pb:1;, /** A Channel data transfer has finished. */ u32 end_chandata:1;, u32 :1;, /** If \c pb_null is set, this was the PB counter value when the PB DMA * reached a non ready descriptor. */ u32 null_pb_index:8;) }; typedef struct phy_pbdma_status_t phy_pbdma_status_t; /** * PB DMA callback called when an interrupt occurs. * \param user user data * \param status_word status read from PB DMA * \return true if a DSR is requested */ typedef bool (*phy_pbdma_cb_t) (void *user, u32 status_word); /** Cast a u32 word to the \c phy_pbdma_status_t structure. The reason behind * this macro is that the callback receive the status as a u32 in order to use * a register, not a pointer, to pass the parameter. */ #define PHY_PBDMA_STATUS(w) (*(phy_pbdma_status_t *) (void *) &(w)) BEGIN_DECLS /** * 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 * * 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); /** * 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 */ void phy_pbdma_update (phy_t *ctx, uint nb_ready, uint nb_pb_it); /** * Retrieve last used PB descriptor. * \param ctx phy context * \return last used PB descriptor */ phy_pb_t * phy_pbdma_get_tail (phy_t *ctx); /** * 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); /** * Start a channel data transfer. * \param ctx phy context * \param first_chandata first transfer descriptor * * 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); END_DECLS #endif /* hal_phy_pbdma_h */