summaryrefslogtreecommitdiff
path: root/cesar/hal/phy/pbdma.h
blob: 1bcf25357f2ab2a22acf33b373f0e343b82a0d5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#ifndef hal_phy_pbdma_h
#define hal_phy_pbdma_h
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \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 */