Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /***********************license start***************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Author: Cavium Networks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Contact: support@caviumnetworks.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * This file is part of the OCTEON SDK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (c) 2003-2008 Cavium Networks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * This file is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * it under the terms of the GNU General Public License, Version 2, as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * This file is distributed in the hope that it will be useful, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * NONINFRINGEMENT.  See the GNU General Public License for more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * along with this file; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * or visit http://www.gnu.org/licenses/.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * This file may also be available under a different license from Cavium.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * Contact Cavium Networks for more information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  ***********************license end**************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * Support library for the hardware Packet Output unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <asm/octeon/octeon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <asm/octeon/cvmx-config.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <asm/octeon/cvmx-pko.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <asm/octeon/cvmx-helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * Internal state of packet output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static int __cvmx_pko_int(int interface, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	switch (interface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		return 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		return index + 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		return index + 0x0c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		return index + 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		return 0x1c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		return 0x1d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		return 0x1e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		return 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) static void __cvmx_pko_iport_config(int pko_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	int queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	const int num_queues = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	const int base_queue = pko_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	const int static_priority_end = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	const int static_priority_base = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	for (queue = 0; queue < num_queues; queue++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		union cvmx_pko_mem_iqueue_ptrs config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		cvmx_cmd_queue_result_t cmd_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		uint64_t *buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		config.u64		= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		config.s.index		= queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		config.s.qid		= base_queue + queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		config.s.ipid		= pko_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		config.s.tail		= (queue == (num_queues - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		config.s.s_tail		= (queue == static_priority_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		config.s.static_p	= (static_priority_base >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		config.s.static_q	= (queue <= static_priority_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		config.s.qos_mask	= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		cmd_res = cvmx_cmd_queue_initialize(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 				CVMX_CMD_QUEUE_PKO(base_queue + queue),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 				CVMX_PKO_MAX_QUEUE_DEPTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 				CVMX_FPA_OUTPUT_BUFFER_POOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 				(CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 				 CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST * 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		WARN(cmd_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		     "%s: cmd_res=%d pko_port=%d base_queue=%d num_queues=%d queue=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			__func__, (int)cmd_res, pko_port, base_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			num_queues, queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		buf_ptr = (uint64_t *)cvmx_cmd_queue_buffer(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 				CVMX_CMD_QUEUE_PKO(base_queue + queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		config.s.buf_ptr = cvmx_ptr_to_phys(buf_ptr) >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		CVMX_SYNCWS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		cvmx_write_csr(CVMX_PKO_MEM_IQUEUE_PTRS, config.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static void __cvmx_pko_queue_alloc_o68(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	for (port = 0; port < 48; port++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		__cvmx_pko_iport_config(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static void __cvmx_pko_port_map_o68(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	int interface, index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	cvmx_helper_interface_mode_t mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	union cvmx_pko_mem_iport_ptrs config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	 * Initialize every iport with the invalid eid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	config.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	config.s.eid = 31; /* Invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	for (port = 0; port < 128; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		config.s.ipid = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		cvmx_write_csr(CVMX_PKO_MEM_IPORT_PTRS, config.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	 * Set up PKO_MEM_IPORT_PTRS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	for (port = 0; port < 48; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		interface = cvmx_helper_get_interface_num(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		index = cvmx_helper_get_interface_index_num(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		mode = cvmx_helper_interface_get_mode(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		if (mode == CVMX_HELPER_INTERFACE_MODE_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		config.s.ipid = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		config.s.qos_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		config.s.crc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		config.s.min_pkt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		config.s.intr = __cvmx_pko_int(interface, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		config.s.eid = config.s.intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		config.s.pipe = (mode == CVMX_HELPER_INTERFACE_MODE_LOOP) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			index : port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		cvmx_write_csr(CVMX_PKO_MEM_IPORT_PTRS, config.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static void __cvmx_pko_chip_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		__cvmx_pko_port_map_o68();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		__cvmx_pko_queue_alloc_o68();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	 * Initialize queues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	for (i = 0; i < CVMX_PKO_MAX_OUTPUT_QUEUES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		const uint64_t priority = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		cvmx_pko_config_port(CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID, i, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 				     &priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  * Call before any other calls to initialize the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * output system.  This does chip global config, and should only be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  * done by one core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) void cvmx_pko_initialize_global(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	union cvmx_pko_reg_cmd_buf config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	 * Set the size of the PKO command buffers to an odd number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	 * 64bit words. This allows the normal two word send to stay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	 * aligned and never span a command word buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	config.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	config.s.pool = CVMX_FPA_OUTPUT_BUFFER_POOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	config.s.size = CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE / 8 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	cvmx_write_csr(CVMX_PKO_REG_CMD_BUF, config.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	 * Chip-specific setup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	__cvmx_pko_chip_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	 * If we aren't using all of the queues optimize PKO's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	 * internal memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	    || OCTEON_IS_MODEL(OCTEON_CN56XX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	    || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		int num_interfaces = cvmx_helper_get_number_of_interfaces();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		int last_port =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		    cvmx_helper_get_last_ipd_port(num_interfaces - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		int max_queues =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		    cvmx_pko_get_base_queue(last_port) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		    cvmx_pko_get_num_queues(last_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			if (max_queues <= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 				cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			else if (max_queues <= 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 				cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			if (max_queues <= 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 				cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			else if (max_queues <= 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 				cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)  * This function does per-core initialization required by the PKO routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)  * This must be called on all cores that will do packet output, and must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  * be called after the FPA has been initialized and filled with pages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  * Returns 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)  *	   !0 on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int cvmx_pko_initialize_local(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	/* Nothing to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  * Enables the packet output hardware. It must already be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  * configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) void cvmx_pko_enable(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	union cvmx_pko_reg_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	if (flags.s.ena_pko)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		cvmx_dprintf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		    ("Warning: Enabling PKO when PKO already enabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	flags.s.ena_dwb = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	flags.s.ena_pko = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	 * always enable big endian for 3-word command. Does nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	 * for 2-word.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	flags.s.store_be = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	cvmx_write_csr(CVMX_PKO_REG_FLAGS, flags.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  * Disables the packet output. Does not affect any configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) void cvmx_pko_disable(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	union cvmx_pko_reg_flags pko_reg_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	pko_reg_flags.s.ena_pko = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) EXPORT_SYMBOL_GPL(cvmx_pko_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  * Reset the packet output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static void __cvmx_pko_reset(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	union cvmx_pko_reg_flags pko_reg_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	pko_reg_flags.s.reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)  * Shutdown and free resources required by packet output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) void cvmx_pko_shutdown(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	union cvmx_pko_mem_queue_ptrs config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	int queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	cvmx_pko_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	for (queue = 0; queue < CVMX_PKO_MAX_OUTPUT_QUEUES; queue++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		config.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		config.s.tail = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		config.s.index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		config.s.port = CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		config.s.queue = queue & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		config.s.qos_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		config.s.buf_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			union cvmx_pko_reg_queue_ptrs1 config1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 			config1.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			config1.s.qid7 = queue >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		cvmx_cmd_queue_shutdown(CVMX_CMD_QUEUE_PKO(queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	__cvmx_pko_reset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) EXPORT_SYMBOL_GPL(cvmx_pko_shutdown);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)  * Configure a output port and the associated queues for use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)  * @port:	Port to configure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)  * @base_queue: First queue number to associate with this port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)  * @num_queues: Number of queues to associate with this port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)  * @priority:	Array of priority levels for each queue. Values are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)  *		     allowed to be 0-8. A value of 8 get 8 times the traffic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)  *		     of a value of 1.  A value of 0 indicates that no rounds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)  *		     will be participated in. These priorities can be changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)  *		     on the fly while the pko is enabled. A priority of 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)  *		     indicates that static priority should be used.  If static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)  *		     priority is used all queues with static priority must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)  *		     contiguous starting at the base_queue, and lower numbered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)  *		     queues have higher priority than higher numbered queues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  *		     There must be num_queues elements in the array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) cvmx_pko_status_t cvmx_pko_config_port(uint64_t port, uint64_t base_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 				       uint64_t num_queues,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 				       const uint64_t priority[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	cvmx_pko_status_t result_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	uint64_t queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	union cvmx_pko_mem_queue_ptrs config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	union cvmx_pko_reg_queue_ptrs1 config1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	int static_priority_base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	int static_priority_end = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		return CVMX_PKO_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	if ((port >= CVMX_PKO_NUM_OUTPUT_PORTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	    && (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid port %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			     (unsigned long long)port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		return CVMX_PKO_INVALID_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	if (base_queue + num_queues > CVMX_PKO_MAX_OUTPUT_QUEUES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		cvmx_dprintf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		    ("ERROR: cvmx_pko_config_port: Invalid queue range %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		     (unsigned long long)(base_queue + num_queues));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		return CVMX_PKO_INVALID_QUEUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		 * Validate the static queue priority setup and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		 * static_priority_base and static_priority_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		 * accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		for (queue = 0; queue < num_queues; queue++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			/* Find first queue of static priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			if (static_priority_base == -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			    && priority[queue] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			    CVMX_PKO_QUEUE_STATIC_PRIORITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 				static_priority_base = queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			/* Find last queue of static priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			if (static_priority_base != -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 			    && static_priority_end == -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			    && priority[queue] != CVMX_PKO_QUEUE_STATIC_PRIORITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			    && queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 				static_priority_end = queue - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 			else if (static_priority_base != -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 				 && static_priority_end == -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 				 && queue == num_queues - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 				/* all queues are static priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 				static_priority_end = queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 			 * Check to make sure all static priority
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			 * queues are contiguous.  Also catches some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 			 * cases of static priorites not starting at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 			 * queue 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 			if (static_priority_end != -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			    && (int)queue > static_priority_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 			    && priority[queue] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			    CVMX_PKO_QUEUE_STATIC_PRIORITY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 				cvmx_dprintf("ERROR: cvmx_pko_config_port: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 					     "Static priority queues aren't "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 					     "contiguous or don't start at "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 					     "base queue. q: %d, eq: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 					(int)queue, static_priority_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 				return CVMX_PKO_INVALID_PRIORITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		if (static_priority_base > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 			cvmx_dprintf("ERROR: cvmx_pko_config_port: Static "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 				     "priority queues don't start at base "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 				     "queue. sq: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 				static_priority_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			return CVMX_PKO_INVALID_PRIORITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		cvmx_dprintf("Port %d: Static priority queue base: %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			     "end: %d\n", port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			static_priority_base, static_priority_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	 * At this point, static_priority_base and static_priority_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	 * are either both -1, or are valid start/end queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	 * numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	result_code = CVMX_PKO_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) #ifdef PKO_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	cvmx_dprintf("num queues: %d (%lld,%lld)\n", num_queues,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		     CVMX_PKO_QUEUES_PER_PORT_INTERFACE0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		     CVMX_PKO_QUEUES_PER_PORT_INTERFACE1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	for (queue = 0; queue < num_queues; queue++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		uint64_t *buf_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		config1.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		config1.s.idx3 = queue >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		config1.s.qid7 = (base_queue + queue) >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		config.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		config.s.tail = queue == (num_queues - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		config.s.index = queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		config.s.port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		config.s.queue = base_queue + queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		if (!cvmx_octeon_is_pass1()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			config.s.static_p = static_priority_base >= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			config.s.static_q = (int)queue <= static_priority_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			config.s.s_tail = (int)queue == static_priority_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		 * Convert the priority into an enable bit field. Try
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		 * to space the bits out evenly so the packet don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		 * get grouped up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		switch ((int)priority[queue]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 			config.s.qos_mask = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 			config.s.qos_mask = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 			config.s.qos_mask = 0x11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			config.s.qos_mask = 0x49;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 			config.s.qos_mask = 0x55;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 			config.s.qos_mask = 0x57;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			config.s.qos_mask = 0x77;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 			config.s.qos_mask = 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			config.s.qos_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		case CVMX_PKO_QUEUE_STATIC_PRIORITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 			if (!cvmx_octeon_is_pass1()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 				config.s.qos_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 			fallthrough;	/* to the error case, when Pass 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 			cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 				     "priority %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 				(unsigned long long)priority[queue]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 			config.s.qos_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 			result_code = CVMX_PKO_INVALID_PRIORITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 			cvmx_cmd_queue_result_t cmd_res =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 			    cvmx_cmd_queue_initialize(CVMX_CMD_QUEUE_PKO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 						      (base_queue + queue),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 						      CVMX_PKO_MAX_QUEUE_DEPTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 						      CVMX_FPA_OUTPUT_BUFFER_POOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 						      CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 						      -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 						      CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 						      * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 			if (cmd_res != CVMX_CMD_QUEUE_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 				switch (cmd_res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 				case CVMX_CMD_QUEUE_NO_MEMORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 					cvmx_dprintf("ERROR: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 						     "cvmx_pko_config_port: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 						     "Unable to allocate "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 						     "output buffer.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 					return CVMX_PKO_NO_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 				case CVMX_CMD_QUEUE_ALREADY_SETUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 					cvmx_dprintf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 					    ("ERROR: cvmx_pko_config_port: Port already setup.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 					return CVMX_PKO_PORT_ALREADY_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 				case CVMX_CMD_QUEUE_INVALID_PARAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 				default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 					cvmx_dprintf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 					    ("ERROR: cvmx_pko_config_port: Command queue initialization failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 					return CVMX_PKO_CMD_QUEUE_INIT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 			buf_ptr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 			    (uint64_t *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 			    cvmx_cmd_queue_buffer(CVMX_CMD_QUEUE_PKO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 						  (base_queue + queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			config.s.buf_ptr = cvmx_ptr_to_phys(buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 			config.s.buf_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		CVMX_SYNCWS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		if (!OCTEON_IS_MODEL(OCTEON_CN3XXX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 			cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	return result_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) #ifdef PKO_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)  * Show map of ports -> queues for different cores.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) void cvmx_pko_show_queue_map()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	int core, port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	int pko_output_ports = 36;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	cvmx_dprintf("port");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	for (port = 0; port < pko_output_ports; port++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		cvmx_dprintf("%3d ", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	cvmx_dprintf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	for (core = 0; core < CVMX_MAX_CORES; core++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		cvmx_dprintf("\n%2d: ", core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		for (port = 0; port < pko_output_ports; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			cvmx_dprintf("%3d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 				     cvmx_pko_get_base_queue_per_core(port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 								      core));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	cvmx_dprintf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)  * Rate limit a PKO port to a max packets/sec. This function is only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)  * supported on CN51XX and higher, excluding CN58XX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)  * @port:      Port to rate limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)  * @packets_s: Maximum packet/sec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)  * @burst:     Maximum number of packets to burst in a row before rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)  *		    limiting cuts in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)  * Returns Zero on success, negative on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	union cvmx_pko_mem_port_rate0 pko_mem_port_rate0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	union cvmx_pko_mem_port_rate1 pko_mem_port_rate1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	pko_mem_port_rate0.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	pko_mem_port_rate0.s.pid = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	pko_mem_port_rate0.s.rate_pkt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	    cvmx_sysinfo_get()->cpu_clock_hz / packets_s / 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	/* No cost per word since we are limited by packets/sec, not bits/sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	pko_mem_port_rate0.s.rate_word = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	pko_mem_port_rate1.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	pko_mem_port_rate1.s.pid = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	pko_mem_port_rate1.s.rate_lim =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	    ((uint64_t) pko_mem_port_rate0.s.rate_pkt * burst) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)  * Rate limit a PKO port to a max bits/sec. This function is only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)  * supported on CN51XX and higher, excluding CN58XX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)  * @port:   Port to rate limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)  * @bits_s: PKO rate limit in bits/sec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)  * @burst:  Maximum number of bits to burst before rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)  *		 limiting cuts in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)  * Returns Zero on success, negative on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	union cvmx_pko_mem_port_rate0 pko_mem_port_rate0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	union cvmx_pko_mem_port_rate1 pko_mem_port_rate1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	uint64_t clock_rate = cvmx_sysinfo_get()->cpu_clock_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	uint64_t tokens_per_bit = clock_rate * 16 / bits_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	pko_mem_port_rate0.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	pko_mem_port_rate0.s.pid = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	 * Each packet has a 12 bytes of interframe gap, an 8 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	 * preamble, and a 4 byte CRC. These are not included in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	 * per word count. Multiply by 8 to covert to bits and divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	 * by 256 for limit granularity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	pko_mem_port_rate0.s.rate_pkt = (12 + 8 + 4) * 8 * tokens_per_bit / 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	/* Each 8 byte word has 64bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	pko_mem_port_rate0.s.rate_word = 64 * tokens_per_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	pko_mem_port_rate1.u64 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	pko_mem_port_rate1.s.pid = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	pko_mem_port_rate1.s.rate_lim = tokens_per_bit * burst / 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }