// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2018-2022 Marvell International Ltd. * * Helper Functions for the PKO */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static s64 pko_fpa_config_pool = -1; static u64 pko_fpa_config_size = 1024; /** * cvmx_override_pko_queue_priority(int pko_port, u64 * priorities[16]) is a function pointer. It is meant to allow * customization of the PKO queue priorities based on the port * number. Users should set this pointer to a function before * calling any cvmx-helper operations. */ void (*cvmx_override_pko_queue_priority)(int ipd_port, uint8_t *priorities) = NULL; int64_t cvmx_fpa_get_pko_pool(void) { return pko_fpa_config_pool; } /** * Gets the buffer size of pko pool */ u64 cvmx_fpa_get_pko_pool_block_size(void) { return pko_fpa_config_size; } /** * Initialize PKO command queue buffer pool */ static int cvmx_helper_pko_pool_init(void) { u8 pool; unsigned int buf_count; unsigned int pkt_buf_count; int rc; /* Reserve pool */ pool = cvmx_fpa_get_pko_pool(); /* Avoid redundant pool creation */ if (cvmx_fpa_get_block_size(pool) > 0) { #ifdef DEBUG debug("WARNING: %s: pool %d already initialized\n", __func__, pool); #endif /* It is up to the app to have sufficient buffer count */ return pool; } /* Calculate buffer count: one per queue + 3-word-cmds * max_pkts */ pkt_buf_count = cvmx_fpa_get_packet_pool_buffer_count(); buf_count = CVMX_PKO_MAX_OUTPUT_QUEUES + (pkt_buf_count * 3) / 8; /* Allocate pools for pko command queues */ rc = __cvmx_helper_initialize_fpa_pool(pool, cvmx_fpa_get_pko_pool_block_size(), buf_count, "PKO Cmd-bufs"); if (rc < 0) debug("%s: ERROR: in PKO buffer pool\n", __func__); pool = rc; return pool; } /** * Initialize the PKO * */ int cvmx_helper_pko_init(void) { int rc; rc = cvmx_helper_pko_pool_init(); if (rc < 0) return rc; __cvmx_helper_init_port_config_data(0); cvmx_pko_hw_init(cvmx_fpa_get_pko_pool(), cvmx_fpa_get_pko_pool_block_size()); return 0; } /** * @INTERNAL * Setup the PKO for the ports on an interface. The number of * queues per port and the priority of each PKO output queue * is set here. PKO must be disabled when this function is called. * * @param interface to setup PKO for * * @return Zero on success, negative on failure * * @note This is for PKO1/PKO2, and is not used for PKO3. */ int __cvmx_helper_interface_setup_pko(int interface) { /* * Each packet output queue has an associated priority. The * higher the priority, the more often it can send a packet. A * priority of 8 means it can send in all 8 rounds of * contention. We're going to make each queue one less than * the last. The vector of priorities has been extended to * support CN5xxx CPUs, where up to 16 queues can be * associated to a port. To keep backward compatibility we * don't change the initial 8 priorities and replicate them in * the second half. With per-core PKO queues (PKO lockless * operation) all queues have the same priority. */ /* uint8_t priorities[16] = {8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1}; */ u8 priorities[16] = { [0 ... 15] = 8 }; /* * Setup the IPD/PIP and PKO for the ports discovered * above. Here packet classification, tagging and output * priorities are set. */ int num_ports = cvmx_helper_ports_on_interface(interface); while (num_ports--) { int ipd_port; if (!cvmx_helper_is_port_valid(interface, num_ports)) continue; ipd_port = cvmx_helper_get_ipd_port(interface, num_ports); /* * Give the user a chance to override the per queue * priorities. */ if (cvmx_override_pko_queue_priority) cvmx_override_pko_queue_priority(ipd_port, priorities); cvmx_pko_config_port(ipd_port, cvmx_pko_get_base_queue(ipd_port), cvmx_pko_get_num_queues(ipd_port), priorities); ipd_port++; } return 0; /* NOTE: * Now this function is called for all chips including 68xx, * but on the 68xx it does not enable multiple pko_iports per * eport, while before it was doing 3 pko_iport per eport * buf the reason for that is not clear. */ }