18c2ecf20Sopenharmony_ci/***********************license start***************
28c2ecf20Sopenharmony_ci * Author: Cavium Networks
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Contact: support@caviumnetworks.com
58c2ecf20Sopenharmony_ci * This file is part of the OCTEON SDK
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (c) 2003-2008 Cavium Networks
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * This file is free software; you can redistribute it and/or modify
108c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License, Version 2, as
118c2ecf20Sopenharmony_ci * published by the Free Software Foundation.
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * This file is distributed in the hope that it will be useful, but
148c2ecf20Sopenharmony_ci * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
158c2ecf20Sopenharmony_ci * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
168c2ecf20Sopenharmony_ci * NONINFRINGEMENT.  See the GNU General Public License for more
178c2ecf20Sopenharmony_ci * details.
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci * You should have received a copy of the GNU General Public License
208c2ecf20Sopenharmony_ci * along with this file; if not, write to the Free Software
218c2ecf20Sopenharmony_ci * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
228c2ecf20Sopenharmony_ci * or visit http://www.gnu.org/licenses/.
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci * This file may also be available under a different license from Cavium.
258c2ecf20Sopenharmony_ci * Contact Cavium Networks for more information
268c2ecf20Sopenharmony_ci ***********************license end**************************************/
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/**
298c2ecf20Sopenharmony_ci *
308c2ecf20Sopenharmony_ci * Interface to the hardware Packet Output unit.
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci * Starting with SDK 1.7.0, the PKO output functions now support
338c2ecf20Sopenharmony_ci * two types of locking. CVMX_PKO_LOCK_ATOMIC_TAG continues to
348c2ecf20Sopenharmony_ci * function similarly to previous SDKs by using POW atomic tags
358c2ecf20Sopenharmony_ci * to preserve ordering and exclusivity. As a new option, you
368c2ecf20Sopenharmony_ci * can now pass CVMX_PKO_LOCK_CMD_QUEUE which uses a ll/sc
378c2ecf20Sopenharmony_ci * memory based locking instead. This locking has the advantage
388c2ecf20Sopenharmony_ci * of not affecting the tag state but doesn't preserve packet
398c2ecf20Sopenharmony_ci * ordering. CVMX_PKO_LOCK_CMD_QUEUE is appropriate in most
408c2ecf20Sopenharmony_ci * generic code while CVMX_PKO_LOCK_CMD_QUEUE should be used
418c2ecf20Sopenharmony_ci * with hand tuned fast path code.
428c2ecf20Sopenharmony_ci *
438c2ecf20Sopenharmony_ci * Some of other SDK differences visible to the command queuing:
448c2ecf20Sopenharmony_ci * - PKO indexes are no longer stored in the FAU. A large
458c2ecf20Sopenharmony_ci *   percentage of the FAU register block used to be tied up
468c2ecf20Sopenharmony_ci *   maintaining PKO queue pointers. These are now stored in a
478c2ecf20Sopenharmony_ci *   global named block.
488c2ecf20Sopenharmony_ci * - The PKO <b>use_locking</b> parameter can now have a global
498c2ecf20Sopenharmony_ci *   effect. Since all application use the same named block,
508c2ecf20Sopenharmony_ci *   queue locking correctly applies across all operating
518c2ecf20Sopenharmony_ci *   systems when using CVMX_PKO_LOCK_CMD_QUEUE.
528c2ecf20Sopenharmony_ci * - PKO 3 word commands are now supported. Use
538c2ecf20Sopenharmony_ci *   cvmx_pko_send_packet_finish3().
548c2ecf20Sopenharmony_ci *
558c2ecf20Sopenharmony_ci */
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci#ifndef __CVMX_PKO_H__
588c2ecf20Sopenharmony_ci#define __CVMX_PKO_H__
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-fpa.h>
618c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-pow.h>
628c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-cmd-queue.h>
638c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-pko-defs.h>
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci/* Adjust the command buffer size by 1 word so that in the case of using only
668c2ecf20Sopenharmony_ci * two word PKO commands no command words stradle buffers.  The useful values
678c2ecf20Sopenharmony_ci * for this are 0 and 1. */
688c2ecf20Sopenharmony_ci#define CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST (1)
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#define CVMX_PKO_MAX_OUTPUT_QUEUES_STATIC 256
718c2ecf20Sopenharmony_ci#define CVMX_PKO_MAX_OUTPUT_QUEUES	((OCTEON_IS_MODEL(OCTEON_CN31XX) || \
728c2ecf20Sopenharmony_ci	OCTEON_IS_MODEL(OCTEON_CN3010) || OCTEON_IS_MODEL(OCTEON_CN3005) || \
738c2ecf20Sopenharmony_ci	OCTEON_IS_MODEL(OCTEON_CN50XX)) ? 32 : \
748c2ecf20Sopenharmony_ci		(OCTEON_IS_MODEL(OCTEON_CN58XX) || \
758c2ecf20Sopenharmony_ci		OCTEON_IS_MODEL(OCTEON_CN56XX)) ? 256 : 128)
768c2ecf20Sopenharmony_ci#define CVMX_PKO_NUM_OUTPUT_PORTS	40
778c2ecf20Sopenharmony_ci/* use this for queues that are not used */
788c2ecf20Sopenharmony_ci#define CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID 63
798c2ecf20Sopenharmony_ci#define CVMX_PKO_QUEUE_STATIC_PRIORITY	9
808c2ecf20Sopenharmony_ci#define CVMX_PKO_ILLEGAL_QUEUE	0xFFFF
818c2ecf20Sopenharmony_ci#define CVMX_PKO_MAX_QUEUE_DEPTH 0
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_citypedef enum {
848c2ecf20Sopenharmony_ci	CVMX_PKO_SUCCESS,
858c2ecf20Sopenharmony_ci	CVMX_PKO_INVALID_PORT,
868c2ecf20Sopenharmony_ci	CVMX_PKO_INVALID_QUEUE,
878c2ecf20Sopenharmony_ci	CVMX_PKO_INVALID_PRIORITY,
888c2ecf20Sopenharmony_ci	CVMX_PKO_NO_MEMORY,
898c2ecf20Sopenharmony_ci	CVMX_PKO_PORT_ALREADY_SETUP,
908c2ecf20Sopenharmony_ci	CVMX_PKO_CMD_QUEUE_INIT_ERROR
918c2ecf20Sopenharmony_ci} cvmx_pko_status_t;
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci/**
948c2ecf20Sopenharmony_ci * This enumeration represents the differnet locking modes supported by PKO.
958c2ecf20Sopenharmony_ci */
968c2ecf20Sopenharmony_citypedef enum {
978c2ecf20Sopenharmony_ci	/*
988c2ecf20Sopenharmony_ci	 * PKO doesn't do any locking. It is the responsibility of the
998c2ecf20Sopenharmony_ci	 * application to make sure that no other core is accessing
1008c2ecf20Sopenharmony_ci	 * the same queue at the same time
1018c2ecf20Sopenharmony_ci	 */
1028c2ecf20Sopenharmony_ci	CVMX_PKO_LOCK_NONE = 0,
1038c2ecf20Sopenharmony_ci	/*
1048c2ecf20Sopenharmony_ci	 * PKO performs an atomic tagswitch to insure exclusive access
1058c2ecf20Sopenharmony_ci	 * to the output queue. This will maintain packet ordering on
1068c2ecf20Sopenharmony_ci	 * output.
1078c2ecf20Sopenharmony_ci	 */
1088c2ecf20Sopenharmony_ci	CVMX_PKO_LOCK_ATOMIC_TAG = 1,
1098c2ecf20Sopenharmony_ci	/*
1108c2ecf20Sopenharmony_ci	 * PKO uses the common command queue locks to insure exclusive
1118c2ecf20Sopenharmony_ci	 * access to the output queue. This is a memory based
1128c2ecf20Sopenharmony_ci	 * ll/sc. This is the most portable locking mechanism.
1138c2ecf20Sopenharmony_ci	 */
1148c2ecf20Sopenharmony_ci	CVMX_PKO_LOCK_CMD_QUEUE = 2,
1158c2ecf20Sopenharmony_ci} cvmx_pko_lock_t;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_citypedef struct {
1188c2ecf20Sopenharmony_ci	uint32_t packets;
1198c2ecf20Sopenharmony_ci	uint64_t octets;
1208c2ecf20Sopenharmony_ci	uint64_t doorbell;
1218c2ecf20Sopenharmony_ci} cvmx_pko_port_status_t;
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci/**
1248c2ecf20Sopenharmony_ci * This structure defines the address to use on a packet enqueue
1258c2ecf20Sopenharmony_ci */
1268c2ecf20Sopenharmony_citypedef union {
1278c2ecf20Sopenharmony_ci	uint64_t u64;
1288c2ecf20Sopenharmony_ci	struct {
1298c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD
1308c2ecf20Sopenharmony_ci		/* Must CVMX_IO_SEG */
1318c2ecf20Sopenharmony_ci		uint64_t mem_space:2;
1328c2ecf20Sopenharmony_ci		/* Must be zero */
1338c2ecf20Sopenharmony_ci		uint64_t reserved:13;
1348c2ecf20Sopenharmony_ci		/* Must be one */
1358c2ecf20Sopenharmony_ci		uint64_t is_io:1;
1368c2ecf20Sopenharmony_ci		/* The ID of the device on the non-coherent bus */
1378c2ecf20Sopenharmony_ci		uint64_t did:8;
1388c2ecf20Sopenharmony_ci		/* Must be zero */
1398c2ecf20Sopenharmony_ci		uint64_t reserved2:4;
1408c2ecf20Sopenharmony_ci		/* Must be zero */
1418c2ecf20Sopenharmony_ci		uint64_t reserved3:18;
1428c2ecf20Sopenharmony_ci		/*
1438c2ecf20Sopenharmony_ci		 * The hardware likes to have the output port in
1448c2ecf20Sopenharmony_ci		 * addition to the output queue,
1458c2ecf20Sopenharmony_ci		 */
1468c2ecf20Sopenharmony_ci		uint64_t port:6;
1478c2ecf20Sopenharmony_ci		/*
1488c2ecf20Sopenharmony_ci		 * The output queue to send the packet to (0-127 are
1498c2ecf20Sopenharmony_ci		 * legal)
1508c2ecf20Sopenharmony_ci		 */
1518c2ecf20Sopenharmony_ci		uint64_t queue:9;
1528c2ecf20Sopenharmony_ci		/* Must be zero */
1538c2ecf20Sopenharmony_ci		uint64_t reserved4:3;
1548c2ecf20Sopenharmony_ci#else
1558c2ecf20Sopenharmony_ci	        uint64_t reserved4:3;
1568c2ecf20Sopenharmony_ci	        uint64_t queue:9;
1578c2ecf20Sopenharmony_ci	        uint64_t port:9;
1588c2ecf20Sopenharmony_ci	        uint64_t reserved3:15;
1598c2ecf20Sopenharmony_ci	        uint64_t reserved2:4;
1608c2ecf20Sopenharmony_ci	        uint64_t did:8;
1618c2ecf20Sopenharmony_ci	        uint64_t is_io:1;
1628c2ecf20Sopenharmony_ci	        uint64_t reserved:13;
1638c2ecf20Sopenharmony_ci	        uint64_t mem_space:2;
1648c2ecf20Sopenharmony_ci#endif
1658c2ecf20Sopenharmony_ci	} s;
1668c2ecf20Sopenharmony_ci} cvmx_pko_doorbell_address_t;
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci/**
1698c2ecf20Sopenharmony_ci * Structure of the first packet output command word.
1708c2ecf20Sopenharmony_ci */
1718c2ecf20Sopenharmony_ciunion cvmx_pko_command_word0 {
1728c2ecf20Sopenharmony_ci	uint64_t u64;
1738c2ecf20Sopenharmony_ci	struct {
1748c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD
1758c2ecf20Sopenharmony_ci		/*
1768c2ecf20Sopenharmony_ci		 * The size of the reg1 operation - could be 8, 16,
1778c2ecf20Sopenharmony_ci		 * 32, or 64 bits.
1788c2ecf20Sopenharmony_ci		 */
1798c2ecf20Sopenharmony_ci		uint64_t size1:2;
1808c2ecf20Sopenharmony_ci		/*
1818c2ecf20Sopenharmony_ci		 * The size of the reg0 operation - could be 8, 16,
1828c2ecf20Sopenharmony_ci		 * 32, or 64 bits.
1838c2ecf20Sopenharmony_ci		 */
1848c2ecf20Sopenharmony_ci		uint64_t size0:2;
1858c2ecf20Sopenharmony_ci		/*
1868c2ecf20Sopenharmony_ci		 * If set, subtract 1, if clear, subtract packet
1878c2ecf20Sopenharmony_ci		 * size.
1888c2ecf20Sopenharmony_ci		 */
1898c2ecf20Sopenharmony_ci		uint64_t subone1:1;
1908c2ecf20Sopenharmony_ci		/*
1918c2ecf20Sopenharmony_ci		 * The register, subtract will be done if reg1 is
1928c2ecf20Sopenharmony_ci		 * non-zero.
1938c2ecf20Sopenharmony_ci		 */
1948c2ecf20Sopenharmony_ci		uint64_t reg1:11;
1958c2ecf20Sopenharmony_ci		/* If set, subtract 1, if clear, subtract packet size */
1968c2ecf20Sopenharmony_ci		uint64_t subone0:1;
1978c2ecf20Sopenharmony_ci		/* The register, subtract will be done if reg0 is non-zero */
1988c2ecf20Sopenharmony_ci		uint64_t reg0:11;
1998c2ecf20Sopenharmony_ci		/*
2008c2ecf20Sopenharmony_ci		 * When set, interpret segment pointer and segment
2018c2ecf20Sopenharmony_ci		 * bytes in little endian order.
2028c2ecf20Sopenharmony_ci		 */
2038c2ecf20Sopenharmony_ci		uint64_t le:1;
2048c2ecf20Sopenharmony_ci		/*
2058c2ecf20Sopenharmony_ci		 * When set, packet data not allocated in L2 cache by
2068c2ecf20Sopenharmony_ci		 * PKO.
2078c2ecf20Sopenharmony_ci		 */
2088c2ecf20Sopenharmony_ci		uint64_t n2:1;
2098c2ecf20Sopenharmony_ci		/*
2108c2ecf20Sopenharmony_ci		 * If set and rsp is set, word3 contains a pointer to
2118c2ecf20Sopenharmony_ci		 * a work queue entry.
2128c2ecf20Sopenharmony_ci		 */
2138c2ecf20Sopenharmony_ci		uint64_t wqp:1;
2148c2ecf20Sopenharmony_ci		/* If set, the hardware will send a response when done */
2158c2ecf20Sopenharmony_ci		uint64_t rsp:1;
2168c2ecf20Sopenharmony_ci		/*
2178c2ecf20Sopenharmony_ci		 * If set, the supplied pkt_ptr is really a pointer to
2188c2ecf20Sopenharmony_ci		 * a list of pkt_ptr's.
2198c2ecf20Sopenharmony_ci		 */
2208c2ecf20Sopenharmony_ci		uint64_t gather:1;
2218c2ecf20Sopenharmony_ci		/*
2228c2ecf20Sopenharmony_ci		 * If ipoffp1 is non zero, (ipoffp1-1) is the number
2238c2ecf20Sopenharmony_ci		 * of bytes to IP header, and the hardware will
2248c2ecf20Sopenharmony_ci		 * calculate and insert the UDP/TCP checksum.
2258c2ecf20Sopenharmony_ci		 */
2268c2ecf20Sopenharmony_ci		uint64_t ipoffp1:7;
2278c2ecf20Sopenharmony_ci		/*
2288c2ecf20Sopenharmony_ci		 * If set, ignore the I bit (force to zero) from all
2298c2ecf20Sopenharmony_ci		 * pointer structures.
2308c2ecf20Sopenharmony_ci		 */
2318c2ecf20Sopenharmony_ci		uint64_t ignore_i:1;
2328c2ecf20Sopenharmony_ci		/*
2338c2ecf20Sopenharmony_ci		 * If clear, the hardware will attempt to free the
2348c2ecf20Sopenharmony_ci		 * buffers containing the packet.
2358c2ecf20Sopenharmony_ci		 */
2368c2ecf20Sopenharmony_ci		uint64_t dontfree:1;
2378c2ecf20Sopenharmony_ci		/*
2388c2ecf20Sopenharmony_ci		 * The total number of segs in the packet, if gather
2398c2ecf20Sopenharmony_ci		 * set, also gather list length.
2408c2ecf20Sopenharmony_ci		 */
2418c2ecf20Sopenharmony_ci		uint64_t segs:6;
2428c2ecf20Sopenharmony_ci		/* Including L2, but no trailing CRC */
2438c2ecf20Sopenharmony_ci		uint64_t total_bytes:16;
2448c2ecf20Sopenharmony_ci#else
2458c2ecf20Sopenharmony_ci	        uint64_t total_bytes:16;
2468c2ecf20Sopenharmony_ci	        uint64_t segs:6;
2478c2ecf20Sopenharmony_ci	        uint64_t dontfree:1;
2488c2ecf20Sopenharmony_ci	        uint64_t ignore_i:1;
2498c2ecf20Sopenharmony_ci	        uint64_t ipoffp1:7;
2508c2ecf20Sopenharmony_ci	        uint64_t gather:1;
2518c2ecf20Sopenharmony_ci	        uint64_t rsp:1;
2528c2ecf20Sopenharmony_ci	        uint64_t wqp:1;
2538c2ecf20Sopenharmony_ci	        uint64_t n2:1;
2548c2ecf20Sopenharmony_ci	        uint64_t le:1;
2558c2ecf20Sopenharmony_ci	        uint64_t reg0:11;
2568c2ecf20Sopenharmony_ci	        uint64_t subone0:1;
2578c2ecf20Sopenharmony_ci	        uint64_t reg1:11;
2588c2ecf20Sopenharmony_ci	        uint64_t subone1:1;
2598c2ecf20Sopenharmony_ci	        uint64_t size0:2;
2608c2ecf20Sopenharmony_ci	        uint64_t size1:2;
2618c2ecf20Sopenharmony_ci#endif
2628c2ecf20Sopenharmony_ci	} s;
2638c2ecf20Sopenharmony_ci};
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci/* CSR typedefs have been moved to cvmx-csr-*.h */
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci/**
2688c2ecf20Sopenharmony_ci * Definition of internal state for Packet output processing
2698c2ecf20Sopenharmony_ci */
2708c2ecf20Sopenharmony_citypedef struct {
2718c2ecf20Sopenharmony_ci	/* ptr to start of buffer, offset kept in FAU reg */
2728c2ecf20Sopenharmony_ci	uint64_t *start_ptr;
2738c2ecf20Sopenharmony_ci} cvmx_pko_state_elem_t;
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci/**
2768c2ecf20Sopenharmony_ci * Call before any other calls to initialize the packet
2778c2ecf20Sopenharmony_ci * output system.
2788c2ecf20Sopenharmony_ci */
2798c2ecf20Sopenharmony_ciextern void cvmx_pko_initialize_global(void);
2808c2ecf20Sopenharmony_ciextern int cvmx_pko_initialize_local(void);
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci/**
2838c2ecf20Sopenharmony_ci * Enables the packet output hardware. It must already be
2848c2ecf20Sopenharmony_ci * configured.
2858c2ecf20Sopenharmony_ci */
2868c2ecf20Sopenharmony_ciextern void cvmx_pko_enable(void);
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci/**
2898c2ecf20Sopenharmony_ci * Disables the packet output. Does not affect any configuration.
2908c2ecf20Sopenharmony_ci */
2918c2ecf20Sopenharmony_ciextern void cvmx_pko_disable(void);
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci/**
2948c2ecf20Sopenharmony_ci * Shutdown and free resources required by packet output.
2958c2ecf20Sopenharmony_ci */
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ciextern void cvmx_pko_shutdown(void);
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci/**
3008c2ecf20Sopenharmony_ci * Configure a output port and the associated queues for use.
3018c2ecf20Sopenharmony_ci *
3028c2ecf20Sopenharmony_ci * @port:	Port to configure.
3038c2ecf20Sopenharmony_ci * @base_queue: First queue number to associate with this port.
3048c2ecf20Sopenharmony_ci * @num_queues: Number of queues t oassociate with this port
3058c2ecf20Sopenharmony_ci * @priority:	Array of priority levels for each queue. Values are
3068c2ecf20Sopenharmony_ci *		     allowed to be 1-8. A value of 8 get 8 times the traffic
3078c2ecf20Sopenharmony_ci *		     of a value of 1. There must be num_queues elements in the
3088c2ecf20Sopenharmony_ci *		     array.
3098c2ecf20Sopenharmony_ci */
3108c2ecf20Sopenharmony_ciextern cvmx_pko_status_t cvmx_pko_config_port(uint64_t port,
3118c2ecf20Sopenharmony_ci					      uint64_t base_queue,
3128c2ecf20Sopenharmony_ci					      uint64_t num_queues,
3138c2ecf20Sopenharmony_ci					      const uint64_t priority[]);
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci/**
3168c2ecf20Sopenharmony_ci * Ring the packet output doorbell. This tells the packet
3178c2ecf20Sopenharmony_ci * output hardware that "len" command words have been added
3188c2ecf20Sopenharmony_ci * to its pending list.	 This command includes the required
3198c2ecf20Sopenharmony_ci * CVMX_SYNCWS before the doorbell ring.
3208c2ecf20Sopenharmony_ci *
3218c2ecf20Sopenharmony_ci * @port:   Port the packet is for
3228c2ecf20Sopenharmony_ci * @queue:  Queue the packet is for
3238c2ecf20Sopenharmony_ci * @len:    Length of the command in 64 bit words
3248c2ecf20Sopenharmony_ci */
3258c2ecf20Sopenharmony_cistatic inline void cvmx_pko_doorbell(uint64_t port, uint64_t queue,
3268c2ecf20Sopenharmony_ci				     uint64_t len)
3278c2ecf20Sopenharmony_ci{
3288c2ecf20Sopenharmony_ci	cvmx_pko_doorbell_address_t ptr;
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	ptr.u64 = 0;
3318c2ecf20Sopenharmony_ci	ptr.s.mem_space = CVMX_IO_SEG;
3328c2ecf20Sopenharmony_ci	ptr.s.did = CVMX_OCT_DID_PKT_SEND;
3338c2ecf20Sopenharmony_ci	ptr.s.is_io = 1;
3348c2ecf20Sopenharmony_ci	ptr.s.port = port;
3358c2ecf20Sopenharmony_ci	ptr.s.queue = queue;
3368c2ecf20Sopenharmony_ci	/*
3378c2ecf20Sopenharmony_ci	 * Need to make sure output queue data is in DRAM before
3388c2ecf20Sopenharmony_ci	 * doorbell write.
3398c2ecf20Sopenharmony_ci	 */
3408c2ecf20Sopenharmony_ci	CVMX_SYNCWS;
3418c2ecf20Sopenharmony_ci	cvmx_write_io(ptr.u64, len);
3428c2ecf20Sopenharmony_ci}
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci/**
3458c2ecf20Sopenharmony_ci * Prepare to send a packet.  This may initiate a tag switch to
3468c2ecf20Sopenharmony_ci * get exclusive access to the output queue structure, and
3478c2ecf20Sopenharmony_ci * performs other prep work for the packet send operation.
3488c2ecf20Sopenharmony_ci *
3498c2ecf20Sopenharmony_ci * cvmx_pko_send_packet_finish() MUST be called after this function is called,
3508c2ecf20Sopenharmony_ci * and must be called with the same port/queue/use_locking arguments.
3518c2ecf20Sopenharmony_ci *
3528c2ecf20Sopenharmony_ci * The use_locking parameter allows the caller to use three
3538c2ecf20Sopenharmony_ci * possible locking modes.
3548c2ecf20Sopenharmony_ci * - CVMX_PKO_LOCK_NONE
3558c2ecf20Sopenharmony_ci *	- PKO doesn't do any locking. It is the responsibility
3568c2ecf20Sopenharmony_ci *	    of the application to make sure that no other core
3578c2ecf20Sopenharmony_ci *	    is accessing the same queue at the same time.
3588c2ecf20Sopenharmony_ci * - CVMX_PKO_LOCK_ATOMIC_TAG
3598c2ecf20Sopenharmony_ci *	- PKO performs an atomic tagswitch to insure exclusive
3608c2ecf20Sopenharmony_ci *	    access to the output queue. This will maintain
3618c2ecf20Sopenharmony_ci *	    packet ordering on output.
3628c2ecf20Sopenharmony_ci * - CVMX_PKO_LOCK_CMD_QUEUE
3638c2ecf20Sopenharmony_ci *	- PKO uses the common command queue locks to insure
3648c2ecf20Sopenharmony_ci *	    exclusive access to the output queue. This is a
3658c2ecf20Sopenharmony_ci *	    memory based ll/sc. This is the most portable
3668c2ecf20Sopenharmony_ci *	    locking mechanism.
3678c2ecf20Sopenharmony_ci *
3688c2ecf20Sopenharmony_ci * NOTE: If atomic locking is used, the POW entry CANNOT be
3698c2ecf20Sopenharmony_ci * descheduled, as it does not contain a valid WQE pointer.
3708c2ecf20Sopenharmony_ci *
3718c2ecf20Sopenharmony_ci * @port:   Port to send it on
3728c2ecf20Sopenharmony_ci * @queue:  Queue to use
3738c2ecf20Sopenharmony_ci * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
3748c2ecf20Sopenharmony_ci *		 CVMX_PKO_LOCK_CMD_QUEUE
3758c2ecf20Sopenharmony_ci */
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_cistatic inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue,
3788c2ecf20Sopenharmony_ci						cvmx_pko_lock_t use_locking)
3798c2ecf20Sopenharmony_ci{
3808c2ecf20Sopenharmony_ci	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) {
3818c2ecf20Sopenharmony_ci		/*
3828c2ecf20Sopenharmony_ci		 * Must do a full switch here to handle all cases.  We
3838c2ecf20Sopenharmony_ci		 * use a fake WQE pointer, as the POW does not access
3848c2ecf20Sopenharmony_ci		 * this memory.	 The WQE pointer and group are only
3858c2ecf20Sopenharmony_ci		 * used if this work is descheduled, which is not
3868c2ecf20Sopenharmony_ci		 * supported by the
3878c2ecf20Sopenharmony_ci		 * cvmx_pko_send_packet_prepare/cvmx_pko_send_packet_finish
3888c2ecf20Sopenharmony_ci		 * combination.	 Note that this is a special case in
3898c2ecf20Sopenharmony_ci		 * which these fake values can be used - this is not a
3908c2ecf20Sopenharmony_ci		 * general technique.
3918c2ecf20Sopenharmony_ci		 */
3928c2ecf20Sopenharmony_ci		uint32_t tag =
3938c2ecf20Sopenharmony_ci		    CVMX_TAG_SW_BITS_INTERNAL << CVMX_TAG_SW_SHIFT |
3948c2ecf20Sopenharmony_ci		    CVMX_TAG_SUBGROUP_PKO << CVMX_TAG_SUBGROUP_SHIFT |
3958c2ecf20Sopenharmony_ci		    (CVMX_TAG_SUBGROUP_MASK & queue);
3968c2ecf20Sopenharmony_ci		cvmx_pow_tag_sw_full((struct cvmx_wqe *) cvmx_phys_to_ptr(0x80), tag,
3978c2ecf20Sopenharmony_ci				     CVMX_POW_TAG_TYPE_ATOMIC, 0);
3988c2ecf20Sopenharmony_ci	}
3998c2ecf20Sopenharmony_ci}
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_ci/**
4028c2ecf20Sopenharmony_ci * Complete packet output. cvmx_pko_send_packet_prepare() must be
4038c2ecf20Sopenharmony_ci * called exactly once before this, and the same parameters must be
4048c2ecf20Sopenharmony_ci * passed to both cvmx_pko_send_packet_prepare() and
4058c2ecf20Sopenharmony_ci * cvmx_pko_send_packet_finish().
4068c2ecf20Sopenharmony_ci *
4078c2ecf20Sopenharmony_ci * @port:   Port to send it on
4088c2ecf20Sopenharmony_ci * @queue:  Queue to use
4098c2ecf20Sopenharmony_ci * @pko_command:
4108c2ecf20Sopenharmony_ci *		 PKO HW command word
4118c2ecf20Sopenharmony_ci * @packet: Packet to send
4128c2ecf20Sopenharmony_ci * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
4138c2ecf20Sopenharmony_ci *		 CVMX_PKO_LOCK_CMD_QUEUE
4148c2ecf20Sopenharmony_ci *
4158c2ecf20Sopenharmony_ci * Returns: CVMX_PKO_SUCCESS on success, or error code on
4168c2ecf20Sopenharmony_ci * failure of output
4178c2ecf20Sopenharmony_ci */
4188c2ecf20Sopenharmony_cistatic inline cvmx_pko_status_t cvmx_pko_send_packet_finish(
4198c2ecf20Sopenharmony_ci	uint64_t port,
4208c2ecf20Sopenharmony_ci	uint64_t queue,
4218c2ecf20Sopenharmony_ci	union cvmx_pko_command_word0 pko_command,
4228c2ecf20Sopenharmony_ci	union cvmx_buf_ptr packet,
4238c2ecf20Sopenharmony_ci	cvmx_pko_lock_t use_locking)
4248c2ecf20Sopenharmony_ci{
4258c2ecf20Sopenharmony_ci	cvmx_cmd_queue_result_t result;
4268c2ecf20Sopenharmony_ci	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
4278c2ecf20Sopenharmony_ci		cvmx_pow_tag_sw_wait();
4288c2ecf20Sopenharmony_ci	result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue),
4298c2ecf20Sopenharmony_ci				       (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
4308c2ecf20Sopenharmony_ci				       pko_command.u64, packet.u64);
4318c2ecf20Sopenharmony_ci	if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
4328c2ecf20Sopenharmony_ci		cvmx_pko_doorbell(port, queue, 2);
4338c2ecf20Sopenharmony_ci		return CVMX_PKO_SUCCESS;
4348c2ecf20Sopenharmony_ci	} else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
4358c2ecf20Sopenharmony_ci		   || (result == CVMX_CMD_QUEUE_FULL)) {
4368c2ecf20Sopenharmony_ci		return CVMX_PKO_NO_MEMORY;
4378c2ecf20Sopenharmony_ci	} else {
4388c2ecf20Sopenharmony_ci		return CVMX_PKO_INVALID_QUEUE;
4398c2ecf20Sopenharmony_ci	}
4408c2ecf20Sopenharmony_ci}
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci/**
4438c2ecf20Sopenharmony_ci * Complete packet output. cvmx_pko_send_packet_prepare() must be
4448c2ecf20Sopenharmony_ci * called exactly once before this, and the same parameters must be
4458c2ecf20Sopenharmony_ci * passed to both cvmx_pko_send_packet_prepare() and
4468c2ecf20Sopenharmony_ci * cvmx_pko_send_packet_finish().
4478c2ecf20Sopenharmony_ci *
4488c2ecf20Sopenharmony_ci * @port:   Port to send it on
4498c2ecf20Sopenharmony_ci * @queue:  Queue to use
4508c2ecf20Sopenharmony_ci * @pko_command:
4518c2ecf20Sopenharmony_ci *		 PKO HW command word
4528c2ecf20Sopenharmony_ci * @packet: Packet to send
4538c2ecf20Sopenharmony_ci * @addr: Plysical address of a work queue entry or physical address
4548c2ecf20Sopenharmony_ci *	  to zero on complete.
4558c2ecf20Sopenharmony_ci * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
4568c2ecf20Sopenharmony_ci *		 CVMX_PKO_LOCK_CMD_QUEUE
4578c2ecf20Sopenharmony_ci *
4588c2ecf20Sopenharmony_ci * Returns: CVMX_PKO_SUCCESS on success, or error code on
4598c2ecf20Sopenharmony_ci * failure of output
4608c2ecf20Sopenharmony_ci */
4618c2ecf20Sopenharmony_cistatic inline cvmx_pko_status_t cvmx_pko_send_packet_finish3(
4628c2ecf20Sopenharmony_ci	uint64_t port,
4638c2ecf20Sopenharmony_ci	uint64_t queue,
4648c2ecf20Sopenharmony_ci	union cvmx_pko_command_word0 pko_command,
4658c2ecf20Sopenharmony_ci	union cvmx_buf_ptr packet,
4668c2ecf20Sopenharmony_ci	uint64_t addr,
4678c2ecf20Sopenharmony_ci	cvmx_pko_lock_t use_locking)
4688c2ecf20Sopenharmony_ci{
4698c2ecf20Sopenharmony_ci	cvmx_cmd_queue_result_t result;
4708c2ecf20Sopenharmony_ci	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
4718c2ecf20Sopenharmony_ci		cvmx_pow_tag_sw_wait();
4728c2ecf20Sopenharmony_ci	result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue),
4738c2ecf20Sopenharmony_ci				       (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
4748c2ecf20Sopenharmony_ci				       pko_command.u64, packet.u64, addr);
4758c2ecf20Sopenharmony_ci	if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
4768c2ecf20Sopenharmony_ci		cvmx_pko_doorbell(port, queue, 3);
4778c2ecf20Sopenharmony_ci		return CVMX_PKO_SUCCESS;
4788c2ecf20Sopenharmony_ci	} else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
4798c2ecf20Sopenharmony_ci		   || (result == CVMX_CMD_QUEUE_FULL)) {
4808c2ecf20Sopenharmony_ci		return CVMX_PKO_NO_MEMORY;
4818c2ecf20Sopenharmony_ci	} else {
4828c2ecf20Sopenharmony_ci		return CVMX_PKO_INVALID_QUEUE;
4838c2ecf20Sopenharmony_ci	}
4848c2ecf20Sopenharmony_ci}
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci/**
4878c2ecf20Sopenharmony_ci * Return the pko output queue associated with a port and a specific core.
4888c2ecf20Sopenharmony_ci * In normal mode (PKO lockless operation is disabled), the value returned
4898c2ecf20Sopenharmony_ci * is the base queue.
4908c2ecf20Sopenharmony_ci *
4918c2ecf20Sopenharmony_ci * @port:   Port number
4928c2ecf20Sopenharmony_ci * @core:   Core to get queue for
4938c2ecf20Sopenharmony_ci *
4948c2ecf20Sopenharmony_ci * Returns Core-specific output queue
4958c2ecf20Sopenharmony_ci */
4968c2ecf20Sopenharmony_cistatic inline int cvmx_pko_get_base_queue_per_core(int port, int core)
4978c2ecf20Sopenharmony_ci{
4988c2ecf20Sopenharmony_ci#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
4998c2ecf20Sopenharmony_ci#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0 16
5008c2ecf20Sopenharmony_ci#endif
5018c2ecf20Sopenharmony_ci#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
5028c2ecf20Sopenharmony_ci#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1 16
5038c2ecf20Sopenharmony_ci#endif
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci	if (port < CVMX_PKO_MAX_PORTS_INTERFACE0)
5068c2ecf20Sopenharmony_ci		return port * CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + core;
5078c2ecf20Sopenharmony_ci	else if (port >= 16 && port < 16 + CVMX_PKO_MAX_PORTS_INTERFACE1)
5088c2ecf20Sopenharmony_ci		return CVMX_PKO_MAX_PORTS_INTERFACE0 *
5098c2ecf20Sopenharmony_ci		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + (port -
5108c2ecf20Sopenharmony_ci							   16) *
5118c2ecf20Sopenharmony_ci		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + core;
5128c2ecf20Sopenharmony_ci	else if ((port >= 32) && (port < 36))
5138c2ecf20Sopenharmony_ci		return CVMX_PKO_MAX_PORTS_INTERFACE0 *
5148c2ecf20Sopenharmony_ci		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
5158c2ecf20Sopenharmony_ci		    CVMX_PKO_MAX_PORTS_INTERFACE1 *
5168c2ecf20Sopenharmony_ci		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + (port -
5178c2ecf20Sopenharmony_ci							   32) *
5188c2ecf20Sopenharmony_ci		    CVMX_PKO_QUEUES_PER_PORT_PCI;
5198c2ecf20Sopenharmony_ci	else if ((port >= 36) && (port < 40))
5208c2ecf20Sopenharmony_ci		return CVMX_PKO_MAX_PORTS_INTERFACE0 *
5218c2ecf20Sopenharmony_ci		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
5228c2ecf20Sopenharmony_ci		    CVMX_PKO_MAX_PORTS_INTERFACE1 *
5238c2ecf20Sopenharmony_ci		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 +
5248c2ecf20Sopenharmony_ci		    4 * CVMX_PKO_QUEUES_PER_PORT_PCI + (port -
5258c2ecf20Sopenharmony_ci							36) *
5268c2ecf20Sopenharmony_ci		    CVMX_PKO_QUEUES_PER_PORT_LOOP;
5278c2ecf20Sopenharmony_ci	else
5288c2ecf20Sopenharmony_ci		/* Given the limit on the number of ports we can map to
5298c2ecf20Sopenharmony_ci		 * CVMX_MAX_OUTPUT_QUEUES_STATIC queues (currently 256,
5308c2ecf20Sopenharmony_ci		 * divided among all cores), the remaining unmapped ports
5318c2ecf20Sopenharmony_ci		 * are assigned an illegal queue number */
5328c2ecf20Sopenharmony_ci		return CVMX_PKO_ILLEGAL_QUEUE;
5338c2ecf20Sopenharmony_ci}
5348c2ecf20Sopenharmony_ci
5358c2ecf20Sopenharmony_ci/**
5368c2ecf20Sopenharmony_ci * For a given port number, return the base pko output queue
5378c2ecf20Sopenharmony_ci * for the port.
5388c2ecf20Sopenharmony_ci *
5398c2ecf20Sopenharmony_ci * @port:   Port number
5408c2ecf20Sopenharmony_ci * Returns Base output queue
5418c2ecf20Sopenharmony_ci */
5428c2ecf20Sopenharmony_cistatic inline int cvmx_pko_get_base_queue(int port)
5438c2ecf20Sopenharmony_ci{
5448c2ecf20Sopenharmony_ci	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
5458c2ecf20Sopenharmony_ci		return port;
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_ci	return cvmx_pko_get_base_queue_per_core(port, 0);
5488c2ecf20Sopenharmony_ci}
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_ci/**
5518c2ecf20Sopenharmony_ci * For a given port number, return the number of pko output queues.
5528c2ecf20Sopenharmony_ci *
5538c2ecf20Sopenharmony_ci * @port:   Port number
5548c2ecf20Sopenharmony_ci * Returns Number of output queues
5558c2ecf20Sopenharmony_ci */
5568c2ecf20Sopenharmony_cistatic inline int cvmx_pko_get_num_queues(int port)
5578c2ecf20Sopenharmony_ci{
5588c2ecf20Sopenharmony_ci	if (port < 16)
5598c2ecf20Sopenharmony_ci		return CVMX_PKO_QUEUES_PER_PORT_INTERFACE0;
5608c2ecf20Sopenharmony_ci	else if (port < 32)
5618c2ecf20Sopenharmony_ci		return CVMX_PKO_QUEUES_PER_PORT_INTERFACE1;
5628c2ecf20Sopenharmony_ci	else if (port < 36)
5638c2ecf20Sopenharmony_ci		return CVMX_PKO_QUEUES_PER_PORT_PCI;
5648c2ecf20Sopenharmony_ci	else if (port < 40)
5658c2ecf20Sopenharmony_ci		return CVMX_PKO_QUEUES_PER_PORT_LOOP;
5668c2ecf20Sopenharmony_ci	else
5678c2ecf20Sopenharmony_ci		return 0;
5688c2ecf20Sopenharmony_ci}
5698c2ecf20Sopenharmony_ci
5708c2ecf20Sopenharmony_ci/**
5718c2ecf20Sopenharmony_ci * Get the status counters for a port.
5728c2ecf20Sopenharmony_ci *
5738c2ecf20Sopenharmony_ci * @port_num: Port number to get statistics for.
5748c2ecf20Sopenharmony_ci * @clear:    Set to 1 to clear the counters after they are read
5758c2ecf20Sopenharmony_ci * @status:   Where to put the results.
5768c2ecf20Sopenharmony_ci */
5778c2ecf20Sopenharmony_cistatic inline void cvmx_pko_get_port_status(uint64_t port_num, uint64_t clear,
5788c2ecf20Sopenharmony_ci					    cvmx_pko_port_status_t *status)
5798c2ecf20Sopenharmony_ci{
5808c2ecf20Sopenharmony_ci	union cvmx_pko_reg_read_idx pko_reg_read_idx;
5818c2ecf20Sopenharmony_ci	union cvmx_pko_mem_count0 pko_mem_count0;
5828c2ecf20Sopenharmony_ci	union cvmx_pko_mem_count1 pko_mem_count1;
5838c2ecf20Sopenharmony_ci
5848c2ecf20Sopenharmony_ci	pko_reg_read_idx.u64 = 0;
5858c2ecf20Sopenharmony_ci	pko_reg_read_idx.s.index = port_num;
5868c2ecf20Sopenharmony_ci	cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
5878c2ecf20Sopenharmony_ci
5888c2ecf20Sopenharmony_ci	pko_mem_count0.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT0);
5898c2ecf20Sopenharmony_ci	status->packets = pko_mem_count0.s.count;
5908c2ecf20Sopenharmony_ci	if (clear) {
5918c2ecf20Sopenharmony_ci		pko_mem_count0.s.count = port_num;
5928c2ecf20Sopenharmony_ci		cvmx_write_csr(CVMX_PKO_MEM_COUNT0, pko_mem_count0.u64);
5938c2ecf20Sopenharmony_ci	}
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci	pko_mem_count1.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT1);
5968c2ecf20Sopenharmony_ci	status->octets = pko_mem_count1.s.count;
5978c2ecf20Sopenharmony_ci	if (clear) {
5988c2ecf20Sopenharmony_ci		pko_mem_count1.s.count = port_num;
5998c2ecf20Sopenharmony_ci		cvmx_write_csr(CVMX_PKO_MEM_COUNT1, pko_mem_count1.u64);
6008c2ecf20Sopenharmony_ci	}
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_ci	if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
6038c2ecf20Sopenharmony_ci		union cvmx_pko_mem_debug9 debug9;
6048c2ecf20Sopenharmony_ci		pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
6058c2ecf20Sopenharmony_ci		cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
6068c2ecf20Sopenharmony_ci		debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
6078c2ecf20Sopenharmony_ci		status->doorbell = debug9.cn38xx.doorbell;
6088c2ecf20Sopenharmony_ci	} else {
6098c2ecf20Sopenharmony_ci		union cvmx_pko_mem_debug8 debug8;
6108c2ecf20Sopenharmony_ci		pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
6118c2ecf20Sopenharmony_ci		cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
6128c2ecf20Sopenharmony_ci		debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
6138c2ecf20Sopenharmony_ci		status->doorbell = debug8.cn50xx.doorbell;
6148c2ecf20Sopenharmony_ci	}
6158c2ecf20Sopenharmony_ci}
6168c2ecf20Sopenharmony_ci
6178c2ecf20Sopenharmony_ci/**
6188c2ecf20Sopenharmony_ci * Rate limit a PKO port to a max packets/sec. This function is only
6198c2ecf20Sopenharmony_ci * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
6208c2ecf20Sopenharmony_ci *
6218c2ecf20Sopenharmony_ci * @port:      Port to rate limit
6228c2ecf20Sopenharmony_ci * @packets_s: Maximum packet/sec
6238c2ecf20Sopenharmony_ci * @burst:     Maximum number of packets to burst in a row before rate
6248c2ecf20Sopenharmony_ci *		    limiting cuts in.
6258c2ecf20Sopenharmony_ci *
6268c2ecf20Sopenharmony_ci * Returns Zero on success, negative on failure
6278c2ecf20Sopenharmony_ci */
6288c2ecf20Sopenharmony_ciextern int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst);
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_ci/**
6318c2ecf20Sopenharmony_ci * Rate limit a PKO port to a max bits/sec. This function is only
6328c2ecf20Sopenharmony_ci * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
6338c2ecf20Sopenharmony_ci *
6348c2ecf20Sopenharmony_ci * @port:   Port to rate limit
6358c2ecf20Sopenharmony_ci * @bits_s: PKO rate limit in bits/sec
6368c2ecf20Sopenharmony_ci * @burst:  Maximum number of bits to burst before rate
6378c2ecf20Sopenharmony_ci *		 limiting cuts in.
6388c2ecf20Sopenharmony_ci *
6398c2ecf20Sopenharmony_ci * Returns Zero on success, negative on failure
6408c2ecf20Sopenharmony_ci */
6418c2ecf20Sopenharmony_ciextern int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst);
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci#endif /* __CVMX_PKO_H__ */
644