freebsd-dev/sys/mips/octeon1/dev/rgmii/octeon_pko.h

293 lines
9.0 KiB
C
Raw Normal View History

/*------------------------------------------------------------------
* octeon_pko.h Packet Output Block
*
*------------------------------------------------------------------
*/
#ifndef ___OCTEON_PKO__H___
#define ___OCTEON_PKO__H___
/*
* PKO Command Buffer Register.
* Specify Pool-# and Size of each entry in Pool. For Output Cmd Buffers.
*/
typedef union {
uint64_t word64;
struct {
uint64_t unused_mbz : 41; /* Must be zero */
uint64_t pool : 3; /* FPA Pool to use */
uint64_t unused_mbz2 : 7; /* Must be zero */
uint64_t size : 13; /* Size of the pool blocks */
} bits;
} octeon_pko_pool_cfg_t;
/*
* PKO GMX Mode Register
* Specify the # of GMX1 ports and GMX0 ports
*/
typedef union {
uint64_t word64;
struct {
uint64_t unused_mbz : 58; /* MBZ */
uint64_t mode1 : 3; /* # GMX1 ports; */
/* 16 >> MODE1, 0 <= MODE1 <=4 */
uint64_t mode0 : 3; /* # GMX0 ports; */
/* 16 >> MODE0, 0 <= MODE0 <=4 */
} bits;
} octeon_pko_reg_gmx_port_mode_t;
typedef union {
uint64_t word64;
struct {
uint64_t unused_mbz : 62; /* MBZ */
uint64_t mode : 2; /* Queues Mode */
} bits;
} octeon_pko_queue_mode_t;
typedef union {
uint64_t word64;
struct {
uint64_t unused_mbz : 32; /* MBZ */
uint64_t crc_ports_mask : 32; /* CRC Ports Enable mask */
} bits;
} octeon_pko_crc_ports_enable_t;
#define OCTEON_PKO_QUEUES_MAX 128
#define OCTEON_PKO_PORTS_MAX 36
#define OCTEON_PKO_PORT_ILLEGAL 63
/* Defines how the PKO command buffer FAU register is used */
#define OCTEON_PKO_INDEX_BITS 12
#define OCTEON_PKO_INDEX_MASK ((1ull << OCTEON_PKO_INDEX_BITS) - 1)
typedef enum {
OCTEON_PKO_SUCCESS,
OCTEON_PKO_INVALID_PORT,
OCTEON_PKO_INVALID_QUEUE,
OCTEON_PKO_INVALID_PRIORITY,
OCTEON_PKO_NO_MEMORY
} octeon_pko_status_t;
typedef struct {
long packets;
uint64_t octets;
uint64_t doorbell;
} octeon_pko_port_status_t;
typedef union {
uint64_t word64;
struct {
octeon_mips_space_t mem_space : 2; /* Octeon IO_SEG */
uint64_t unused_mbz :13; /* Must be zero */
uint64_t is_io : 1; /* Must be one */
uint64_t did : 8; /* device-ID on non-coherent bus*/
uint64_t unused_mbz2 : 4; /* Must be zero */
uint64_t unused_mbz3 :18; /* Must be zero */
uint64_t port : 6; /* output port */
uint64_t queue : 9; /* output queue to send */
uint64_t unused_mbz4 : 3; /* Must be zero */
} bits;
} octeon_pko_doorbell_address_t;
/*
* Structure of the first packet output command word.
*/
typedef union {
uint64_t word64;
struct {
octeon_fau_op_size_t size1 : 2; /* The size of reg1 operation */
/* - could be 8, 16, 32, or 64 bits */
octeon_fau_op_size_t size0 : 2; /* The size of the reg0 operation */
/* - could be 8, 16, 32, or 64 bits */
uint64_t subone1 : 1; /* Subtract 1, else sub pkt size */
uint64_t reg1 :11; /* The register, subtract will be */
/* done if reg1 is non-zero */
uint64_t subone0 : 1; /* Subtract 1, else sub pkt size */
uint64_t reg0 :11; /* The register, subtract will be */
/* done if reg0 is non-zero */
uint64_t unused : 2; /* Must be zero */
uint64_t wqp : 1; /* If rsp, then word3 contains a */
/* ptr to a work queue entry */
uint64_t rsp : 1; /* HW will respond when done */
uint64_t gather : 1; /* If set, the supplied pkt_ptr is */
/* a ptr to a list of pkt_ptr's */
uint64_t ipoffp1 : 7; /* Off to IP hdr. For HW checksum */
uint64_t ignore_i : 1; /* Ignore I bit in all pointers */
uint64_t dontfree : 1; /* Don't free buffs containing pkt */
uint64_t segs : 6; /* Number of segs. If gather set, */
/* also gather list length */
uint64_t total_bytes :16; /* Includes L2, w/o trailing CRC */
} bits;
} octeon_pko_command_word0_t;
typedef union {
void* ptr;
uint64_t word64;
struct {
uint64_t i : 1; /* Invert the "free" pick of the overall pkt. */
/* For inbound pkts, HW always sets this to 0 */
uint64_t back : 4; /* Amount to back up to get to buffer start */
/* in cache lines. This is mostly less than 1 */
/* complete cache line; so the value is zero */
uint64_t pool : 3; /* FPA pool that the buffer belongs to */
uint64_t size :16; /* segment size (bytes) pointed at by addr */
uint64_t addr :40; /* Ptr to 1st data byte. NOT buffer */
} bits;
} octeon_pko_packet_ptr_t;
/*
* Definition of the hardware structure used to configure an
* output queue.
*/
typedef union {
uint64_t word64;
struct {
uint64_t unused_mbz : 3; /* Must be zero */
uint64_t qos_mask : 8; /* Control Mask priority */
/* across 8 QOS levels */
uint64_t buf_ptr : 36; /* Command buffer pointer, */
/* 8 byte-aligned */
uint64_t tail : 1; /* Set if this queue is the tail */
/* of the port queue array */
uint64_t index : 3; /* Index (distance from head) in */
/* the port queue array */
uint64_t port : 6; /* Port ID for this queue mapping */
uint64_t queue : 7; /* Hardware queue number */
} bits;
} octeon_pko_queue_cfg_t;
typedef union {
uint64_t word64;
struct {
uint64_t unused_mbz : 48;
uint64_t inc : 8;
uint64_t idx : 8;
} bits;
} octeon_pko_read_idx_t;
typedef struct octeon_pko_sw_queue_info_t_
{
uint64_t xmit_command_state;
octeon_spinlock_t lock;
uint32_t pad[29];
} octeon_pko_sw_queue_info_t;
#define OCTEON_DID_PKT 10ULL
#define OCTEON_DID_PKT_SEND OCTEON_ADDR_FULL_DID(OCTEON_DID_PKT,2ULL)
/*
* Ring the packet output doorbell. This tells the packet
* output hardware that "len" command words have been added
* to its pending list. This command includes the required
* SYNCW before the doorbell ring.
*
* @param port Port the packet is for
* @param queue Queue the packet is for
* @param len Length of the command in 64 bit words
*/
extern void octeon_pko_doorbell_data(u_int port);
//#define CORE_0_ONLY 1
static inline void octeon_pko_ring_doorbell (u_int port, u_int queue,
u_int len)
{
octeon_pko_doorbell_address_t ptr;
ptr.word64 = 0;
ptr.bits.mem_space = OCTEON_IO_SEG;
ptr.bits.did = OCTEON_DID_PKT_SEND;
ptr.bits.is_io = 1;
ptr.bits.port = port;
ptr.bits.queue = queue;
OCTEON_SYNCWS;
oct_write64(ptr.word64, len);
}
#define OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0 1
#define OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1 1
#define OCTEON_PKO_QUEUES_PER_PORT_PCI 1
/*
* octeon_pko_get_base_queue
*
* For a given port number, return the base pko output queue
* for the port.
*/
static inline u_int octeon_pko_get_base_queue (u_int port)
{
if (port < 16) {
return (port * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0);
}
if (port < 32) {
return (16 * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0 +
(port - 16) * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1);
}
return (16 * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0 +
16 * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1 +
(port - 32) * OCTEON_PKO_QUEUES_PER_PORT_PCI);
}
/*
* For a given port number, return the number of pko output queues.
*
* @param port Port number
* @return Number of output queues
*/
static inline u_int octeon_pko_get_num_queues(u_int port)
{
if (port < 16) {
return (OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0);
} else if (port<32) {
return (OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1);
}
return (OCTEON_PKO_QUEUES_PER_PORT_PCI);
}
/*
* Externs
*/
extern void octeon_pko_init(void);
extern void octeon_pko_enable(void);
extern void octeon_pko_disable(void);
extern void octeon_pko_show(u_int start_port, u_int end_port);
extern void octeon_pko_config(void);
extern void octeon_pko_config_cmdbuf_global_defaults(u_int cmdbuf_pool, u_int elem_size);
extern void octeon_pko_config_rgmx_ports(void);
extern void octeon_pko_get_port_status(u_int, u_int, octeon_pko_port_status_t *status);
extern octeon_pko_status_t octeon_pko_config_port(u_int port,
u_int base_queue,
u_int num_queues,
const u_int priority[],
u_int pko_output_cmdbuf_fpa_pool,
octeon_pko_sw_queue_info_t sw_queues[]);
#endif /* ___OCTEON_PKO__H___ */