1130391Sle/***********************license start*************** 2190507Slulf * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights 3190507Slulf * reserved. 4190507Slulf * 5130391Sle * 6152631Sle * Redistribution and use in source and binary forms, with or without 7152631Sle * modification, are permitted provided that the following conditions are 8152631Sle * met: 9152631Sle * 10152631Sle * * Redistributions of source code must retain the above copyright 11130391Sle * notice, this list of conditions and the following disclaimer. 12130391Sle * 13130391Sle * * Redistributions in binary form must reproduce the above 14130391Sle * copyright notice, this list of conditions and the following 15130391Sle * disclaimer in the documentation and/or other materials provided 16130391Sle * with the distribution. 17130391Sle 18130391Sle * * Neither the name of Cavium Networks nor the names of 19152631Sle * its contributors may be used to endorse or promote products 20130391Sle * derived from this software without specific prior written 21130391Sle * permission. 22130391Sle 23130391Sle * This Software, including technical data, may be subject to U.S. export control 24130391Sle * laws, including the U.S. Export Administration Act and its associated 25130391Sle * regulations, and may be subject to export or import regulations in other 26130391Sle * countries. 27130391Sle 28130391Sle * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 29130391Sle * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR 30130391Sle * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 31130391Sle * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 32130391Sle * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 33130391Sle * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 34130391Sle * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 35130391Sle * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 36130391Sle * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 37130391Sle * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 38130391Sle ***********************license end**************************************/ 39130391Sle 40130391Sle 41130391Sle 42130391Sle 43130391Sle 44130391Sle 45130391Sle 46130391Sle/** 47130391Sle * @file 48190507Slulf * 49130391Sle * Small helper utilities. 50130391Sle * 51130391Sle * <hr>$Revision: 49448 $<hr> 52130391Sle */ 53130391Sle#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 54130391Sle#include <linux/module.h> 55130391Sle 56130391Sle#include <asm/octeon/cvmx.h> 57130391Sle#include <asm/octeon/cvmx-config.h> 58130391Sle#include <asm/octeon/cvmx-pip.h> 59130391Sle#include <asm/octeon/cvmx-ipd.h> 60190507Slulf#include <asm/octeon/cvmx-helper.h> 61190507Slulf#include <asm/octeon/cvmx-gmxx-defs.h> 62130391Sle#include <asm/octeon/cvmx-pko-defs.h> 63190507Slulf#else 64190884Slulf#if !defined(__FreeBSD__) || !defined(_KERNEL) 65130391Sle#include "executive-config.h" 66130391Sle#include "cvmx-config.h" 67152616Sle#endif 68190507Slulf#include "cvmx.h" 69138110Sle#include "cvmx-bootmem.h" 70130391Sle#include "cvmx-fpa.h" 71190507Slulf#include "cvmx-pip.h" 72152616Sle#include "cvmx-pko.h" 73157052Sle#include "cvmx-ipd.h" 74130391Sle#include "cvmx-gmx.h" 75130391Sle#include "cvmx-spi.h" 76138112Sle#include "cvmx-sysinfo.h" 77130391Sle#include "cvmx-helper.h" 78130391Sle#include "cvmx-helper-util.h" 79190507Slulf#include "cvmx-version.h" 80130391Sle#endif 81130391Sle 82130391Sle#ifdef CVMX_ENABLE_HELPER_FUNCTIONS 83190507Slulf 84190507Slulf#ifndef CVMX_BUILD_FOR_LINUX_KERNEL 85190507Slulf/** 86190507Slulf * Get the version of the CVMX libraries. 87204665Slulf * 88204665Slulf * @return Version string. Note this buffer is allocated statically 89190507Slulf * and will be shared by all callers. 90130391Sle */ 91130391Sleconst char *cvmx_helper_get_version(void) 92130391Sle{ 93130391Sle return OCTEON_SDK_VERSION_STRING; 94130391Sle} 95130391Sle#endif 96130391Sle 97130391Sle/** 98130391Sle * Convert a interface mode into a human readable string 99130391Sle * 100130391Sle * @param mode Mode to convert 101130391Sle * 102130391Sle * @return String 103130391Sle */ 104130391Sleconst char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t mode) 105130391Sle{ 106130391Sle switch (mode) 107130391Sle { 108130391Sle case CVMX_HELPER_INTERFACE_MODE_DISABLED: return "DISABLED"; 109130391Sle case CVMX_HELPER_INTERFACE_MODE_RGMII: return "RGMII"; 110130391Sle case CVMX_HELPER_INTERFACE_MODE_GMII: return "GMII"; 111130391Sle case CVMX_HELPER_INTERFACE_MODE_SPI: return "SPI"; 112130391Sle case CVMX_HELPER_INTERFACE_MODE_PCIE: return "PCIE"; 113130391Sle case CVMX_HELPER_INTERFACE_MODE_XAUI: return "XAUI"; 114130391Sle case CVMX_HELPER_INTERFACE_MODE_SGMII: return "SGMII"; 115130391Sle case CVMX_HELPER_INTERFACE_MODE_PICMG: return "PICMG"; 116130391Sle case CVMX_HELPER_INTERFACE_MODE_NPI: return "NPI"; 117130391Sle case CVMX_HELPER_INTERFACE_MODE_LOOP: return "LOOP"; 118130391Sle case CVMX_HELPER_INTERFACE_MODE_SRIO: return "SRIO"; 119130391Sle } 120130391Sle return "UNKNOWN"; 121130391Sle} 122130391Sle 123130391Sle 124130391Sle/** 125130391Sle * Debug routine to dump the packet structure to the console 126130391Sle * 127130391Sle * @param work Work queue entry containing the packet to dump 128130391Sle * @return 129130391Sle */ 130130391Sleint cvmx_helper_dump_packet(cvmx_wqe_t *work) 131190507Slulf{ 132130391Sle uint64_t count; 133190507Slulf uint64_t remaining_bytes; 134190507Slulf cvmx_buf_ptr_t buffer_ptr; 135190507Slulf uint64_t start_of_buffer; 136190507Slulf uint8_t * data_address; 137190507Slulf uint8_t * end_of_data; 138190507Slulf 139190507Slulf cvmx_dprintf("Packet Length: %u\n", work->len); 140190507Slulf cvmx_dprintf(" Input Port: %u\n", work->ipprt); 141190507Slulf cvmx_dprintf(" QoS: %u\n", work->qos); 142190507Slulf cvmx_dprintf(" Buffers: %u\n", work->word2.s.bufs); 143190507Slulf 144190507Slulf if (work->word2.s.bufs == 0) 145190507Slulf { 146190507Slulf cvmx_ipd_wqe_fpa_queue_t wqe_pool; 147190507Slulf wqe_pool.u64 = cvmx_read_csr(CVMX_IPD_WQE_FPA_QUEUE); 148190507Slulf buffer_ptr.u64 = 0; 149190507Slulf buffer_ptr.s.pool = wqe_pool.s.wqe_pool; 150190507Slulf buffer_ptr.s.size = 128; 151190507Slulf buffer_ptr.s.addr = cvmx_ptr_to_phys(work->packet_data); 152190507Slulf if (cvmx_likely(!work->word2.s.not_IP)) 153190507Slulf { 154190507Slulf cvmx_pip_ip_offset_t pip_ip_offset; 155190507Slulf pip_ip_offset.u64 = cvmx_read_csr(CVMX_PIP_IP_OFFSET); 156190507Slulf buffer_ptr.s.addr += (pip_ip_offset.s.offset<<3) - work->word2.s.ip_offset; 157190507Slulf buffer_ptr.s.addr += (work->word2.s.is_v6^1)<<2; 158190507Slulf } 159190507Slulf else 160190507Slulf { 161190507Slulf /* WARNING: This code assume that the packet is not RAW. If it was, 162190507Slulf we would use PIP_GBL_CFG[RAW_SHF] instead of 163190507Slulf PIP_GBL_CFG[NIP_SHF] */ 164190507Slulf cvmx_pip_gbl_cfg_t pip_gbl_cfg; 165190507Slulf pip_gbl_cfg.u64 = cvmx_read_csr(CVMX_PIP_GBL_CFG); 166190507Slulf buffer_ptr.s.addr += pip_gbl_cfg.s.nip_shf; 167190507Slulf } 168190507Slulf } 169190507Slulf else 170130391Sle buffer_ptr = work->packet_ptr; 171130391Sle remaining_bytes = work->len; 172130391Sle 173130391Sle while (remaining_bytes) 174130391Sle { 175130391Sle start_of_buffer = ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7; 176130391Sle cvmx_dprintf(" Buffer Start:%llx\n", (unsigned long long)start_of_buffer); 177130391Sle cvmx_dprintf(" Buffer I : %u\n", buffer_ptr.s.i); 178190507Slulf cvmx_dprintf(" Buffer Back: %u\n", buffer_ptr.s.back); 179190507Slulf cvmx_dprintf(" Buffer Pool: %u\n", buffer_ptr.s.pool); 180130391Sle cvmx_dprintf(" Buffer Data: %llx\n", (unsigned long long)buffer_ptr.s.addr); 181190507Slulf cvmx_dprintf(" Buffer Size: %u\n", buffer_ptr.s.size); 182130391Sle 183130391Sle cvmx_dprintf("\t\t"); 184130391Sle data_address = (uint8_t *)cvmx_phys_to_ptr(buffer_ptr.s.addr); 185190507Slulf end_of_data = data_address + buffer_ptr.s.size; 186190507Slulf count = 0; 187190507Slulf while (data_address < end_of_data) 188190507Slulf { 189190507Slulf if (remaining_bytes == 0) 190190507Slulf break; 191190507Slulf else 192190507Slulf remaining_bytes--; 193190507Slulf cvmx_dprintf("%02x", (unsigned int)*data_address); 194190507Slulf data_address++; 195190507Slulf if (remaining_bytes && (count == 7)) 196190507Slulf { 197190507Slulf cvmx_dprintf("\n\t\t"); 198190507Slulf count = 0; 199190507Slulf } 200190507Slulf else 201190507Slulf count++; 202133097Sle } 203133097Sle cvmx_dprintf("\n"); 204133097Sle 205133097Sle if (remaining_bytes) 206133097Sle buffer_ptr = *(cvmx_buf_ptr_t*)cvmx_phys_to_ptr(buffer_ptr.s.addr - 8); 207133097Sle } 208133097Sle return 0; 209133097Sle} 210133097Sle 211133097Sle 212133097Sle/** 213133097Sle * Setup Random Early Drop on a specific input queue 214133097Sle * 215133097Sle * @param queue Input queue to setup RED on (0-7) 216133097Sle * @param pass_thresh 217133097Sle * Packets will begin slowly dropping when there are less than 218133097Sle * this many packet buffers free in FPA 0. 219133097Sle * @param drop_thresh 220133097Sle * All incomming packets will be dropped when there are less 221133097Sle * than this many free packet buffers in FPA 0. 222133097Sle * @return Zero on success. Negative on failure 223133097Sle */ 224133097Sleint cvmx_helper_setup_red_queue(int queue, int pass_thresh, int drop_thresh) 225133097Sle{ 226133097Sle cvmx_ipd_qosx_red_marks_t red_marks; 227133097Sle cvmx_ipd_red_quex_param_t red_param; 228133097Sle 229133097Sle /* Set RED to begin dropping packets when there are pass_thresh buffers 230133097Sle left. It will linearly drop more packets until reaching drop_thresh 231130391Sle buffers */ 232130391Sle red_marks.u64 = 0; 233130391Sle red_marks.s.drop = drop_thresh; 234130391Sle red_marks.s.pass = pass_thresh; 235130391Sle cvmx_write_csr(CVMX_IPD_QOSX_RED_MARKS(queue), red_marks.u64); 236190507Slulf 237130391Sle /* Use the actual queue 0 counter, not the average */ 238130391Sle red_param.u64 = 0; 239190507Slulf red_param.s.prb_con = (255ul<<24) / (red_marks.s.pass - red_marks.s.drop); 240190507Slulf red_param.s.avg_con = 1; 241130391Sle red_param.s.new_con = 255; 242130391Sle red_param.s.use_pcnt = 1; 243130391Sle cvmx_write_csr(CVMX_IPD_RED_QUEX_PARAM(queue), red_param.u64); 244130391Sle return 0; 245130391Sle} 246130391Sle 247130391Sle 248130391Sle/** 249130391Sle * Setup Random Early Drop to automatically begin dropping packets. 250130391Sle * 251130391Sle * @param pass_thresh 252130391Sle * Packets will begin slowly dropping when there are less than 253130391Sle * this many packet buffers free in FPA 0. 254130391Sle * @param drop_thresh 255130391Sle * All incomming packets will be dropped when there are less 256130391Sle * than this many free packet buffers in FPA 0. 257130391Sle * @return Zero on success. Negative on failure 258190507Slulf */ 259130391Sleint cvmx_helper_setup_red(int pass_thresh, int drop_thresh) 260130391Sle{ 261150044Sle cvmx_ipd_portx_bp_page_cnt_t page_cnt; 262150044Sle cvmx_ipd_bp_prt_red_end_t ipd_bp_prt_red_end; 263150044Sle cvmx_ipd_red_port_enable_t red_port_enable; 264150044Sle int queue; 265130391Sle int interface; 266150044Sle int port; 267150044Sle 268150044Sle /* Disable backpressure based on queued buffers. It needs SW support */ 269150044Sle page_cnt.u64 = 0; 270150044Sle page_cnt.s.bp_enb = 0; 271150044Sle page_cnt.s.page_cnt = 100; 272150044Sle for (interface=0; interface<2; interface++) 273150044Sle { 274150044Sle for (port=cvmx_helper_get_first_ipd_port(interface); port<cvmx_helper_get_last_ipd_port(interface); port++) 275150044Sle cvmx_write_csr(CVMX_IPD_PORTX_BP_PAGE_CNT(port), page_cnt.u64); 276150044Sle } 277130391Sle 278150044Sle for (queue=0; queue<8; queue++) 279150044Sle cvmx_helper_setup_red_queue(queue, pass_thresh, drop_thresh); 280130391Sle 281150044Sle /* Shutoff the dropping based on the per port page count. SW isn't 282150044Sle decrementing it right now */ 283150044Sle ipd_bp_prt_red_end.u64 = 0; 284150044Sle ipd_bp_prt_red_end.s.prt_enb = 0; 285190507Slulf cvmx_write_csr(CVMX_IPD_BP_PRT_RED_END, ipd_bp_prt_red_end.u64); 286130391Sle 287150044Sle red_port_enable.u64 = 0; 288150044Sle red_port_enable.s.prt_enb = 0xfffffffffull; 289150044Sle red_port_enable.s.avg_dly = 10000; 290130391Sle red_port_enable.s.prb_dly = 10000; 291150044Sle cvmx_write_csr(CVMX_IPD_RED_PORT_ENABLE, red_port_enable.u64); 292150044Sle 293150044Sle /* Shutoff the dropping of packets based on RED for SRIO ports */ 294150044Sle if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) 295150044Sle { 296150044Sle cvmx_ipd_red_port_enable2_t red_port_enable2; 297150044Sle red_port_enable2.u64 = 0; 298150044Sle red_port_enable2.s.prt_enb = 0xf0; 299150044Sle cvmx_write_csr(CVMX_IPD_RED_PORT_ENABLE2, red_port_enable2.u64); 300150044Sle } 301130391Sle 302150044Sle return 0; 303150044Sle} 304130391Sle#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 305150044SleEXPORT_SYMBOL(cvmx_helper_setup_red); 306150044Sle#endif 307190507Slulf 308150044Sle 309150044Sle/** 310130391Sle * @INTERNAL 311150044Sle * Setup the common GMX settings that determine the number of 312150044Sle * ports. These setting apply to almost all configurations of all 313190507Slulf * chips. 314150044Sle * 315150044Sle * @param interface Interface to configure 316130391Sle * @param num_ports Number of ports on the interface 317150044Sle * 318150044Sle * @return Zero on success, negative on failure 319150044Sle */ 320150044Sleint __cvmx_helper_setup_gmx(int interface, int num_ports) 321190507Slulf{ 322130391Sle cvmx_gmxx_tx_prts_t gmx_tx_prts; 323150044Sle cvmx_gmxx_rx_prts_t gmx_rx_prts; 324150044Sle cvmx_pko_reg_gmx_port_mode_t pko_mode; 325150044Sle cvmx_gmxx_txx_thresh_t gmx_tx_thresh; 326130391Sle int index; 327150044Sle 328150044Sle /* Tell GMX the number of TX ports on this interface */ 329150044Sle gmx_tx_prts.u64 = cvmx_read_csr(CVMX_GMXX_TX_PRTS(interface)); 330150044Sle gmx_tx_prts.s.prts = num_ports; 331150044Sle cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), gmx_tx_prts.u64); 332150044Sle 333150044Sle /* Tell GMX the number of RX ports on this interface. This only 334150044Sle ** applies to *GMII and XAUI ports */ 335150044Sle if (cvmx_helper_interface_get_mode(interface) == CVMX_HELPER_INTERFACE_MODE_RGMII 336150044Sle || cvmx_helper_interface_get_mode(interface) == CVMX_HELPER_INTERFACE_MODE_SGMII 337150044Sle || cvmx_helper_interface_get_mode(interface) == CVMX_HELPER_INTERFACE_MODE_GMII 338130391Sle || cvmx_helper_interface_get_mode(interface) == CVMX_HELPER_INTERFACE_MODE_XAUI) 339150044Sle { 340150044Sle if (num_ports > 4) 341190507Slulf { 342190507Slulf cvmx_dprintf("__cvmx_helper_setup_gmx: Illegal num_ports\n"); 343190507Slulf return(-1); 344190507Slulf } 345190507Slulf 346190507Slulf gmx_rx_prts.u64 = cvmx_read_csr(CVMX_GMXX_RX_PRTS(interface)); 347190507Slulf gmx_rx_prts.s.prts = num_ports; 348190507Slulf cvmx_write_csr(CVMX_GMXX_RX_PRTS(interface), gmx_rx_prts.u64); 349190507Slulf } 350190507Slulf 351150044Sle /* Skip setting CVMX_PKO_REG_GMX_PORT_MODE on 30XX, 31XX, and 50XX */ 352150044Sle if (!OCTEON_IS_MODEL(OCTEON_CN30XX) && !OCTEON_IS_MODEL(OCTEON_CN31XX) && !OCTEON_IS_MODEL(OCTEON_CN50XX)) 353150044Sle { 354150044Sle /* Tell PKO the number of ports on this interface */ 355190507Slulf pko_mode.u64 = cvmx_read_csr(CVMX_PKO_REG_GMX_PORT_MODE); 356150044Sle if (interface == 0) 357150044Sle { 358150044Sle if (num_ports == 1) 359150044Sle pko_mode.s.mode0 = 4; 360150044Sle else if (num_ports == 2) 361150044Sle pko_mode.s.mode0 = 3; 362150044Sle else if (num_ports <= 4) 363150044Sle pko_mode.s.mode0 = 2; 364150044Sle else if (num_ports <= 8) 365150044Sle pko_mode.s.mode0 = 1; 366150044Sle else 367130391Sle pko_mode.s.mode0 = 0; 368130391Sle } 369150044Sle else 370150044Sle { 371130391Sle if (num_ports == 1) 372150044Sle pko_mode.s.mode1 = 4; 373150044Sle else if (num_ports == 2) 374150044Sle pko_mode.s.mode1 = 3; 375150044Sle else if (num_ports <= 4) 376150044Sle pko_mode.s.mode1 = 2; 377150044Sle else if (num_ports <= 8) 378150044Sle pko_mode.s.mode1 = 1; 379150044Sle else 380150044Sle pko_mode.s.mode1 = 0; 381150044Sle } 382130391Sle cvmx_write_csr(CVMX_PKO_REG_GMX_PORT_MODE, pko_mode.u64); 383130391Sle } 384130391Sle 385130391Sle /* Set GMX to buffer as much data as possible before starting transmit. 386130391Sle This reduces the chances that we have a TX under run due to memory 387130391Sle contention. Any packet that fits entirely in the GMX FIFO can never 388130391Sle have an under run regardless of memory load */ 389130391Sle gmx_tx_thresh.u64 = cvmx_read_csr(CVMX_GMXX_TXX_THRESH(0, interface)); 390130391Sle if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) 391130391Sle { 392130391Sle /* These chips have a fixed max threshold of 0x40 */ 393130391Sle gmx_tx_thresh.s.cnt = 0x40; 394130391Sle } 395130391Sle else 396130391Sle { 397130391Sle /* Choose the max value for the number of ports */ 398130391Sle if (num_ports <= 1) 399130391Sle gmx_tx_thresh.s.cnt = 0x100 / 1; 400130391Sle else if (num_ports == 2) 401190507Slulf gmx_tx_thresh.s.cnt = 0x100 / 2; 402130391Sle else 403190507Slulf gmx_tx_thresh.s.cnt = 0x100 / 4; 404190507Slulf } 405190507Slulf /* SPI and XAUI can have lots of ports but the GMX hardware only ever has 406190507Slulf a max of 4 */ 407190507Slulf if (num_ports > 4) 408190507Slulf num_ports = 4; 409190507Slulf for (index=0; index<num_ports; index++) 410190507Slulf cvmx_write_csr(CVMX_GMXX_TXX_THRESH(index, interface), gmx_tx_thresh.u64); 411190507Slulf 412190507Slulf return 0; 413190507Slulf} 414190507Slulf 415190507Slulf 416190507Slulf/** 417190507Slulf * Returns the IPD/PKO port number for a port on the given 418190507Slulf * interface. 419190507Slulf * 420190507Slulf * @param interface Interface to use 421190507Slulf * @param port Port on the interface 422190507Slulf * 423190507Slulf * @return IPD/PKO port number 424190507Slulf */ 425190507Slulfint cvmx_helper_get_ipd_port(int interface, int port) 426190507Slulf{ 427190507Slulf switch (interface) 428204665Slulf { 429190507Slulf case 0: return port; 430190507Slulf case 1: return port + 16; 431190507Slulf case 2: return port + 32; 432190507Slulf case 3: return port + 36; 433190507Slulf case 4: return port + 40; 434190507Slulf case 5: return port + 42; 435190881Slulf } 436190507Slulf return -1; 437190507Slulf} 438190507Slulf#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 439190507SlulfEXPORT_SYMBOL(cvmx_helper_get_ipd_port); 440204665Slulf#endif 441190507Slulf 442190507Slulf#endif /* CVMX_ENABLE_HELPER_FUNCTIONS */ 443190507Slulf 444190507Slulf 445190507Slulf/** 446190507Slulf * Returns the interface number for an IPD/PKO port number. 447190507Slulf * 448190507Slulf * @param ipd_port IPD/PKO port number 449190507Slulf * 450190507Slulf * @return Interface number 451190507Slulf */ 452190507Slulfint cvmx_helper_get_interface_num(int ipd_port) 453190507Slulf{ 454190507Slulf if (ipd_port < 16) 455190507Slulf return 0; 456190507Slulf else if (ipd_port < 32) 457190507Slulf return 1; 458190507Slulf else if (ipd_port < 36) 459190507Slulf return 2; 460190507Slulf else if (ipd_port < 40) 461190507Slulf return 3; 462190507Slulf else if (ipd_port < 42) 463190507Slulf return 4; 464190507Slulf else if (ipd_port < 44) 465190507Slulf return 5; 466190507Slulf else 467190507Slulf cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD port number\n"); 468190507Slulf 469190507Slulf return -1; 470190507Slulf} 471190507Slulf#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 472190507SlulfEXPORT_SYMBOL(cvmx_helper_get_interface_num); 473190507Slulf#endif 474190507Slulf 475190507Slulf 476190507Slulf/** 477190507Slulf * Returns the interface index number for an IPD/PKO port 478190507Slulf * number. 479190507Slulf * 480190507Slulf * @param ipd_port IPD/PKO port number 481190507Slulf * 482190507Slulf * @return Interface index number 483190507Slulf */ 484190507Slulfint cvmx_helper_get_interface_index_num(int ipd_port) 485190507Slulf{ 486190507Slulf if (ipd_port < 32) 487190507Slulf return ipd_port & 15; 488190507Slulf else if (ipd_port < 40) 489190507Slulf return ipd_port & 3; 490190507Slulf else if (ipd_port < 44) 491190507Slulf return ipd_port & 1; 492190507Slulf else 493190507Slulf cvmx_dprintf("cvmx_helper_get_interface_index_num: Illegal IPD port number\n"); 494190507Slulf 495190507Slulf return -1; 496190507Slulf} 497190507Slulf#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 498190507SlulfEXPORT_SYMBOL(cvmx_helper_get_interface_index_num); 499190507Slulf#endif 500190507Slulf