From 7b0ec8a5dba7da95294237d327815ca3f730e363 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 10 Jul 2014 19:28:37 +0000 Subject: [PATCH] octeon: backport a few upstream fixes Signed-off-by: Felix Fietkau SVN-Revision: 41568 --- ...cteon-fix-out-of-bounds-array-access.patch | 28 +++ ...on-fix-early-boot-hang-on-EBH5600-bo.patch | 42 ++++ ...interface-mode-detection-for-Octeon-.patch | 202 ++++++++++++++++++ ...twsi-interrupt-initialization-for-OC.patch | 47 ++++ 4 files changed, 319 insertions(+) create mode 100644 target/linux/octeon/patches-3.10/0008-MIPS-cavium-octeon-fix-out-of-bounds-array-access.patch create mode 100644 target/linux/octeon/patches-3.10/0009-MIPS-cavium-octeon-fix-early-boot-hang-on-EBH5600-bo.patch create mode 100644 target/linux/octeon/patches-3.10/0010-MIPS-octeon-Add-interface-mode-detection-for-Octeon-.patch create mode 100644 target/linux/octeon/patches-3.10/0011-MIPS-Octeon-Add-twsi-interrupt-initialization-for-OC.patch diff --git a/target/linux/octeon/patches-3.10/0008-MIPS-cavium-octeon-fix-out-of-bounds-array-access.patch b/target/linux/octeon/patches-3.10/0008-MIPS-cavium-octeon-fix-out-of-bounds-array-access.patch new file mode 100644 index 0000000000..78194bf261 --- /dev/null +++ b/target/linux/octeon/patches-3.10/0008-MIPS-cavium-octeon-fix-out-of-bounds-array-access.patch @@ -0,0 +1,28 @@ +From 8b75e77048a378339ada86eff548a5b253212859 Mon Sep 17 00:00:00 2001 +From: Aaro Koskinen +Date: Fri, 1 Nov 2013 17:06:03 +0200 +Subject: [PATCH] MIPS: cavium-octeon: fix out-of-bounds array access + +When booting with in-kernel DTBs, the pruning code will enumerate +interfaces 0-4. However, there is memory reserved only for 4 so some +other data will get overwritten by cvmx_helper_interface_enumerate(). + +Signed-off-by: Aaro Koskinen +Acked-by: David Daney +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/6102/ +--- + arch/mips/cavium-octeon/executive/cvmx-helper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- 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) + 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 diff --git a/target/linux/octeon/patches-3.10/0009-MIPS-cavium-octeon-fix-early-boot-hang-on-EBH5600-bo.patch b/target/linux/octeon/patches-3.10/0009-MIPS-cavium-octeon-fix-early-boot-hang-on-EBH5600-bo.patch new file mode 100644 index 0000000000..6cbbe348a0 --- /dev/null +++ b/target/linux/octeon/patches-3.10/0009-MIPS-cavium-octeon-fix-early-boot-hang-on-EBH5600-bo.patch @@ -0,0 +1,42 @@ +From b2e4f1560f7388f8157dd2c828211abbfad0e806 Mon Sep 17 00:00:00 2001 +From: Aaro Koskinen +Date: Fri, 1 Nov 2013 17:06:04 +0200 +Subject: [PATCH] MIPS: cavium-octeon: fix early boot hang on EBH5600 board + +The boot hangs early on EBH5600 board when octeon_fdt_pip_iface() is +trying enumerate a non-existant interface. The actual hang happens in +cvmx_helper_interface_get_mode(): + + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); + +when interface == 4. We can avoid this situation by first checking that +the interface exists in the DTB. + +Signed-off-by: Aaro Koskinen +Acked-by: David Daney +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/6101/ +--- + arch/mips/cavium-octeon/octeon-platform.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/mips/cavium-octeon/octeon-platform.c ++++ b/arch/mips/cavium-octeon/octeon-platform.c +@@ -336,14 +336,14 @@ static void __init octeon_fdt_pip_iface( + int p; + int count = 0; + +- if (cvmx_helper_interface_enumerate(idx) == 0) +- count = cvmx_helper_ports_on_interface(idx); +- + snprintf(name_buffer, sizeof(name_buffer), "interface@%d", idx); + iface = fdt_subnode_offset(initial_boot_params, pip, name_buffer); + if (iface < 0) + return; + ++ if (cvmx_helper_interface_enumerate(idx) == 0) ++ count = cvmx_helper_ports_on_interface(idx); ++ + for (p = 0; p < 16; p++) + octeon_fdt_pip_port(iface, idx, p, count - 1, pmac); + } diff --git a/target/linux/octeon/patches-3.10/0010-MIPS-octeon-Add-interface-mode-detection-for-Octeon-.patch b/target/linux/octeon/patches-3.10/0010-MIPS-octeon-Add-interface-mode-detection-for-Octeon-.patch new file mode 100644 index 0000000000..2002dd1d76 --- /dev/null +++ b/target/linux/octeon/patches-3.10/0010-MIPS-octeon-Add-interface-mode-detection-for-Octeon-.patch @@ -0,0 +1,202 @@ +From d8ce75934b888df0bd73dfd9c030a2b034a04977 Mon Sep 17 00:00:00 2001 +From: Alex Smith +Date: Thu, 29 May 2014 11:10:01 +0100 +Subject: [PATCH] MIPS: octeon: Add interface mode detection for Octeon II + +Add interface mode detection for Octeon II. This is necessary to detect +the interface modes correctly on the UBNT E200 board. Code is taken +from the UBNT GPL source release, with some alterations: SRIO, ILK and +RXAUI interface modes are removed and instead return disabled as these +modes are not currently supported. + +Signed-off-by: Alex Smith +Tested-by: David Daney +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/7039/ +Signed-off-by: Ralf Baechle +--- + arch/mips/cavium-octeon/executive/cvmx-helper.c | 166 ++++++++++++++++++++++++ + 1 file changed, 166 insertions(+) + +--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c ++++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c +@@ -104,6 +104,158 @@ int cvmx_helper_ports_on_interface(int i + } + + /** ++ * @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 + * chip and configuration, this function returns an enumeration + * of the type of packet I/O supported by an interface. +@@ -116,6 +268,20 @@ int cvmx_helper_ports_on_interface(int i + 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; + diff --git a/target/linux/octeon/patches-3.10/0011-MIPS-Octeon-Add-twsi-interrupt-initialization-for-OC.patch b/target/linux/octeon/patches-3.10/0011-MIPS-Octeon-Add-twsi-interrupt-initialization-for-OC.patch new file mode 100644 index 0000000000..382410f239 --- /dev/null +++ b/target/linux/octeon/patches-3.10/0011-MIPS-Octeon-Add-twsi-interrupt-initialization-for-OC.patch @@ -0,0 +1,47 @@ +From a53825ef4e9b2f42a21ad2b903f4d0ce691a5d63 Mon Sep 17 00:00:00 2001 +From: Eunbong Song +Date: Tue, 22 Apr 2014 06:16:15 +0000 +Subject: [PATCH] MIPS: Octeon: Add twsi interrupt initialization for OCTEON + 3XXX, 5XXX, 63XX + +In octeon_3xxx.dts file, there is a definiton for twsi/twsi2 interrupts. +But there is no code for initialization of this interrupts. This patch adds +code for initialization of twsi interrupts. + +Signed-off-by: Eunbong Song +Cc: linux-kernel@vger.kernel.org +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/6816/ +Signed-off-by: Ralf Baechle +--- + arch/mips/cavium-octeon/octeon-irq.c | 2 ++ + arch/mips/include/asm/mach-cavium-octeon/irq.h | 2 ++ + 2 files changed, 4 insertions(+) + +--- a/arch/mips/cavium-octeon/octeon-irq.c ++++ b/arch/mips/cavium-octeon/octeon-irq.c +@@ -1260,11 +1260,13 @@ static void __init octeon_irq_init_ciu(v + for (i = 0; i < 4; i++) + octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_MSI0, 0, i + 40); + ++ octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_TWSI, 0, 45); + octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_RML, 0, 46); + for (i = 0; i < 4; i++) + octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 0, i + 52); + + octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 0, 56); ++ octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_TWSI2, 0, 59); + + /* CIU_1 */ + for (i = 0; i < 16; i++) +--- a/arch/mips/include/asm/mach-cavium-octeon/irq.h ++++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h +@@ -35,6 +35,8 @@ enum octeon_irq { + OCTEON_IRQ_PCI_MSI2, + OCTEON_IRQ_PCI_MSI3, + ++ OCTEON_IRQ_TWSI, ++ OCTEON_IRQ_TWSI2, + OCTEON_IRQ_RML, + OCTEON_IRQ_TIMER0, + OCTEON_IRQ_TIMER1,