Warner Losh fe36702132 Add Cavium's standard copyright to those files that are currently
lacking a copyright/license statement.  All these files were in the
Cavium FreeBSD source drop and appear to be written by Cavium (some
are nearly verbatim copies of files from the cnusers' 1.9.0 SDK, which
also uses this copyright).
2010-01-28 20:46:40 +00:00

333 lines
11 KiB
C

/***********************license start***************
* Copyright (c) 2003-2008 Cavium Networks (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 Networks nor the names of
* its contributors may be used to endorse or promote products
* derived from this software without specific prior written
* permission.
*
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
* AND WITH ALL FAULTS AND CAVIUM NETWORKS 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.
*
*
* For any questions regarding licensing please contact marketing@caviumnetworks.com
*
***********************license end**************************************/
/* $FreeBSD$ */
/*------------------------------------------------------------------
* 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___ */