diff options
Diffstat (limited to 'arch/mips/cavium-octeon/executive/cvmx-helper.c')
| -rw-r--r-- | arch/mips/cavium-octeon/executive/cvmx-helper.c | 176 |
1 files changed, 175 insertions, 1 deletions
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c index d63d20dfbfb..7e5cf7a5e2f 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c @@ -67,7 +67,7 @@ void (*cvmx_override_pko_queue_priority) (int pko_port, void (*cvmx_override_ipd_port_setup) (int ipd_port); /* Port count per interface */ -static int interface_port_count[4] = { 0, 0, 0, 0 }; +static int interface_port_count[5]; /* Port last configured link info index by IPD/PKO port */ static cvmx_helper_link_info_t @@ -88,6 +88,7 @@ int cvmx_helper_get_number_of_interfaces(void) else return 3; } +EXPORT_SYMBOL_GPL(cvmx_helper_get_number_of_interfaces); /** * Return the number of ports on an interface. Depending on the @@ -102,6 +103,159 @@ int cvmx_helper_ports_on_interface(int interface) { return interface_port_count[interface]; } +EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface); + +/** + * @INTERNAL + * Return interface mode for CN68xx. + */ +static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface) +{ + union cvmx_mio_qlmx_cfg qlm_cfg; + switch (interface) { + case 0: + qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0)); + /* QLM is disabled when QLM SPD is 15. */ + if (qlm_cfg.s.qlm_spd == 15) + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + + if (qlm_cfg.s.qlm_cfg == 2) + return CVMX_HELPER_INTERFACE_MODE_SGMII; + else if (qlm_cfg.s.qlm_cfg == 3) + return CVMX_HELPER_INTERFACE_MODE_XAUI; + else + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + case 2: + case 3: + case 4: + qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(interface)); + /* QLM is disabled when QLM SPD is 15. */ + if (qlm_cfg.s.qlm_spd == 15) + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + + if (qlm_cfg.s.qlm_cfg == 2) + return CVMX_HELPER_INTERFACE_MODE_SGMII; + else if (qlm_cfg.s.qlm_cfg == 3) + return CVMX_HELPER_INTERFACE_MODE_XAUI; + else + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + case 7: + qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(3)); + /* QLM is disabled when QLM SPD is 15. */ + if (qlm_cfg.s.qlm_spd == 15) { + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + } else if (qlm_cfg.s.qlm_cfg != 0) { + qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1)); + if (qlm_cfg.s.qlm_cfg != 0) + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + } + return CVMX_HELPER_INTERFACE_MODE_NPI; + case 8: + return CVMX_HELPER_INTERFACE_MODE_LOOP; + default: + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + } +} + +/** + * @INTERNAL + * Return interface mode for an Octeon II + */ +static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface) +{ + union cvmx_gmxx_inf_mode mode; + + if (OCTEON_IS_MODEL(OCTEON_CN68XX)) + return __cvmx_get_mode_cn68xx(interface); + + if (interface == 2) + return CVMX_HELPER_INTERFACE_MODE_NPI; + + if (interface == 3) + return CVMX_HELPER_INTERFACE_MODE_LOOP; + + /* Only present in CN63XX & CN66XX Octeon model */ + if ((OCTEON_IS_MODEL(OCTEON_CN63XX) && + (interface == 4 || interface == 5)) || + (OCTEON_IS_MODEL(OCTEON_CN66XX) && + interface >= 4 && interface <= 7)) { + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + } + + if (OCTEON_IS_MODEL(OCTEON_CN66XX)) { + union cvmx_mio_qlmx_cfg mio_qlm_cfg; + + /* QLM2 is SGMII0 and QLM1 is SGMII1 */ + if (interface == 0) + mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2)); + else if (interface == 1) + mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1)); + else + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + + if (mio_qlm_cfg.s.qlm_spd == 15) + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + + if (mio_qlm_cfg.s.qlm_cfg == 9) + return CVMX_HELPER_INTERFACE_MODE_SGMII; + else if (mio_qlm_cfg.s.qlm_cfg == 11) + return CVMX_HELPER_INTERFACE_MODE_XAUI; + else + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + } else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) { + union cvmx_mio_qlmx_cfg qlm_cfg; + + if (interface == 0) { + qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2)); + if (qlm_cfg.s.qlm_cfg == 2) + return CVMX_HELPER_INTERFACE_MODE_SGMII; + else if (qlm_cfg.s.qlm_cfg == 3) + return CVMX_HELPER_INTERFACE_MODE_XAUI; + else + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + } else if (interface == 1) { + qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0)); + if (qlm_cfg.s.qlm_cfg == 2) + return CVMX_HELPER_INTERFACE_MODE_SGMII; + else if (qlm_cfg.s.qlm_cfg == 3) + return CVMX_HELPER_INTERFACE_MODE_XAUI; + else + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + } + } else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) { + if (interface == 0) { + union cvmx_mio_qlmx_cfg qlm_cfg; + qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0)); + if (qlm_cfg.s.qlm_cfg == 2) + return CVMX_HELPER_INTERFACE_MODE_SGMII; + } + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + } + + if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX)) + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); + + if (OCTEON_IS_MODEL(OCTEON_CN63XX)) { + switch (mode.cn63xx.mode) { + case 0: + return CVMX_HELPER_INTERFACE_MODE_SGMII; + case 1: + return CVMX_HELPER_INTERFACE_MODE_XAUI; + default: + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + } + } else { + if (!mode.s.en) + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + + if (mode.s.type) + return CVMX_HELPER_INTERFACE_MODE_GMII; + else + return CVMX_HELPER_INTERFACE_MODE_RGMII; + } +} /** * Get the operating mode of an interface. Depending on the Octeon @@ -116,6 +270,20 @@ int cvmx_helper_ports_on_interface(int interface) cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface) { union cvmx_gmxx_inf_mode mode; + + if (interface < 0 || + interface >= cvmx_helper_get_number_of_interfaces()) + return CVMX_HELPER_INTERFACE_MODE_DISABLED; + + /* + * Octeon II models + */ + if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX)) + return __cvmx_get_mode_octeon2(interface); + + /* + * Octeon and Octeon Plus models + */ if (interface == 2) return CVMX_HELPER_INTERFACE_MODE_NPI; @@ -179,6 +347,7 @@ cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface) return CVMX_HELPER_INTERFACE_MODE_RGMII; } } +EXPORT_SYMBOL_GPL(cvmx_helper_interface_get_mode); /** * Configure the IPD/PIP tagging and QoS options for a specific @@ -825,6 +994,7 @@ int cvmx_helper_ipd_and_packet_input_enable(void) __cvmx_helper_errata_fix_ipd_ptr_alignment(); return 0; } +EXPORT_SYMBOL_GPL(cvmx_helper_ipd_and_packet_input_enable); /** * Initialize the PIP, IPD, and PKO hardware to support @@ -903,6 +1073,7 @@ int cvmx_helper_initialize_packet_io_global(void) #endif return result; } +EXPORT_SYMBOL_GPL(cvmx_helper_initialize_packet_io_global); /** * Does core local initialization for packet io @@ -947,6 +1118,7 @@ cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port) */ return port_link_info[ipd_port]; } +EXPORT_SYMBOL_GPL(cvmx_helper_link_autoconf); /** * Return the link state of an IPD/PKO port as returned by @@ -1005,6 +1177,7 @@ cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port) } return result; } +EXPORT_SYMBOL_GPL(cvmx_helper_link_get); /** * Configure an IPD/PKO port for the specified link state. This @@ -1060,6 +1233,7 @@ int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info) port_link_info[ipd_port].u64 = link_info.u64; return result; } +EXPORT_SYMBOL_GPL(cvmx_helper_link_set); /** * Configure a port for internal and/or external loopback. Internal loopback |
