mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 18:35:42 +01:00 
			
		
		
		
	Import cvmx-helper-pko.c from 2013 U-Boot. It will be used by the later added drivers to support networking on the MIPS Octeon II / III platforms. Signed-off-by: Aaron Williams <awilliams@marvell.com> Signed-off-by: Stefan Roese <sr@denx.de>
		
			
				
	
	
		
			204 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0
 | |
| /*
 | |
|  * Copyright (C) 2018-2022 Marvell International Ltd.
 | |
|  *
 | |
|  * Helper Functions for the PKO
 | |
|  */
 | |
| 
 | |
| #include <errno.h>
 | |
| #include <log.h>
 | |
| #include <time.h>
 | |
| #include <linux/delay.h>
 | |
| 
 | |
| #include <mach/cvmx-regs.h>
 | |
| #include <mach/cvmx-csr.h>
 | |
| #include <mach/cvmx-bootmem.h>
 | |
| #include <mach/octeon-model.h>
 | |
| #include <mach/cvmx-fuse.h>
 | |
| #include <mach/octeon-feature.h>
 | |
| #include <mach/cvmx-qlm.h>
 | |
| #include <mach/octeon_qlm.h>
 | |
| #include <mach/cvmx-pcie.h>
 | |
| #include <mach/cvmx-coremask.h>
 | |
| #include <mach/cvmx-range.h>
 | |
| #include <mach/cvmx-global-resources.h>
 | |
| 
 | |
| #include <mach/cvmx-agl-defs.h>
 | |
| #include <mach/cvmx-bgxx-defs.h>
 | |
| #include <mach/cvmx-ciu-defs.h>
 | |
| #include <mach/cvmx-gmxx-defs.h>
 | |
| #include <mach/cvmx-gserx-defs.h>
 | |
| #include <mach/cvmx-ilk-defs.h>
 | |
| #include <mach/cvmx-ipd-defs.h>
 | |
| #include <mach/cvmx-pcsx-defs.h>
 | |
| #include <mach/cvmx-pcsxx-defs.h>
 | |
| #include <mach/cvmx-pki-defs.h>
 | |
| #include <mach/cvmx-pko-defs.h>
 | |
| #include <mach/cvmx-xcv-defs.h>
 | |
| 
 | |
| #include <mach/cvmx-hwpko.h>
 | |
| #include <mach/cvmx-ilk.h>
 | |
| #include <mach/cvmx-ipd.h>
 | |
| #include <mach/cvmx-pki.h>
 | |
| #include <mach/cvmx-pko3.h>
 | |
| #include <mach/cvmx-pko3-queue.h>
 | |
| #include <mach/cvmx-pko3-resources.h>
 | |
| 
 | |
| #include <mach/cvmx-helper.h>
 | |
| #include <mach/cvmx-helper-board.h>
 | |
| #include <mach/cvmx-helper-cfg.h>
 | |
| 
 | |
| #include <mach/cvmx-helper-bgx.h>
 | |
| #include <mach/cvmx-helper-cfg.h>
 | |
| #include <mach/cvmx-helper-util.h>
 | |
| #include <mach/cvmx-helper-pki.h>
 | |
| 
 | |
| 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.
 | |
| 	 */
 | |
| }
 |