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 * Small helper utilities. 308c2ecf20Sopenharmony_ci */ 318c2ecf20Sopenharmony_ci#include <linux/kernel.h> 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#include <asm/octeon/octeon.h> 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-config.h> 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-fpa.h> 388c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-pip.h> 398c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-pko.h> 408c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-ipd.h> 418c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-spi.h> 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-helper.h> 448c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-helper-util.h> 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-ipd-defs.h> 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/** 498c2ecf20Sopenharmony_ci * Convert a interface mode into a human readable string 508c2ecf20Sopenharmony_ci * 518c2ecf20Sopenharmony_ci * @mode: Mode to convert 528c2ecf20Sopenharmony_ci * 538c2ecf20Sopenharmony_ci * Returns String 548c2ecf20Sopenharmony_ci */ 558c2ecf20Sopenharmony_ciconst char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t 568c2ecf20Sopenharmony_ci mode) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci switch (mode) { 598c2ecf20Sopenharmony_ci case CVMX_HELPER_INTERFACE_MODE_DISABLED: 608c2ecf20Sopenharmony_ci return "DISABLED"; 618c2ecf20Sopenharmony_ci case CVMX_HELPER_INTERFACE_MODE_RGMII: 628c2ecf20Sopenharmony_ci return "RGMII"; 638c2ecf20Sopenharmony_ci case CVMX_HELPER_INTERFACE_MODE_GMII: 648c2ecf20Sopenharmony_ci return "GMII"; 658c2ecf20Sopenharmony_ci case CVMX_HELPER_INTERFACE_MODE_SPI: 668c2ecf20Sopenharmony_ci return "SPI"; 678c2ecf20Sopenharmony_ci case CVMX_HELPER_INTERFACE_MODE_PCIE: 688c2ecf20Sopenharmony_ci return "PCIE"; 698c2ecf20Sopenharmony_ci case CVMX_HELPER_INTERFACE_MODE_XAUI: 708c2ecf20Sopenharmony_ci return "XAUI"; 718c2ecf20Sopenharmony_ci case CVMX_HELPER_INTERFACE_MODE_SGMII: 728c2ecf20Sopenharmony_ci return "SGMII"; 738c2ecf20Sopenharmony_ci case CVMX_HELPER_INTERFACE_MODE_PICMG: 748c2ecf20Sopenharmony_ci return "PICMG"; 758c2ecf20Sopenharmony_ci case CVMX_HELPER_INTERFACE_MODE_NPI: 768c2ecf20Sopenharmony_ci return "NPI"; 778c2ecf20Sopenharmony_ci case CVMX_HELPER_INTERFACE_MODE_LOOP: 788c2ecf20Sopenharmony_ci return "LOOP"; 798c2ecf20Sopenharmony_ci } 808c2ecf20Sopenharmony_ci return "UNKNOWN"; 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci/** 848c2ecf20Sopenharmony_ci * Setup Random Early Drop on a specific input queue 858c2ecf20Sopenharmony_ci * 868c2ecf20Sopenharmony_ci * @queue: Input queue to setup RED on (0-7) 878c2ecf20Sopenharmony_ci * @pass_thresh: 888c2ecf20Sopenharmony_ci * Packets will begin slowly dropping when there are less than 898c2ecf20Sopenharmony_ci * this many packet buffers free in FPA 0. 908c2ecf20Sopenharmony_ci * @drop_thresh: 918c2ecf20Sopenharmony_ci * All incoming packets will be dropped when there are less 928c2ecf20Sopenharmony_ci * than this many free packet buffers in FPA 0. 938c2ecf20Sopenharmony_ci * Returns Zero on success. Negative on failure 948c2ecf20Sopenharmony_ci */ 958c2ecf20Sopenharmony_cistatic int cvmx_helper_setup_red_queue(int queue, int pass_thresh, 968c2ecf20Sopenharmony_ci int drop_thresh) 978c2ecf20Sopenharmony_ci{ 988c2ecf20Sopenharmony_ci union cvmx_ipd_qosx_red_marks red_marks; 998c2ecf20Sopenharmony_ci union cvmx_ipd_red_quex_param red_param; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci /* Set RED to begin dropping packets when there are pass_thresh buffers 1028c2ecf20Sopenharmony_ci left. It will linearly drop more packets until reaching drop_thresh 1038c2ecf20Sopenharmony_ci buffers */ 1048c2ecf20Sopenharmony_ci red_marks.u64 = 0; 1058c2ecf20Sopenharmony_ci red_marks.s.drop = drop_thresh; 1068c2ecf20Sopenharmony_ci red_marks.s.pass = pass_thresh; 1078c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_IPD_QOSX_RED_MARKS(queue), red_marks.u64); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci /* Use the actual queue 0 counter, not the average */ 1108c2ecf20Sopenharmony_ci red_param.u64 = 0; 1118c2ecf20Sopenharmony_ci red_param.s.prb_con = 1128c2ecf20Sopenharmony_ci (255ul << 24) / (red_marks.s.pass - red_marks.s.drop); 1138c2ecf20Sopenharmony_ci red_param.s.avg_con = 1; 1148c2ecf20Sopenharmony_ci red_param.s.new_con = 255; 1158c2ecf20Sopenharmony_ci red_param.s.use_pcnt = 1; 1168c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_IPD_RED_QUEX_PARAM(queue), red_param.u64); 1178c2ecf20Sopenharmony_ci return 0; 1188c2ecf20Sopenharmony_ci} 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci/** 1218c2ecf20Sopenharmony_ci * Setup Random Early Drop to automatically begin dropping packets. 1228c2ecf20Sopenharmony_ci * 1238c2ecf20Sopenharmony_ci * @pass_thresh: 1248c2ecf20Sopenharmony_ci * Packets will begin slowly dropping when there are less than 1258c2ecf20Sopenharmony_ci * this many packet buffers free in FPA 0. 1268c2ecf20Sopenharmony_ci * @drop_thresh: 1278c2ecf20Sopenharmony_ci * All incoming packets will be dropped when there are less 1288c2ecf20Sopenharmony_ci * than this many free packet buffers in FPA 0. 1298c2ecf20Sopenharmony_ci * Returns Zero on success. Negative on failure 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_ciint cvmx_helper_setup_red(int pass_thresh, int drop_thresh) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci union cvmx_ipd_portx_bp_page_cnt page_cnt; 1348c2ecf20Sopenharmony_ci union cvmx_ipd_bp_prt_red_end ipd_bp_prt_red_end; 1358c2ecf20Sopenharmony_ci union cvmx_ipd_red_port_enable red_port_enable; 1368c2ecf20Sopenharmony_ci int queue; 1378c2ecf20Sopenharmony_ci int interface; 1388c2ecf20Sopenharmony_ci int port; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci /* Disable backpressure based on queued buffers. It needs SW support */ 1418c2ecf20Sopenharmony_ci page_cnt.u64 = 0; 1428c2ecf20Sopenharmony_ci page_cnt.s.bp_enb = 0; 1438c2ecf20Sopenharmony_ci page_cnt.s.page_cnt = 100; 1448c2ecf20Sopenharmony_ci for (interface = 0; interface < 2; interface++) { 1458c2ecf20Sopenharmony_ci for (port = cvmx_helper_get_first_ipd_port(interface); 1468c2ecf20Sopenharmony_ci port < cvmx_helper_get_last_ipd_port(interface); port++) 1478c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_IPD_PORTX_BP_PAGE_CNT(port), 1488c2ecf20Sopenharmony_ci page_cnt.u64); 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci for (queue = 0; queue < 8; queue++) 1528c2ecf20Sopenharmony_ci cvmx_helper_setup_red_queue(queue, pass_thresh, drop_thresh); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci /* Shutoff the dropping based on the per port page count. SW isn't 1558c2ecf20Sopenharmony_ci decrementing it right now */ 1568c2ecf20Sopenharmony_ci ipd_bp_prt_red_end.u64 = 0; 1578c2ecf20Sopenharmony_ci ipd_bp_prt_red_end.s.prt_enb = 0; 1588c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_IPD_BP_PRT_RED_END, ipd_bp_prt_red_end.u64); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci red_port_enable.u64 = 0; 1618c2ecf20Sopenharmony_ci red_port_enable.s.prt_enb = 0xfffffffffull; 1628c2ecf20Sopenharmony_ci red_port_enable.s.avg_dly = 10000; 1638c2ecf20Sopenharmony_ci red_port_enable.s.prb_dly = 10000; 1648c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_IPD_RED_PORT_ENABLE, red_port_enable.u64); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci return 0; 1678c2ecf20Sopenharmony_ci} 1688c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(cvmx_helper_setup_red); 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci/** 1718c2ecf20Sopenharmony_ci * Setup the common GMX settings that determine the number of 1728c2ecf20Sopenharmony_ci * ports. These setting apply to almost all configurations of all 1738c2ecf20Sopenharmony_ci * chips. 1748c2ecf20Sopenharmony_ci * 1758c2ecf20Sopenharmony_ci * @interface: Interface to configure 1768c2ecf20Sopenharmony_ci * @num_ports: Number of ports on the interface 1778c2ecf20Sopenharmony_ci * 1788c2ecf20Sopenharmony_ci * Returns Zero on success, negative on failure 1798c2ecf20Sopenharmony_ci */ 1808c2ecf20Sopenharmony_ciint __cvmx_helper_setup_gmx(int interface, int num_ports) 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci union cvmx_gmxx_tx_prts gmx_tx_prts; 1838c2ecf20Sopenharmony_ci union cvmx_gmxx_rx_prts gmx_rx_prts; 1848c2ecf20Sopenharmony_ci union cvmx_pko_reg_gmx_port_mode pko_mode; 1858c2ecf20Sopenharmony_ci union cvmx_gmxx_txx_thresh gmx_tx_thresh; 1868c2ecf20Sopenharmony_ci int index; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci /* Tell GMX the number of TX ports on this interface */ 1898c2ecf20Sopenharmony_ci gmx_tx_prts.u64 = cvmx_read_csr(CVMX_GMXX_TX_PRTS(interface)); 1908c2ecf20Sopenharmony_ci gmx_tx_prts.s.prts = num_ports; 1918c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), gmx_tx_prts.u64); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci /* Tell GMX the number of RX ports on this interface. This only 1948c2ecf20Sopenharmony_ci ** applies to *GMII and XAUI ports */ 1958c2ecf20Sopenharmony_ci if (cvmx_helper_interface_get_mode(interface) == 1968c2ecf20Sopenharmony_ci CVMX_HELPER_INTERFACE_MODE_RGMII 1978c2ecf20Sopenharmony_ci || cvmx_helper_interface_get_mode(interface) == 1988c2ecf20Sopenharmony_ci CVMX_HELPER_INTERFACE_MODE_SGMII 1998c2ecf20Sopenharmony_ci || cvmx_helper_interface_get_mode(interface) == 2008c2ecf20Sopenharmony_ci CVMX_HELPER_INTERFACE_MODE_GMII 2018c2ecf20Sopenharmony_ci || cvmx_helper_interface_get_mode(interface) == 2028c2ecf20Sopenharmony_ci CVMX_HELPER_INTERFACE_MODE_XAUI) { 2038c2ecf20Sopenharmony_ci if (num_ports > 4) { 2048c2ecf20Sopenharmony_ci cvmx_dprintf("__cvmx_helper_setup_gmx: Illegal " 2058c2ecf20Sopenharmony_ci "num_ports\n"); 2068c2ecf20Sopenharmony_ci return -1; 2078c2ecf20Sopenharmony_ci } 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci gmx_rx_prts.u64 = cvmx_read_csr(CVMX_GMXX_RX_PRTS(interface)); 2108c2ecf20Sopenharmony_ci gmx_rx_prts.s.prts = num_ports; 2118c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_GMXX_RX_PRTS(interface), gmx_rx_prts.u64); 2128c2ecf20Sopenharmony_ci } 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci /* Skip setting CVMX_PKO_REG_GMX_PORT_MODE on 30XX, 31XX, and 50XX */ 2158c2ecf20Sopenharmony_ci if (!OCTEON_IS_MODEL(OCTEON_CN30XX) && !OCTEON_IS_MODEL(OCTEON_CN31XX) 2168c2ecf20Sopenharmony_ci && !OCTEON_IS_MODEL(OCTEON_CN50XX)) { 2178c2ecf20Sopenharmony_ci /* Tell PKO the number of ports on this interface */ 2188c2ecf20Sopenharmony_ci pko_mode.u64 = cvmx_read_csr(CVMX_PKO_REG_GMX_PORT_MODE); 2198c2ecf20Sopenharmony_ci if (interface == 0) { 2208c2ecf20Sopenharmony_ci if (num_ports == 1) 2218c2ecf20Sopenharmony_ci pko_mode.s.mode0 = 4; 2228c2ecf20Sopenharmony_ci else if (num_ports == 2) 2238c2ecf20Sopenharmony_ci pko_mode.s.mode0 = 3; 2248c2ecf20Sopenharmony_ci else if (num_ports <= 4) 2258c2ecf20Sopenharmony_ci pko_mode.s.mode0 = 2; 2268c2ecf20Sopenharmony_ci else if (num_ports <= 8) 2278c2ecf20Sopenharmony_ci pko_mode.s.mode0 = 1; 2288c2ecf20Sopenharmony_ci else 2298c2ecf20Sopenharmony_ci pko_mode.s.mode0 = 0; 2308c2ecf20Sopenharmony_ci } else { 2318c2ecf20Sopenharmony_ci if (num_ports == 1) 2328c2ecf20Sopenharmony_ci pko_mode.s.mode1 = 4; 2338c2ecf20Sopenharmony_ci else if (num_ports == 2) 2348c2ecf20Sopenharmony_ci pko_mode.s.mode1 = 3; 2358c2ecf20Sopenharmony_ci else if (num_ports <= 4) 2368c2ecf20Sopenharmony_ci pko_mode.s.mode1 = 2; 2378c2ecf20Sopenharmony_ci else if (num_ports <= 8) 2388c2ecf20Sopenharmony_ci pko_mode.s.mode1 = 1; 2398c2ecf20Sopenharmony_ci else 2408c2ecf20Sopenharmony_ci pko_mode.s.mode1 = 0; 2418c2ecf20Sopenharmony_ci } 2428c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_PKO_REG_GMX_PORT_MODE, pko_mode.u64); 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci /* 2468c2ecf20Sopenharmony_ci * Set GMX to buffer as much data as possible before starting 2478c2ecf20Sopenharmony_ci * transmit. This reduces the chances that we have a TX under 2488c2ecf20Sopenharmony_ci * run due to memory contention. Any packet that fits entirely 2498c2ecf20Sopenharmony_ci * in the GMX FIFO can never have an under run regardless of 2508c2ecf20Sopenharmony_ci * memory load. 2518c2ecf20Sopenharmony_ci */ 2528c2ecf20Sopenharmony_ci gmx_tx_thresh.u64 = cvmx_read_csr(CVMX_GMXX_TXX_THRESH(0, interface)); 2538c2ecf20Sopenharmony_ci if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN31XX) 2548c2ecf20Sopenharmony_ci || OCTEON_IS_MODEL(OCTEON_CN50XX)) { 2558c2ecf20Sopenharmony_ci /* These chips have a fixed max threshold of 0x40 */ 2568c2ecf20Sopenharmony_ci gmx_tx_thresh.s.cnt = 0x40; 2578c2ecf20Sopenharmony_ci } else { 2588c2ecf20Sopenharmony_ci /* Choose the max value for the number of ports */ 2598c2ecf20Sopenharmony_ci if (num_ports <= 1) 2608c2ecf20Sopenharmony_ci gmx_tx_thresh.s.cnt = 0x100 / 1; 2618c2ecf20Sopenharmony_ci else if (num_ports == 2) 2628c2ecf20Sopenharmony_ci gmx_tx_thresh.s.cnt = 0x100 / 2; 2638c2ecf20Sopenharmony_ci else 2648c2ecf20Sopenharmony_ci gmx_tx_thresh.s.cnt = 0x100 / 4; 2658c2ecf20Sopenharmony_ci } 2668c2ecf20Sopenharmony_ci /* 2678c2ecf20Sopenharmony_ci * SPI and XAUI can have lots of ports but the GMX hardware 2688c2ecf20Sopenharmony_ci * only ever has a max of 4. 2698c2ecf20Sopenharmony_ci */ 2708c2ecf20Sopenharmony_ci if (num_ports > 4) 2718c2ecf20Sopenharmony_ci num_ports = 4; 2728c2ecf20Sopenharmony_ci for (index = 0; index < num_ports; index++) 2738c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_GMXX_TXX_THRESH(index, interface), 2748c2ecf20Sopenharmony_ci gmx_tx_thresh.u64); 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci return 0; 2778c2ecf20Sopenharmony_ci} 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci/** 2808c2ecf20Sopenharmony_ci * Returns the IPD/PKO port number for a port on the given 2818c2ecf20Sopenharmony_ci * interface. 2828c2ecf20Sopenharmony_ci * 2838c2ecf20Sopenharmony_ci * @interface: Interface to use 2848c2ecf20Sopenharmony_ci * @port: Port on the interface 2858c2ecf20Sopenharmony_ci * 2868c2ecf20Sopenharmony_ci * Returns IPD/PKO port number 2878c2ecf20Sopenharmony_ci */ 2888c2ecf20Sopenharmony_ciint cvmx_helper_get_ipd_port(int interface, int port) 2898c2ecf20Sopenharmony_ci{ 2908c2ecf20Sopenharmony_ci switch (interface) { 2918c2ecf20Sopenharmony_ci case 0: 2928c2ecf20Sopenharmony_ci return port; 2938c2ecf20Sopenharmony_ci case 1: 2948c2ecf20Sopenharmony_ci return port + 16; 2958c2ecf20Sopenharmony_ci case 2: 2968c2ecf20Sopenharmony_ci return port + 32; 2978c2ecf20Sopenharmony_ci case 3: 2988c2ecf20Sopenharmony_ci return port + 36; 2998c2ecf20Sopenharmony_ci case 4: 3008c2ecf20Sopenharmony_ci return port + 40; 3018c2ecf20Sopenharmony_ci case 5: 3028c2ecf20Sopenharmony_ci return port + 44; 3038c2ecf20Sopenharmony_ci } 3048c2ecf20Sopenharmony_ci return -1; 3058c2ecf20Sopenharmony_ci} 3068c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(cvmx_helper_get_ipd_port); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci/** 3098c2ecf20Sopenharmony_ci * Returns the interface number for an IPD/PKO port number. 3108c2ecf20Sopenharmony_ci * 3118c2ecf20Sopenharmony_ci * @ipd_port: IPD/PKO port number 3128c2ecf20Sopenharmony_ci * 3138c2ecf20Sopenharmony_ci * Returns Interface number 3148c2ecf20Sopenharmony_ci */ 3158c2ecf20Sopenharmony_ciint cvmx_helper_get_interface_num(int ipd_port) 3168c2ecf20Sopenharmony_ci{ 3178c2ecf20Sopenharmony_ci if (ipd_port < 16) 3188c2ecf20Sopenharmony_ci return 0; 3198c2ecf20Sopenharmony_ci else if (ipd_port < 32) 3208c2ecf20Sopenharmony_ci return 1; 3218c2ecf20Sopenharmony_ci else if (ipd_port < 36) 3228c2ecf20Sopenharmony_ci return 2; 3238c2ecf20Sopenharmony_ci else if (ipd_port < 40) 3248c2ecf20Sopenharmony_ci return 3; 3258c2ecf20Sopenharmony_ci else if (ipd_port < 44) 3268c2ecf20Sopenharmony_ci return 4; 3278c2ecf20Sopenharmony_ci else if (ipd_port < 48) 3288c2ecf20Sopenharmony_ci return 5; 3298c2ecf20Sopenharmony_ci else 3308c2ecf20Sopenharmony_ci cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD " 3318c2ecf20Sopenharmony_ci "port number\n"); 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci return -1; 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(cvmx_helper_get_interface_num); 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci/** 3388c2ecf20Sopenharmony_ci * Returns the interface index number for an IPD/PKO port 3398c2ecf20Sopenharmony_ci * number. 3408c2ecf20Sopenharmony_ci * 3418c2ecf20Sopenharmony_ci * @ipd_port: IPD/PKO port number 3428c2ecf20Sopenharmony_ci * 3438c2ecf20Sopenharmony_ci * Returns Interface index number 3448c2ecf20Sopenharmony_ci */ 3458c2ecf20Sopenharmony_ciint cvmx_helper_get_interface_index_num(int ipd_port) 3468c2ecf20Sopenharmony_ci{ 3478c2ecf20Sopenharmony_ci if (ipd_port < 32) 3488c2ecf20Sopenharmony_ci return ipd_port & 15; 3498c2ecf20Sopenharmony_ci else if (ipd_port < 36) 3508c2ecf20Sopenharmony_ci return ipd_port & 3; 3518c2ecf20Sopenharmony_ci else if (ipd_port < 40) 3528c2ecf20Sopenharmony_ci return ipd_port & 3; 3538c2ecf20Sopenharmony_ci else if (ipd_port < 44) 3548c2ecf20Sopenharmony_ci return ipd_port & 3; 3558c2ecf20Sopenharmony_ci else if (ipd_port < 48) 3568c2ecf20Sopenharmony_ci return ipd_port & 3; 3578c2ecf20Sopenharmony_ci else 3588c2ecf20Sopenharmony_ci cvmx_dprintf("cvmx_helper_get_interface_index_num: " 3598c2ecf20Sopenharmony_ci "Illegal IPD port number\n"); 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci return -1; 3628c2ecf20Sopenharmony_ci} 3638c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(cvmx_helper_get_interface_index_num); 364