summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/aic8800/aic8800_fdrv/ipc_host.h
blob: c008a316c0109b6f5d7e8251cf0c60fc6eadcf5c (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
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
/**
 ******************************************************************************
 *
 * @file ipc_host.h
 *
 * @brief IPC module.
 *
 * Copyright (C) RivieraWaves 2011-2019
 *
 ******************************************************************************
 */
#ifndef _IPC_HOST_H_
#define _IPC_HOST_H_

/*
 * INCLUDE FILES
 ******************************************************************************
 */
#include "ipc_shared.h"
#ifndef __KERNEL__
#include "arch.h"
#else
#include "ipc_compat.h"
#endif

/*
 * ENUMERATION
 ******************************************************************************
 */

enum ipc_host_desc_status
{
    /// Descriptor is IDLE
    IPC_HOST_DESC_IDLE      = 0,
    /// Data can be forwarded
    IPC_HOST_DESC_FORWARD,
    /// Data has to be kept in UMAC memory
    IPC_HOST_DESC_KEEP,
    /// Delete stored packet
    IPC_HOST_DESC_DELETE,
    /// Update Frame Length status
    IPC_HOST_DESC_LEN_UPDATE,
};

/**
 ******************************************************************************
 * @brief This structure is used to initialize the MAC SW
 *
 * The WLAN device driver provides functions call-back with this structure
 ******************************************************************************
 */
struct ipc_host_cb_tag
{
    /// WLAN driver call-back function: send_data_cfm
    int (*send_data_cfm)(void *pthis, void *host_id);

    /// WLAN driver call-back function: recv_data_ind
    uint8_t (*recv_data_ind)(void *pthis, void *host_id);

    /// WLAN driver call-back function: recv_radar_ind
    uint8_t (*recv_radar_ind)(void *pthis, void *host_id);

    /// WLAN driver call-back function: recv_unsup_rx_vec_ind
    uint8_t (*recv_unsup_rx_vec_ind)(void *pthis, void *host_id);

    /// WLAN driver call-back function: recv_msg_ind
    uint8_t (*recv_msg_ind)(void *pthis, void *host_id);

    /// WLAN driver call-back function: recv_msgack_ind
    uint8_t (*recv_msgack_ind)(void *pthis, void *host_id);

    /// WLAN driver call-back function: recv_dbg_ind
    uint8_t (*recv_dbg_ind)(void *pthis, void *host_id);

    /// WLAN driver call-back function: prim_tbtt_ind
    void (*prim_tbtt_ind)(void *pthis);

    /// WLAN driver call-back function: sec_tbtt_ind
    void (*sec_tbtt_ind)(void *pthis);

};

/*
 * Struct used to store information about host buffers (DMA Address and local pointer)
 */
struct ipc_hostbuf
{
    void    *hostid;     ///< ptr to hostbuf client (ipc_host client) structure
    uint32_t dma_addr;   ///< ptr to real hostbuf dma address
};

/// Definition of the IPC Host environment structure.
struct ipc_host_env_tag
{
    /// Structure containing the callback pointers
    struct ipc_host_cb_tag cb;

    /// Pointer to the shared environment
    struct ipc_shared_env_tag *shared;

    #ifdef CONFIG_RWNX_FULLMAC
    // Array used to store the descriptor addresses
    struct ipc_hostbuf ipc_host_rxdesc_array[IPC_RXDESC_CNT];
    // Index of the host RX descriptor array (ipc_shared environment)
    uint8_t ipc_host_rxdesc_idx;
    /// Store the number of RX Descriptors
    uint8_t rxdesc_nb;
    #endif //(CONFIG_RWNX_FULLMAC)

    /// Fields for Data Rx handling
    // Index used for ipc_host_rxbuf_array to point to current buffer
    uint8_t ipc_host_rxbuf_idx;
    // Store the number of Rx Data buffers
    uint32_t rx_bufnb;
    // Store the size of the Rx Data buffers
    uint32_t rx_bufsz;

    /// Fields for Radar events handling
    // Global array used to store the hostid and hostbuf addresses
    struct ipc_hostbuf ipc_host_radarbuf_array[IPC_RADARBUF_CNT];
    // Index used for ipc_host_rxbuf_array to point to current buffer
    uint8_t ipc_host_radarbuf_idx;
    // Store the number of radar event buffers
    uint32_t radar_bufnb;
    // Store the size of the radar event buffers
    uint32_t radar_bufsz;

    ///Fields for Unsupported frame handling
    // Global array used to store the hostid and hostbuf addresses
    struct ipc_hostbuf ipc_host_unsuprxvecbuf_array[IPC_UNSUPRXVECBUF_CNT];
    // Index used for ipc_host_unsuprxvecbuf_array to point to current buffer
    uint8_t ipc_host_unsuprxvecbuf_idx;
    // Store the number of unsupported rx vector buffers
    uint32_t unsuprxvec_bufnb;
    // Store the size of unsupported rx vector buffers
    uint32_t unsuprxvec_bufsz;

    // Index used that points to the first free TX desc
    uint32_t txdesc_free_idx[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];
    // Index used that points to the first used TX desc
    uint32_t txdesc_used_idx[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];
    // Array storing the currently pushed host ids for the BK queue
    void *tx_host_id0[CONFIG_USER_MAX][NX_TXDESC_CNT0];
    // Array storing the currently pushed host ids for the BE queue
    void *tx_host_id1[CONFIG_USER_MAX][NX_TXDESC_CNT1];
    // Array storing the currently pushed host ids for the VI queue
    void *tx_host_id2[CONFIG_USER_MAX][NX_TXDESC_CNT2];
    // Array storing the currently pushed host ids for the VO queue
    void *tx_host_id3[CONFIG_USER_MAX][NX_TXDESC_CNT3];
    #if NX_TXQ_CNT == 5
    // Array storing the currently pushed host ids for the BCN queue
    void *tx_host_id4[1][NX_TXDESC_CNT4];
    #endif
    // Pointer to the different host ids arrays, per IPC queue
    void **tx_host_id[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];
    // Pointer to the different TX descriptor arrays, per IPC queue
    volatile struct txdesc_host *txdesc[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];

    /// Fields for Emb->App MSGs handling
    // Global array used to store the hostid and hostbuf addresses for msg/ind
    struct ipc_hostbuf ipc_host_msgbuf_array[IPC_MSGE2A_BUF_CNT];
    // Index of the MSG E2A buffers array to point to current buffer
    uint8_t ipc_host_msge2a_idx;
    // Store the number of E2A MSG buffers
    uint32_t ipc_e2amsg_bufnb;
    // Store the size of the E2A MSG buffers
    uint32_t ipc_e2amsg_bufsz;

    /// E2A ACKs of A2E MSGs
    uint8_t msga2e_cnt;
    void *msga2e_hostid;

    /// Fields for Debug MSGs handling
    // Global array used to store the hostid and hostbuf addresses for Debug messages
    struct ipc_hostbuf ipc_host_dbgbuf_array[IPC_DBGBUF_CNT];
    // Index of the Debug messages buffers array to point to current buffer
    uint8_t ipc_host_dbg_idx;
    // Store the number of Debug messages buffers
    uint32_t ipc_dbg_bufnb;
    // Store the size of the Debug messages buffers
    uint32_t ipc_dbg_bufsz;

    /// Pointer to the attached object (used in callbacks and register accesses)
    void *pthis;
};

extern const int nx_txdesc_cnt[];
extern const int nx_txuser_cnt[];

/**
 ******************************************************************************
 * @brief Returns the full/not full status of the queue the index of which is
 * passed as parameter.
 *
 * @param[in]   env       Pointer to the IPC host environment
 * @param[in]   queue_idx Index of the queue to be checked
 *
 * @return true if the queue is full, false otherwise
 *
 ******************************************************************************
 */
__INLINE bool ipc_host_queue_full(struct ipc_host_env_tag *env,
                                  const int queue_idx)
{
    return (env->txdesc_free_idx[queue_idx] ==
                      (env->txdesc_used_idx[queue_idx] + nx_txdesc_cnt[queue_idx]));
}

/**
 ******************************************************************************
 * @brief Initialize the IPC running on the Application CPU.
 *
 * This function:
 *   - initializes the IPC software environments
 *   - enables the interrupts in the IPC block
 *
 * @param[in]   env   Pointer to the IPC host environment
 *
 * @warning Since this function resets the IPC Shared memory, it must be called
 * before the LMAC FW is launched because LMAC sets some init values in IPC
 * Shared memory at boot.
 *
 ******************************************************************************
 */
void ipc_host_init(struct ipc_host_env_tag *env,
                  struct ipc_host_cb_tag *cb,
                  struct ipc_shared_env_tag *shared_env_ptr,
                  void *pthis);

/** @addtogroup IPC_TX
 *  @{
 */

/**
 ******************************************************************************
 * @brief Retrieve a new free Tx descriptor (host side).
 *
 * This function returns a pointer to the next Tx descriptor available from the
 * queue queue_idx to the host driver. The driver will have to fill it with the
 * appropriate endianness and to send it to the
 * emb side with ipc_host_txdesc_push().
 *
 * This function should only be called once until ipc_host_txdesc_push() is called.
 *
 * This function will return NULL if the queue is full.
 *
 * @param[in]   env   Pointer to the IPC host environment
 * @param[in]   queue_idx   Queue index. The index can be inferred from the
 *                          user priority of the incoming packet.
 * @param[in]   user_pos    User position. If MU-MIMO is not used, this value
 *                          shall be 0.
 * @return                  Pointer to the next Tx descriptor free. This can
 *                          point to the host memory or to shared memory,
 *                          depending on IPC implementation.
 *
 ******************************************************************************
 */
volatile struct txdesc_host *ipc_host_txdesc_get(struct ipc_host_env_tag *env,
                                                 const int queue_idx,
                                                 const int user_pos);


/**
 ******************************************************************************
 * @brief Push a filled Tx descriptor (host side).
 *
 * This function sets the next Tx descriptor available by the host side:
 * - as used for the host side
 * - as available for the emb side.
 * The Tx descriptor must be correctly filled before calling this function.
 *
 * This function may trigger an IRQ to the emb CPU depending on the interrupt
 * mitigation policy and on the push count.
 *
 * @param[in]   env   Pointer to the IPC host environment
 * @param[in]   queue_idx   Queue index. Same value than ipc_host_txdesc_get()
 * @param[in]   user_pos    User position. If MU-MIMO is not used, this value
 *                          shall be 0.
 * @param[in]   host_id     Parameter indicated by the IPC at TX confirmation,
 *                          that allows the driver finding the buffer
 *
 ******************************************************************************
 */
void ipc_host_txdesc_push(struct ipc_host_env_tag *env, const int queue_idx,
                          const int user_pos, void *host_id);


/**
 ******************************************************************************
 * @brief Check if there are TX frames pending in the TX queues.
 *
 * @param[in]   env   Pointer to the IPC host environment
 *
 * @return true if there are frames pending, false otherwise.
 *
 ******************************************************************************
 */
bool ipc_host_tx_frames_pending(struct ipc_host_env_tag *env);

/**
 ******************************************************************************
 * @brief Get and flush a packet from the IPC queue passed as parameter.
 *
 * @param[in]   env        Pointer to the IPC host environment
 * @param[in]   queue_idx  Index of the queue to flush
 * @param[in]   user_pos   User position to flush
 *
 * @return The flushed hostid if there is one, 0 otherwise.
 *
 ******************************************************************************
 */
void *ipc_host_tx_flush(struct ipc_host_env_tag *env, const int queue_idx,
                        const int user_pos);

/// @} IPC_TX

/** @addtogroup IPC_RX
 *  @{
 */
void ipc_host_patt_addr_push(struct ipc_host_env_tag *env, uint32_t addr);

/**
 ******************************************************************************
 * @brief Push a pre-allocated buffer descriptor for Rx packet (host side)
 *
 * This function should be called by the host IRQ handler to supply the
 * embedded side with new empty buffer.
 *
 * @param[in]   env         Pointer to the IPC host environment
 * @param[in]   hostid      Packet ID used by the host (skbuff pointer on Linux)
 * @param[in]   hostbuf     Pointer to the start of the buffer payload in the
 *                          host memory (this may be inferred from the skbuff?)
 *                          The length of this buffer should be predefined
 *                          between host and emb statically (constant needed?).
 *
 ******************************************************************************
 */
int ipc_host_rxbuf_push(struct ipc_host_env_tag *env,
#ifdef CONFIG_RWNX_FULLMAC
                        uint32_t hostid,
#endif
                        uint32_t hostbuf);

/**
 ******************************************************************************
 * @brief Push a pre-allocated Descriptor
 *
 * This function should be called by the host IRQ handler to supply the
 * embedded side with new empty buffer.
 *
 * @param[in]   env         Pointer to the IPC host environment
 * @param[in]   hostid      Address of packet for host
 * @param[in]   hostbuf     Pointer to the start of the buffer payload in the
 *                          host memory. The length of this buffer should be
 *                          predefined between host and emb statically.
 *
 ******************************************************************************
 */
int ipc_host_rxdesc_push(struct ipc_host_env_tag *env, void *hostid,
                         uint32_t hostbuf);

/**
 ******************************************************************************
 * @brief Push a pre-allocated radar event buffer descriptor
 *
 * This function is called at Init time to initialize all radar event buffers.
 * Then each time embedded send a radar event, this function is used to push
 * back the same buffer once it has been handled.
 *
 * @param[in]   env         Pointer to the IPC host environment
 * @param[in]   hostid      Address of packet for host
 * @param[in]   hostbuf     Pointer to the start of the buffer payload in the
 *                          host memory. The length of this buffer should be
 *                          predefined between host and emb statically.
 *
 ******************************************************************************
 */
int ipc_host_radarbuf_push(struct ipc_host_env_tag *env, void *hostid,
                           uint32_t hostbuf);

/**
 ******************************************************************************
 * @brief Push a pre-allocated unsupported rx vector buffer descriptor
 *
 * This function is called at Init time to initialize all unsupported rx vector
 * buffers. Then each time the embedded sends a unsupported rx vector, this
 * function is used to push a new unsupported rx vector buffer.
 *
 * @param[in]   env         Pointer to the IPC host environment
 * @param[in]   hostid      Address of packet for host
 * @param[in]   hostbuf     Pointer to the start of the buffer payload in the
 *                          host memory. The length of this buffer should be
 *                          predefined between host and emb statically.
 *
 ******************************************************************************
 */
int ipc_host_unsup_rx_vec_buf_push(struct ipc_host_env_tag *env, void *hostid,
                                    uint32_t hostbuf);

/**
 ******************************************************************************
 * @brief Push a pre-allocated buffer descriptor for IPC MSGs (host side)
 *
 * This function is called at Init time to initialize all Emb2App messages
 * buffers. Then each time embedded send a IPC message, this function is used
 * to push back the same buffer once it has been handled.
 *
 * @param[in]   env         Pointer to the IPC host environment
 * @param[in]   hostid      Address of buffer for host
 * @param[in]   hostbuf     Address of buffer for embedded
 *                          The length of this buffer should be predefined
 *                          between host and emb statically.
 *
 ******************************************************************************
 */
int ipc_host_msgbuf_push(struct ipc_host_env_tag *env, void *hostid,
                         uint32_t hostbuf);

/**
 ******************************************************************************
 * @brief Push a pre-allocated buffer descriptor for Debug messages (host side)
 *
 * This function is called at Init time to initialize all debug messages.
 * Then each time embedded send a debug message, this function is used to push
 * back the same buffer once it has been handled.
 *
 * @param[in]   env         Pointer to the IPC host environment
 * @param[in]   hostid      Address of buffer for host
 * @param[in]   hostbuf     Address of buffer for embedded
 *                          The length of this buffer should be predefined
 *                          between host and emb statically.
 *
 ******************************************************************************
 */
int ipc_host_dbgbuf_push(struct ipc_host_env_tag *env, void *hostid,
                         uint32_t hostbuf);

/**
 ******************************************************************************
 * @brief Push the pre-allocated logic analyzer and debug information buffer
 *
 * @param[in]   env         Pointer to the IPC host environment
 * @param[in]   infobuf     Address of buffer for embedded
 *                          The length of this buffer should be predefined
 *                          between host and emb statically.
 *
 ******************************************************************************
 */
void ipc_host_dbginfobuf_push(struct ipc_host_env_tag *env, uint32_t infobuf);

/// @} IPC_RX



/** @addtogroup IPC_MISC
 *  @{
 */

/**
 ******************************************************************************
 * @brief Handle all IPC interrupts on the host side.
 *
 * The following interrupts should be handled:
 * Tx confirmation, Rx buffer requests, Rx packet ready and kernel messages
 *
 * @param[in]   env   Pointer to the IPC host environment
 *
 ******************************************************************************
 */
void ipc_host_irq(struct ipc_host_env_tag *env, uint32_t status);

/**
 ******************************************************************************
 * @brief Send a message to the embedded side
 *
 * @param[in]   env      Pointer to the IPC host environment
 * @param[in]   msg_buf  Pointer to the message buffer
 * @param[in]   msg_len  Length of the message to be transmitted
 *
 * @return      Non-null value on failure
 *
 ******************************************************************************
 */
int ipc_host_msg_push(struct ipc_host_env_tag *env, void *msg_buf, uint16_t len);

/**
 ******************************************************************************
 * @brief Enable IPC interrupts
 *
 * @param[in]   env  Global ipc_host environment pointer
 * @param[in]   value  Bitfield of the interrupts to enable
 *
 * @warning After calling this function, IPC interrupts can be triggered at any
 * time. Potentially, an interrupt could happen even before returning from the
 * function if there is a request pending from the embedded side.
 *
 ******************************************************************************
 */
void ipc_host_enable_irq(struct ipc_host_env_tag *env, uint32_t value);
void ipc_host_disable_irq(struct ipc_host_env_tag *env, uint32_t value);

uint32_t ipc_host_get_status(struct ipc_host_env_tag *env);
uint32_t ipc_host_get_rawstatus(struct ipc_host_env_tag *env);

/// @} IPC_MISC


#endif // _IPC_HOST_H_