1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided
5 *that the following conditions are met:
6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8 *2. Redistributions in binary form must reproduce the above copyright notice,
9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10 *with the distribution.
12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
23 ********************************************************************************/
25 /*******************************************************************************/
27 * \brief The file defines the MPI constants and structures
29 * The file defines the MPI constants and structures
32 /*******************************************************************************/
37 /*******************************************************************************/
39 /*******************************************************************************/
41 /*******************************************************************************/
42 /*******************************************************************************/
43 #define MPI_QUEUE_PRIORITY_HIGHEST 0xFF /**< Highest queue priority */
44 #define MPI_QUEUE_PRIORITY_LOWEST 0x00 /**< Lowest queue priority */
46 #define MPI_MAX_INBOUND_QUEUES 64 /**< Maximum number of inbound queues */
47 #define MPI_MAX_OUTBOUND_QUEUES 64 /**< Maximum number of outbound queues */
49 /**< Max # of memory chunks supported */
50 #define MPI_MAX_MEM_REGIONS (MPI_MAX_INBOUND_QUEUES + MPI_MAX_OUTBOUND_QUEUES) + 4
51 #define MPI_LOGSIZE 4096 /**< default size */
53 #define MPI_IB_NUM_MASK 0x0000FFFF /**< Mask of Inbound Queue Number */
54 #define MPI_OB_NUM_MASK 0xFFFF0000 /**< Mask of Outbound Queue Number */
55 #define MPI_OB_SHIFT 16 /**< bits shift for outbound queue number */
65 /*******************************************************************************/
66 /*******************************************************************************/
68 /*******************************************************************************/
70 /*******************************************************************************/
71 /*******************************************************************************/
72 /** \enum mpiMsgCategory_e,
73 * \brief MPI message categories
75 /*******************************************************************************/
78 MPI_CATEGORY_ETHERNET = 0,
80 MPI_CATEGORY_SAS_SATA,
84 typedef enum mpiMsgCategory_e mpiMsgCategory_t;
86 /*******************************************************************************/
87 /*******************************************************************************/
89 /*******************************************************************************/
90 /*******************************************************************************/
93 /*******************************************************************************/
94 /*******************************************************************************/
96 /*******************************************************************************/
97 /*******************************************************************************/
99 /*******************************************************************************/
101 * \brief Structure that descibes memory regions
103 * The mpiMemoryDescriptor_t is used to describe the attributes for a memory
104 * region. Each element in the memory chunk has to be physically contiguous.
105 * Different elements in the memory chunk do not necessarily have to be
106 * contiguous to each other.
108 /*******************************************************************************/
111 void* virtPtr; /**< Virtual pointer to the memory region */
112 void* appHandle; /**< Handle used for the application to free memory */
113 bit32 physAddrUpper; /**< Upper 32 bits of physical address */
114 bit32 physAddrLower; /**< Lower 32 bits of physical address */
115 bit32 totalLength; /**< Total length in bytes allocated */
116 bit32 numElements; /**< Number of elements */
117 bit32 elementSize; /**< Size in bytes of an element */
118 bit32 alignment; /**< Alignment in bytes needed. A value of one indicates */
119 /**< no specific alignment requirement */
120 bit32 type; /**< Memory type */
121 bit32 reserved; /**< Reserved */
124 typedef struct mpiMem_s mpiMem_t;
126 /*******************************************************************************/
127 /** \struct mpiMemReq_s
128 * \brief Describes MPI memory requirements
130 * The mpiMemRequirements_t is used to specify the memory allocation requirement
131 * for the MPI. This is the data structure used in the mpiGetRequirements()
132 * and the mpiInitialize() function calls
134 /*******************************************************************************/
137 bit32 count; /**< The number of element in the mpiMemory array */
138 mpiMem_t region[MPI_MAX_MEM_REGIONS]; /**< Pointer to the array of structures that define memroy regions */
141 typedef struct mpiMemReq_s mpiMemReq_t;
143 /*******************************************************************************/
144 /** \struct mpiQCQueue_s
145 * \brief Circular Queue descriptor
147 * This structure holds outbound circular queue attributes.
149 /*******************************************************************************/
152 bit32 qNumber; /**< this queue number */
153 bit32 numElements; /**< The total number of queue elements. A value 0 disables the queue */
154 bit32 elementSize; /**< The size of each queue element, in bytes */
155 bit32 priority; /**< The queue priority. Possible values for this field are */
156 /**< MPI_QUEUE_PRIORITY_HIGHEST and MPI_QUEUE_PRIORITY_LOWEST */
157 bit32 CIPCIBar; /**< PCI Bar */
158 bit32 CIPCIOffset; /**< PCI Offset */
159 bit32 DIntTOffset; /**< Dynamic Interrupt Coalescing Timeout offset */
160 void* piPointer; /**< pointer of PI (virtual address)*/
161 mpiMem_t memoryRegion; /**< Queue's memory region descriptor */
162 bit32 producerIdx; /**< Copy of the producer index */
163 bit32 consumerIdx; /**< Copy of the consumer index */
164 bit32 pcibar; /**< CPI Logical Bar Number */
165 agsaRoot_t *agRoot; /**< Pointer of LL Layer structure */
168 typedef struct mpiOCQueue_s mpiOCQueue_t;
170 /*******************************************************************************/
171 /** \struct mpiICQueue_s
172 * \brief Circular Queue descriptor
174 * This structure holds inbound circular queue attributes.
176 /*******************************************************************************/
179 bit32 qNumber; /**< this queue number */
180 bit32 numElements; /**< The total number of queue elements. A value 0 disables the queue */
181 bit32 elementSize; /**< The size of each queue element, in bytes */
182 bit32 priority; /**< The queue priority. Possible values for this field are */
183 /**< MPI_QUEUE_PRIORITY_HIGHEST and MPI_QUEUE_PRIORITY_LOWEST */
184 bit32 PIPCIBar; /**< PCI Bar */
185 bit32 PIPCIOffset; /**< PCI Offset */
186 void* ciPointer; /**< Pointer of CI (virtual Address) */
187 mpiMem_t memoryRegion; /**< Queue's memory region descriptor */
188 bit32 producerIdx; /**< Copy of the producer index */
189 bit32 consumerIdx; /**< Copy of the consumer index */
190 #ifdef SA_FW_TEST_BUNCH_STARTS
191 bit32 BunchStarts_QPending; // un-started bunched IOs on queue
192 bit32 BunchStarts_QPendingTick; // tick value when 1st IO is bunched
193 #endif /* SA_FW_TEST_BUNCH_STARTS */
194 agsaRoot_t *agRoot; /**< Pointer of LL Layer structure */
197 typedef struct mpiICQueue_s mpiICQueue_t;
199 struct mpiHostLLConfigDescriptor_s
202 bit32 iQNPPD_HPPD_GEvent; /**< inbound Queue Process depth */
203 /* bit0-7 inbound normal priority process depth */
204 /* bit8-15 inbound high priority process depth */
205 /* bit16-23 OQ number to receive GENERAL_EVENT Notification */
206 /* bit24-31 reserved */
207 bit32 outboundHWEventPID0_3; /**< outbound HW event for PortId 0 to 3 */
208 /* bit0-7 outbound queue number of SAS_HW event for PortId 0 */
209 /* bit8-15 outbound queue number of SAS_HW event for PortId 1 */
210 /* bit16-23 outbound queue number of SAS_HW event for PortId 2 */
211 /* bit24-31 outbound queue number of SAS_HW event for PortId 3 */
212 bit32 outboundHWEventPID4_7; /**< outbound HW event for PortId 4 to 7 */
213 /* bit0-7 outbound queue number of SAS_HW event for PortId 4 */
214 /* bit8-15 outbound queue number of SAS_HW event for PortId 5 */
215 /* bit16-23 outbound queue number of SAS_HW event for PortId 6 */
216 /* bit24-31 outbound queue number of SAS_HW event for PortId 7 */
217 bit32 outboundNCQEventPID0_3; /**< outbound NCQ event for PortId 0 to 3 */
218 /* bit0-7 outbound queue number of SATA_NCQ event for PortId 0 */
219 /* bit8-15 outbound queue number of SATA_NCQ event for PortId 1 */
220 /* bit16-23 outbound queue number of SATA_NCQ event for PortId 2 */
221 /* bit24-31 outbound queue number of SATA_NCQ event for PortId 3 */
222 bit32 outboundNCQEventPID4_7; /**< outbound NCQ event for PortId 4 to 7 */
223 /* bit0-7 outbound queue number of SATA_NCQ event for PortId 4 */
224 /* bit8-15 outbound queue number of SATA_NCQ event for PortId 5 */
225 /* bit16-23 outbound queue number of SATA_NCQ event for PortId 6 */
226 /* bit24-31 outbound queue number of SATA_NCQ event for PortId 7 */
227 bit32 outboundTargetITNexusEventPID0_3; /**< outbound target ITNexus Event for PortId 0 to 3 */
228 /* bit0-7 outbound queue number of ITNexus event for PortId 0 */
229 /* bit8-15 outbound queue number of ITNexus event for PortId 1 */
230 /* bit16-23 outbound queue number of ITNexus event for PortId 2 */
231 /* bit24-31 outbound queue number of ITNexus event for PortId 3 */
232 bit32 outboundTargetITNexusEventPID4_7; /**< outbound target ITNexus Event for PortId 4 to 7 */
233 /* bit0-7 outbound queue number of ITNexus event for PortId 4 */
234 /* bit8-15 outbound queue number of ITNexus event for PortId 5 */
235 /* bit16-23 outbound queue number of ITNexus event for PortId 6 */
236 /* bit24-31 outbound queue number of ITNexus event for PortId 7 */
237 bit32 outboundTargetSSPEventPID0_3; /**< outbound target SSP event for PordId 0 to 3 */
238 /* bit0-7 outbound queue number of SSP event for PortId 0 */
239 /* bit8-15 outbound queue number of SSP event for PortId 1 */
240 /* bit16-23 outbound queue number of SSP event for PortId 2 */
241 /* bit24-31 outbound queue number of SSP event for PortId 3 */
242 bit32 outboundTargetSSPEventPID4_7; /**< outbound target SSP event for PordId 4 to 7 */
243 /* bit0-7 outbound queue number of SSP event for PortId 4 */
244 /* bit8-15 outbound queue number of SSP event for PortId 5 */
245 /* bit16-23 outbound queue number of SSP event for PortId 6 */
246 /* bit24-31 outbound queue number of SSP event for PortId 7 */
247 bit32 ioAbortDelay; /* was reserved */ /**< io Abort delay MPI_TABLE_CHANGE */
248 bit32 custset; /**< custset */
249 bit32 upperEventLogAddress; /**< Upper physical MSGU Event log address */
250 bit32 lowerEventLogAddress; /**< Lower physical MSGU Event log address */
251 bit32 eventLogSize; /**< Size of MSGU Event log, 0 means log disable */
252 bit32 eventLogOption; /**< Option of MSGU Event log */
253 /* bit3-0 log severity, 0x0 Disable Logging */
254 /* 0x1 Critical Error */
255 /* 0x2 Minor Error */
257 /* 0x4 Information */
259 /* 0x6 - 0xF Reserved */
260 bit32 upperIOPeventLogAddress; /**< Upper physical IOP Event log address */
261 bit32 lowerIOPeventLogAddress; /**< Lower physical IOP Event log address */
262 bit32 IOPeventLogSize; /**< Size of IOP Event log, 0 means log disable */
263 bit32 IOPeventLogOption; /**< Option of IOP Event log */
264 /* bit3-0 log severity, 0x0 Disable Logging */
265 /* 0x1 Critical Error */
266 /* 0x2 Minor Error */
268 /* 0x4 Information */
270 /* 0x6 - 0xF Reserved */
271 bit32 FatalErrorInterrupt; /**< Fatal Error Interrupt enable and vector */
272 /* bit0 Fatal Error Interrupt Enable */
273 /* bit1 PI/CI Address */
274 /* bit5 enable or disable outbound coalesce */
275 /* bit7-6 reserved */
276 /* bit15-8 Fatal Error Interrupt Vector */
277 /* bit31-16 Reserved */
278 bit32 FatalErrorDumpOffset0; /**< Fatal Error Register Dump Offset for MSGU */
279 bit32 FatalErrorDumpLength0; /**< Fatal Error Register Dump Length for MSGU */
280 bit32 FatalErrorDumpOffset1; /**< Fatal Error Register Dump Offset for IOP */
281 bit32 FatalErrorDumpLength1; /**< Fatal Error Register Dump Length for IOP */
282 bit32 HDAModeFlags; /**< HDA Mode Flags */
283 /* bit1-0 Bootstrap pins */
284 /* bit2 Force HDA Mode bit */
285 /* bit3 HDA Firmware load method */
286 bit32 analogSetupTblOffset; /**< Phy Calibration Table offset */
287 /* bit23-0 phy calib table offset */
288 /* bit31-24 entry size */
289 bit32 InterruptVecTblOffset; /**< DW23 Interrupt Vector Table */
290 /* bit23-0 interrupt vector table offset */
291 /* bit31-24 entry size */
292 bit32 phyAttributeTblOffset; /**< DW24 SAS Phy Attribute Table Offset */
293 /* bit23-0 phy attribute table offset */
294 /* bit31-24 entry size */
295 bit32 PortRecoveryTimerPortResetTimer; /**< DW25 Port Recovery Timer and Port Reset Timer */
296 bit32 InterruptReassertionDelay; /**< DW26 Interrupt Reassertion Delay 0:23 Reserved 24:31 */
299 typedef struct mpiHostLLConfigDescriptor_s mpiHostLLConfigDescriptor_t;
301 /*******************************************************************************/
302 /** \struct mpiInboundQueueDescriptor_s
303 * \brief MPI inbound queue attributes
305 * The mpiInboundQueueDescriptor_t structure is used to describe an inbound queue
308 /*******************************************************************************/
309 struct mpiInboundQueueDescriptor_s
311 bit32 numElements; /**< The total number of queue elements. A value 0 disables the queue */
312 bit32 elementSize; /**< The size of each queue element, in bytes */
313 bit32 priority; /**< The queue priority. Possible values for this field are */
314 /**< MPI_QUEUE_PRIORITY_HIGHEST and MPI_QUEUE_PRIORITY_LOWEST */
315 bit32 PIPCIBar; /**< PI PCIe Bar */
316 bit32 PIOffset; /**< PI PCI Bar Offset */
317 void* ciPointer; /**< Pointer of CI (virtual Address) */
320 typedef struct mpiInboundQueueDescriptor_s mpiInboundQueueDescriptor_t;
322 /*******************************************************************************/
323 /** \struct mpiOutboundQueueDescriptor_s
324 * \brief MPI outbound queue attributes
326 * The mpiOutboundQueueDescriptor_t structure is used to describe an outbound queue
329 /*******************************************************************************/
330 struct mpiOutboundQueueDescriptor_s
332 bit32 numElements; /**< The total number of queue elements. A value 0 disables the queue */
333 bit32 elementSize; /**< The size of each queue element, in bytes */
334 bit32 interruptDelay; /**< Delay in microseconds before the interrupt is asserted */
335 /**< if the interrupt threshold has not been reached */
336 bit32 interruptThreshold; /**< Number of interrupt events before the interrupt is asserted */
337 /**< If set to 0, interrupts for this queue are disablec */
338 bit32 interruptVector; /**< Interrupt vector assigned to this queue */
339 bit32 CIPCIBar; /**< offset 0x14:PCI BAR for CI Offset */
340 bit32 CIOffset; /**< offset 0x18:Offset address for outbound queue CI */
341 bit32 DIntTOffset; /**< Dynamic Interrupt Coalescing Timeout offset */
342 bit32 interruptEnable; /**< Interrupt enable flag */
343 void* piPointer; /**< pointer of PI (virtual address)*/
346 typedef struct mpiOutboundQueueDescriptor_s mpiOutboundQueueDescriptor_t;
348 /*******************************************************************************/
349 /** \struct mpiPhyCalibration_s
350 * \brief MPI Phy Calibration Table
352 * The mpiPhyCalibration_s structure is used to set Phy Calibration
355 /*******************************************************************************/
356 struct mpiPhyCalibration_s
358 bit32 spaReg0; /* transmitter per port configuration 1 SAS_SATA G1 */
359 bit32 spaReg1; /* transmitter per port configuration 2 SAS_SATA G1*/
360 bit32 spaReg2; /* transmitter per port configuration 3 SAS_SATA G1*/
361 bit32 spaReg3; /* transmitter configuration 1 */
362 bit32 spaReg4; /* reveiver per port configuration 1 SAS_SATA G1G2 */
363 bit32 spaReg5; /* reveiver per port configuration 2 SAS_SATA G3 */
364 bit32 spaReg6; /* reveiver per configuration 1 */
365 bit32 spaReg7; /* reveiver per configuration 2 */
366 bit32 reserved[2]; /* reserved */
369 typedef struct mpiPhyCalibration_s mpiPhyCalibration_t;
371 #define ANALOG_SETUP_ENTRY_NO 10
372 #define ANALOG_SETUP_ENTRY_SIZE 10
375 /*******************************************************************************/
376 /** \struct mpiConfig_s
377 * \brief MPI layer configuration parameters
379 * The mpiConfig_s structure is used as a parameter passed in
380 * mpiGetRequirements() and mpiInitialize() to describe the MPI software
383 /*******************************************************************************/
386 mpiHostLLConfigDescriptor_t mainConfig; /**< main part of configuration table */
387 mpiInboundQueueDescriptor_t inboundQueues[MPI_MAX_INBOUND_QUEUES]; /**< mpiQueueDescriptor structures that provide initialization */
388 /**< attributes for the inbound queues. The maximum number of */
389 /**< inbound queues is MPI_MAX_INBOUND_QUEUES */
390 mpiOutboundQueueDescriptor_t outboundQueues[MPI_MAX_OUTBOUND_QUEUES]; /**< mpiQueueDescriptor structures that provide initialization */
391 /**< attributes for the outbound queues. The maximum number of */
392 /**< inbound queues is MPI_MAX_OUTBOUND_QUEUES */
393 agsaPhyAnalogSetupTable_t phyAnalogConfig;
394 mpiInterruptVT_t interruptVTable;
395 sasPhyAttribute_t phyAttributeTable;
396 bit16 numInboundQueues;
397 bit16 numOutboundQueues;
398 bit16 maxNumInboundQueues;
399 bit16 maxNumOutboundQueues;
403 /*******************************************************************************/
404 /** \struct mpiConfig_s
405 * \brief MPI layer configuration parameters
407 * The mpiConfig_s structure is used as a parameter passed in
408 * mpiGetRequirements() and mpiInitialize() to describe the MPI software
411 /*******************************************************************************/
414 mpiHostLLConfigDescriptor_t mainConfig; /**< main part of configuration table */
415 mpiInboundQueueDescriptor_t inboundQueues[MPI_MAX_INBOUND_QUEUES]; /**< mpiQueueDescriptor structures that provide initialization */
416 /**< attributes for the inbound queues. The maximum number of */
417 /**< inbound queues is MPI_MAX_INBOUND_QUEUES */
418 mpiOutboundQueueDescriptor_t outboundQueues[MPI_MAX_OUTBOUND_QUEUES]; /**< mpiQueueDescriptor structures that provide initialization */
419 /**< attributes for the outbound queues. The maximum number of */
420 /**< inbound queues is MPI_MAX_OUTBOUND_QUEUES */
421 agsaPhyAnalogSetupTable_t phyAnalogConfig;
422 bit16 numInboundQueues;
423 bit16 numOutboundQueues;
424 bit16 maxNumInboundQueues;
425 bit16 maxNumOutboundQueues;
429 typedef struct mpiConfig_s mpiConfig_t;
431 #define TX_PORT_CFG1_OFFSET 0x00
432 #define TX_PORT_CFG2_OFFSET 0x04
433 #define TX_PORT_CFG3_OFFSET 0x08
434 #define TX_CFG_OFFSET 0x0c
435 #define RV_PORT_CFG1_OFFSET 0x10
436 #define RV_PORT_CFG2_OFFSET 0x14
437 #define RV_CFG1_OFFSET 0x18
438 #define RV_CFG2_OFFSET 0x1c
440 /*******************************************************************************/
441 /*******************************************************************************/
443 /*******************************************************************************/
444 /*******************************************************************************/
445 /*******************************************************************************/
446 void mpiRequirementsGet(mpiConfig_t *config, mpiMemReq_t *memoryRequirement);
447 FORCEINLINE bit32 mpiMsgFreeGet(mpiICQueue_t *circularQ, bit16 messageSize, void** messagePtr);
448 FORCEINLINE bit32 mpiMsgProduce(mpiICQueue_t *circularQ, void* messagePtr,
449 mpiMsgCategory_t category, bit16 opCode,
450 bit8 responseQueue, bit8 hiPriority);
452 GLOBAL bit32 mpiMsgProduceOQ(mpiOCQueue_t *circularQ, void *messagePtr,
453 mpiMsgCategory_t category, bit16 opCode,
454 bit8 responseQueue, bit8 hiPriority);
455 GLOBAL bit32 mpiMsgFreeGetOQ(mpiOCQueue_t *circularQ, bit16 messageSize,
460 bit32 mpiMsgPrepare(mpiICQueue_t *circularQ, void* messagePtr,
461 mpiMsgCategory_t category, bit16 opCode,
462 bit8 responseQueue, bit8 hiPriority);
464 bit32 mpiMsgProduceSend(mpiICQueue_t *circularQ, void* messagePtr,
465 mpiMsgCategory_t category, bit16 opCode,
466 bit8 responseQueue, bit8 hiPriority, int sendFl);
467 GLOBAL void mpiIBQMsgSend(mpiICQueue_t *circularQ);
468 #define INQ(queueNum) (bit8)(queueNum & MPI_IB_NUM_MASK)
469 #define OUQ(queueNum) (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT)
472 FORCEINLINE bit32 mpiMsgConsume(mpiOCQueue_t *circularQ, void** messagePtr1, mpiMsgCategory_t *pCategory, bit16* pOpCode, bit8 *pBC);
473 FORCEINLINE bit32 mpiMsgFreeSet(mpiOCQueue_t *circularQ, void* messagePtr1, bit8 bc);
475 #endif /* __MPI_H__ */