1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2018-2022 Marvell International Ltd. 4 * 5 * Helper Functions for the PKO 6 */ 7 8#include <errno.h> 9#include <log.h> 10#include <time.h> 11#include <linux/delay.h> 12 13#include <mach/cvmx-regs.h> 14#include <mach/cvmx-csr.h> 15#include <mach/cvmx-bootmem.h> 16#include <mach/octeon-model.h> 17#include <mach/cvmx-fuse.h> 18#include <mach/octeon-feature.h> 19#include <mach/cvmx-qlm.h> 20#include <mach/octeon_qlm.h> 21#include <mach/cvmx-pcie.h> 22#include <mach/cvmx-coremask.h> 23#include <mach/cvmx-range.h> 24#include <mach/cvmx-global-resources.h> 25 26#include <mach/cvmx-agl-defs.h> 27#include <mach/cvmx-bgxx-defs.h> 28#include <mach/cvmx-ciu-defs.h> 29#include <mach/cvmx-gmxx-defs.h> 30#include <mach/cvmx-gserx-defs.h> 31#include <mach/cvmx-ilk-defs.h> 32#include <mach/cvmx-ipd-defs.h> 33#include <mach/cvmx-pcsx-defs.h> 34#include <mach/cvmx-pcsxx-defs.h> 35#include <mach/cvmx-pki-defs.h> 36#include <mach/cvmx-pko-defs.h> 37#include <mach/cvmx-xcv-defs.h> 38 39#include <mach/cvmx-hwpko.h> 40#include <mach/cvmx-ilk.h> 41#include <mach/cvmx-ipd.h> 42#include <mach/cvmx-pki.h> 43#include <mach/cvmx-pko3.h> 44#include <mach/cvmx-pko3-queue.h> 45#include <mach/cvmx-pko3-resources.h> 46 47#include <mach/cvmx-helper.h> 48#include <mach/cvmx-helper-board.h> 49#include <mach/cvmx-helper-cfg.h> 50 51#include <mach/cvmx-helper-bgx.h> 52#include <mach/cvmx-helper-cfg.h> 53#include <mach/cvmx-helper-util.h> 54#include <mach/cvmx-helper-pki.h> 55 56static s64 pko_fpa_config_pool = -1; 57static u64 pko_fpa_config_size = 1024; 58 59/** 60 * cvmx_override_pko_queue_priority(int pko_port, u64 61 * priorities[16]) is a function pointer. It is meant to allow 62 * customization of the PKO queue priorities based on the port 63 * number. Users should set this pointer to a function before 64 * calling any cvmx-helper operations. 65 */ 66void (*cvmx_override_pko_queue_priority)(int ipd_port, 67 uint8_t *priorities) = NULL; 68 69int64_t cvmx_fpa_get_pko_pool(void) 70{ 71 return pko_fpa_config_pool; 72} 73 74/** 75 * Gets the buffer size of pko pool 76 */ 77u64 cvmx_fpa_get_pko_pool_block_size(void) 78{ 79 return pko_fpa_config_size; 80} 81 82/** 83 * Initialize PKO command queue buffer pool 84 */ 85static int cvmx_helper_pko_pool_init(void) 86{ 87 u8 pool; 88 unsigned int buf_count; 89 unsigned int pkt_buf_count; 90 int rc; 91 92 /* Reserve pool */ 93 pool = cvmx_fpa_get_pko_pool(); 94 95 /* Avoid redundant pool creation */ 96 if (cvmx_fpa_get_block_size(pool) > 0) { 97#ifdef DEBUG 98 debug("WARNING: %s: pool %d already initialized\n", __func__, 99 pool); 100#endif 101 /* It is up to the app to have sufficient buffer count */ 102 return pool; 103 } 104 105 /* Calculate buffer count: one per queue + 3-word-cmds * max_pkts */ 106 pkt_buf_count = cvmx_fpa_get_packet_pool_buffer_count(); 107 buf_count = CVMX_PKO_MAX_OUTPUT_QUEUES + (pkt_buf_count * 3) / 8; 108 109 /* Allocate pools for pko command queues */ 110 rc = __cvmx_helper_initialize_fpa_pool(pool, 111 cvmx_fpa_get_pko_pool_block_size(), 112 buf_count, "PKO Cmd-bufs"); 113 114 if (rc < 0) 115 debug("%s: ERROR: in PKO buffer pool\n", __func__); 116 117 pool = rc; 118 return pool; 119} 120 121/** 122 * Initialize the PKO 123 * 124 */ 125int cvmx_helper_pko_init(void) 126{ 127 int rc; 128 129 rc = cvmx_helper_pko_pool_init(); 130 if (rc < 0) 131 return rc; 132 133 __cvmx_helper_init_port_config_data(0); 134 135 cvmx_pko_hw_init(cvmx_fpa_get_pko_pool(), 136 cvmx_fpa_get_pko_pool_block_size()); 137 return 0; 138} 139 140/** 141 * @INTERNAL 142 * Setup the PKO for the ports on an interface. The number of 143 * queues per port and the priority of each PKO output queue 144 * is set here. PKO must be disabled when this function is called. 145 * 146 * @param interface to setup PKO for 147 * 148 * @return Zero on success, negative on failure 149 * 150 * @note This is for PKO1/PKO2, and is not used for PKO3. 151 */ 152int __cvmx_helper_interface_setup_pko(int interface) 153{ 154 /* 155 * Each packet output queue has an associated priority. The 156 * higher the priority, the more often it can send a packet. A 157 * priority of 8 means it can send in all 8 rounds of 158 * contention. We're going to make each queue one less than 159 * the last. The vector of priorities has been extended to 160 * support CN5xxx CPUs, where up to 16 queues can be 161 * associated to a port. To keep backward compatibility we 162 * don't change the initial 8 priorities and replicate them in 163 * the second half. With per-core PKO queues (PKO lockless 164 * operation) all queues have the same priority. 165 */ 166 /* uint8_t priorities[16] = {8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1}; */ 167 u8 priorities[16] = { [0 ... 15] = 8 }; 168 169 /* 170 * Setup the IPD/PIP and PKO for the ports discovered 171 * above. Here packet classification, tagging and output 172 * priorities are set. 173 */ 174 int num_ports = cvmx_helper_ports_on_interface(interface); 175 176 while (num_ports--) { 177 int ipd_port; 178 179 if (!cvmx_helper_is_port_valid(interface, num_ports)) 180 continue; 181 182 ipd_port = cvmx_helper_get_ipd_port(interface, num_ports); 183 /* 184 * Give the user a chance to override the per queue 185 * priorities. 186 */ 187 if (cvmx_override_pko_queue_priority) 188 cvmx_override_pko_queue_priority(ipd_port, priorities); 189 190 cvmx_pko_config_port(ipd_port, 191 cvmx_pko_get_base_queue(ipd_port), 192 cvmx_pko_get_num_queues(ipd_port), 193 priorities); 194 ipd_port++; 195 } 196 return 0; 197 /* NOTE: 198 * Now this function is called for all chips including 68xx, 199 * but on the 68xx it does not enable multiple pko_iports per 200 * eport, while before it was doing 3 pko_iport per eport 201 * buf the reason for that is not clear. 202 */ 203} 204