summaryrefslogtreecommitdiff
path: root/cesar/mac/pbproc/pbproc.h
blob: 020e1a8fb56a4ca4cf303bfc094a6bba943bd694 (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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
#ifndef mac_pbproc_pbproc_h
#define mac_pbproc_pbproc_h
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    mac/pbproc/pbproc.h
 * \brief   PB Processing public interface.
 * \ingroup mac_pbproc
 */
#include "mac/common/mfs.h"
#include "mac/common/pb.h"

#include "mac/ca/ca.h"
#include "hal/phy/spoc/spoc.h"

/* Forward declarations. */
typedef struct pbproc_t pbproc_t;

/** Parameters of the received MPDU. */
struct pbproc_rx_params_t
{
    /** Preamble start NTB. */
    u32 preamble_ntb;
    /** TEI of the transmitter. */
    u8 tei;
    /** Link ID of this MPDU. */
    u8 lid;
    /** Short network identifier. */
    uint snid:4;
    /** Whether this is a multicast frame. */
    bool bcast:1;
    /** Whether it was transmitted in contention free period. */
    bool cfp:1;
    /** Multi-network broadcast flag. */
    bool multi_net_bcast:1;
    /** Whether this is a sound frame. */
    bool sound:1;
    /** Network encryption key select. */
    uint eks:4;
    /** Pending PB. */
    uint pending_seg_nb:8;
    /** Bit loading estimate. */
    uint ble:8;
    /** PB size (PHY_PB_SIZE_136 or PHY_PB_SIZE_520). */
    uint pb_size:1;
    /** Tone map index. */
    uint tmi_av:5;
    /** MPDU count. */
    uint mpdu_cnt:2;
    /** Beacon detect flag. */
    bool bdf:1;
    /** Homeplug 1.0.1 detect flag. */
    bool hp10df:1;
    /** Homeplug 1.1 detect flag. */
    bool hp11df:1;
    /** Data MFS FSM command. */
    mfs_fsm_cmd_t mfs_cmd_data:3;
    /** MME MFS FSM command. */
    mfs_fsm_cmd_t mfs_cmd_mme:3;
    /** For sound frames: sound reason code. */
    tonemap_sound_reason_code_t sound_src:8;
    /** For sound frames: maximum number of tone maps requested. */
    uint sound_req_tm:8;
    /** For sound frames: whether we responded with the sound complete flag. */
    bool sound_complete:1;
};
typedef struct pbproc_rx_params_t pbproc_rx_params_t;

/** Received MPDU. */
struct pbproc_rx_t
{
    /** Received MPDU parameters. */
    pbproc_rx_params_t params;
    /** Reference to MFS for this RX or NULL. */
    mfs_t *mfs;
    /** Reference to MME MFS for this RX or NULL. */
    mfs_t *mfs_mme;
    /** First PB descriptor. */
    pb_t *pb_first;
    /** Last PB descriptor. */
    pb_t *pb_last;
    /** Number of PB. */
    uint pb_nb;
    /** First channel data descriptor. */
    pb_t *chandata_first;
    /** Number of channel data blocks. */
    uint chandata_nb;
};
typedef struct pbproc_rx_t pbproc_rx_t;

/** Received MPDU descriptor. */
union pbproc_rx_desc_t
{
    /** Common block descriptor. */
    blk_t blk;
    struct
    {
        /** Pointer to next descriptor. */
        union pbproc_rx_desc_t *next;
        /** Pointer to data. */
        pbproc_rx_t *rx;
    };
};
typedef union pbproc_rx_desc_t pbproc_rx_desc_t;

/**
 * MPDU RX callback.
 * \param  user  user data
 * \param  rx_desc  received MPDU block descriptor
 *
 * The received MPDU block, PBs, and channel data blocks are taken from the
 * reception segment pool.  Callee must give new segments back using
 * pbproc_rx_segment_refill().
 *
 * When the MFS does not exist, \a mfs is NULL and the upper layer may create
 * it.
 *
 * All references are passed to the callee.
 */
typedef void (*pbproc_rx_cb_t) (void *user, pbproc_rx_desc_t *rx_desc);

/** Parameters of the received beacon. */
struct pbproc_rx_beacon_params_t
{
    /** Preamble start SYS date. */
    u32 preamble_sysdate;
    /** Preamble start date. */
    u32 preamble_date;
    /** Beacon Time Stamp. */
    u32 bts;
    /** Beacon Transmission Offset. */
    u16 bto[4];
    /** Short network identifier. */
    u8 snid;
    /** Access flag. */
    bool access;
};
typedef struct pbproc_rx_beacon_params_t pbproc_rx_beacon_params_t;

/**
 * Beacon RX callback.
 * \param  user  user data
 * \param  pb  single beacon PB descriptor
 * \param  params  more parameters for this beacon
 *
 * The PB reference is passed to the callee.  The parameters are allocated
 * inside the BP block and therefore released automatically with the beacon
 * PB.
 */
typedef void (*pbproc_rx_beacon_cb_t) (void *user, pb_beacon_t *pb,
                                       pbproc_rx_beacon_params_t *params);

/** Extra parameters for beacon transmission. */
struct pbproc_tx_beacon_params_t
{
    /** Beacon Transmission Offset. */
    u16 bto[4];
    /** Pointer to Beacon Period Start Time Offset (BPSTO) 3 byte field, or
     * null if not present. */
    u8 *bpsto;
};
typedef struct pbproc_tx_beacon_params_t pbproc_tx_beacon_params_t;

BEGIN_DECLS

/**
 * Initialise pbproc and return its context.
 * \param  config  global mac configuration
 * \param  store  MFS and STA store
 * \return  pbproc context
 */
pbproc_t *
pbproc_init (mac_config_t *config, mac_store_t *store);

/**
 * Initialise callback contexts.
 * \param  ctx  pbproc context
 * \param  user_data  user data passed to any callback
 * \param  rx_cb  MPDU RX callback
 * \param  rx_beacon_cb  beacon RX callback
 */
void
pbproc_init_cb (pbproc_t *ctx, void *user_data, pbproc_rx_cb_t rx_cb,
                pbproc_rx_beacon_cb_t rx_beacon_cb);

/**
 * Uninitialise a pbproc context.
 * \param  ctx  pbproc context
 */
void
pbproc_uninit (pbproc_t *ctx);

/**
 * Get the PHY context.
 * \param  ctx  pbproc context
 * \return  PHY context
 */
phy_t *
pbproc_get_phy (pbproc_t *ctx);

/**
 * Get the channel access context.
 * \param  ctx  pbproc context
 * \return  channel access context
 */
ca_t *
pbproc_get_ca (pbproc_t *ctx);

/**
 * Activate or deactivate RX.
 * \param  ctx  pbproc context
 * \param  flag  true for activate
 */
void
pbproc_activate (pbproc_t *ctx, bool flag);

/**
 * Signal the beacon was successfully received.
 * \param  ctx  pbproc context
 * \param  detect_expiration_date  detection is valid until this date
 */
void
pbproc_beacon_detected (pbproc_t *ctx, u32 detect_expiration_date);

/**
 * Give segments back to pbproc for reception.
 * \param  ctx  pbproc context
 * \param  first  first segment
 * \param  last  last segment
 * \param  nb  number of segment
 *
 * A reference is transfered to pbproc.
 */
void
pbproc_rx_segment_refill (pbproc_t *ctx, pb_t *first, pb_t *last,
                          uint nb);

/**
 * Set configuration for channel data to retrieve after each frame.
 * \param  ctx  pbproc context
 * \param  conf  table of channel data configuration
 * \param  nb  number of channel data configuration handled
 * \param  data  collect channel data for data MPDU
 *
 * Configuration table will be copied to pbproc context.  On each reception, a
 * block is used for each given configuration to fetch channel data from
 * hardware.
 */
void
pbproc_set_chandata_conf (pbproc_t *ctx, phy_chandata_conf_t *conf, uint nb,
                          bool data);

/**
 * Set the coefficients of SPOC in SPOC registers when possible.
 * \param  ctx  pbproc context
 * \param  coeff  the SPOC coefficients
 */
void
pbproc_spoc_coeff_set (pbproc_t *ctx, phy_spoc_coeff_t *coeff);

/**
 * Extract the last segment from an MFS in order to segment more data.
 * \param  mfs  MFS to extract from
 * \return  the last segment or NULL
 *
 * When the SAR needs to enqueue data, it may have to use the last enqueued
 * segment before starting to fill new one.  However, if the last segment has
 * been given to the PB Processing, it can not be used without being taken
 * back. This function return this last segment unless there is none or it has
 * been taken by the PB Processing already.
 *
 * This involves the following actions:
 *  - In any cases, if there is no room left in the tail segment (because it
 *  was full or it was sent on medium yet), NULL is returned.
 *  - If the tail is not owned by the PB Processing, tail is returned without
 *  any delay.
 *  - If the tail is owned by the PB Processing, this function tries to take
 *  it back.  If it manages to take possession of this segment, it is
 *  returned.  In the other case, NULL is returned, the SAR should start a new
 *  segment.
 *
 * In every cases, the returned segment is always part of the MFS segment
 * chain and the SAR promises to give this segment back later.  This segment
 * should not be enqueued twice!
 */
pb_t *
pbproc_mfs_extract_tail (mfs_tx_t *mfs);

/**
 * Insert segments into an MFS.
 * \param  mfs  MFS to insert to
 * \param  first  first segment to insert
 * \param  last  last segment to insert
 * \param  nb  number of inserted segments
 *
 * Before starting the bridge, the SAR will enqueue segment in the MFS.  This
 * function will do exactly this, taking concurrent access into account.
 *
 * A segment previously extracted should not be inserted a second time!
 */
void
pbproc_mfs_insert (mfs_tx_t *mfs, pb_t *first, pb_t *last, uint nb);

/**
 * Provide PB Processing with segments for an MFS.
 * \param  mfs  provided MFS
 * \param  nb  number of segments available for transmission
 *
 * Once segmentation is completed, segment are ready to be sent.  The SAR
 * layer calls this function to inform the PB Processing that new segments are
 * available and can be selected for transmission.
 */
void
pbproc_mfs_provide (mfs_tx_t *mfs, uint nb);

/**
 * Prepare a beacon for transmission.
 * \param  ctx  pbproc context
 * \param  mfs  corresponding special MFS
 * \param  pb  beacon payload
 * \param  params  extra parameters for beacon transmission
 *
 * There can only be one beacon prepared in advance (for a given MFS).
 *
 * This will cancel the preceding prepared beacon if it was not sent.
 *
 * PB reference is transfered to PB Processing.  Extra parameters are copied.
 */
void
pbproc_mfs_beacon_prepare (pbproc_t *ctx, mfs_tx_t *mfs, pb_beacon_t *pb,
                           const pbproc_tx_beacon_params_t *params);

/**
 * Expire all PB whose expiration date is less than the given expiration date.
 * \param  ctx  pbproc context
 * \param  mfs  MFS to expire
 * \param  expiration_ntb  expiration date used for comparison
 * \param  first_pb_expiration_ntb  filled by this function: expiration date
 * of the first PB if present
 * \param  expired_nb  filled by this function: number of expired PB
 * \return  true if the MFS is empty
 *
 * This function is able to access any MFS PB, even if the MFS is currently
 * used by PB Processing.  However, PB currently transmitted can not be
 * expired, therefore, the expiration date of the first PB may be lesser than
 * the given expiration date.
 */
bool
pbproc_mfs_expire (pbproc_t *ctx, mfs_tx_t *mfs, u32 expiration_ntb,
                   u32 *first_pb_expiration_ntb, uint *expired_nb);

/**
 * Remove all PB from the given MFS.
 * \param  mfs  MFS to empty
 *
 * If PB are currently transmitted on this MFS, PB Processing could put them
 * back at end of transmission if they were not acknowledged.  To avoid this,
 * the MFS should be put in the release state before calling this function.
 */
void
pbproc_mfs_remove_all (mfs_tx_t *mfs);

END_DECLS

#endif /* mac_pbproc_pbproc_h */