1 /***********************license start*************** 2 * Author: Cavium Networks 3 * 4 * Contact: support@caviumnetworks.com 5 * This file is part of the OCTEON SDK 6 * 7 * Copyright (c) 2003-2008 Cavium Networks 8 * 9 * This file is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License, Version 2, as 11 * published by the Free Software Foundation. 12 * 13 * This file is distributed in the hope that it will be useful, but 14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 16 * NONINFRINGEMENT. See the GNU General Public License for more 17 * details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this file; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 * or visit http://www.gnu.org/licenses/. 23 * 24 * This file may also be available under a different license from Cavium. 25 * Contact Cavium Networks for more information 26 ***********************license end**************************************/ 27 28 /* 29 * Utility functions to decode Octeon's RSL_INT_BLOCKS 30 * interrupts into error messages. 31 */ 32 33 #include <asm/octeon/octeon.h> 34 35 #include <asm/octeon/cvmx-asxx-defs.h> 36 #include <asm/octeon/cvmx-gmxx-defs.h> 37 38 #ifndef PRINT_ERROR 39 #define PRINT_ERROR(format, ...) 40 #endif 41 42 void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block); 43 44 /** 45 * Enable ASX error interrupts that exist on CN3XXX, CN50XX, and 46 * CN58XX. 47 * 48 * @block: Interface to enable 0-1 49 */ 50 void __cvmx_interrupt_asxx_enable(int block) 51 { 52 int mask; 53 union cvmx_asxx_int_en csr; 54 /* 55 * CN38XX and CN58XX have two interfaces with 4 ports per 56 * interface. All other chips have a max of 3 ports on 57 * interface 0 58 */ 59 if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) 60 mask = 0xf; /* Set enables for 4 ports */ 61 else 62 mask = 0x7; /* Set enables for 3 ports */ 63 64 /* Enable interface interrupts */ 65 csr.u64 = cvmx_read_csr(CVMX_ASXX_INT_EN(block)); 66 csr.s.txpsh = mask; 67 csr.s.txpop = mask; 68 csr.s.ovrflw = mask; 69 cvmx_write_csr(CVMX_ASXX_INT_EN(block), csr.u64); 70 } 71 /** 72 * Enable GMX error reporting for the supplied interface 73 * 74 * @interface: Interface to enable 75 */ 76 void __cvmx_interrupt_gmxx_enable(int interface) 77 { 78 union cvmx_gmxx_inf_mode mode; 79 union cvmx_gmxx_tx_int_en gmx_tx_int_en; 80 int num_ports; 81 int index; 82 83 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); 84 85 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) { 86 if (mode.s.en) { 87 switch (mode.cn52xx.mode) { 88 case 1: /* XAUI */ 89 num_ports = 1; 90 break; 91 case 2: /* SGMII */ 92 case 3: /* PICMG */ 93 num_ports = 4; 94 break; 95 default: /* Disabled */ 96 num_ports = 0; 97 break; 98 } 99 } else 100 num_ports = 0; 101 } else { 102 if (mode.s.en) { 103 if (OCTEON_IS_MODEL(OCTEON_CN38XX) 104 || OCTEON_IS_MODEL(OCTEON_CN58XX)) { 105 /* 106 * SPI on CN38XX and CN58XX report all 107 * errors through port 0. RGMII needs 108 * to check all 4 ports 109 */ 110 if (mode.s.type) 111 num_ports = 1; 112 else 113 num_ports = 4; 114 } else { 115 /* 116 * CN30XX, CN31XX, and CN50XX have two 117 * or three ports. GMII and MII has 2, 118 * RGMII has three 119 */ 120 if (mode.s.type) 121 num_ports = 2; 122 else 123 num_ports = 3; 124 } 125 } else 126 num_ports = 0; 127 } 128 129 gmx_tx_int_en.u64 = 0; 130 if (num_ports) { 131 if (OCTEON_IS_MODEL(OCTEON_CN38XX) 132 || OCTEON_IS_MODEL(OCTEON_CN58XX)) 133 gmx_tx_int_en.cn38xx.ncb_nxa = 1; 134 gmx_tx_int_en.s.pko_nxa = 1; 135 } 136 gmx_tx_int_en.s.undflw = (1 << num_ports) - 1; 137 cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64); 138 for (index = 0; index < num_ports; index++) 139 __cvmx_interrupt_gmxx_rxx_int_en_enable(index, interface); 140 } 141