/***********************license start*************** * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights * reserved. * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * Neither the name of Cavium Inc. nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * This Software, including technical data, may be subject to U.S. export control * laws, including the U.S. Export Administration Act and its associated * regulations, and may be subject to export or import regulations in other * countries. * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. ***********************license end**************************************/ /** * @file * * Interface to SRIO * *
$Revision: 41586 $
*/ #ifndef __CVMX_SRIO_H__ #define __CVMX_SRIO_H__ #ifdef __cplusplus extern "C" { #endif /** * Enumeration of the type of operations that can be performed * by a mapped write operation. */ typedef enum { CVMX_SRIO_WRITE_MODE_NWRITE = 0, /**< Only create NWrite operations */ CVMX_SRIO_WRITE_MODE_NWRITE_RESP = 1, /**< Create NWrite with response */ CVMX_SRIO_WRITE_MODE_AUTO = 2, /**< Intelligently breaks writes into multiple transactions based on alignment */ CVMX_SRIO_WRITE_MODE_AUTO_RESP = 3, /**< CVMX_SRIO_WRITE_MODE_WRITE followed with a response */ CVMX_SRIO_WRITE_MODE_MAINTENANCE = 6, /**< Create a MAINTENANCE transaction. Use cvmx_srio_config_write32() instead */ CVMX_SRIO_WRITE_MODE_PORT = 7 /**< Port Write? */ } cvmx_srio_write_mode_t; /** * Enumeration of the type of operations that can be performed * by a mapped read operation. */ typedef enum { CVMX_SRIO_READ_MODE_NORMAL = 0, /**< Perform a normal read */ CVMX_SRIO_READ_MODE_ATOMIC_SET = 2, /**< Atomically sets bits in data on remote device */ CVMX_SRIO_READ_MODE_ATOMIC_CLEAR = 3, /**< Atomically clears bits in data on remote device */ CVMX_SRIO_READ_MODE_ATOMIC_INCREMENT = 4,/**< Atomically increments data on remote device */ CVMX_SRIO_READ_MODE_ATOMIC_DECREMENT = 5,/**< Atomically decrements data on remote device */ CVMX_SRIO_READ_MODE_MAINTENANCE = 6 /**< Create a MAINTENANCE transaction. Use cvmx_srio_config_read32() instead */ } cvmx_srio_read_mode_t; /** * Initialization flags for SRIO */ typedef enum { CVMX_SRIO_INITIALIZE_DEBUG = 1, } cvmx_srio_initialize_flags_t; /** * The possible results from a doorbell operation */ typedef enum { CVMX_SRIO_DOORBELL_DONE, /**< The doorbell is complete */ CVMX_SRIO_DOORBELL_NONE, /**< There wasn't an outstanding doorbell */ CVMX_SRIO_DOORBELL_BUSY, /**< The doorbell is still processing */ CVMX_SRIO_DOORBELL_RETRY, /**< The doorbell needs to be retried */ CVMX_SRIO_DOORBELL_ERROR, /**< The doorbell failed with an error */ CVMX_SRIO_DOORBELL_TMOUT /**< The doorbell failed due to timeout */ } cvmx_srio_doorbell_status_t; /** * This structure represents the SRIO header received from SRIO on * the top of every received message. This header passes through * IPD/PIP unmodified. */ typedef struct { union { uint64_t u64; struct { #ifdef __BIG_ENDIAN_BITFIELD uint64_t prio : 2; /**< The sRIO prio (priority) field in the first sRIO message segment received for the message. */ uint64_t tt : 1; /**< When set, indicates that the first sRIO message segment received for the message had 16-bit source and destination ID's. When clear, indicates 8-bit ID were present. */ uint64_t dis : 1; /**< When set, indicates that the destination ID in the first sRIO message segment received for the message matched the 63xx's secondary ID. When clear, indicates that the destination ID in the first sRIO message segment received for the message matched the 63xx's primary ID. Note that the full destination ID in the received sRIO message can be determined via the combination of WORD0[DIS] in the sRIO inbound message header and WORD1[iprt] in the work queue entry created by PIP/IPD. */ uint64_t ssize : 4; /**< The RIO ssize (standard message packet data size) field used for the message. */ uint64_t sid : 16; /**< The source ID in the first sRIO message segment received for the message. When TT is clear, the most-significant 8 bits are zero. */ uint64_t xmbox : 4; /**< The RIO xmbox (recipient mailbox extension) field in the first sRIO message segment received for the message. Always zero for multi-segment messages. */ uint64_t mbox : 2; /**< The RIO mbox (recipient mailbox) field in the first sRIO message segment received for the message. */ uint64_t letter : 2; /**< The RIO letter (slot within a mailbox) field in the first sRIO message segment received for the message. */ uint64_t seq : 32; /**< A sequence number. Whenever the OCTEON 63xx sRIO hardware accepts the first sRIO segment of either a message or doorbell, it samples the current value of a counter register and increments the counter register. SEQ is the value sampled for the message. The counter increments once per message/doorbell. SEQ can be used to determine the relative order of packets/doorbells. Note that the SEQ-implied order may differ from the order that the WQE's are received by software for a number of reasons, including the fact that the WQE is not created until the end of the message, while SEQ is sampled when the first segment. */ #else uint64_t seq : 32; uint64_t letter : 2; uint64_t mbox : 2; uint64_t xmbox : 4; uint64_t sid : 16; uint64_t ssize : 4; uint64_t dis : 1; uint64_t tt : 1; uint64_t prio : 2; #endif } s; } word0; union { uint64_t u64; struct { #ifdef __BIG_ENDIAN_BITFIELD uint64_t r : 1; /**< When set, WORD1[R]/PKT_INST_HDR[R] selects either RAWFULL or RAWSCHED special PIP instruction form. WORD1[R] may commonly be set so that WORD1[QOS,GRP] will be directly used by the PIP hardware. */ uint64_t reserved_62_58 : 5; uint64_t pm : 2; /**< WORD1[PM]/PKT_INST_HDR[PM] selects the PIP parse mode (uninterpreted, skip-to-L2, skip-to-IP), and chooses between RAWFULL/RAWSCHED when WORD1[R] is set. */ uint64_t reserved_55 : 1; uint64_t sl : 7; /**< WORD1[SL]/PKT_INST_HDR[SL] selects the skip II length. WORD1[SL] may typically be set to 8 (or larger) so that PIP skips this WORD1. */ uint64_t reserved_47_46 : 2; uint64_t nqos : 1; /**< WORD1[NQOS] must not be set when WORD1[R] is clear and PIP interprets WORD1 as a PKT_INST_HDR. When set, WORD1[NQOS]/PKT_INST_HDR[NQOS] prevents PIP from directly using WORD1[QOS]/PKT_INST_HDR[QOS] for the QOS value in the work queue entry created by PIP. WORD1[NQOS] may commonly be clear so that WORD1[QOS] will be directly used by the PIP hardware. PKT_INST_HDR[NQOS] is new to 63xx - this functionality did not exist in prior OCTEON's. */ uint64_t ngrp : 1; /**< WORD1[NGRP] must not be set when WORD1[R] is clear and PIP interprets WORD1 as a PKT_INST_HDR. When set, WORD1[NGRP]/PKT_INST_HDR[NGRP] prevents PIP from directly using WORD1[GRP]/PKT_INST_HDR[GRP] for the GRP value in the work queue entry created by PIP. WORD1[NGRP] may commonly be clear so that WORD1[GRP] will be directly used by the PIP hardware. PKT_INST_HDR[NGRP] is new to 63xx - this functionality did not exist in prior OCTEON's. */ uint64_t ntt : 1; /**< WORD1[NTT] must not be set when WORD1[R] is clear and PIP interprets WORD1 as a PKT_INST_HDR. When set, WORD1[NTT]/PKT_INST_HDR[NTT] prevents PIP from directly using WORD1[TT]/PKT_INST_HDR[TT] for the TT value in the work queue entry created by PIP. PKT_INST_HDR[NTT] is new to 63xx - this functionality did not exist in prior OCTEON's. */ uint64_t ntag : 1; /**< WORD1[NTAG] must not be set when WORD1[R] is clear and PIP interprets WORD1 as a PKT_INST_HDR. When set, WORD1[NTAG]/PKT_INST_HDR[NTAG] prevents PIP from directly using WORD1[TAG]/PKT_INST_HDR[TAG] for the TAG value in the work queue entry created by PIP. PKT_INST_HDR[NTAG] is new to 63xx - this functionality did not exist in prior OCTEON's. */ uint64_t qos : 3; /**< Created by the hardware from an entry in a 256-entry table. The 8-bit value WORD0[PRIO,TT,DIS,MBOX,LETTER] selects the table entry. When WORD1[R] is set and WORD1[NQOS] is clear, WORD1[QOS] becomes the QOS value in the work queue entry created by PIP. The QOS value in the work queue entry determines the priority that SSO/POW will schedule the work, and can also control how/if the sRIO message gets dropped by PIP/IPD. The 256-entry table is unique to each sRIO core, but shared by the two controllers associated with the sRIO core. */ uint64_t grp : 4; /**< Created by the hardware from an entry in a 256-entry table. The 8-bit value WORD0[PRIO,TT,DIS,MBOX,LETTER] selects the table entry. When WORD1[R] is set and WORD1[NGRP] is clear, WORD1[GRP] becomes the GRP value in the work queue entry created by PIP. The GRP value in the work queue entry can direct the work to particular cores or particular groups of cores. The 256-entry table is unique to each sRIO core, but shared by the two controllers associated with the sRIO core. */ uint64_t rs : 1; /**< In some configurations, enables the sRIO message to be buffered solely in the work queue entry, and not otherwise in L2/DRAM. */ uint64_t tt : 2; /**< When WORD1[R] is set and WORD1[NTT] is clear, WORD1[TT]/PKT_INST_HDR[TT] becomes the TT value in the work queue entry created by PIP. The TT and TAG values in the work queue entry determine the scheduling/synchronization constraints for the work (no constraints, tag order, atomic tag order). */ uint64_t tag : 32; /**< Created by the hardware from a CSR associated with the sRIO inbound message controller. When WORD1[R] is set and WORD1[NTAG] is clear, WORD1[TAG]/PKT_INST_HDR[TAG] becomes the TAG value in the work queue entry created by PIP. The TT and TAG values in the work queue entry determine the scheduling/synchronization constraints for the work (no constraints, tag order, atomic tag order). */ #else uint64_t tag : 32; uint64_t tt : 2; uint64_t rs : 1; uint64_t grp : 4; uint64_t qos : 3; uint64_t ntag : 1; uint64_t ntt : 1; uint64_t ngrp : 1; uint64_t nqos : 1; uint64_t reserved_47_46 : 2; uint64_t sl : 7; uint64_t reserved_55 : 1; uint64_t pm : 2; uint64_t reserved_62_58 : 5; uint64_t r : 1; #endif } s; } word1; } cvmx_srio_rx_message_header_t; /** * This structure represents the SRIO header required on the front * of PKO packets destine for SRIO message queues. */ typedef union { uint64_t u64; struct { #ifdef __BIG_ENDIAN_BITFIELD uint64_t prio : 2; /**< The sRIO prio (priority) field for all segments in the message. */ uint64_t tt : 1; /**< When set, the sRIO message segments use a 16-bit source and destination ID for all the segments in the message. When clear, the message segments use an 8-bit ID. */ uint64_t sis : 1; /**< When set, the sRIO message segments use the 63xx's secondary ID as the source ID. When clear, the sRIO message segments use the primary ID as the source ID. */ uint64_t ssize : 4; /**< The RIO ssize (standard message segment data size) field used for the message. */ uint64_t did : 16; /**< The destination ID in the sRIO message segments of the message. When TT is clear, the most-significant 8 bits must be zero. */ uint64_t xmbox : 4; /**< The RIO xmbox (recipient mailbox extension) field in the sRIO message segment for a single-segment message. Must be zero for multi-segment messages. */ uint64_t mbox : 2; /**< The RIO mbox (recipient mailbox) field in the sRIO message segments of the message. */ uint64_t letter : 2; /**< The RIO letter (slot within mailbox) field in the sRIO message segments of the message when LNS is clear. When LNS is set, this LETTER field is not used and must be zero. */ uint64_t reserved_31_2 : 30; uint64_t lns : 1; /**< When set, the outbound message controller will dynamically selects an sRIO letter field for the message (based on LETTER_SP or LETTER_MP - see appendix A), and the LETTER field in this sRIO outbound message descriptor is unused. When clear, the LETTER field in this sRIO outbound message descriptor selects the sRIO letter used for the message. */ uint64_t intr : 1; /**< When set, the outbound message controller will set an interrupt bit after all sRIO segments of the message receive a message DONE response. If the message transfer has errors, the interrupt bit is not set (but others are). */ #else uint64_t intr : 1; uint64_t lns : 1; uint64_t reserved_31_2 : 30; uint64_t letter : 2; uint64_t mbox : 2; uint64_t xmbox : 4; uint64_t did : 16; uint64_t ssize : 4; uint64_t sis : 1; uint64_t tt : 1; uint64_t prio : 2; #endif } s; } cvmx_srio_tx_message_header_t; /** * Reset SRIO to link partner * * @param srio_port SRIO port to initialize * * @return Zero on success */ int cvmx_srio_link_rst(int srio_port); /** * Initialize a SRIO port for use. * * @param srio_port SRIO port to initialize * @param flags Optional flags * * @return Zero on success */ int cvmx_srio_initialize(int srio_port, cvmx_srio_initialize_flags_t flags); /** * Read 32bits from a Device's config space * * @param srio_port SRIO port the device is on * @param srcid_index * Which SRIO source ID to use. 0 = Primary, 1 = Secondary * @param destid RapidIO device ID, or -1 for the local Octeon. * @param is16bit Non zero if the transactions should use 16bit device IDs. Zero * if transactions should use 8bit device IDs. * @param hopcount Number of hops to the remote device. Use 0 for the local Octeon. * @param offset Offset in config space. This must be a multiple of 32 bits. * @param result Result of the read. This will be unmodified on failure. * * @return Zero on success, negative on failure. */ int cvmx_srio_config_read32(int srio_port, int srcid_index, int destid, int is16bit, uint8_t hopcount, uint32_t offset, uint32_t *result); /** * Write 32bits to a Device's config space * * @param srio_port SRIO port the device is on * @param srcid_index * Which SRIO source ID to use. 0 = Primary, 1 = Secondary * @param destid RapidIO device ID, or -1 for the local Octeon. * @param is16bit Non zero if the transactions should use 16bit device IDs. Zero * if transactions should use 8bit device IDs. * @param hopcount Number of hops to the remote device. Use 0 for the local Octeon. * @param offset Offset in config space. This must be a multiple of 32 bits. * @param data Data to write. * * @return Zero on success, negative on failure. */ int cvmx_srio_config_write32(int srio_port, int srcid_index, int destid, int is16bit, uint8_t hopcount, uint32_t offset, uint32_t data); /** * Send a RapidIO doorbell to a remote device * * @param srio_port SRIO port the device is on * @param srcid_index * Which SRIO source ID to use. 0 = Primary, 1 = Secondary * @param destid RapidIO device ID. * @param is16bit Non zero if the transactions should use 16bit device IDs. Zero * if transactions should use 8bit device IDs. * @param priority Doorbell priority (0-3) * @param data Data for doorbell. * * @return Zero on success, negative on failure. */ int cvmx_srio_send_doorbell(int srio_port, int srcid_index, int destid, int is16bit, int priority, uint16_t data); /** * Get the status of the last doorbell sent. If the dooorbell * hardware is done, then the status is cleared to get ready for * the next doorbell (or retry). * * @param srio_port SRIO port to check doorbell on * * @return Doorbell status */ cvmx_srio_doorbell_status_t cvmx_srio_send_doorbell_status(int srio_port); /** * Read a received doorbell and report data about it. * * @param srio_port SRIO port to check for the received doorbell * @param destid_index * Which Octeon destination ID was the doorbell for * @param sequence_num * Sequence number of doorbell (32bits) * @param srcid RapidIO source ID of the doorbell sender * @param priority Priority of the doorbell (0-3) * @param is16bit Non zero if the transactions should use 16bit device IDs. Zero * if transactions should use 8bit device IDs. * @param data Data in the doorbell (16 bits) * * @return Doorbell status. Either DONE, NONE, or ERROR. */ cvmx_srio_doorbell_status_t cvmx_srio_receive_doorbell(int srio_port, int *destid_index, uint32_t *sequence_num, int *srcid, int *priority, int *is16bit, uint16_t *data); /** * Receive a packet from the Soft Packet FIFO (SPF). * * @param srio_port SRIO port to read the packet from. * @param buffer Buffer to receive the packet. * @param buffer_length * Length of the buffer in bytes. * * @return Returns the length of the packet read. Negative on failure. * Zero if no packets are available. */ int cvmx_srio_receive_spf(int srio_port, void *buffer, int buffer_length); /** * Map a remote device's memory region into Octeon's physical * address area. The caller can then map this into a core using * the TLB or XKPHYS. * * @param srio_port SRIO port to map the device on * @param write_op Type of operation to perform on a write to the device. * Normally should be CVMX_SRIO_WRITE_MODE_AUTO. * @param write_priority * SRIO priority of writes (0-3) * @param read_op Type of operation to perform on reads to the device. * Normally should be CVMX_SRIO_READ_MODE_NORMAL. * @param read_priority * SRIO priority of reads (0-3) * @param srcid_index * Which SRIO source ID to use. 0 = Primary, 1 = Secondary * @param destid RapidIO device ID. * @param is16bit Non zero if the transactions should use 16bit device IDs. Zero * if transactions should use 8bit device IDs. * @param base Device base address to start the mapping * @param size Size of the mapping in bytes * * @return Octeon 64bit physical address that accesses the remote device, * or zero on failure. */ uint64_t cvmx_srio_physical_map(int srio_port, cvmx_srio_write_mode_t write_op, int write_priority, cvmx_srio_read_mode_t read_op, int read_priority, int srcid_index, int destid, int is16bit, uint64_t base, uint64_t size); /** * Unmap a physical address window created by cvmx_srio_phys_map(). * * @param physical_address * Physical address returned by cvmx_srio_phys_map(). * @param size Size used on original call. * * @return Zero on success, negative on failure. */ int cvmx_srio_physical_unmap(uint64_t physical_address, uint64_t size); #ifdef CVMX_ENABLE_PKO_FUNCTIONS /** * fill out outbound message descriptor * * @param buf_ptr pointer to a buffer pointer. the buffer pointer points * to a chain of buffers that hold an outbound srio packet. * the packet can take the format of (1) a pip/ipd inbound * message or (2) an application-generated outbound message * @param desc_ptr pointer to an outbound message descriptor. should be null * if *buf_ptr is in the format (1) * * @return 0 on success; negative of failure. */ int cvmx_srio_omsg_desc (uint64_t port, cvmx_buf_ptr_t *buf_ptr, cvmx_srio_tx_message_header_t *desc_ptr); #endif #ifdef __cplusplus } #endif #endif