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