1 /***********************license start********* 1 /***********************license start*************** 2 * Author: Cavium Networks 2 * Author: Cavium Networks 3 * 3 * 4 * Contact: support@caviumnetworks.com 4 * Contact: support@caviumnetworks.com 5 * This file is part of the OCTEON SDK 5 * This file is part of the OCTEON SDK 6 * 6 * 7 * Copyright (c) 2003-2008 Cavium Networks 7 * Copyright (c) 2003-2008 Cavium Networks 8 * 8 * 9 * This file is free software; you can redistr 9 * This file is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Publi 10 * it under the terms of the GNU General Public License, Version 2, as 11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation. 12 * 12 * 13 * This file is distributed in the hope that i 13 * This file is distributed in the hope that it will be useful, but 14 * AS-IS and WITHOUT ANY WARRANTY; without eve 14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 15 * of MERCHANTABILITY or FITNESS FOR A PARTICU 15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 16 * NONINFRINGEMENT. See the GNU General Publi 16 * NONINFRINGEMENT. See the GNU General Public License for more 17 * details. 17 * details. 18 * 18 * 19 * You should have received a copy of the GNU 19 * You should have received a copy of the GNU General Public License 20 * along with this file; if not, write to the 20 * along with this file; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Flo 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 * or visit http://www.gnu.org/licenses/. 22 * or visit http://www.gnu.org/licenses/. 23 * 23 * 24 * This file may also be available under a dif 24 * This file may also be available under a different license from Cavium. 25 * Contact Cavium Networks for more informatio 25 * Contact Cavium Networks for more information 26 ***********************license end*********** 26 ***********************license end**************************************/ 27 27 28 /* 28 /* 29 * 29 * 30 * Helper functions for common, but complicate 30 * Helper functions for common, but complicated tasks. 31 * 31 * 32 */ 32 */ 33 #include <linux/bug.h> 33 #include <linux/bug.h> 34 #include <asm/octeon/octeon.h> 34 #include <asm/octeon/octeon.h> 35 35 36 #include <asm/octeon/cvmx-config.h> 36 #include <asm/octeon/cvmx-config.h> 37 37 38 #include <asm/octeon/cvmx-fpa.h> 38 #include <asm/octeon/cvmx-fpa.h> 39 #include <asm/octeon/cvmx-pip.h> 39 #include <asm/octeon/cvmx-pip.h> 40 #include <asm/octeon/cvmx-pko.h> 40 #include <asm/octeon/cvmx-pko.h> 41 #include <asm/octeon/cvmx-ipd.h> 41 #include <asm/octeon/cvmx-ipd.h> 42 #include <asm/octeon/cvmx-spi.h> 42 #include <asm/octeon/cvmx-spi.h> 43 #include <asm/octeon/cvmx-helper.h> 43 #include <asm/octeon/cvmx-helper.h> 44 #include <asm/octeon/cvmx-helper-board.h> 44 #include <asm/octeon/cvmx-helper-board.h> 45 45 46 #include <asm/octeon/cvmx-pip-defs.h> 46 #include <asm/octeon/cvmx-pip-defs.h> 47 #include <asm/octeon/cvmx-asxx-defs.h> 47 #include <asm/octeon/cvmx-asxx-defs.h> 48 48 49 /* Port count per interface */ 49 /* Port count per interface */ 50 static int interface_port_count[9]; 50 static int interface_port_count[9]; 51 51 52 /** 52 /** 53 * Return the number of interfaces the chip ha 53 * Return the number of interfaces the chip has. Each interface 54 * may have multiple ports. Most chips support 54 * may have multiple ports. Most chips support two interfaces, 55 * but the CNX0XX and CNX1XX are exceptions. T 55 * but the CNX0XX and CNX1XX are exceptions. These only support 56 * one interface. 56 * one interface. 57 * 57 * 58 * Returns Number of interfaces on chip 58 * Returns Number of interfaces on chip 59 */ 59 */ 60 int cvmx_helper_get_number_of_interfaces(void) 60 int cvmx_helper_get_number_of_interfaces(void) 61 { 61 { 62 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) 62 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) 63 return 9; 63 return 9; 64 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) { 64 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) { 65 if (OCTEON_IS_MODEL(OCTEON_CN6 65 if (OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_0)) 66 return 7; 66 return 7; 67 else 67 else 68 return 8; 68 return 8; 69 } 69 } 70 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || 70 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) 71 return 4; 71 return 4; 72 if (OCTEON_IS_MODEL(OCTEON_CN7XXX)) 72 if (OCTEON_IS_MODEL(OCTEON_CN7XXX)) 73 return 5; 73 return 5; 74 else 74 else 75 return 3; 75 return 3; 76 } 76 } 77 EXPORT_SYMBOL_GPL(cvmx_helper_get_number_of_in 77 EXPORT_SYMBOL_GPL(cvmx_helper_get_number_of_interfaces); 78 78 79 /** 79 /** 80 * Return the number of ports on an interface. 80 * Return the number of ports on an interface. Depending on the 81 * chip and configuration, this can be 1-16. A 81 * chip and configuration, this can be 1-16. A value of 0 82 * specifies that the interface doesn't exist 82 * specifies that the interface doesn't exist or isn't usable. 83 * 83 * 84 * @interface: Interface to get the port count 84 * @interface: Interface to get the port count for 85 * 85 * 86 * Returns Number of ports on interface. Can b 86 * Returns Number of ports on interface. Can be Zero. 87 */ 87 */ 88 int cvmx_helper_ports_on_interface(int interfa 88 int cvmx_helper_ports_on_interface(int interface) 89 { 89 { 90 return interface_port_count[interface] 90 return interface_port_count[interface]; 91 } 91 } 92 EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interfa 92 EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface); 93 93 94 /** 94 /** 95 * @INTERNAL 95 * @INTERNAL 96 * Return interface mode for CN68xx. 96 * Return interface mode for CN68xx. 97 */ 97 */ 98 static cvmx_helper_interface_mode_t __cvmx_get 98 static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface) 99 { 99 { 100 union cvmx_mio_qlmx_cfg qlm_cfg; 100 union cvmx_mio_qlmx_cfg qlm_cfg; 101 switch (interface) { 101 switch (interface) { 102 case 0: 102 case 0: 103 qlm_cfg.u64 = cvmx_read_csr(CV 103 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0)); 104 /* QLM is disabled when QLM SP 104 /* QLM is disabled when QLM SPD is 15. */ 105 if (qlm_cfg.s.qlm_spd == 15) 105 if (qlm_cfg.s.qlm_spd == 15) 106 return CVMX_HELPER_INT 106 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 107 107 108 if (qlm_cfg.s.qlm_cfg == 2) 108 if (qlm_cfg.s.qlm_cfg == 2) 109 return CVMX_HELPER_INT 109 return CVMX_HELPER_INTERFACE_MODE_SGMII; 110 else if (qlm_cfg.s.qlm_cfg == 110 else if (qlm_cfg.s.qlm_cfg == 3) 111 return CVMX_HELPER_INT 111 return CVMX_HELPER_INTERFACE_MODE_XAUI; 112 else 112 else 113 return CVMX_HELPER_INT 113 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 114 case 2: 114 case 2: 115 case 3: 115 case 3: 116 case 4: 116 case 4: 117 qlm_cfg.u64 = cvmx_read_csr(CV 117 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(interface)); 118 /* QLM is disabled when QLM SP 118 /* QLM is disabled when QLM SPD is 15. */ 119 if (qlm_cfg.s.qlm_spd == 15) 119 if (qlm_cfg.s.qlm_spd == 15) 120 return CVMX_HELPER_INT 120 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 121 121 122 if (qlm_cfg.s.qlm_cfg == 2) 122 if (qlm_cfg.s.qlm_cfg == 2) 123 return CVMX_HELPER_INT 123 return CVMX_HELPER_INTERFACE_MODE_SGMII; 124 else if (qlm_cfg.s.qlm_cfg == 124 else if (qlm_cfg.s.qlm_cfg == 3) 125 return CVMX_HELPER_INT 125 return CVMX_HELPER_INTERFACE_MODE_XAUI; 126 else 126 else 127 return CVMX_HELPER_INT 127 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 128 case 7: 128 case 7: 129 qlm_cfg.u64 = cvmx_read_csr(CV 129 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(3)); 130 /* QLM is disabled when QLM SP 130 /* QLM is disabled when QLM SPD is 15. */ 131 if (qlm_cfg.s.qlm_spd == 15) { 131 if (qlm_cfg.s.qlm_spd == 15) { 132 return CVMX_HELPER_INT 132 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 133 } else if (qlm_cfg.s.qlm_cfg ! 133 } else if (qlm_cfg.s.qlm_cfg != 0) { 134 qlm_cfg.u64 = cvmx_rea 134 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1)); 135 if (qlm_cfg.s.qlm_cfg 135 if (qlm_cfg.s.qlm_cfg != 0) 136 return CVMX_HE 136 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 137 } 137 } 138 return CVMX_HELPER_INTERFACE_M 138 return CVMX_HELPER_INTERFACE_MODE_NPI; 139 case 8: 139 case 8: 140 return CVMX_HELPER_INTERFACE_M 140 return CVMX_HELPER_INTERFACE_MODE_LOOP; 141 default: 141 default: 142 return CVMX_HELPER_INTERFACE_M 142 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 143 } 143 } 144 } 144 } 145 145 146 /** 146 /** 147 * @INTERNAL 147 * @INTERNAL 148 * Return interface mode for an Octeon II 148 * Return interface mode for an Octeon II 149 */ 149 */ 150 static cvmx_helper_interface_mode_t __cvmx_get 150 static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface) 151 { 151 { 152 union cvmx_gmxx_inf_mode mode; 152 union cvmx_gmxx_inf_mode mode; 153 153 154 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) 154 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) 155 return __cvmx_get_mode_cn68xx( 155 return __cvmx_get_mode_cn68xx(interface); 156 156 157 if (interface == 2) 157 if (interface == 2) 158 return CVMX_HELPER_INTERFACE_M 158 return CVMX_HELPER_INTERFACE_MODE_NPI; 159 159 160 if (interface == 3) 160 if (interface == 3) 161 return CVMX_HELPER_INTERFACE_M 161 return CVMX_HELPER_INTERFACE_MODE_LOOP; 162 162 163 /* Only present in CN63XX & CN66XX Oct 163 /* Only present in CN63XX & CN66XX Octeon model */ 164 if ((OCTEON_IS_MODEL(OCTEON_CN63XX) && 164 if ((OCTEON_IS_MODEL(OCTEON_CN63XX) && 165 (interface == 4 || interface == 5 165 (interface == 4 || interface == 5)) || 166 (OCTEON_IS_MODEL(OCTEON_CN66XX) && 166 (OCTEON_IS_MODEL(OCTEON_CN66XX) && 167 interface >= 4 && interface <= 7) 167 interface >= 4 && interface <= 7)) { 168 return CVMX_HELPER_INTERFACE_M 168 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 169 } 169 } 170 170 171 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) { 171 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) { 172 union cvmx_mio_qlmx_cfg mio_ql 172 union cvmx_mio_qlmx_cfg mio_qlm_cfg; 173 173 174 /* QLM2 is SGMII0 and QLM1 is 174 /* QLM2 is SGMII0 and QLM1 is SGMII1 */ 175 if (interface == 0) 175 if (interface == 0) 176 mio_qlm_cfg.u64 = cvmx 176 mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2)); 177 else if (interface == 1) 177 else if (interface == 1) 178 mio_qlm_cfg.u64 = cvmx 178 mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1)); 179 else 179 else 180 return CVMX_HELPER_INT 180 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 181 181 182 if (mio_qlm_cfg.s.qlm_spd == 1 182 if (mio_qlm_cfg.s.qlm_spd == 15) 183 return CVMX_HELPER_INT 183 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 184 184 185 if (mio_qlm_cfg.s.qlm_cfg == 9 185 if (mio_qlm_cfg.s.qlm_cfg == 9) 186 return CVMX_HELPER_INT 186 return CVMX_HELPER_INTERFACE_MODE_SGMII; 187 else if (mio_qlm_cfg.s.qlm_cfg 187 else if (mio_qlm_cfg.s.qlm_cfg == 11) 188 return CVMX_HELPER_INT 188 return CVMX_HELPER_INTERFACE_MODE_XAUI; 189 else 189 else 190 return CVMX_HELPER_INT 190 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 191 } else if (OCTEON_IS_MODEL(OCTEON_CN61 191 } else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) { 192 union cvmx_mio_qlmx_cfg qlm_cf 192 union cvmx_mio_qlmx_cfg qlm_cfg; 193 193 194 if (interface == 0) { 194 if (interface == 0) { 195 qlm_cfg.u64 = cvmx_rea 195 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2)); 196 if (qlm_cfg.s.qlm_cfg 196 if (qlm_cfg.s.qlm_cfg == 2) 197 return CVMX_HE 197 return CVMX_HELPER_INTERFACE_MODE_SGMII; 198 else if (qlm_cfg.s.qlm 198 else if (qlm_cfg.s.qlm_cfg == 3) 199 return CVMX_HE 199 return CVMX_HELPER_INTERFACE_MODE_XAUI; 200 else 200 else 201 return CVMX_HE 201 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 202 } else if (interface == 1) { 202 } else if (interface == 1) { 203 qlm_cfg.u64 = cvmx_rea 203 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0)); 204 if (qlm_cfg.s.qlm_cfg 204 if (qlm_cfg.s.qlm_cfg == 2) 205 return CVMX_HE 205 return CVMX_HELPER_INTERFACE_MODE_SGMII; 206 else if (qlm_cfg.s.qlm 206 else if (qlm_cfg.s.qlm_cfg == 3) 207 return CVMX_HE 207 return CVMX_HELPER_INTERFACE_MODE_XAUI; 208 else 208 else 209 return CVMX_HE 209 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 210 } 210 } 211 } else if (OCTEON_IS_MODEL(OCTEON_CNF7 211 } else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) { 212 if (interface == 0) { 212 if (interface == 0) { 213 union cvmx_mio_qlmx_cf 213 union cvmx_mio_qlmx_cfg qlm_cfg; 214 qlm_cfg.u64 = cvmx_rea 214 qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0)); 215 if (qlm_cfg.s.qlm_cfg 215 if (qlm_cfg.s.qlm_cfg == 2) 216 return CVMX_HE 216 return CVMX_HELPER_INTERFACE_MODE_SGMII; 217 } 217 } 218 return CVMX_HELPER_INTERFACE_M 218 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 219 } 219 } 220 220 221 if (interface == 1 && OCTEON_IS_MODEL( 221 if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX)) 222 return CVMX_HELPER_INTERFACE_M 222 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 223 223 224 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF 224 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); 225 225 226 if (OCTEON_IS_MODEL(OCTEON_CN63XX)) { 226 if (OCTEON_IS_MODEL(OCTEON_CN63XX)) { 227 switch (mode.cn61xx.mode) { 227 switch (mode.cn61xx.mode) { 228 case 0: 228 case 0: 229 return CVMX_HELPER_INT 229 return CVMX_HELPER_INTERFACE_MODE_SGMII; 230 case 1: 230 case 1: 231 return CVMX_HELPER_INT 231 return CVMX_HELPER_INTERFACE_MODE_XAUI; 232 default: 232 default: 233 return CVMX_HELPER_INT 233 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 234 } 234 } 235 } else { 235 } else { 236 if (!mode.s.en) 236 if (!mode.s.en) 237 return CVMX_HELPER_INT 237 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 238 238 239 if (mode.s.type) 239 if (mode.s.type) 240 return CVMX_HELPER_INT 240 return CVMX_HELPER_INTERFACE_MODE_GMII; 241 else 241 else 242 return CVMX_HELPER_INT 242 return CVMX_HELPER_INTERFACE_MODE_RGMII; 243 } 243 } 244 } 244 } 245 245 246 /** 246 /** 247 * @INTERNAL 247 * @INTERNAL 248 * Return interface mode for CN7XXX. 248 * Return interface mode for CN7XXX. 249 */ 249 */ 250 static cvmx_helper_interface_mode_t __cvmx_get 250 static cvmx_helper_interface_mode_t __cvmx_get_mode_cn7xxx(int interface) 251 { 251 { 252 union cvmx_gmxx_inf_mode mode; 252 union cvmx_gmxx_inf_mode mode; 253 253 254 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF 254 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); 255 255 256 switch (interface) { 256 switch (interface) { 257 case 0: 257 case 0: 258 case 1: 258 case 1: 259 switch (mode.cn68xx.mode) { 259 switch (mode.cn68xx.mode) { 260 case 0: 260 case 0: 261 return CVMX_HELPER_INT 261 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 262 case 1: 262 case 1: 263 case 2: 263 case 2: 264 return CVMX_HELPER_INT 264 return CVMX_HELPER_INTERFACE_MODE_SGMII; 265 case 3: 265 case 3: 266 return CVMX_HELPER_INT 266 return CVMX_HELPER_INTERFACE_MODE_XAUI; 267 default: 267 default: 268 return CVMX_HELPER_INT 268 return CVMX_HELPER_INTERFACE_MODE_SGMII; 269 } 269 } 270 case 2: 270 case 2: 271 return CVMX_HELPER_INTERFACE_M 271 return CVMX_HELPER_INTERFACE_MODE_NPI; 272 case 3: 272 case 3: 273 return CVMX_HELPER_INTERFACE_M 273 return CVMX_HELPER_INTERFACE_MODE_LOOP; 274 case 4: 274 case 4: 275 /* TODO: Implement support for 275 /* TODO: Implement support for AGL (RGMII). */ 276 return CVMX_HELPER_INTERFACE_M 276 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 277 default: 277 default: 278 return CVMX_HELPER_INTERFACE_M 278 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 279 } 279 } 280 } 280 } 281 281 282 /** 282 /** 283 * Get the operating mode of an interface. Dep 283 * Get the operating mode of an interface. Depending on the Octeon 284 * chip and configuration, this function retur 284 * chip and configuration, this function returns an enumeration 285 * of the type of packet I/O supported by an i 285 * of the type of packet I/O supported by an interface. 286 * 286 * 287 * @interface: Interface to probe 287 * @interface: Interface to probe 288 * 288 * 289 * Returns Mode of the interface. Unknown or u 289 * Returns Mode of the interface. Unknown or unsupported interfaces return 290 * DISABLED. 290 * DISABLED. 291 */ 291 */ 292 cvmx_helper_interface_mode_t cvmx_helper_inter 292 cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface) 293 { 293 { 294 union cvmx_gmxx_inf_mode mode; 294 union cvmx_gmxx_inf_mode mode; 295 295 296 if (interface < 0 || 296 if (interface < 0 || 297 interface >= cvmx_helper_get_numbe 297 interface >= cvmx_helper_get_number_of_interfaces()) 298 return CVMX_HELPER_INTERFACE_M 298 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 299 299 300 /* 300 /* 301 * OCTEON III models 301 * OCTEON III models 302 */ 302 */ 303 if (OCTEON_IS_MODEL(OCTEON_CN7XXX)) 303 if (OCTEON_IS_MODEL(OCTEON_CN7XXX)) 304 return __cvmx_get_mode_cn7xxx( 304 return __cvmx_get_mode_cn7xxx(interface); 305 305 306 /* 306 /* 307 * Octeon II models 307 * Octeon II models 308 */ 308 */ 309 if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || 309 if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX)) 310 return __cvmx_get_mode_octeon2 310 return __cvmx_get_mode_octeon2(interface); 311 311 312 /* 312 /* 313 * Octeon and Octeon Plus models 313 * Octeon and Octeon Plus models 314 */ 314 */ 315 if (interface == 2) 315 if (interface == 2) 316 return CVMX_HELPER_INTERFACE_M 316 return CVMX_HELPER_INTERFACE_MODE_NPI; 317 317 318 if (interface == 3) { 318 if (interface == 3) { 319 if (OCTEON_IS_MODEL(OCTEON_CN5 319 if (OCTEON_IS_MODEL(OCTEON_CN56XX) 320 || OCTEON_IS_MODEL(OCTEON_ 320 || OCTEON_IS_MODEL(OCTEON_CN52XX)) 321 return CVMX_HELPER_INT 321 return CVMX_HELPER_INTERFACE_MODE_LOOP; 322 else 322 else 323 return CVMX_HELPER_INT 323 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 324 } 324 } 325 325 326 /* Interface 1 is always disabled on C 326 /* Interface 1 is always disabled on CN31XX and CN30XX */ 327 if ((interface == 1) 327 if ((interface == 1) 328 && (OCTEON_IS_MODEL(OCTEON_CN31XX) 328 && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX) 329 || OCTEON_IS_MODEL(OCTEON_CN50 329 || OCTEON_IS_MODEL(OCTEON_CN50XX) 330 || OCTEON_IS_MODEL(OCTEON_CN52 330 || OCTEON_IS_MODEL(OCTEON_CN52XX))) 331 return CVMX_HELPER_INTERFACE_M 331 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 332 332 333 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF 333 mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); 334 334 335 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || 335 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) { 336 switch (mode.cn52xx.mode) { 336 switch (mode.cn52xx.mode) { 337 case 0: 337 case 0: 338 return CVMX_HELPER_INT 338 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 339 case 1: 339 case 1: 340 return CVMX_HELPER_INT 340 return CVMX_HELPER_INTERFACE_MODE_XAUI; 341 case 2: 341 case 2: 342 return CVMX_HELPER_INT 342 return CVMX_HELPER_INTERFACE_MODE_SGMII; 343 case 3: 343 case 3: 344 return CVMX_HELPER_INT 344 return CVMX_HELPER_INTERFACE_MODE_PICMG; 345 default: 345 default: 346 return CVMX_HELPER_INT 346 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 347 } 347 } 348 } else { 348 } else { 349 if (!mode.s.en) 349 if (!mode.s.en) 350 return CVMX_HELPER_INT 350 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 351 351 352 if (mode.s.type) { 352 if (mode.s.type) { 353 if (OCTEON_IS_MODEL(OC 353 if (OCTEON_IS_MODEL(OCTEON_CN38XX) 354 || OCTEON_IS_MODEL 354 || OCTEON_IS_MODEL(OCTEON_CN58XX)) 355 return CVMX_HE 355 return CVMX_HELPER_INTERFACE_MODE_SPI; 356 else 356 else 357 return CVMX_HE 357 return CVMX_HELPER_INTERFACE_MODE_GMII; 358 } else 358 } else 359 return CVMX_HELPER_INT 359 return CVMX_HELPER_INTERFACE_MODE_RGMII; 360 } 360 } 361 } 361 } 362 EXPORT_SYMBOL_GPL(cvmx_helper_interface_get_mo 362 EXPORT_SYMBOL_GPL(cvmx_helper_interface_get_mode); 363 363 364 /** 364 /** 365 * Configure the IPD/PIP tagging and QoS optio 365 * Configure the IPD/PIP tagging and QoS options for a specific 366 * port. This function determines the POW work 366 * port. This function determines the POW work queue entry 367 * contents for a port. The setup performed he 367 * contents for a port. The setup performed here is controlled by 368 * the defines in executive-config.h. 368 * the defines in executive-config.h. 369 * 369 * 370 * @ipd_port: Port to configure. This follows 370 * @ipd_port: Port to configure. This follows the IPD numbering, not the 371 * per interface numbering 371 * per interface numbering 372 * 372 * 373 * Returns Zero on success, negative on failur 373 * Returns Zero on success, negative on failure 374 */ 374 */ 375 static int __cvmx_helper_port_setup_ipd(int ip 375 static int __cvmx_helper_port_setup_ipd(int ipd_port) 376 { 376 { 377 union cvmx_pip_prt_cfgx port_config; 377 union cvmx_pip_prt_cfgx port_config; 378 union cvmx_pip_prt_tagx tag_config; 378 union cvmx_pip_prt_tagx tag_config; 379 379 380 port_config.u64 = cvmx_read_csr(CVMX_P 380 port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port)); 381 tag_config.u64 = cvmx_read_csr(CVMX_PI 381 tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port)); 382 382 383 /* Have each port go to a different PO 383 /* Have each port go to a different POW queue */ 384 port_config.s.qos = ipd_port & 0x7; 384 port_config.s.qos = ipd_port & 0x7; 385 385 386 /* Process the headers and place the I 386 /* Process the headers and place the IP header in the work queue */ 387 port_config.s.mode = CVMX_HELPER_INPUT 387 port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE; 388 388 389 tag_config.s.ip6_src_flag = CVMX_HELPE 389 tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP; 390 tag_config.s.ip6_dst_flag = CVMX_HELPE 390 tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP; 391 tag_config.s.ip6_sprt_flag = CVMX_HELP 391 tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT; 392 tag_config.s.ip6_dprt_flag = CVMX_HELP 392 tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT; 393 tag_config.s.ip6_nxth_flag = CVMX_HELP 393 tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER; 394 tag_config.s.ip4_src_flag = CVMX_HELPE 394 tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP; 395 tag_config.s.ip4_dst_flag = CVMX_HELPE 395 tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP; 396 tag_config.s.ip4_sprt_flag = CVMX_HELP 396 tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT; 397 tag_config.s.ip4_dprt_flag = CVMX_HELP 397 tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT; 398 tag_config.s.ip4_pctl_flag = CVMX_HELP 398 tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL; 399 tag_config.s.inc_prt_flag = CVMX_HELPE 399 tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT; 400 tag_config.s.tcp6_tag_type = CVMX_HELP 400 tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE; 401 tag_config.s.tcp4_tag_type = CVMX_HELP 401 tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE; 402 tag_config.s.ip6_tag_type = CVMX_HELPE 402 tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE; 403 tag_config.s.ip4_tag_type = CVMX_HELPE 403 tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE; 404 tag_config.s.non_tag_type = CVMX_HELPE 404 tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE; 405 /* Put all packets in group 0. Other g 405 /* Put all packets in group 0. Other groups can be used by the app */ 406 tag_config.s.grp = 0; 406 tag_config.s.grp = 0; 407 407 408 cvmx_pip_config_port(ipd_port, port_co 408 cvmx_pip_config_port(ipd_port, port_config, tag_config); 409 409 410 return 0; 410 return 0; 411 } 411 } 412 412 413 /** 413 /** 414 * This function sets the interface_port_count 414 * This function sets the interface_port_count[interface] correctly, 415 * without modifying any hardware configuratio 415 * without modifying any hardware configuration. Hardware setup of 416 * the ports will be performed later. 416 * the ports will be performed later. 417 * 417 * 418 * @interface: Interface to probe 418 * @interface: Interface to probe 419 * 419 * 420 * Returns Zero on success, negative on failur 420 * Returns Zero on success, negative on failure 421 */ 421 */ 422 int cvmx_helper_interface_enumerate(int interf 422 int cvmx_helper_interface_enumerate(int interface) 423 { 423 { 424 switch (cvmx_helper_interface_get_mode 424 switch (cvmx_helper_interface_get_mode(interface)) { 425 /* These types don't support p 425 /* These types don't support ports to IPD/PKO */ 426 case CVMX_HELPER_INTERFACE_MODE_DISABL 426 case CVMX_HELPER_INTERFACE_MODE_DISABLED: 427 case CVMX_HELPER_INTERFACE_MODE_PCIE: 427 case CVMX_HELPER_INTERFACE_MODE_PCIE: 428 interface_port_count[interface 428 interface_port_count[interface] = 0; 429 break; 429 break; 430 /* XAUI is a single high speed 430 /* XAUI is a single high speed port */ 431 case CVMX_HELPER_INTERFACE_MODE_XAUI: 431 case CVMX_HELPER_INTERFACE_MODE_XAUI: 432 interface_port_count[interface 432 interface_port_count[interface] = 433 __cvmx_helper_xaui_enumera 433 __cvmx_helper_xaui_enumerate(interface); 434 break; 434 break; 435 /* 435 /* 436 * RGMII/GMII/MII are all trea 436 * RGMII/GMII/MII are all treated about the same. Most 437 * functions refer to these po 437 * functions refer to these ports as RGMII. 438 */ 438 */ 439 case CVMX_HELPER_INTERFACE_MODE_RGMII: 439 case CVMX_HELPER_INTERFACE_MODE_RGMII: 440 case CVMX_HELPER_INTERFACE_MODE_GMII: 440 case CVMX_HELPER_INTERFACE_MODE_GMII: 441 interface_port_count[interface 441 interface_port_count[interface] = 442 __cvmx_helper_rgmii_enumer 442 __cvmx_helper_rgmii_enumerate(interface); 443 break; 443 break; 444 /* 444 /* 445 * SPI4 can have 1-16 ports de 445 * SPI4 can have 1-16 ports depending on the device at 446 * the other end. 446 * the other end. 447 */ 447 */ 448 case CVMX_HELPER_INTERFACE_MODE_SPI: 448 case CVMX_HELPER_INTERFACE_MODE_SPI: 449 interface_port_count[interface 449 interface_port_count[interface] = 450 __cvmx_helper_spi_enumerat 450 __cvmx_helper_spi_enumerate(interface); 451 break; 451 break; 452 /* 452 /* 453 * SGMII can have 1-4 ports de 453 * SGMII can have 1-4 ports depending on how many are 454 * hooked up. 454 * hooked up. 455 */ 455 */ 456 case CVMX_HELPER_INTERFACE_MODE_SGMII: 456 case CVMX_HELPER_INTERFACE_MODE_SGMII: 457 case CVMX_HELPER_INTERFACE_MODE_PICMG: 457 case CVMX_HELPER_INTERFACE_MODE_PICMG: 458 interface_port_count[interface 458 interface_port_count[interface] = 459 __cvmx_helper_sgmii_enumer 459 __cvmx_helper_sgmii_enumerate(interface); 460 break; 460 break; 461 /* PCI target Network Packet I 461 /* PCI target Network Packet Interface */ 462 case CVMX_HELPER_INTERFACE_MODE_NPI: 462 case CVMX_HELPER_INTERFACE_MODE_NPI: 463 interface_port_count[interface 463 interface_port_count[interface] = 464 __cvmx_helper_npi_enumerat 464 __cvmx_helper_npi_enumerate(interface); 465 break; 465 break; 466 /* 466 /* 467 * Special loopback only ports 467 * Special loopback only ports. These are not the same 468 * as other ports in loopback 468 * as other ports in loopback mode. 469 */ 469 */ 470 case CVMX_HELPER_INTERFACE_MODE_LOOP: 470 case CVMX_HELPER_INTERFACE_MODE_LOOP: 471 interface_port_count[interface 471 interface_port_count[interface] = 472 __cvmx_helper_loop_enumera 472 __cvmx_helper_loop_enumerate(interface); 473 break; 473 break; 474 } 474 } 475 475 476 interface_port_count[interface] = 476 interface_port_count[interface] = 477 __cvmx_helper_board_interface_prob 477 __cvmx_helper_board_interface_probe(interface, 478 478 interface_port_count 479 479 [interface]); 480 480 481 /* Make sure all global variables prop 481 /* Make sure all global variables propagate to other cores */ 482 CVMX_SYNCWS; 482 CVMX_SYNCWS; 483 483 484 return 0; 484 return 0; 485 } 485 } 486 486 487 /** 487 /** 488 * This function probes an interface to determ 488 * This function probes an interface to determine the actual 489 * number of hardware ports connected to it. I 489 * number of hardware ports connected to it. It doesn't setup the 490 * ports or enable them. The main goal here is 490 * ports or enable them. The main goal here is to set the global 491 * interface_port_count[interface] correctly. 491 * interface_port_count[interface] correctly. Hardware setup of the 492 * ports will be performed later. 492 * ports will be performed later. 493 * 493 * 494 * @interface: Interface to probe 494 * @interface: Interface to probe 495 * 495 * 496 * Returns Zero on success, negative on failur 496 * Returns Zero on success, negative on failure 497 */ 497 */ 498 int cvmx_helper_interface_probe(int interface) 498 int cvmx_helper_interface_probe(int interface) 499 { 499 { 500 cvmx_helper_interface_enumerate(interf 500 cvmx_helper_interface_enumerate(interface); 501 /* At this stage in the game we don't 501 /* At this stage in the game we don't want packets to be moving yet. 502 The following probe calls should pe 502 The following probe calls should perform hardware setup 503 needed to determine port counts. Re 503 needed to determine port counts. Receive must still be disabled */ 504 switch (cvmx_helper_interface_get_mode 504 switch (cvmx_helper_interface_get_mode(interface)) { 505 /* These types don't support p 505 /* These types don't support ports to IPD/PKO */ 506 case CVMX_HELPER_INTERFACE_MODE_DISABL 506 case CVMX_HELPER_INTERFACE_MODE_DISABLED: 507 case CVMX_HELPER_INTERFACE_MODE_PCIE: 507 case CVMX_HELPER_INTERFACE_MODE_PCIE: 508 break; 508 break; 509 /* XAUI is a single high speed 509 /* XAUI is a single high speed port */ 510 case CVMX_HELPER_INTERFACE_MODE_XAUI: 510 case CVMX_HELPER_INTERFACE_MODE_XAUI: 511 __cvmx_helper_xaui_probe(inter 511 __cvmx_helper_xaui_probe(interface); 512 break; 512 break; 513 /* 513 /* 514 * RGMII/GMII/MII are all trea 514 * RGMII/GMII/MII are all treated about the same. Most 515 * functions refer to these po 515 * functions refer to these ports as RGMII. 516 */ 516 */ 517 case CVMX_HELPER_INTERFACE_MODE_RGMII: 517 case CVMX_HELPER_INTERFACE_MODE_RGMII: 518 case CVMX_HELPER_INTERFACE_MODE_GMII: 518 case CVMX_HELPER_INTERFACE_MODE_GMII: 519 __cvmx_helper_rgmii_probe(inte 519 __cvmx_helper_rgmii_probe(interface); 520 break; 520 break; 521 /* 521 /* 522 * SPI4 can have 1-16 ports de 522 * SPI4 can have 1-16 ports depending on the device at 523 * the other end. 523 * the other end. 524 */ 524 */ 525 case CVMX_HELPER_INTERFACE_MODE_SPI: 525 case CVMX_HELPER_INTERFACE_MODE_SPI: 526 __cvmx_helper_spi_probe(interf 526 __cvmx_helper_spi_probe(interface); 527 break; 527 break; 528 /* 528 /* 529 * SGMII can have 1-4 ports de 529 * SGMII can have 1-4 ports depending on how many are 530 * hooked up. 530 * hooked up. 531 */ 531 */ 532 case CVMX_HELPER_INTERFACE_MODE_SGMII: 532 case CVMX_HELPER_INTERFACE_MODE_SGMII: 533 case CVMX_HELPER_INTERFACE_MODE_PICMG: 533 case CVMX_HELPER_INTERFACE_MODE_PICMG: 534 __cvmx_helper_sgmii_probe(inte 534 __cvmx_helper_sgmii_probe(interface); 535 break; 535 break; 536 /* PCI target Network Packet I 536 /* PCI target Network Packet Interface */ 537 case CVMX_HELPER_INTERFACE_MODE_NPI: 537 case CVMX_HELPER_INTERFACE_MODE_NPI: 538 __cvmx_helper_npi_probe(interf 538 __cvmx_helper_npi_probe(interface); 539 break; 539 break; 540 /* 540 /* 541 * Special loopback only ports 541 * Special loopback only ports. These are not the same 542 * as other ports in loopback 542 * as other ports in loopback mode. 543 */ 543 */ 544 case CVMX_HELPER_INTERFACE_MODE_LOOP: 544 case CVMX_HELPER_INTERFACE_MODE_LOOP: 545 __cvmx_helper_loop_probe(inter 545 __cvmx_helper_loop_probe(interface); 546 break; 546 break; 547 } 547 } 548 548 549 /* Make sure all global variables prop 549 /* Make sure all global variables propagate to other cores */ 550 CVMX_SYNCWS; 550 CVMX_SYNCWS; 551 551 552 return 0; 552 return 0; 553 } 553 } 554 554 555 /** 555 /** 556 * Setup the IPD/PIP for the ports on an inter 556 * Setup the IPD/PIP for the ports on an interface. Packet 557 * classification and tagging are set for ever 557 * classification and tagging are set for every port on the 558 * interface. The number of ports on the inter 558 * interface. The number of ports on the interface must already 559 * have been probed. 559 * have been probed. 560 * 560 * 561 * @interface: Interface to setup IPD/PIP for 561 * @interface: Interface to setup IPD/PIP for 562 * 562 * 563 * Returns Zero on success, negative on failur 563 * Returns Zero on success, negative on failure 564 */ 564 */ 565 static int __cvmx_helper_interface_setup_ipd(i 565 static int __cvmx_helper_interface_setup_ipd(int interface) 566 { 566 { 567 int ipd_port = cvmx_helper_get_ipd_por 567 int ipd_port = cvmx_helper_get_ipd_port(interface, 0); 568 int num_ports = interface_port_count[i 568 int num_ports = interface_port_count[interface]; 569 569 570 while (num_ports--) { 570 while (num_ports--) { 571 __cvmx_helper_port_setup_ipd(i 571 __cvmx_helper_port_setup_ipd(ipd_port); 572 ipd_port++; 572 ipd_port++; 573 } 573 } 574 return 0; 574 return 0; 575 } 575 } 576 576 577 /** 577 /** 578 * Setup global setting for IPD/PIP not relate 578 * Setup global setting for IPD/PIP not related to a specific 579 * interface or port. This must be called befo 579 * interface or port. This must be called before IPD is enabled. 580 * 580 * 581 * Returns Zero on success, negative on failur 581 * Returns Zero on success, negative on failure. 582 */ 582 */ 583 static int __cvmx_helper_global_setup_ipd(void 583 static int __cvmx_helper_global_setup_ipd(void) 584 { 584 { 585 /* Setup the global packet input optio 585 /* Setup the global packet input options */ 586 cvmx_ipd_config(CVMX_FPA_PACKET_POOL_S 586 cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE / 8, 587 CVMX_HELPER_FIRST_MBUF 587 CVMX_HELPER_FIRST_MBUFF_SKIP / 8, 588 CVMX_HELPER_NOT_FIRST_ 588 CVMX_HELPER_NOT_FIRST_MBUFF_SKIP / 8, 589 /* The +8 is to accoun 589 /* The +8 is to account for the next ptr */ 590 (CVMX_HELPER_FIRST_MBU 590 (CVMX_HELPER_FIRST_MBUFF_SKIP + 8) / 128, 591 /* The +8 is to accoun 591 /* The +8 is to account for the next ptr */ 592 (CVMX_HELPER_NOT_FIRST 592 (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP + 8) / 128, 593 CVMX_FPA_WQE_POOL, 593 CVMX_FPA_WQE_POOL, 594 CVMX_IPD_OPC_MODE_STT, 594 CVMX_IPD_OPC_MODE_STT, 595 CVMX_HELPER_ENABLE_BAC 595 CVMX_HELPER_ENABLE_BACK_PRESSURE); 596 return 0; 596 return 0; 597 } 597 } 598 598 599 /** 599 /** 600 * Setup the PKO for the ports on an interface 600 * Setup the PKO for the ports on an interface. The number of 601 * queues per port and the priority of each PK 601 * queues per port and the priority of each PKO output queue 602 * is set here. PKO must be disabled when this 602 * is set here. PKO must be disabled when this function is called. 603 * 603 * 604 * @interface: Interface to setup PKO for 604 * @interface: Interface to setup PKO for 605 * 605 * 606 * Returns Zero on success, negative on failur 606 * Returns Zero on success, negative on failure 607 */ 607 */ 608 static int __cvmx_helper_interface_setup_pko(i 608 static int __cvmx_helper_interface_setup_pko(int interface) 609 { 609 { 610 /* 610 /* 611 * Each packet output queue has an ass 611 * Each packet output queue has an associated priority. The 612 * higher the priority, the more often 612 * higher the priority, the more often it can send a packet. A 613 * priority of 8 means it can send in 613 * priority of 8 means it can send in all 8 rounds of 614 * contention. We're going to make eac 614 * contention. We're going to make each queue one less than 615 * the last. The vector of priorities 615 * the last. The vector of priorities has been extended to 616 * support CN5xxx CPUs, where up to 16 616 * support CN5xxx CPUs, where up to 16 queues can be 617 * associated to a port. To keep back 617 * associated to a port. To keep backward compatibility we 618 * don't change the initial 8 prioriti 618 * don't change the initial 8 priorities and replicate them in 619 * the second half. With per-core PKO 619 * the second half. With per-core PKO queues (PKO lockless 620 * operation) all queues have the same 620 * operation) all queues have the same priority. 621 */ 621 */ 622 uint64_t priorities[16] = 622 uint64_t priorities[16] = 623 { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 623 { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 }; 624 624 625 /* 625 /* 626 * Setup the IPD/PIP and PKO for the p 626 * Setup the IPD/PIP and PKO for the ports discovered 627 * above. Here packet classification, 627 * above. Here packet classification, tagging and output 628 * priorities are set. 628 * priorities are set. 629 */ 629 */ 630 int ipd_port = cvmx_helper_get_ipd_por 630 int ipd_port = cvmx_helper_get_ipd_port(interface, 0); 631 int num_ports = interface_port_count[i 631 int num_ports = interface_port_count[interface]; 632 while (num_ports--) { 632 while (num_ports--) { 633 cvmx_pko_config_port(ipd_port, 633 cvmx_pko_config_port(ipd_port, 634 cvmx_pko_ 634 cvmx_pko_get_base_queue_per_core(ipd_port, 635 635 0), 636 cvmx_pko_ 636 cvmx_pko_get_num_queues(ipd_port), 637 prioritie 637 priorities); 638 ipd_port++; 638 ipd_port++; 639 } 639 } 640 return 0; 640 return 0; 641 } 641 } 642 642 643 /** 643 /** 644 * Setup global setting for PKO not related to 644 * Setup global setting for PKO not related to a specific 645 * interface or port. This must be called befo 645 * interface or port. This must be called before PKO is enabled. 646 * 646 * 647 * Returns Zero on success, negative on failur 647 * Returns Zero on success, negative on failure. 648 */ 648 */ 649 static int __cvmx_helper_global_setup_pko(void 649 static int __cvmx_helper_global_setup_pko(void) 650 { 650 { 651 /* 651 /* 652 * Disable tagwait FAU timeout. This n 652 * Disable tagwait FAU timeout. This needs to be done before 653 * anyone might start packet output us 653 * anyone might start packet output using tags. 654 */ 654 */ 655 union cvmx_iob_fau_timeout fau_to; 655 union cvmx_iob_fau_timeout fau_to; 656 fau_to.u64 = 0; 656 fau_to.u64 = 0; 657 fau_to.s.tout_val = 0xfff; 657 fau_to.s.tout_val = 0xfff; 658 fau_to.s.tout_enb = 0; 658 fau_to.s.tout_enb = 0; 659 cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, f 659 cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64); 660 660 661 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { 661 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { 662 union cvmx_pko_reg_min_pkt min 662 union cvmx_pko_reg_min_pkt min_pkt; 663 663 664 min_pkt.u64 = 0; 664 min_pkt.u64 = 0; 665 min_pkt.s.size1 = 59; 665 min_pkt.s.size1 = 59; 666 min_pkt.s.size2 = 59; 666 min_pkt.s.size2 = 59; 667 min_pkt.s.size3 = 59; 667 min_pkt.s.size3 = 59; 668 min_pkt.s.size4 = 59; 668 min_pkt.s.size4 = 59; 669 min_pkt.s.size5 = 59; 669 min_pkt.s.size5 = 59; 670 min_pkt.s.size6 = 59; 670 min_pkt.s.size6 = 59; 671 min_pkt.s.size7 = 59; 671 min_pkt.s.size7 = 59; 672 cvmx_write_csr(CVMX_PKO_REG_MI 672 cvmx_write_csr(CVMX_PKO_REG_MIN_PKT, min_pkt.u64); 673 } 673 } 674 674 675 return 0; 675 return 0; 676 } 676 } 677 677 678 /** 678 /** 679 * Setup global backpressure setting. 679 * Setup global backpressure setting. 680 * 680 * 681 * Returns Zero on success, negative on failur 681 * Returns Zero on success, negative on failure 682 */ 682 */ 683 static int __cvmx_helper_global_setup_backpres 683 static int __cvmx_helper_global_setup_backpressure(void) 684 { 684 { 685 #if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE 685 #if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE 686 /* Disable backpressure if configured 686 /* Disable backpressure if configured to do so */ 687 /* Disable backpressure (pause frame) 687 /* Disable backpressure (pause frame) generation */ 688 int num_interfaces = cvmx_helper_get_n 688 int num_interfaces = cvmx_helper_get_number_of_interfaces(); 689 int interface; 689 int interface; 690 for (interface = 0; interface < num_in 690 for (interface = 0; interface < num_interfaces; interface++) { 691 switch (cvmx_helper_interface_ 691 switch (cvmx_helper_interface_get_mode(interface)) { 692 case CVMX_HELPER_INTERFACE_MOD 692 case CVMX_HELPER_INTERFACE_MODE_DISABLED: 693 case CVMX_HELPER_INTERFACE_MOD 693 case CVMX_HELPER_INTERFACE_MODE_PCIE: 694 case CVMX_HELPER_INTERFACE_MOD 694 case CVMX_HELPER_INTERFACE_MODE_NPI: 695 case CVMX_HELPER_INTERFACE_MOD 695 case CVMX_HELPER_INTERFACE_MODE_LOOP: 696 case CVMX_HELPER_INTERFACE_MOD 696 case CVMX_HELPER_INTERFACE_MODE_XAUI: 697 break; 697 break; 698 case CVMX_HELPER_INTERFACE_MOD 698 case CVMX_HELPER_INTERFACE_MODE_RGMII: 699 case CVMX_HELPER_INTERFACE_MOD 699 case CVMX_HELPER_INTERFACE_MODE_GMII: 700 case CVMX_HELPER_INTERFACE_MOD 700 case CVMX_HELPER_INTERFACE_MODE_SPI: 701 case CVMX_HELPER_INTERFACE_MOD 701 case CVMX_HELPER_INTERFACE_MODE_SGMII: 702 case CVMX_HELPER_INTERFACE_MOD 702 case CVMX_HELPER_INTERFACE_MODE_PICMG: 703 cvmx_gmx_set_backpress 703 cvmx_gmx_set_backpressure_override(interface, 0xf); 704 break; 704 break; 705 } 705 } 706 } 706 } 707 #endif 707 #endif 708 708 709 return 0; 709 return 0; 710 } 710 } 711 711 712 /** 712 /** 713 * Enable packet input/output from the hardwar 713 * Enable packet input/output from the hardware. This function is 714 * called after all internal setup is complete 714 * called after all internal setup is complete and IPD is enabled. 715 * After this function completes, packets will 715 * After this function completes, packets will be accepted from the 716 * hardware ports. PKO should still be disable 716 * hardware ports. PKO should still be disabled to make sure packets 717 * aren't sent out partially setup hardware. 717 * aren't sent out partially setup hardware. 718 * 718 * 719 * @interface: Interface to enable 719 * @interface: Interface to enable 720 * 720 * 721 * Returns Zero on success, negative on failur 721 * Returns Zero on success, negative on failure 722 */ 722 */ 723 static int __cvmx_helper_packet_hardware_enabl 723 static int __cvmx_helper_packet_hardware_enable(int interface) 724 { 724 { 725 int result = 0; 725 int result = 0; 726 switch (cvmx_helper_interface_get_mode 726 switch (cvmx_helper_interface_get_mode(interface)) { 727 /* These types don't support p 727 /* These types don't support ports to IPD/PKO */ 728 case CVMX_HELPER_INTERFACE_MODE_DISABL 728 case CVMX_HELPER_INTERFACE_MODE_DISABLED: 729 case CVMX_HELPER_INTERFACE_MODE_PCIE: 729 case CVMX_HELPER_INTERFACE_MODE_PCIE: 730 /* Nothing to do */ 730 /* Nothing to do */ 731 break; 731 break; 732 /* XAUI is a single high speed 732 /* XAUI is a single high speed port */ 733 case CVMX_HELPER_INTERFACE_MODE_XAUI: 733 case CVMX_HELPER_INTERFACE_MODE_XAUI: 734 result = __cvmx_helper_xaui_en 734 result = __cvmx_helper_xaui_enable(interface); 735 break; 735 break; 736 /* 736 /* 737 * RGMII/GMII/MII are all trea 737 * RGMII/GMII/MII are all treated about the same. Most 738 * functions refer to these po 738 * functions refer to these ports as RGMII 739 */ 739 */ 740 case CVMX_HELPER_INTERFACE_MODE_RGMII: 740 case CVMX_HELPER_INTERFACE_MODE_RGMII: 741 case CVMX_HELPER_INTERFACE_MODE_GMII: 741 case CVMX_HELPER_INTERFACE_MODE_GMII: 742 result = __cvmx_helper_rgmii_e 742 result = __cvmx_helper_rgmii_enable(interface); 743 break; 743 break; 744 /* 744 /* 745 * SPI4 can have 1-16 ports de 745 * SPI4 can have 1-16 ports depending on the device at 746 * the other end 746 * the other end 747 */ 747 */ 748 case CVMX_HELPER_INTERFACE_MODE_SPI: 748 case CVMX_HELPER_INTERFACE_MODE_SPI: 749 result = __cvmx_helper_spi_ena 749 result = __cvmx_helper_spi_enable(interface); 750 break; 750 break; 751 /* 751 /* 752 * SGMII can have 1-4 ports de 752 * SGMII can have 1-4 ports depending on how many are 753 * hooked up 753 * hooked up 754 */ 754 */ 755 case CVMX_HELPER_INTERFACE_MODE_SGMII: 755 case CVMX_HELPER_INTERFACE_MODE_SGMII: 756 case CVMX_HELPER_INTERFACE_MODE_PICMG: 756 case CVMX_HELPER_INTERFACE_MODE_PICMG: 757 result = __cvmx_helper_sgmii_e 757 result = __cvmx_helper_sgmii_enable(interface); 758 break; 758 break; 759 /* PCI target Network Packet I 759 /* PCI target Network Packet Interface */ 760 case CVMX_HELPER_INTERFACE_MODE_NPI: 760 case CVMX_HELPER_INTERFACE_MODE_NPI: 761 result = __cvmx_helper_npi_ena 761 result = __cvmx_helper_npi_enable(interface); 762 break; 762 break; 763 /* 763 /* 764 * Special loopback only ports 764 * Special loopback only ports. These are not the same 765 * as other ports in loopback 765 * as other ports in loopback mode 766 */ 766 */ 767 case CVMX_HELPER_INTERFACE_MODE_LOOP: 767 case CVMX_HELPER_INTERFACE_MODE_LOOP: 768 result = __cvmx_helper_loop_en 768 result = __cvmx_helper_loop_enable(interface); 769 break; 769 break; 770 } 770 } 771 return result; 771 return result; 772 } 772 } 773 773 774 /** 774 /** 775 * Function to adjust internal IPD pointer ali 775 * Function to adjust internal IPD pointer alignments 776 * 776 * 777 * Returns 0 on success 777 * Returns 0 on success 778 * !0 on failure 778 * !0 on failure 779 */ 779 */ 780 static int __cvmx_helper_errata_fix_ipd_ptr_al 780 static int __cvmx_helper_errata_fix_ipd_ptr_alignment(void) 781 { 781 { 782 #define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \ 782 #define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \ 783 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_ 783 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP) 784 #define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \ 784 #define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \ 785 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELP 785 (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_NOT_FIRST_MBUFF_SKIP) 786 #define FIX_IPD_OUTPORT 0 786 #define FIX_IPD_OUTPORT 0 787 /* Ports 0-15 are interface 0, 16-31 a 787 /* Ports 0-15 are interface 0, 16-31 are interface 1 */ 788 #define INTERFACE(port) (port >> 4) 788 #define INTERFACE(port) (port >> 4) 789 #define INDEX(port) (port & 0xf) 789 #define INDEX(port) (port & 0xf) 790 uint64_t *p64; 790 uint64_t *p64; 791 union cvmx_pko_command_word0 pko_comma 791 union cvmx_pko_command_word0 pko_command; 792 union cvmx_buf_ptr g_buffer, pkt_buffe 792 union cvmx_buf_ptr g_buffer, pkt_buffer; 793 struct cvmx_wqe *work; 793 struct cvmx_wqe *work; 794 int size, num_segs = 0, wqe_pcnt, pkt_ 794 int size, num_segs = 0, wqe_pcnt, pkt_pcnt; 795 union cvmx_gmxx_prtx_cfg gmx_cfg; 795 union cvmx_gmxx_prtx_cfg gmx_cfg; 796 int retry_cnt; 796 int retry_cnt; 797 int retry_loop_cnt; 797 int retry_loop_cnt; 798 int i; 798 int i; 799 799 800 /* Save values for restore at end */ 800 /* Save values for restore at end */ 801 uint64_t prtx_cfg = 801 uint64_t prtx_cfg = 802 cvmx_read_csr(CVMX_GMXX_PRTX_CFG 802 cvmx_read_csr(CVMX_GMXX_PRTX_CFG 803 (INDEX(FIX_IPD_OUTPO 803 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT))); 804 uint64_t tx_ptr_en = 804 uint64_t tx_ptr_en = 805 cvmx_read_csr(CVMX_ASXX_TX_PRT_EN( 805 cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT))); 806 uint64_t rx_ptr_en = 806 uint64_t rx_ptr_en = 807 cvmx_read_csr(CVMX_ASXX_RX_PRT_EN( 807 cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT))); 808 uint64_t rxx_jabber = 808 uint64_t rxx_jabber = 809 cvmx_read_csr(CVMX_GMXX_RXX_JABBER 809 cvmx_read_csr(CVMX_GMXX_RXX_JABBER 810 (INDEX(FIX_IPD_OUTPO 810 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT))); 811 uint64_t frame_max = 811 uint64_t frame_max = 812 cvmx_read_csr(CVMX_GMXX_RXX_FRM_MA 812 cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX 813 (INDEX(FIX_IPD_OUTPO 813 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT))); 814 814 815 /* Configure port to gig FDX as requir 815 /* Configure port to gig FDX as required for loopback mode */ 816 cvmx_helper_rgmii_internal_loopback(FI 816 cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT); 817 817 818 /* 818 /* 819 * Disable reception on all ports so i 819 * Disable reception on all ports so if traffic is present it 820 * will not interfere. 820 * will not interfere. 821 */ 821 */ 822 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INT 822 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0); 823 823 824 __delay(100000000ull); 824 __delay(100000000ull); 825 825 826 for (retry_loop_cnt = 0; retry_loop_cn 826 for (retry_loop_cnt = 0; retry_loop_cnt < 10; retry_loop_cnt++) { 827 retry_cnt = 100000; 827 retry_cnt = 100000; 828 wqe_pcnt = cvmx_read_csr(CVMX_ 828 wqe_pcnt = cvmx_read_csr(CVMX_IPD_PTR_COUNT); 829 pkt_pcnt = (wqe_pcnt >> 7) & 0 829 pkt_pcnt = (wqe_pcnt >> 7) & 0x7f; 830 wqe_pcnt &= 0x7f; 830 wqe_pcnt &= 0x7f; 831 831 832 num_segs = (2 + pkt_pcnt - wqe 832 num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3; 833 833 834 if (num_segs == 0) 834 if (num_segs == 0) 835 goto fix_ipd_exit; 835 goto fix_ipd_exit; 836 836 837 num_segs += 1; 837 num_segs += 1; 838 838 839 size = 839 size = 840 FIX_IPD_FIRST_BUFF_PAYLOAD 840 FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES + 841 ((num_segs - 1) * FIX_IPD_ 841 ((num_segs - 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES) - 842 (FIX_IPD_NON_FIRST_BUFF_PA 842 (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES / 2); 843 843 844 cvmx_write_csr(CVMX_ASXX_PRT_L 844 cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 845 1 << INDEX(FIX_ 845 1 << INDEX(FIX_IPD_OUTPORT)); 846 CVMX_SYNC; 846 CVMX_SYNC; 847 847 848 g_buffer.u64 = 0; 848 g_buffer.u64 = 0; 849 g_buffer.s.addr = 849 g_buffer.s.addr = 850 cvmx_ptr_to_phys(cvmx_fpa_ 850 cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL)); 851 if (g_buffer.s.addr == 0) { 851 if (g_buffer.s.addr == 0) { 852 cvmx_dprintf("WARNING: 852 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT " 853 "buffer a 853 "buffer allocation failure.\n"); 854 goto fix_ipd_exit; 854 goto fix_ipd_exit; 855 } 855 } 856 856 857 g_buffer.s.pool = CVMX_FPA_WQE 857 g_buffer.s.pool = CVMX_FPA_WQE_POOL; 858 g_buffer.s.size = num_segs; 858 g_buffer.s.size = num_segs; 859 859 860 pkt_buffer.u64 = 0; 860 pkt_buffer.u64 = 0; 861 pkt_buffer.s.addr = 861 pkt_buffer.s.addr = 862 cvmx_ptr_to_phys(cvmx_fpa_ 862 cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL)); 863 if (pkt_buffer.s.addr == 0) { 863 if (pkt_buffer.s.addr == 0) { 864 cvmx_dprintf("WARNING: 864 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT " 865 "buffer a 865 "buffer allocation failure.\n"); 866 goto fix_ipd_exit; 866 goto fix_ipd_exit; 867 } 867 } 868 pkt_buffer.s.i = 1; 868 pkt_buffer.s.i = 1; 869 pkt_buffer.s.pool = CVMX_FPA_P 869 pkt_buffer.s.pool = CVMX_FPA_PACKET_POOL; 870 pkt_buffer.s.size = FIX_IPD_FI 870 pkt_buffer.s.size = FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES; 871 871 872 p64 = (uint64_t *) cvmx_phys_t 872 p64 = (uint64_t *) cvmx_phys_to_ptr(pkt_buffer.s.addr); 873 p64[0] = 0xffffffffffff0000ull 873 p64[0] = 0xffffffffffff0000ull; 874 p64[1] = 0x08004510ull; 874 p64[1] = 0x08004510ull; 875 p64[2] = ((uint64_t) (size - 1 875 p64[2] = ((uint64_t) (size - 14) << 48) | 0x5ae740004000ull; 876 p64[3] = 0x3a5fc0a81073c0a8ull 876 p64[3] = 0x3a5fc0a81073c0a8ull; 877 877 878 for (i = 0; i < num_segs; i++) 878 for (i = 0; i < num_segs; i++) { 879 if (i > 0) 879 if (i > 0) 880 pkt_buffer.s.s 880 pkt_buffer.s.size = 881 FIX_IPD_NO 881 FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES; 882 882 883 if (i == (num_segs - 1 883 if (i == (num_segs - 1)) 884 pkt_buffer.s.i 884 pkt_buffer.s.i = 0; 885 885 886 *(uint64_t *) cvmx_phy 886 *(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr + 887 887 8 * i) = pkt_buffer.u64; 888 } 888 } 889 889 890 /* Build the PKO command */ 890 /* Build the PKO command */ 891 pko_command.u64 = 0; 891 pko_command.u64 = 0; 892 pko_command.s.segs = num_segs; 892 pko_command.s.segs = num_segs; 893 pko_command.s.total_bytes = si 893 pko_command.s.total_bytes = size; 894 pko_command.s.dontfree = 0; 894 pko_command.s.dontfree = 0; 895 pko_command.s.gather = 1; 895 pko_command.s.gather = 1; 896 896 897 gmx_cfg.u64 = 897 gmx_cfg.u64 = 898 cvmx_read_csr(CVMX_GMXX_PR 898 cvmx_read_csr(CVMX_GMXX_PRTX_CFG 899 (INDEX(FIX_I 899 (INDEX(FIX_IPD_OUTPORT), 900 INTERFACE(F 900 INTERFACE(FIX_IPD_OUTPORT))); 901 gmx_cfg.s.en = 1; 901 gmx_cfg.s.en = 1; 902 cvmx_write_csr(CVMX_GMXX_PRTX_ 902 cvmx_write_csr(CVMX_GMXX_PRTX_CFG 903 (INDEX(FIX_IPD_ 903 (INDEX(FIX_IPD_OUTPORT), 904 INTERFACE(FIX_ 904 INTERFACE(FIX_IPD_OUTPORT)), gmx_cfg.u64); 905 cvmx_write_csr(CVMX_ASXX_TX_PR 905 cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 906 1 << INDEX(FIX_ 906 1 << INDEX(FIX_IPD_OUTPORT)); 907 cvmx_write_csr(CVMX_ASXX_RX_PR 907 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 908 1 << INDEX(FIX_ 908 1 << INDEX(FIX_IPD_OUTPORT)); 909 909 910 cvmx_write_csr(CVMX_GMXX_RXX_J 910 cvmx_write_csr(CVMX_GMXX_RXX_JABBER 911 (INDEX(FIX_IPD_ 911 (INDEX(FIX_IPD_OUTPORT), 912 INTERFACE(FIX_ 912 INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4); 913 cvmx_write_csr(CVMX_GMXX_RXX_F 913 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX 914 (INDEX(FIX_IPD_ 914 (INDEX(FIX_IPD_OUTPORT), 915 INTERFACE(FIX_ 915 INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4); 916 916 917 cvmx_pko_send_packet_prepare(F 917 cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT, 918 c 918 cvmx_pko_get_base_queue 919 ( 919 (FIX_IPD_OUTPORT), 920 C 920 CVMX_PKO_LOCK_CMD_QUEUE); 921 cvmx_pko_send_packet_finish(FI 921 cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT, 922 cv 922 cvmx_pko_get_base_queue 923 (F 923 (FIX_IPD_OUTPORT), pko_command, 924 g_ 924 g_buffer, CVMX_PKO_LOCK_CMD_QUEUE); 925 925 926 CVMX_SYNC; 926 CVMX_SYNC; 927 927 928 do { 928 do { 929 work = cvmx_pow_work_r 929 work = cvmx_pow_work_request_sync(CVMX_POW_WAIT); 930 retry_cnt--; 930 retry_cnt--; 931 } while ((work == NULL) && (re 931 } while ((work == NULL) && (retry_cnt > 0)); 932 932 933 if (!retry_cnt) 933 if (!retry_cnt) 934 cvmx_dprintf("WARNING: 934 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT " 935 "get_work 935 "get_work() timeout occurred.\n"); 936 936 937 /* Free packet */ 937 /* Free packet */ 938 if (work) 938 if (work) 939 cvmx_helper_free_packe 939 cvmx_helper_free_packet_data(work); 940 } 940 } 941 941 942 fix_ipd_exit: 942 fix_ipd_exit: 943 943 944 /* Return CSR configs to saved values 944 /* Return CSR configs to saved values */ 945 cvmx_write_csr(CVMX_GMXX_PRTX_CFG 945 cvmx_write_csr(CVMX_GMXX_PRTX_CFG 946 (INDEX(FIX_IPD_OUTPORT) 946 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)), 947 prtx_cfg); 947 prtx_cfg); 948 cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INT 948 cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 949 tx_ptr_en); 949 tx_ptr_en); 950 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INT 950 cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 951 rx_ptr_en); 951 rx_ptr_en); 952 cvmx_write_csr(CVMX_GMXX_RXX_JABBER 952 cvmx_write_csr(CVMX_GMXX_RXX_JABBER 953 (INDEX(FIX_IPD_OUTPORT) 953 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)), 954 rxx_jabber); 954 rxx_jabber); 955 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX 955 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX 956 (INDEX(FIX_IPD_OUTPORT) 956 (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)), 957 frame_max); 957 frame_max); 958 cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTE 958 cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0); 959 959 960 CVMX_SYNC; 960 CVMX_SYNC; 961 if (num_segs) 961 if (num_segs) 962 cvmx_dprintf("WARNING: FIX_IPD 962 cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n"); 963 963 964 return !!num_segs; 964 return !!num_segs; 965 965 966 } 966 } 967 967 968 /** 968 /** 969 * Called after all internal packet IO paths a 969 * Called after all internal packet IO paths are setup. This 970 * function enables IPD/PIP and begins packet 970 * function enables IPD/PIP and begins packet input and output. 971 * 971 * 972 * Returns Zero on success, negative on failur 972 * Returns Zero on success, negative on failure 973 */ 973 */ 974 int cvmx_helper_ipd_and_packet_input_enable(vo 974 int cvmx_helper_ipd_and_packet_input_enable(void) 975 { 975 { 976 int num_interfaces; 976 int num_interfaces; 977 int interface; 977 int interface; 978 978 979 /* Enable IPD */ 979 /* Enable IPD */ 980 cvmx_ipd_enable(); 980 cvmx_ipd_enable(); 981 981 982 /* 982 /* 983 * Time to enable hardware ports packe 983 * Time to enable hardware ports packet input and output. Note 984 * that at this point IPD/PIP must be 984 * that at this point IPD/PIP must be fully functional and PKO 985 * must be disabled 985 * must be disabled 986 */ 986 */ 987 num_interfaces = cvmx_helper_get_numbe 987 num_interfaces = cvmx_helper_get_number_of_interfaces(); 988 for (interface = 0; interface < num_in 988 for (interface = 0; interface < num_interfaces; interface++) { 989 if (cvmx_helper_ports_on_inter 989 if (cvmx_helper_ports_on_interface(interface) > 0) 990 __cvmx_helper_packet_h 990 __cvmx_helper_packet_hardware_enable(interface); 991 } 991 } 992 992 993 /* Finally enable PKO now that the ent 993 /* Finally enable PKO now that the entire path is up and running */ 994 cvmx_pko_enable(); 994 cvmx_pko_enable(); 995 995 996 if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PAS 996 if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1) 997 || OCTEON_IS_MODEL(OCTEON_CN30XX_ 997 || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1)) 998 && (cvmx_sysinfo_get()->board_type 998 && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM)) 999 __cvmx_helper_errata_fix_ipd_p 999 __cvmx_helper_errata_fix_ipd_ptr_alignment(); 1000 return 0; 1000 return 0; 1001 } 1001 } 1002 EXPORT_SYMBOL_GPL(cvmx_helper_ipd_and_packet_ 1002 EXPORT_SYMBOL_GPL(cvmx_helper_ipd_and_packet_input_enable); 1003 1003 1004 /** 1004 /** 1005 * Initialize the PIP, IPD, and PKO hardware 1005 * Initialize the PIP, IPD, and PKO hardware to support 1006 * simple priority based queues for the ether 1006 * simple priority based queues for the ethernet ports. Each 1007 * port is configured with a number of priori 1007 * port is configured with a number of priority queues based 1008 * on CVMX_PKO_QUEUES_PER_PORT_* where each q 1008 * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower 1009 * priority than the previous. 1009 * priority than the previous. 1010 * 1010 * 1011 * Returns Zero on success, non-zero on failu 1011 * Returns Zero on success, non-zero on failure 1012 */ 1012 */ 1013 int cvmx_helper_initialize_packet_io_global(v 1013 int cvmx_helper_initialize_packet_io_global(void) 1014 { 1014 { 1015 int result = 0; 1015 int result = 0; 1016 int interface; 1016 int interface; 1017 union cvmx_l2c_cfg l2c_cfg; 1017 union cvmx_l2c_cfg l2c_cfg; 1018 const int num_interfaces = cvmx_helpe 1018 const int num_interfaces = cvmx_helper_get_number_of_interfaces(); 1019 1019 1020 /* 1020 /* 1021 * CN52XX pass 1: Due to a bug in 2nd 1021 * CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to 1022 * be disabled. 1022 * be disabled. 1023 */ 1023 */ 1024 if (OCTEON_IS_MODEL(OCTEON_CN52XX_PAS 1024 if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0)) 1025 __cvmx_helper_errata_qlm_disa 1025 __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1); 1026 1026 1027 /* 1027 /* 1028 * Tell L2 to give the IOB statically 1028 * Tell L2 to give the IOB statically higher priority compared 1029 * to the cores. This avoids conditio 1029 * to the cores. This avoids conditions where IO blocks might 1030 * be starved under very high L2 load 1030 * be starved under very high L2 loads. 1031 */ 1031 */ 1032 l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_ 1032 l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG); 1033 l2c_cfg.s.lrf_arb_mode = 0; 1033 l2c_cfg.s.lrf_arb_mode = 0; 1034 l2c_cfg.s.rfb_arb_mode = 0; 1034 l2c_cfg.s.rfb_arb_mode = 0; 1035 cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg. 1035 cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64); 1036 1036 1037 cvmx_pko_initialize_global(); 1037 cvmx_pko_initialize_global(); 1038 for (interface = 0; interface < num_i 1038 for (interface = 0; interface < num_interfaces; interface++) { 1039 result |= cvmx_helper_interfa 1039 result |= cvmx_helper_interface_probe(interface); 1040 if (cvmx_helper_ports_on_inte 1040 if (cvmx_helper_ports_on_interface(interface) > 0) 1041 cvmx_dprintf("Interfa 1041 cvmx_dprintf("Interface %d has %d ports (%s)\n", 1042 interfac 1042 interface, 1043 cvmx_hel 1043 cvmx_helper_ports_on_interface(interface), 1044 cvmx_hel 1044 cvmx_helper_interface_mode_to_string 1045 (cvmx_he 1045 (cvmx_helper_interface_get_mode 1046 (interf 1046 (interface))); 1047 result |= __cvmx_helper_inter 1047 result |= __cvmx_helper_interface_setup_ipd(interface); 1048 result |= __cvmx_helper_inter 1048 result |= __cvmx_helper_interface_setup_pko(interface); 1049 } 1049 } 1050 1050 1051 result |= __cvmx_helper_global_setup_ 1051 result |= __cvmx_helper_global_setup_ipd(); 1052 result |= __cvmx_helper_global_setup_ 1052 result |= __cvmx_helper_global_setup_pko(); 1053 1053 1054 /* Enable any flow control and backpr 1054 /* Enable any flow control and backpressure */ 1055 result |= __cvmx_helper_global_setup_ 1055 result |= __cvmx_helper_global_setup_backpressure(); 1056 1056 1057 #if CVMX_HELPER_ENABLE_IPD 1057 #if CVMX_HELPER_ENABLE_IPD 1058 result |= cvmx_helper_ipd_and_packet_ 1058 result |= cvmx_helper_ipd_and_packet_input_enable(); 1059 #endif 1059 #endif 1060 return result; 1060 return result; 1061 } 1061 } 1062 EXPORT_SYMBOL_GPL(cvmx_helper_initialize_pack 1062 EXPORT_SYMBOL_GPL(cvmx_helper_initialize_packet_io_global); 1063 1063 1064 /** 1064 /** 1065 * Return the link state of an IPD/PKO port a 1065 * Return the link state of an IPD/PKO port as returned by 1066 * auto negotiation. The result of this funct 1066 * auto negotiation. The result of this function may not match 1067 * Octeon's link config if auto negotiation h 1067 * Octeon's link config if auto negotiation has changed since 1068 * the last call to cvmx_helper_link_set(). 1068 * the last call to cvmx_helper_link_set(). 1069 * 1069 * 1070 * @ipd_port: IPD/PKO port to query 1070 * @ipd_port: IPD/PKO port to query 1071 * 1071 * 1072 * Returns Link state 1072 * Returns Link state 1073 */ 1073 */ 1074 union cvmx_helper_link_info cvmx_helper_link_ 1074 union cvmx_helper_link_info cvmx_helper_link_get(int ipd_port) 1075 { 1075 { 1076 union cvmx_helper_link_info result; 1076 union cvmx_helper_link_info result; 1077 int interface = cvmx_helper_get_inter 1077 int interface = cvmx_helper_get_interface_num(ipd_port); 1078 int index = cvmx_helper_get_interface 1078 int index = cvmx_helper_get_interface_index_num(ipd_port); 1079 1079 1080 /* The default result will be a down 1080 /* The default result will be a down link unless the code below 1081 changes it */ 1081 changes it */ 1082 result.u64 = 0; 1082 result.u64 = 0; 1083 1083 1084 if (index >= cvmx_helper_ports_on_int 1084 if (index >= cvmx_helper_ports_on_interface(interface)) 1085 return result; 1085 return result; 1086 1086 1087 switch (cvmx_helper_interface_get_mod 1087 switch (cvmx_helper_interface_get_mode(interface)) { 1088 case CVMX_HELPER_INTERFACE_MODE_DISAB 1088 case CVMX_HELPER_INTERFACE_MODE_DISABLED: 1089 case CVMX_HELPER_INTERFACE_MODE_PCIE: 1089 case CVMX_HELPER_INTERFACE_MODE_PCIE: 1090 /* Network links are not supp 1090 /* Network links are not supported */ 1091 break; 1091 break; 1092 case CVMX_HELPER_INTERFACE_MODE_XAUI: 1092 case CVMX_HELPER_INTERFACE_MODE_XAUI: 1093 result = __cvmx_helper_xaui_l 1093 result = __cvmx_helper_xaui_link_get(ipd_port); 1094 break; 1094 break; 1095 case CVMX_HELPER_INTERFACE_MODE_GMII: 1095 case CVMX_HELPER_INTERFACE_MODE_GMII: 1096 if (index == 0) 1096 if (index == 0) 1097 result = __cvmx_helpe 1097 result = __cvmx_helper_rgmii_link_get(ipd_port); 1098 else { 1098 else { 1099 WARN_ONCE(1, "Using d 1099 WARN_ONCE(1, "Using deprecated link status - please update your DT"); 1100 result.s.full_duplex 1100 result.s.full_duplex = 1; 1101 result.s.link_up = 1; 1101 result.s.link_up = 1; 1102 result.s.speed = 1000 1102 result.s.speed = 1000; 1103 } 1103 } 1104 break; 1104 break; 1105 case CVMX_HELPER_INTERFACE_MODE_RGMII 1105 case CVMX_HELPER_INTERFACE_MODE_RGMII: 1106 result = __cvmx_helper_rgmii_ 1106 result = __cvmx_helper_rgmii_link_get(ipd_port); 1107 break; 1107 break; 1108 case CVMX_HELPER_INTERFACE_MODE_SPI: 1108 case CVMX_HELPER_INTERFACE_MODE_SPI: 1109 result = __cvmx_helper_spi_li 1109 result = __cvmx_helper_spi_link_get(ipd_port); 1110 break; 1110 break; 1111 case CVMX_HELPER_INTERFACE_MODE_SGMII 1111 case CVMX_HELPER_INTERFACE_MODE_SGMII: 1112 case CVMX_HELPER_INTERFACE_MODE_PICMG 1112 case CVMX_HELPER_INTERFACE_MODE_PICMG: 1113 result = __cvmx_helper_sgmii_ 1113 result = __cvmx_helper_sgmii_link_get(ipd_port); 1114 break; 1114 break; 1115 case CVMX_HELPER_INTERFACE_MODE_NPI: 1115 case CVMX_HELPER_INTERFACE_MODE_NPI: 1116 case CVMX_HELPER_INTERFACE_MODE_LOOP: 1116 case CVMX_HELPER_INTERFACE_MODE_LOOP: 1117 /* Network links are not supp 1117 /* Network links are not supported */ 1118 break; 1118 break; 1119 } 1119 } 1120 return result; 1120 return result; 1121 } 1121 } 1122 EXPORT_SYMBOL_GPL(cvmx_helper_link_get); 1122 EXPORT_SYMBOL_GPL(cvmx_helper_link_get); 1123 1123 1124 /** 1124 /** 1125 * Configure an IPD/PKO port for the specifie 1125 * Configure an IPD/PKO port for the specified link state. This 1126 * function does not influence auto negotiati 1126 * function does not influence auto negotiation at the PHY level. 1127 * The passed link state must always match th 1127 * The passed link state must always match the link state returned 1128 * by cvmx_helper_link_get(). 1128 * by cvmx_helper_link_get(). 1129 * 1129 * 1130 * @ipd_port: IPD/PKO port to configure 1130 * @ipd_port: IPD/PKO port to configure 1131 * @link_info: The new link state 1131 * @link_info: The new link state 1132 * 1132 * 1133 * Returns Zero on success, negative on failu 1133 * Returns Zero on success, negative on failure 1134 */ 1134 */ 1135 int cvmx_helper_link_set(int ipd_port, union 1135 int cvmx_helper_link_set(int ipd_port, union cvmx_helper_link_info link_info) 1136 { 1136 { 1137 int result = -1; 1137 int result = -1; 1138 int interface = cvmx_helper_get_inter 1138 int interface = cvmx_helper_get_interface_num(ipd_port); 1139 int index = cvmx_helper_get_interface 1139 int index = cvmx_helper_get_interface_index_num(ipd_port); 1140 1140 1141 if (index >= cvmx_helper_ports_on_int 1141 if (index >= cvmx_helper_ports_on_interface(interface)) 1142 return -1; 1142 return -1; 1143 1143 1144 switch (cvmx_helper_interface_get_mod 1144 switch (cvmx_helper_interface_get_mode(interface)) { 1145 case CVMX_HELPER_INTERFACE_MODE_DISAB 1145 case CVMX_HELPER_INTERFACE_MODE_DISABLED: 1146 case CVMX_HELPER_INTERFACE_MODE_PCIE: 1146 case CVMX_HELPER_INTERFACE_MODE_PCIE: 1147 break; 1147 break; 1148 case CVMX_HELPER_INTERFACE_MODE_XAUI: 1148 case CVMX_HELPER_INTERFACE_MODE_XAUI: 1149 result = __cvmx_helper_xaui_l 1149 result = __cvmx_helper_xaui_link_set(ipd_port, link_info); 1150 break; 1150 break; 1151 /* 1151 /* 1152 * RGMII/GMII/MII are all tre 1152 * RGMII/GMII/MII are all treated about the same. Most 1153 * functions refer to these p 1153 * functions refer to these ports as RGMII. 1154 */ 1154 */ 1155 case CVMX_HELPER_INTERFACE_MODE_RGMII 1155 case CVMX_HELPER_INTERFACE_MODE_RGMII: 1156 case CVMX_HELPER_INTERFACE_MODE_GMII: 1156 case CVMX_HELPER_INTERFACE_MODE_GMII: 1157 result = __cvmx_helper_rgmii_ 1157 result = __cvmx_helper_rgmii_link_set(ipd_port, link_info); 1158 break; 1158 break; 1159 case CVMX_HELPER_INTERFACE_MODE_SPI: 1159 case CVMX_HELPER_INTERFACE_MODE_SPI: 1160 result = __cvmx_helper_spi_li 1160 result = __cvmx_helper_spi_link_set(ipd_port, link_info); 1161 break; 1161 break; 1162 case CVMX_HELPER_INTERFACE_MODE_SGMII 1162 case CVMX_HELPER_INTERFACE_MODE_SGMII: 1163 case CVMX_HELPER_INTERFACE_MODE_PICMG 1163 case CVMX_HELPER_INTERFACE_MODE_PICMG: 1164 result = __cvmx_helper_sgmii_ 1164 result = __cvmx_helper_sgmii_link_set(ipd_port, link_info); 1165 break; 1165 break; 1166 case CVMX_HELPER_INTERFACE_MODE_NPI: 1166 case CVMX_HELPER_INTERFACE_MODE_NPI: 1167 case CVMX_HELPER_INTERFACE_MODE_LOOP: 1167 case CVMX_HELPER_INTERFACE_MODE_LOOP: 1168 break; 1168 break; 1169 } 1169 } 1170 return result; 1170 return result; 1171 } 1171 } 1172 EXPORT_SYMBOL_GPL(cvmx_helper_link_set); 1172 EXPORT_SYMBOL_GPL(cvmx_helper_link_set); 1173 1173
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.