Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

  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
/*******************************************************************************
*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved. 
*
*Redistribution and use in source and binary forms, with or without modification, are permitted provided 
*that the following conditions are met: 
*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
*following disclaimer. 
*2. Redistributions in binary form must reproduce the above copyright notice, 
*this list of conditions and the following disclaimer in the documentation and/or other materials provided
*with the distribution. 
*
*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 
*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*
* $FreeBSD$
*
********************************************************************************/

/*******************************************************************************/
/*! \file mpi.h
 *  \brief The file defines the MPI constants and structures
 *
 * The file defines the MPI constants and structures
 *
 */
/*******************************************************************************/

#ifndef __MPI_H__
#define __MPI_H__

/*******************************************************************************/

/*******************************************************************************/
/* CONSTANTS                                                                   */
/*******************************************************************************/
/*******************************************************************************/
#define MPI_QUEUE_PRIORITY_HIGHEST      0xFF  /**< Highest queue priority */
#define MPI_QUEUE_PRIORITY_LOWEST       0x00  /**< Lowest queue priority */

#define MPI_MAX_INBOUND_QUEUES          64     /**< Maximum number of inbound queues */
#define MPI_MAX_OUTBOUND_QUEUES         64     /**< Maximum number of outbound queues */

                                               /**< Max # of memory chunks supported */
#define MPI_MAX_MEM_REGIONS             (MPI_MAX_INBOUND_QUEUES + MPI_MAX_OUTBOUND_QUEUES) + 4
#define MPI_LOGSIZE                     4096  /**< default size */

#define MPI_IB_NUM_MASK                 0x0000FFFF /**< Mask of Inbound Queue Number */
#define MPI_OB_NUM_MASK                 0xFFFF0000 /**< Mask of Outbound Queue Number */
#define MPI_OB_SHIFT                    16         /**< bits shift for outbound queue number */


#define BAR0                            0x10
#define BAR1                            0x14
#define BAR2                            0x18
#define BAR3                            0x1C
#define BAR4                            0x20
#define BAR5                            0x24

/*******************************************************************************/
/*******************************************************************************/
/* ENUMERATIONS                                                                */
/*******************************************************************************/

/*******************************************************************************/
/*******************************************************************************/
/** \enum mpiMsgCategory_e,
 *  \brief MPI message categories
 */
/*******************************************************************************/
enum mpiMsgCategory_e
{
  MPI_CATEGORY_ETHERNET = 0,
  MPI_CATEGORY_FC,
  MPI_CATEGORY_SAS_SATA,
  MPI_CATEGORY_SCSI
};

typedef enum mpiMsgCategory_e mpiMsgCategory_t;

/*******************************************************************************/
/*******************************************************************************/
/* TYPES                                                                       */
/*******************************************************************************/
/*******************************************************************************/


/*******************************************************************************/
/*******************************************************************************/
/* DATA STRUCTURES                                                             */
/*******************************************************************************/
/*******************************************************************************/

/*******************************************************************************/
/** \struct mpiMem_s
 *  \brief Structure that descibes memory regions
 *
 * The mpiMemoryDescriptor_t is used to describe the attributes for a memory
 * region. Each element in the memory chunk has to be physically contiguous.
 * Different elements in the memory chunk do not necessarily have to be
 * contiguous to each other.
 */
/*******************************************************************************/
struct mpiMem_s
{
  void*        virtPtr;       /**< Virtual pointer to the memory region */
  void*        appHandle;     /**< Handle used for the application to free memory */
  bit32        physAddrUpper; /**< Upper 32 bits of physical address */
  bit32        physAddrLower; /**< Lower 32 bits of physical address */
  bit32        totalLength;   /**< Total length in bytes allocated */
  bit32        numElements;   /**< Number of elements */
  bit32        elementSize;   /**< Size in bytes of an element */
  bit32        alignment;     /**< Alignment in bytes needed. A value of one indicates */
                              /**< no specific alignment requirement */
  bit32        type;          /**< Memory type */
  bit32        reserved;      /**< Reserved */
};

typedef struct mpiMem_s mpiMem_t;

/*******************************************************************************/
/** \struct mpiMemReq_s
 *  \brief Describes MPI memory requirements
 *
 * The mpiMemRequirements_t  is used to specify the memory allocation requirement
 * for the MPI. This is the data structure used in the mpiGetRequirements()
 * and the mpiInitialize() function calls
 */
/*******************************************************************************/
struct mpiMemReq_s
{
  bit32     count;                        /**< The number of element in the mpiMemory array */
  mpiMem_t  region[MPI_MAX_MEM_REGIONS];  /**< Pointer to the array of structures that define memroy regions */
};

typedef struct mpiMemReq_s mpiMemReq_t;

/*******************************************************************************/
/** \struct mpiQCQueue_s
 *  \brief Circular Queue descriptor
 *
 * This structure holds outbound circular queue attributes.
 */
/*******************************************************************************/
struct mpiOCQueue_s
{
  bit32                     qNumber;      /**< this queue number */
  bit32                     numElements;  /**< The total number of queue elements. A value 0 disables the queue */
  bit32                     elementSize;  /**< The size of each queue element, in bytes */
  bit32                     priority;     /**< The queue priority. Possible values for this field are */
                                          /**< MPI_QUEUE_PRIORITY_HIGHEST and MPI_QUEUE_PRIORITY_LOWEST */
  bit32                     CIPCIBar;     /**< PCI Bar */
  bit32                     CIPCIOffset;  /**< PCI Offset */
  bit32                     DIntTOffset;  /**< Dynamic Interrupt Coalescing Timeout offset */
  void*                     piPointer;    /**< pointer of PI (virtual address)*/
  mpiMem_t                  memoryRegion; /**< Queue's memory region descriptor */
  bit32                     producerIdx;  /**< Copy of the producer index */
  bit32                     consumerIdx;  /**< Copy of the consumer index */
  bit32                     pcibar;       /**< CPI Logical Bar Number */
  agsaRoot_t                *agRoot;      /**< Pointer of LL Layer structure */
};

typedef struct mpiOCQueue_s mpiOCQueue_t;

/*******************************************************************************/
/** \struct mpiICQueue_s
 *  \brief Circular Queue descriptor
 *
 * This structure holds inbound circular queue attributes.
 */
/*******************************************************************************/
struct mpiICQueue_s
{
  bit32                     qNumber;      /**< this queue number */
  bit32                     numElements;  /**< The total number of queue elements. A value 0 disables the queue */
  bit32                     elementSize;  /**< The size of each queue element, in bytes */
  bit32                     priority;     /**< The queue priority. Possible values for this field are */
                                          /**< MPI_QUEUE_PRIORITY_HIGHEST and MPI_QUEUE_PRIORITY_LOWEST */
  bit32                     PIPCIBar;     /**< PCI Bar */
  bit32                     PIPCIOffset;  /**< PCI Offset */
  void*                     ciPointer;    /**< Pointer of CI (virtual Address) */
  mpiMem_t                  memoryRegion; /**< Queue's memory region descriptor */
  bit32                     producerIdx;  /**< Copy of the producer index */
  bit32                     consumerIdx;  /**< Copy of the consumer index */
#ifdef SA_FW_TEST_BUNCH_STARTS
  bit32                     BunchStarts_QPending;     // un-started bunched IOs on queue
  bit32                     BunchStarts_QPendingTick; // tick value when 1st IO is bunched 
#endif /* SA_FW_TEST_BUNCH_STARTS */
  agsaRoot_t                *agRoot;      /**< Pointer of LL Layer structure */
};

typedef struct mpiICQueue_s mpiICQueue_t;

struct mpiHostLLConfigDescriptor_s
{
  bit32 regDumpPCIBAR;
  bit32 iQNPPD_HPPD_GEvent;                 /**< inbound Queue Process depth */
        /* bit0-7   inbound normal priority process depth */
        /* bit8-15  inbound high priority process depth */
        /* bit16-23 OQ number to receive GENERAL_EVENT Notification */
        /* bit24-31 reserved */
  bit32 outboundHWEventPID0_3;              /**< outbound HW event for PortId 0 to 3 */
        /* bit0-7   outbound queue number of SAS_HW event for PortId 0 */
        /* bit8-15  outbound queue number of SAS_HW event for PortId 1 */
        /* bit16-23 outbound queue number of SAS_HW event for PortId 2 */
        /* bit24-31 outbound queue number of SAS_HW event for PortId 3 */
  bit32 outboundHWEventPID4_7;              /**< outbound HW event for PortId 4 to 7 */
        /* bit0-7   outbound queue number of SAS_HW event for PortId 4 */
        /* bit8-15  outbound queue number of SAS_HW event for PortId 5 */
        /* bit16-23 outbound queue number of SAS_HW event for PortId 6 */
        /* bit24-31 outbound queue number of SAS_HW event for PortId 7 */
  bit32 outboundNCQEventPID0_3;             /**< outbound NCQ event for PortId 0 to 3 */
        /* bit0-7   outbound queue number of SATA_NCQ event for PortId 0 */
        /* bit8-15  outbound queue number of SATA_NCQ event for PortId 1 */
        /* bit16-23 outbound queue number of SATA_NCQ event for PortId 2 */
        /* bit24-31 outbound queue number of SATA_NCQ event for PortId 3 */
  bit32 outboundNCQEventPID4_7;             /**< outbound NCQ event for PortId 4 to 7 */
        /* bit0-7   outbound queue number of SATA_NCQ event for PortId 4 */
        /* bit8-15  outbound queue number of SATA_NCQ event for PortId 5 */
        /* bit16-23 outbound queue number of SATA_NCQ event for PortId 6 */
        /* bit24-31 outbound queue number of SATA_NCQ event for PortId 7 */
  bit32 outboundTargetITNexusEventPID0_3;   /**< outbound target ITNexus Event for PortId 0 to 3 */
        /* bit0-7   outbound queue number of ITNexus event for PortId 0 */
        /* bit8-15  outbound queue number of ITNexus event for PortId 1 */
        /* bit16-23 outbound queue number of ITNexus event for PortId 2 */
        /* bit24-31 outbound queue number of ITNexus event for PortId 3 */
  bit32 outboundTargetITNexusEventPID4_7;   /**< outbound target ITNexus Event for PortId 4 to 7 */
        /* bit0-7   outbound queue number of ITNexus event for PortId 4 */
        /* bit8-15  outbound queue number of ITNexus event for PortId 5 */
        /* bit16-23 outbound queue number of ITNexus event for PortId 6 */
        /* bit24-31 outbound queue number of ITNexus event for PortId 7 */
  bit32 outboundTargetSSPEventPID0_3;       /**< outbound target SSP event for PordId 0 to 3 */
        /* bit0-7   outbound queue number of SSP event for PortId 0 */
        /* bit8-15  outbound queue number of SSP event for PortId 1 */
        /* bit16-23 outbound queue number of SSP event for PortId 2 */
        /* bit24-31 outbound queue number of SSP event for PortId 3 */
  bit32 outboundTargetSSPEventPID4_7;       /**< outbound target SSP event for PordId 4 to 7 */
        /* bit0-7   outbound queue number of SSP event for PortId 4 */
        /* bit8-15  outbound queue number of SSP event for PortId 5 */
        /* bit16-23 outbound queue number of SSP event for PortId 6 */
        /* bit24-31 outbound queue number of SSP event for PortId 7 */
  bit32 ioAbortDelay;   /* was reserved */                 /**< io Abort delay MPI_TABLE_CHANGE */
  bit32 custset;                          /**< custset */
  bit32 upperEventLogAddress;               /**< Upper physical MSGU Event log address */
  bit32 lowerEventLogAddress;               /**< Lower physical MSGU Event log address */
  bit32 eventLogSize;                       /**< Size of MSGU Event log, 0 means log disable */
  bit32 eventLogOption;                     /**< Option of MSGU Event log */
        /* bit3-0 log severity, 0x0 Disable Logging */
        /*                      0x1 Critical Error */
        /*                      0x2 Minor Error    */
        /*                      0x3 Warning        */
        /*                      0x4 Information    */
        /*                      0x5 Debugging      */
        /*                      0x6 - 0xF Reserved */
  bit32 upperIOPeventLogAddress;           /**< Upper physical IOP Event log address */
  bit32 lowerIOPeventLogAddress;           /**< Lower physical IOP Event log address */
  bit32 IOPeventLogSize;                   /**< Size of IOP Event log, 0 means log disable */
  bit32 IOPeventLogOption;                 /**< Option of IOP Event log */
        /* bit3-0 log severity, 0x0 Disable Logging */
        /*                      0x1 Critical Error */
        /*                      0x2 Minor Error    */
        /*                      0x3 Warning        */
        /*                      0x4 Information    */
        /*                      0x5 Debugging      */
        /*                      0x6 - 0xF Reserved */
  bit32 FatalErrorInterrupt;               /**< Fatal Error Interrupt enable and vector */
        /* bit0     Fatal Error Interrupt Enable   */
        /* bit1     PI/CI Address                  */
        /* bit5     enable or disable outbound coalesce   */
        /* bit7-6  reserved */
        /* bit15-8  Fatal Error Interrupt Vector   */
        /* bit31-16 Reserved                       */
  bit32 FatalErrorDumpOffset0;             /**< Fatal Error Register Dump Offset for MSGU */
  bit32 FatalErrorDumpLength0;             /**< Fatal Error Register Dump Length for MSGU */
  bit32 FatalErrorDumpOffset1;             /**< Fatal Error Register Dump Offset for IOP */
  bit32 FatalErrorDumpLength1;             /**< Fatal Error Register Dump Length for IOP */
  bit32 HDAModeFlags;                      /**< HDA Mode Flags */
        /* bit1-0   Bootstrap pins */
        /* bit2     Force HDA Mode bit */
        /* bit3     HDA Firmware load method */
  bit32 analogSetupTblOffset;              /**< Phy Calibration Table offset */
        /* bit23-0  phy calib table offset */
        /* bit31-24 entry size */
  bit32 InterruptVecTblOffset;             /**< DW23 Interrupt Vector Table */
        /* bit23-0  interrupt vector table offset */
        /* bit31-24 entry size */
  bit32 phyAttributeTblOffset;             /**< DW24 SAS Phy Attribute Table Offset */
        /* bit23-0  phy attribute table offset */
        /* bit31-24 entry size */
  bit32 PortRecoveryTimerPortResetTimer;  /**< DW25 Port Recovery Timer and Port Reset Timer */
  bit32 InterruptReassertionDelay;        /**< DW26 Interrupt Reassertion Delay 0:23 Reserved 24:31 */
};

typedef struct mpiHostLLConfigDescriptor_s mpiHostLLConfigDescriptor_t;

/*******************************************************************************/
/** \struct mpiInboundQueueDescriptor_s
 *  \brief MPI inbound queue attributes
 *
 * The mpiInboundQueueDescriptor_t structure is used to describe an inbound queue
 * attributes
 */
/*******************************************************************************/
struct mpiInboundQueueDescriptor_s
{
  bit32                     numElements;     /**< The total number of queue elements. A value 0 disables the queue */
  bit32                     elementSize;     /**< The size of each queue element, in bytes */
  bit32                     priority;        /**< The queue priority. Possible values for this field are */
                                              /**< MPI_QUEUE_PRIORITY_HIGHEST and MPI_QUEUE_PRIORITY_LOWEST */
  bit32                     PIPCIBar;        /**< PI PCIe Bar */
  bit32                     PIOffset;        /**< PI PCI Bar Offset */
  void*                     ciPointer;       /**< Pointer of CI (virtual Address) */
};

typedef struct mpiInboundQueueDescriptor_s mpiInboundQueueDescriptor_t;

/*******************************************************************************/
/** \struct mpiOutboundQueueDescriptor_s
 *  \brief MPI outbound queue attributes
 *
 * The mpiOutboundQueueDescriptor_t structure is used to describe an outbound queue
 * attributes
 */
/*******************************************************************************/
struct mpiOutboundQueueDescriptor_s
{
  bit32                     numElements;        /**< The total number of queue elements. A value 0 disables the queue */
  bit32                     elementSize;        /**< The size of each queue element, in bytes */
  bit32                     interruptDelay;     /**< Delay in microseconds before the interrupt is asserted */
                                                 /**< if the interrupt threshold has not been reached */
  bit32                     interruptThreshold; /**< Number of interrupt events before the interrupt is asserted */
                                                 /**< If set to 0, interrupts for this queue are disablec */
  bit32                     interruptVector;    /**< Interrupt vector assigned to this queue */
  bit32                     CIPCIBar;           /**< offset 0x14:PCI BAR for CI Offset */
  bit32                     CIOffset;           /**< offset 0x18:Offset address for outbound queue CI */
  bit32                     DIntTOffset;        /**< Dynamic Interrupt Coalescing Timeout offset */
  bit32                     interruptEnable;    /**< Interrupt enable flag */
  void*                     piPointer;          /**< pointer of PI (virtual address)*/
};

typedef struct mpiOutboundQueueDescriptor_s mpiOutboundQueueDescriptor_t;

/*******************************************************************************/
/** \struct mpiPhyCalibration_s
 *  \brief MPI Phy Calibration Table
 *
 * The mpiPhyCalibration_s structure is used to set Phy Calibration
 * attributes
 */
/*******************************************************************************/
struct mpiPhyCalibration_s
{
  bit32   spaReg0;            /* transmitter per port configuration 1 SAS_SATA G1 */
  bit32   spaReg1;            /* transmitter per port configuration 2 SAS_SATA G1*/
  bit32   spaReg2;            /* transmitter per port configuration 3 SAS_SATA G1*/
  bit32   spaReg3;            /* transmitter configuration 1 */
  bit32   spaReg4;            /* reveiver per port configuration 1 SAS_SATA G1G2 */
  bit32   spaReg5;            /* reveiver per port configuration 2 SAS_SATA G3 */
  bit32   spaReg6;            /* reveiver per configuration 1 */
  bit32   spaReg7;            /* reveiver per configuration 2 */
  bit32   reserved[2];        /* reserved */
};

typedef struct mpiPhyCalibration_s mpiPhyCalibration_t;

#define ANALOG_SETUP_ENTRY_NO              10
#define ANALOG_SETUP_ENTRY_SIZE            10


/*******************************************************************************/
/** \struct mpiConfig_s
 *  \brief MPI layer configuration parameters
 *
 * The mpiConfig_s structure is used as a parameter passed in
 * mpiGetRequirements() and mpiInitialize() to describe the MPI software
 * configuration
 */
/*******************************************************************************/
struct mpiVConfig_s
{
  mpiHostLLConfigDescriptor_t  mainConfig;                              /**< main part of configuration table */
  mpiInboundQueueDescriptor_t  inboundQueues[MPI_MAX_INBOUND_QUEUES];   /**< mpiQueueDescriptor structures that provide initialization */
                                                                        /**< attributes for the inbound queues. The maximum number of */
                                                                        /**< inbound queues is MPI_MAX_INBOUND_QUEUES */
  mpiOutboundQueueDescriptor_t outboundQueues[MPI_MAX_OUTBOUND_QUEUES]; /**< mpiQueueDescriptor structures that provide initialization */
                                                                        /**< attributes for the outbound queues. The maximum number of */
                                                                        /**< inbound queues is MPI_MAX_OUTBOUND_QUEUES */
  agsaPhyAnalogSetupTable_t    phyAnalogConfig;
  mpiInterruptVT_t             interruptVTable;
  sasPhyAttribute_t            phyAttributeTable;
  bit16   numInboundQueues;
  bit16   numOutboundQueues;
  bit16   maxNumInboundQueues;
  bit16   maxNumOutboundQueues;
  bit32   queueOption;
};

/*******************************************************************************/
/** \struct mpiConfig_s
 *  \brief MPI layer configuration parameters
 *
 * The mpiConfig_s structure is used as a parameter passed in
 * mpiGetRequirements() and mpiInitialize() to describe the MPI software
 * configuration
 */
/*******************************************************************************/
struct mpiConfig_s
{
  mpiHostLLConfigDescriptor_t  mainConfig;                              /**< main part of configuration table */
  mpiInboundQueueDescriptor_t  inboundQueues[MPI_MAX_INBOUND_QUEUES];   /**< mpiQueueDescriptor structures that provide initialization */
                                                                        /**< attributes for the inbound queues. The maximum number of */
                                                                        /**< inbound queues is MPI_MAX_INBOUND_QUEUES */
  mpiOutboundQueueDescriptor_t outboundQueues[MPI_MAX_OUTBOUND_QUEUES]; /**< mpiQueueDescriptor structures that provide initialization */
                                                                        /**< attributes for the outbound queues. The maximum number of */
                                                                        /**< inbound queues is MPI_MAX_OUTBOUND_QUEUES */
  agsaPhyAnalogSetupTable_t    phyAnalogConfig;
  bit16   numInboundQueues;
  bit16   numOutboundQueues;
  bit16   maxNumInboundQueues;
  bit16   maxNumOutboundQueues;
  bit32   queueOption;
};

typedef struct mpiConfig_s  mpiConfig_t;

#define TX_PORT_CFG1_OFFSET                0x00
#define TX_PORT_CFG2_OFFSET                0x04
#define TX_PORT_CFG3_OFFSET                0x08
#define TX_CFG_OFFSET                      0x0c
#define RV_PORT_CFG1_OFFSET                0x10
#define RV_PORT_CFG2_OFFSET                0x14
#define RV_CFG1_OFFSET                     0x18
#define RV_CFG2_OFFSET                     0x1c

/*******************************************************************************/
/*******************************************************************************/
/* FUNCTIONS                                                                   */
/*******************************************************************************/
/*******************************************************************************/
/*******************************************************************************/
void      mpiRequirementsGet(mpiConfig_t *config, mpiMemReq_t *memoryRequirement);
FORCEINLINE bit32 mpiMsgFreeGet(mpiICQueue_t *circularQ, bit16 messageSize, void** messagePtr);
FORCEINLINE bit32 mpiMsgProduce(mpiICQueue_t *circularQ, void* messagePtr,
                        mpiMsgCategory_t category, bit16 opCode,
                        bit8 responseQueue, bit8 hiPriority);
#ifdef LOOPBACK_MPI
GLOBAL bit32 mpiMsgProduceOQ(mpiOCQueue_t *circularQ, void *messagePtr,
                             mpiMsgCategory_t category, bit16 opCode,
                             bit8 responseQueue, bit8 hiPriority);
GLOBAL bit32 mpiMsgFreeGetOQ(mpiOCQueue_t *circularQ, bit16 messageSize,
                             void** messagePtr);
#endif

#ifdef FAST_IO_TEST
bit32     mpiMsgPrepare(mpiICQueue_t *circularQ, void* messagePtr,
                        mpiMsgCategory_t category, bit16 opCode,
                        bit8 responseQueue, bit8 hiPriority);

bit32     mpiMsgProduceSend(mpiICQueue_t *circularQ, void* messagePtr,
                        mpiMsgCategory_t category, bit16 opCode,
                        bit8 responseQueue, bit8 hiPriority, int sendFl);
GLOBAL void mpiIBQMsgSend(mpiICQueue_t *circularQ);
#define INQ(queueNum) (bit8)(queueNum & MPI_IB_NUM_MASK)
#define OUQ(queueNum) (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT)
#endif

FORCEINLINE bit32 mpiMsgConsume(mpiOCQueue_t *circularQ, void** messagePtr1, mpiMsgCategory_t *pCategory, bit16* pOpCode, bit8 *pBC);
FORCEINLINE bit32 mpiMsgFreeSet(mpiOCQueue_t *circularQ, void* messagePtr1, bit8 bc);

#endif /* __MPI_H__ */